Skip to content

Commit c5fb2ce

Browse files
committed
Implement compress without object initialization
1 parent e04a068 commit c5fb2ce

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

src/isal/igzip.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
import os
2828
import struct
2929
import sys
30-
from typing import List
30+
import time
31+
from typing import List, Optional
3132

3233
from . import isal_zlib
3334

@@ -221,16 +222,29 @@ def _add_read_data(self, data):
221222
_GzipReader = _IGzipReader
222223

223224

224-
# Plagiarized from gzip.py from python's stdlib.
225+
def _create_simple_gzip_header(compresslevel: int,
226+
mtime: Optional[int] = None) -> bytes:
227+
if mtime is None:
228+
mtime = int(time.time())
229+
# There is no best compression level. ISA-L only provides algorithms for
230+
# fast and medium levels.
231+
xfl = 4 if compresslevel == _COMPRESS_LEVEL_FAST else 0
232+
# Pack ID1 and ID2 magic bytes, method (8=deflate), header flags (no extra
233+
# fields added to header), mtime, xfl and os (255 for unknown OS).
234+
return struct.pack("<BBBBLBB", 0x1f, 0x8b, 8, 0, mtime, xfl, 255)
235+
236+
225237
def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=None):
226238
"""Compress data in one shot and return the compressed string.
227239
Optional argument is the compression level, in range of 0-3.
228240
"""
229-
buf = io.BytesIO()
230-
with IGzipFile(fileobj=buf, mode='wb',
231-
compresslevel=compresslevel, mtime=mtime) as f:
232-
f.write(data)
233-
return buf.getvalue()
241+
header = _create_simple_gzip_header(compresslevel, mtime)
242+
# Compress the data without header or trailer in a raw deflate block.
243+
compressed = isal_zlib.compress(data, compresslevel, wbits=-15)
244+
length = len(data) & 0xFFFFFFFF
245+
crc = isal_zlib.crc32(data)
246+
trailer = struct.pack("<LL", crc, length)
247+
return header + compressed + trailer
234248

235249

236250
def _gzip_header_end(data: bytes) -> int:
@@ -244,8 +258,8 @@ def _gzip_header_end(data: bytes) -> int:
244258
raise BadGzipFile("Unknown compression method")
245259
pos = 10
246260
if flags & FHEXTRA:
247-
xlen = struct.unpack("<H", data[pos: pos+2])
248-
pos += xlen
261+
xlen = int.from_bytes(data[pos: pos + 2], "little", signed=False)
262+
pos += 2 + xlen
249263
if flags & FNAME:
250264
fname_end = data.index(b"\x00", pos) + 1
251265
pos = fname_end

0 commit comments

Comments
 (0)