X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2Fxstreams.pas;h=270d292e88bc80464d699d34951672e4bfa1b4e4;hb=2e947b5f49a88b13f489320be6129a85f097b9b2;hp=5e026e19e6ef9b196087a62e7d5f59d762fd654a;hpb=ac201b02f10ef558087d50f6b03b4519ab567558;p=d2df-sdl.git diff --git a/src/shared/xstreams.pas b/src/shared/xstreams.pas index 5e026e1..270d292 100644 --- a/src/shared/xstreams.pas +++ b/src/shared/xstreams.pas @@ -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 rd <= 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;