فهرست منبع

* try to emulate backwards seek. Patch from p_daniel (bug ID 30428)

git-svn-id: trunk@34477 -
michael 9 سال پیش
والد
کامیت
abc33b81cc
3فایلهای تغییر یافته به همراه81 افزوده شده و 25 حذف شده
  1. 1 0
      .gitattributes
  2. 22 25
      packages/paszlib/src/zstream.pp
  3. 58 0
      packages/paszlib/tests/tczstreamseek.pp

+ 1 - 0
.gitattributes

@@ -6663,6 +6663,7 @@ packages/paszlib/src/ziputils.pas svneol=native#text/plain
 packages/paszlib/src/zstream.pp svneol=native#text/plain
 packages/paszlib/src/zuncompr.pas svneol=native#text/plain
 packages/paszlib/tests/tczipper.pp svneol=native#text/plain
+packages/paszlib/tests/tczstreamseek.pp svneol=native#text/plain
 packages/pcap/Makefile svneol=native#text/plain
 packages/pcap/Makefile.fpc svneol=native#text/plain
 packages/pcap/Makefile.fpc.fpcmake svneol=native#text/plain

+ 22 - 25
packages/paszlib/src/zstream.pp

@@ -324,7 +324,7 @@ begin
     raise Edecompressionerror.create(zerror(err));
 end;
 
-function Tdecompressionstream.GetPosition() : Int64; 
+function Tdecompressionstream.GetPosition() : Int64;
 begin
   GetPosition := raw_read;
 end;
@@ -335,31 +335,28 @@ var c,off: int64;
 
 begin
   off:=Offset;
-  if (origin=soBeginning) or  ((origin=soCurrent) and (off+raw_read>=0)) then
-    begin
-      if origin = soCurrent then
-        seek := raw_read + off
-      else
-        seek := off;
-        
-      if origin=soBeginning then
-        dec(off,raw_read);
-      if offset<0 then
-        begin
-          inc(off,raw_read);
-          reset;
-        end;
-      while off>0 do
-        begin
-          c:=off;
-          if c>bufsize then
-            c:=bufsize;
-          c:=read(Fbuffer^,c);
-          dec(off,c);
-        end;
-    end
-  else
+
+  if origin=soCurrent then
+    inc(off,raw_read);
+  if (origin=soEnd) or (off<0) then
     raise Edecompressionerror.create(Sseek_failed);
+
+  seek:=off;
+
+  if off<raw_read then
+    reset
+  else
+    dec(off,raw_read);
+
+  while off>0 do
+    begin
+      c:=off;
+      if c>bufsize then
+        c:=bufsize;
+      if read(Fbuffer^,c)<>c then
+        raise Edecompressionerror.create(Sseek_failed);
+      dec(off,c);
+    end;
 end;
 
 function Tdecompressionstream.get_compressionrate:single;

+ 58 - 0
packages/paszlib/tests/tczstreamseek.pp

@@ -0,0 +1,58 @@
+program tczstreamseek;
+{$MODE OBJFPC}
+{$ASSERTIONS ON}
+
+uses
+  classes,
+  zstream;
+
+const
+  val: Uint32 = $123456;
+  wasError: boolean = False;
+var
+  data: TMemoryStream;
+  comprStream: TCompressionStream;
+  decomprStream: TDecompressionStream;
+begin
+  data := TMemoryStream.Create();
+
+  comprStream := TCompressionStream.Create(clMax, data);
+  comprStream.WriteDWord(val);
+  comprStream.Free;
+
+  data.Seek(0, soFromBeginning);
+
+  decomprStream := TDecompressionStream.Create(data);
+  Assert(decomprStream.ReadDWord() = val);
+  Assert(decomprStream.Position = SizeOf(val));
+
+  decomprStream.Seek(0, soFromBeginning);
+  Assert(decomprStream.Position = 0);
+  Assert(decomprStream.ReadDWord() = val);
+
+  decomprStream.Seek(-SizeOf(val), soFromCurrent);
+  Assert(decomprStream.Position = 0);
+  Assert(decomprStream.ReadDWord() = val);
+
+  wasError := False;
+  decomprStream.Seek(0, soFromBeginning);
+  try
+    decomprStream.Seek(-SizeOf(val), soFromCurrent);
+  except
+    on EDecompressionError do
+      wasError := True;
+  end;
+  assert(wasError);
+
+  decomprStream.Seek(SizeOf(val), soFromBeginning);
+  Assert(decomprStream.Position = SizeOf(val));
+
+  wasError := False;
+  try
+    decomprStream.Seek(40, soFromBeginning);
+  except
+    on EDecompressionError do
+      wasError := True;
+  end;
+  assert(wasError);
+end.