Esempio n. 1
0
def uncompress(data):
    _out_data, _out_size = prepare(data)

    result = ffi.new('size_t*', 0)

    rc = C.snappy_validate_compressed_buffer(_out_data, _out_size)

    if not rc == C.SNAPPY_OK:
        raise UncompressError()

    rc = C.snappy_uncompressed_length(_out_data, _out_size, result)

    if not rc == C.SNAPPY_OK:
        raise UncompressError()

    _uncompressed_data = ffi.new('char[]', result[0])

    rc = C.snappy_uncompress(_out_data, _out_size, _uncompressed_data, result)

    if rc != C.SNAPPY_OK:
        raise UncompressError()

    buf = ffi.buffer(ffi.cast('char*', _uncompressed_data), result[0])

    return buf[:]
Esempio n. 2
0
 def flush(self):
     """All pending input is processed, and a string containing the
     remaining uncompressed output is returned. After calling flush(), the
     decompress() method cannot be called again; the only realistic action
     is to delete the object.
     """
     if self._buf != b"":
         raise UncompressError("chunk truncated")
     return b""
Esempio n. 3
0
 def decompress(self, data):
     """Decompress 'data', returning a string containing the uncompressed
     data corresponding to at least part of the data in string. This data
     should be concatenated to the output produced by any preceding calls to
     the decompress() method. Some of the input data may be preserved in
     internal buffers for later processing.
     """
     self._buf += data
     uncompressed = []
     while True:
         if len(self._buf) < 4:
             return b"".join(uncompressed)
         chunk_type = struct.unpack("<L", self._buf[:4])[0]
         size = (chunk_type >> 8)
         chunk_type &= 0xff
         if not self._header_found:
             if (chunk_type != _IDENTIFIER_CHUNK
                     or size != len(_STREAM_IDENTIFIER)):
                 raise UncompressError("stream missing snappy identifier")
             self._header_found = True
         if (_RESERVED_UNSKIPPABLE[0] <= chunk_type
                 and chunk_type < _RESERVED_UNSKIPPABLE[1]):
             raise UncompressError(
                 "stream received unskippable but unknown chunk")
         if len(self._buf) < 4 + size:
             return b"".join(uncompressed)
         chunk, self._buf = self._buf[4:4 + size], self._buf[4 + size:]
         if chunk_type == _IDENTIFIER_CHUNK:
             if chunk != _STREAM_IDENTIFIER:
                 raise UncompressError(
                     "stream has invalid snappy identifier")
             continue
         if (_RESERVED_SKIPPABLE[0] <= chunk_type
                 and chunk_type < _RESERVED_SKIPPABLE[1]):
             continue
         assert chunk_type in (_COMPRESSED_CHUNK, _UNCOMPRESSED_CHUNK)
         crc, chunk = chunk[:4], chunk[4:]
         if chunk_type == _COMPRESSED_CHUNK:
             chunk = _uncompress(chunk)
         if struct.pack("<L", _masked_crc32c(chunk)) != crc:
             raise UncompressError("crc mismatch")
         uncompressed.append(chunk)
Esempio n. 4
0
def uncompress(data, decoding=None):
    if isinstance(data, unicode):
        raise UncompressError("It's only possible to uncompress bytes")
    if decoding:
        return _uncompress(data).decode(decoding)
    return _uncompress(data)
Esempio n. 5
0
 def flush(self):
     if self._buf != b"":
         raise UncompressError("chunk truncated")
     return b""