X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2Fxstreams.pas;h=c34f2e820989016fe9ec6e0f02fa6b690f9fde02;hb=a2e634cf318657af3a04f3c0a5caba4c158ac965;hp=abf8bec0e731e8e5da1f2c12f12241acb862a033;hpb=0254d3a7db2238dbb2f4f376ba5fd5559becd161;p=d2df-sdl.git diff --git a/src/shared/xstreams.pas b/src/shared/xstreams.pas index abf8bec..c34f2e8 100644 --- a/src/shared/xstreams.pas +++ b/src/shared/xstreams.pas @@ -1,5 +1,5 @@ // special stream classes -{$MODE OBJFPC} +{$MODE DELPHI} {$R+} unit xstreams; @@ -301,9 +301,10 @@ begin fSize := aSize; GetMem(fBuffer, ZBufSize); fSkipHeader := aSkipHeader; + fSrcStPos := fSrcSt.position; + FillChar(fZlibSt, sizeof(fZlibSt), 0); if fSkipHeader then err := inflateInit2(fZlibSt, -MAX_WBITS) else err := inflateInit(fZlibSt); if err <> Z_OK then raise XStreamError.Create(zerror(err)); - fSrcStPos := fSrcSt.position; end; @@ -319,29 +320,31 @@ end; function TUnZStream.readBuf (var buffer; count: LongInt): LongInt; var err: Integer; - lastavail: LongInt; + sz: LongInt; begin - fZlibSt.next_out := @buffer; - fZlibSt.avail_out := count; - lastavail := count; - while fZlibSt.avail_out <> 0 do + result := 0; + if (fSize >= 0) and (fPos >= fSize) then exit; + if count > 0 then begin - if fZlibSt.avail_in = 0 then + fZlibSt.next_out := @buffer; + fZlibSt.avail_out := count; + sz := fZlibSt.avail_out; + while fZlibSt.avail_out > 0 do begin - // refill the buffer - fZlibSt.next_in := fBuffer; - fZlibSt.avail_in := fSrcSt.read(Fbuffer^, ZBufSize); - //Inc(compressed_read, fZlibSt.avail_in); - Inc(fPos, lastavail-fZlibSt.avail_out); - lastavail := fZlibSt.avail_out; + if fZlibSt.avail_in = 0 then + begin + // refill the buffer + fZlibSt.next_in := fBuffer; + fZlibSt.avail_in := fSrcSt.read(Fbuffer^, ZBufSize); + end; + err := inflate(fZlibSt, Z_NO_FLUSH); + if (err <> Z_OK) and (err <> Z_STREAM_END) then raise XStreamError.Create(zerror(err)); + Inc(result, sz-fZlibSt.avail_out); + Inc(fPos, sz-fZlibSt.avail_out); + sz := fZlibSt.avail_out; + if err = Z_STREAM_END then begin fSize := fPos; break; end; end; - err := inflate(fZlibSt, Z_NO_FLUSH); - if err = Z_STREAM_END then fSize := fPos; break; - if err <> Z_OK then raise XStreamError.Create(zerror(err)); end; - //if err = Z_STREAM_END then Dec(compressed_read, fZlibSt.avail_in); - Inc(fPos, lastavail-fZlibSt.avail_out); - result := count-fZlibSt.avail_out; end; @@ -359,7 +362,7 @@ begin //writeln(' reading ', rd, ' bytes...'); rr := readBuf(buf, rd); //writeln(' got ', rr, ' bytes; fPos=', fPos, '; fSkipToPos=', fSkipToPos); - if rd <> rr then raise XStreamError.Create('seek error'); + if rr <= 0 then raise XStreamError.Create('seek error'); end; //writeln(' pos: fPos=', fPos, '; fSkipToPos=', fSkipToPos); fSkipToPos := -1; @@ -379,12 +382,12 @@ begin while true do begin rd := readBuf(buf, 4096); - if rd <> 4096 then break; + if rd = 0 then break; end; fSize := fPos; //writeln(' unzstream size is ', fSize); finally - fSkipToPos := opos; + if fSkipToPos < 0 then fSkipToPos := opos; end; end; @@ -407,9 +410,11 @@ procedure TUnZStream.reset (); var err: Integer; begin + //writeln('doing RESET'); fSrcSt.position := fSrcStPos; fPos := 0; inflateEnd(fZlibSt); + FillChar(fZlibSt, sizeof(fZlibSt), 0); if fSkipHeader then err := inflateInit2(fZlibSt, -MAX_WBITS) else err := inflateInit(fZlibSt); if err <> Z_OK then raise XStreamError.Create(zerror(err)); end;