return None
+class BytesTellWrapper:
+ """
+ Wrapper around a write-only stream that supports tell but not seek
+
+ copy of zipfile._Tellable
+ """
+ def __init__(self, fp):
+ self.fp = fp
+ self.offset = 0
+
+ def write(self, data):
+ n = self.fp.write(data)
+ self.offset += n
+ return n
+
+ def tell(self):
+ return self.offset
+
+ def flush(self):
+ self.fp.flush()
+
+ def close(self):
+ self.fp.close()
+
+
class ZipStream(ZipFile):
"""Subclass of ZipFile that supports non-seekable input and output"""
+ def __init__(self, file, *args, **kwargs):
+ """
+ Create ZipStream instance which is like a ZipFile plus functions
+ create_zipinfo and write_stream.
+
+ ZipFile determines whether output stream can seek() and tell().
+ Unfortunately some streams (like sys.stdout.buffer when redirecting
+ output) seem to support these methods but only return 0 from tell.
+
+ :param bool force_wrap: force wrapping of output stream with
+ BytesTellWrapper.
+ """
+ if 'force_wrap' in kwargs and kwargs['force_wrap']:
+ if isstr(file):
+ raise ValueError('force_wrap only makes sense for streams')
+ del kwargs['force_wrap']
+ super(ZipStream, self).__init__(BytesTellWrapper(file), *args,
+ **kwargs)
+ else:
+ super(ZipStream, self).__init__(file, *args, **kwargs)
+
def create_zipinfo(self, filename, arcname=None):
"""
Create ZipInfo for given file
if not buf:
break
file_size = file_size + len(buf)
- CRC = crc32(buf, CRC)
+ CRC = crc32(buf, CRC) & 0xffffffff
if cmpr:
buf = cmpr.compress(buf)
compress_size = compress_size + len(buf)