Kaydet (Commit) 68de3797 authored tarafından Guido van Rossum's avatar Guido van Rossum

Add the option to pass an open file object to GzipFile. This obviates

the need for the StringIO subclass.
üst 6576dd6a
...@@ -2,6 +2,7 @@ import time ...@@ -2,6 +2,7 @@ import time
import string import string
import zlib import zlib
import StringIO import StringIO
import __builtin__
# implements a python function that reads and writes a gzipped file # implements a python function that reads and writes a gzipped file
# the user of the file doesn't have to worry about the compression, # the user of the file doesn't have to worry about the compression,
...@@ -38,23 +39,31 @@ def read32(input): ...@@ -38,23 +39,31 @@ def read32(input):
v = v + (ord(buf[3]) << 24) v = v + (ord(buf[3]) << 24)
return v return v
written = [] def open(filename, mode="r", compresslevel=9):
_py_open = open
def open(filename, mode, compresslevel=9):
return GzipFile(filename, mode, compresslevel) return GzipFile(filename, mode, compresslevel)
class GzipFile: class GzipFile:
def __init__(self, filename, mode='r', compresslevel=9): myfileobj = None
if mode == 'r' or mode == 'rb':
def __init__(self, filename=None, mode=None,
compresslevel=9, fileobj=None):
if fileobj is None:
fileobj = self.myfileobj = __builtin__.open(filename, mode or 'r')
if filename is None:
if hasattr(fileobj, 'name'): filename = fileobj.name
else: filename = 'GzippedFile'
if mode is None:
if hasattr(fileobj, 'mode'): mode = fileobj.mode
else: mode = 'r'
if mode[0:1] == 'r':
self.mode = READ self.mode = READ
self._init_read() self._init_read()
self.filename = filename self.filename = filename
self.decompress = zlib.decompressobj(-zlib.MAX_WBITS) self.decompress = zlib.decompressobj(-zlib.MAX_WBITS)
elif mode == 'w' or mode == 'wb': elif mode[0:1] == 'w':
self.mode = WRITE self.mode = WRITE
self._init_write(filename) self._init_write(filename)
self.compress = zlib.compressobj(compresslevel, self.compress = zlib.compressobj(compresslevel,
...@@ -65,7 +74,7 @@ class GzipFile: ...@@ -65,7 +74,7 @@ class GzipFile:
else: else:
raise ValueError, "Mode " + mode + " not supported" raise ValueError, "Mode " + mode + " not supported"
self.fileobj = _py_open(self.filename,mode) self.fileobj = fileobj
if self.mode == WRITE: if self.mode == WRITE:
self._write_gzip_header() self._write_gzip_header()
...@@ -134,6 +143,8 @@ class GzipFile: ...@@ -134,6 +143,8 @@ class GzipFile:
def write(self,data): def write(self,data):
if self.fileobj is None:
raise ValueError, "write() on closed GzipFile object"
if len(data) > 0: if len(data) > 0:
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)
...@@ -143,7 +154,7 @@ class GzipFile: ...@@ -143,7 +154,7 @@ class GzipFile:
self.write(string.join(lines)) self.write(string.join(lines))
def read(self,size=None): def read(self,size=None):
if self.extrasize <= 0 and self.fileobj.closed: if self.extrasize <= 0 and self.fileobj is None:
return '' return ''
if not size: if not size:
...@@ -173,7 +184,7 @@ class GzipFile: ...@@ -173,7 +184,7 @@ class GzipFile:
uncompress = self.decompress.flush() uncompress = self.decompress.flush()
if uncompress == "": if uncompress == "":
self._read_eof() self._read_eof()
self.fileobj.close() self.fileobj = None
raise EOFError, 'Reached EOF' raise EOFError, 'Reached EOF'
else: else:
uncompress = self.decompress.decompress(buf) uncompress = self.decompress.decompress(buf)
...@@ -201,9 +212,12 @@ class GzipFile: ...@@ -201,9 +212,12 @@ class GzipFile:
self.fileobj.write(self.compress.flush()) self.fileobj.write(self.compress.flush())
write32(self.fileobj, self.crc) write32(self.fileobj, self.crc)
write32(self.fileobj, self.size) write32(self.fileobj, self.size)
self.fileobj.close() self.fileobj = None
elif self.mode == READ: elif self.mode == READ:
self.fileobj.close() self.fileobj = None
if self.myfileobj:
self.myfileobj.close()
self.myfileobj = None
def flush(self): def flush(self):
self.fileobj.flush() self.fileobj.flush()
...@@ -218,47 +232,22 @@ class GzipFile: ...@@ -218,47 +232,22 @@ class GzipFile:
return 0 return 0
def readline(self): def readline(self):
# should I bother with this # XXX This function isn't implemented in a very efficient way
raise RuntimeError, "not implemented" line=""
while 1:
c = self.read(1)
line = line + c
if c=='\n' or c=="": break
return line
def readlines(self): def readlines(self):
# should I bother with this L=[]
raise RuntimeError, "not implemented" line = self.readline()
while line!="":
L.append(line)
class StringIOgz(GzipFile): line = self.readline()
return L
"""A StringIO substitute that reads/writes gzipped buffers."""
def writelines(self, L):
def __init__(self, buf=None, filename="StringIOgz"): for line in L:
"""Read/write mode depends on first argument. self.write(line)
If __init__ is passed a buffer, it will treat that as the
gzipped data and set up the StringIO for reading. Without the
initial argument, it will assume a new file for writing.
The filename argument is written in the header of buffers
opened for writing. Not sure that this is useful, but the
GzipFile code expects *some* filename."""
if buf:
self.mode = READ
self._init_read()
self.filename = filename
self.decompress = zlib.decompressobj(-zlib.MAX_WBITS)
self.fileobj = StringIO.StringIO(buf)
else:
self.mode = WRITE
self._init_write(filename)
self.compress = zlib.compressobj(compresslevel,
zlib.DEFLATED,
-zlib.MAX_WBITS,
zlib.DEF_MEM_LEVEL,
0)
self.fileobj = StringIO.StringIO()
if self.mode == WRITE:
self._write_gzip_header()
elif self.mode == READ:
self._read_gzip_header()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment