from gzip import GzipFile # 256K buffer to Gzip GZIP_BUFFER_SIZE = 1024 * 256 class GzipWrap(object): def __init__(self, input, filename=None, compresslevel=1): self.input = iter(input) self.buffer = '' self.zipper = GzipFile(filename, mode='wb', fileobj=self, compresslevel=compresslevel, mtime=0) self.is_done = False def read(self, size=-1): if size is None or size < 0: raise Exception('Call to GzipWrap with unbound size will result in poor performance') # If the buffer already has enough bytes, then simply pop them off of # the beginning and return them. if len(self.buffer) >= size or self.is_done: ret = self.buffer[0:size] self.buffer = self.buffer[size:] return ret # Otherwise, zip the input until we have enough bytes. while True: # Attempt to retrieve the next bytes to write. is_done = False input_size = 0 input_buffer = '' while input_size < GZIP_BUFFER_SIZE: try: s = self.input.next() input_buffer += s input_size = input_size + len(s) except StopIteration: is_done = True break self.zipper.write(input_buffer) if is_done: self.zipper.flush() self.zipper.close() self.is_done = True if len(self.buffer) >= size or is_done: ret = self.buffer[0:size] self.buffer = self.buffer[size:] return ret def flush(self): pass def write(self, data): self.buffer += data def close(self): self.input.close()