mirror of https://github.com/python/cpython
Patch #448474: Add support for tell() and seek() to gzip.GzipFile.
This commit is contained in:
parent
f30f1fc900
commit
8cc965c1fb
|
@ -21,8 +21,8 @@ The module defines the following items:
|
||||||
\begin{classdesc}{GzipFile}{\optional{filename\optional{, mode\optional{,
|
\begin{classdesc}{GzipFile}{\optional{filename\optional{, mode\optional{,
|
||||||
compresslevel\optional{, fileobj}}}}}
|
compresslevel\optional{, fileobj}}}}}
|
||||||
Constructor for the \class{GzipFile} class, which simulates most of
|
Constructor for the \class{GzipFile} class, which simulates most of
|
||||||
the methods of a file object, with the exception of the
|
the methods of a file object, with the exception of the \method{readinto()},
|
||||||
\method{seek()} and \method{tell()} methods. At least one of
|
\method{truncate()}, and \method{xreadlines()} methods. At least one of
|
||||||
\var{fileobj} and \var{filename} must be given a non-trivial value.
|
\var{fileobj} and \var{filename} must be given a non-trivial value.
|
||||||
|
|
||||||
The new class instance is based on \var{fileobj}, which can be a
|
The new class instance is based on \var{fileobj}, which can be a
|
||||||
|
|
36
Lib/gzip.py
36
Lib/gzip.py
|
@ -64,6 +64,7 @@ class GzipFile:
|
||||||
raise ValueError, "Mode " + mode + " not supported"
|
raise ValueError, "Mode " + mode + " not supported"
|
||||||
|
|
||||||
self.fileobj = fileobj
|
self.fileobj = fileobj
|
||||||
|
self.offset = 0
|
||||||
|
|
||||||
if self.mode == WRITE:
|
if self.mode == WRITE:
|
||||||
self._write_gzip_header()
|
self._write_gzip_header()
|
||||||
|
@ -138,6 +139,7 @@ class GzipFile:
|
||||||
self.size = self.size + len(data)
|
self.size = self.size + len(data)
|
||||||
self.crc = zlib.crc32(data, self.crc)
|
self.crc = zlib.crc32(data, self.crc)
|
||||||
self.fileobj.write( self.compress.compress(data) )
|
self.fileobj.write( self.compress.compress(data) )
|
||||||
|
self.offset += len(data)
|
||||||
|
|
||||||
def writelines(self,lines):
|
def writelines(self,lines):
|
||||||
self.write(" ".join(lines))
|
self.write(" ".join(lines))
|
||||||
|
@ -167,11 +169,13 @@ class GzipFile:
|
||||||
self.extrabuf = self.extrabuf[size:]
|
self.extrabuf = self.extrabuf[size:]
|
||||||
self.extrasize = self.extrasize - size
|
self.extrasize = self.extrasize - size
|
||||||
|
|
||||||
|
self.offset += size
|
||||||
return chunk
|
return chunk
|
||||||
|
|
||||||
def _unread(self, buf):
|
def _unread(self, buf):
|
||||||
self.extrabuf = buf + self.extrabuf
|
self.extrabuf = buf + self.extrabuf
|
||||||
self.extrasize = len(buf) + self.extrasize
|
self.extrasize = len(buf) + self.extrasize
|
||||||
|
self.offset -= len(buf)
|
||||||
|
|
||||||
def _read(self, size=1024):
|
def _read(self, size=1024):
|
||||||
if self.fileobj is None: raise EOFError, "Reached EOF"
|
if self.fileobj is None: raise EOFError, "Reached EOF"
|
||||||
|
@ -185,7 +189,6 @@ class GzipFile:
|
||||||
pos = self.fileobj.tell() # Save current position
|
pos = self.fileobj.tell() # Save current position
|
||||||
self.fileobj.seek(0, 2) # Seek to end of file
|
self.fileobj.seek(0, 2) # Seek to end of file
|
||||||
if pos == self.fileobj.tell():
|
if pos == self.fileobj.tell():
|
||||||
self.fileobj = None
|
|
||||||
raise EOFError, "Reached EOF"
|
raise EOFError, "Reached EOF"
|
||||||
else:
|
else:
|
||||||
self.fileobj.seek( pos ) # Return to original position
|
self.fileobj.seek( pos ) # Return to original position
|
||||||
|
@ -204,7 +207,6 @@ class GzipFile:
|
||||||
if buf == "":
|
if buf == "":
|
||||||
uncompress = self.decompress.flush()
|
uncompress = self.decompress.flush()
|
||||||
self._read_eof()
|
self._read_eof()
|
||||||
self.fileobj = None
|
|
||||||
self._add_read_data( uncompress )
|
self._add_read_data( uncompress )
|
||||||
raise EOFError, 'Reached EOF'
|
raise EOFError, 'Reached EOF'
|
||||||
|
|
||||||
|
@ -270,6 +272,36 @@ class GzipFile:
|
||||||
def isatty(self):
|
def isatty(self):
|
||||||
return 0
|
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):
|
def readline(self, size=-1):
|
||||||
if size < 0: size = sys.maxint
|
if size < 0: size = sys.maxint
|
||||||
bufs = []
|
bufs = []
|
||||||
|
|
|
@ -50,5 +50,29 @@ while 1:
|
||||||
if L == []: break
|
if L == []: break
|
||||||
f.close()
|
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)
|
os.unlink(filename)
|
||||||
|
|
Loading…
Reference in New Issue