summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2001-08-09 07:21:56 +0000
committerMartin v. Löwis <martin@v.loewis.de>2001-08-09 07:21:56 +0000
commit8cc965c1fb7da494c5abfb3eef49f017dcdc9939 (patch)
tree51d8b26474351a7bbfdf2a7e3e4e18a5e9e36998 /Lib
parentf30f1fc900d214f11d351daa9ae88013f16cd039 (diff)
downloadcpython-git-8cc965c1fb7da494c5abfb3eef49f017dcdc9939.tar.gz
Patch #448474: Add support for tell() and seek() to gzip.GzipFile.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/gzip.py36
-rw-r--r--Lib/test/test_gzip.py24
2 files changed, 58 insertions, 2 deletions
diff --git a/Lib/gzip.py b/Lib/gzip.py
index 79ca2050d2..9df8e5d180 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -64,6 +64,7 @@ class GzipFile:
raise ValueError, "Mode " + mode + " not supported"
self.fileobj = fileobj
+ self.offset = 0
if self.mode == WRITE:
self._write_gzip_header()
@@ -138,6 +139,7 @@ class GzipFile:
self.size = self.size + len(data)
self.crc = zlib.crc32(data, self.crc)
self.fileobj.write( self.compress.compress(data) )
+ self.offset += len(data)
def writelines(self,lines):
self.write(" ".join(lines))
@@ -167,11 +169,13 @@ class GzipFile:
self.extrabuf = self.extrabuf[size:]
self.extrasize = self.extrasize - size
+ self.offset += size
return chunk
def _unread(self, buf):
self.extrabuf = buf + self.extrabuf
self.extrasize = len(buf) + self.extrasize
+ self.offset -= len(buf)
def _read(self, size=1024):
if self.fileobj is None: raise EOFError, "Reached EOF"
@@ -185,7 +189,6 @@ class GzipFile:
pos = self.fileobj.tell() # Save current position
self.fileobj.seek(0, 2) # Seek to end of file
if pos == self.fileobj.tell():
- self.fileobj = None
raise EOFError, "Reached EOF"
else:
self.fileobj.seek( pos ) # Return to original position
@@ -204,7 +207,6 @@ class GzipFile:
if buf == "":
uncompress = self.decompress.flush()
self._read_eof()
- self.fileobj = None
self._add_read_data( uncompress )
raise EOFError, 'Reached EOF'
@@ -270,6 +272,36 @@ class GzipFile:
def isatty(self):
return 0
+ def tell(self):
+ return self.offset
+
+ def rewind(self):
+ '''Return the uncompressed stream file position indicator to the
+ beginning of the file'''
+ if self.mode != READ:
+ raise IOError("Can't rewind in write mode")
+ self.fileobj.seek(0)
+ self._new_member = 1
+ self.extrabuf = ""
+ self.extrasize = 0
+ self.offset = 0
+
+ def seek(self, offset):
+ if self.mode == WRITE:
+ if offset < self.offset:
+ raise IOError('Negative seek in write mode')
+ count = offset - self.offset
+ for i in range(count/1024):
+ f.write(1024*'\0')
+ self.write((count%1024)*'\0')
+ elif self.mode == READ:
+ if offset < self.offset:
+ # for negative seek, rewind and do positive seek
+ self.rewind()
+ count = offset - self.offset
+ for i in range(count/1024): self.read(1024)
+ self.read(count % 1024)
+
def readline(self, size=-1):
if size < 0: size = sys.maxint
bufs = []
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index 8ff8c337e7..6d69c3f281 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -50,5 +50,29 @@ while 1:
if L == []: break
f.close()
+# Try seek, read test
+
+f = gzip.GzipFile(filename)
+while 1:
+ oldpos = f.tell()
+ line1 = f.readline()
+ if not line1: break
+ newpos = f.tell()
+ f.seek(oldpos) # negative seek
+ if len(line1)>10:
+ amount = 10
+ else:
+ amount = len(line1)
+ line2 = f.read(amount)
+ verify(line1[:amount] == line2)
+ f.seek(newpos) # positive seek
+f.close()
+
+# Try seek, write test
+f = gzip.GzipFile(filename, 'w')
+for pos in range(0, 256, 16):
+ f.seek(pos)
+ f.write('GZ\n')
+f.close()
os.unlink(filename)