Skip to content

Commit b0d61ee

Browse files
authored
Merge pull request #152 from pycompression/bufferable2
Also allow buffer protocol objects into _GzipReader
2 parents 463c0bd + 6f81e8f commit b0d61ee

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ version 1.4.0-dev
1212
+ The internal ``igzip._IGzipReader`` has been rewritten in C. As a result the
1313
overhead of decompressing files has significantly been reduced and
1414
``python -m isal.igzip`` is now very close to the C ``igzip`` application.
15-
+ The ``igzip._IGZipReader`` in C is now used in ``igzip.decompress``. This
16-
has reduced overhead significantly.
15+
+ The ``igzip._IGZipReader`` in C is now used in ``igzip.decompress``. The
16+
``_GzipReader`` also can read from objects that support the buffer protocol
17+
This has reduced overhead significantly.
1718

1819
version 1.3.0
1920
-----------------

src/isal/igzip.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,7 @@ def decompress(data):
260260
isal_zlib.decompress(data, wbits=31) is faster in cases where only one
261261
gzip member is guaranteed to be present.
262262
"""
263-
fp = io.BytesIO(data)
264-
reader = _GzipReader(fp, max(len(data), 16))
263+
reader = _GzipReader(data)
265264
return reader.readall()
266265

267266

src/isal/isal_zlibmodule.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,7 @@ typedef struct _GzipReaderStruct {
12681268
int64_t _pos;
12691269
int64_t _size;
12701270
PyObject *fp;
1271+
Py_buffer *memview;
12711272
char stream_phase;
12721273
char all_bytes_read;
12731274
char closed;
@@ -1278,7 +1279,12 @@ typedef struct _GzipReaderStruct {
12781279

12791280
static void GzipReader_dealloc(GzipReader *self)
12801281
{
1281-
PyMem_Free(self->input_buffer);
1282+
if (self->memview == NULL) {
1283+
PyMem_Free(self->input_buffer);
1284+
} else {
1285+
PyBuffer_Release(self->memview);
1286+
PyMem_Free(self->memview);
1287+
}
12821288
Py_XDECREF(self->fp);
12831289
PyThread_free_lock(self->lock);
12841290
Py_TYPE(self)->tp_free(self);
@@ -1303,20 +1309,36 @@ GzipReader__new__(PyTypeObject *type, PyObject *args, PyObject *kwargs)
13031309
return NULL;
13041310
}
13051311
GzipReader *self = PyObject_New(GzipReader, type);
1306-
self->buffer_size = buffer_size;
1307-
self->input_buffer = PyMem_Malloc(self->buffer_size);
1308-
if (self->input_buffer == NULL) {
1309-
Py_DECREF(self);
1310-
return PyErr_NoMemory();
1312+
if (PyObject_HasAttrString(fp, "read")) {
1313+
self->memview = NULL;
1314+
self->buffer_size = buffer_size;
1315+
self->input_buffer = PyMem_Malloc(self->buffer_size);
1316+
if (self->input_buffer == NULL) {
1317+
Py_DECREF(self);
1318+
return PyErr_NoMemory();
1319+
}
1320+
self->buffer_end = self->input_buffer;
1321+
self->all_bytes_read = 0;
1322+
} else {
1323+
self->memview = PyMem_Malloc(sizeof(Py_buffer));
1324+
if (self->memview == NULL) {
1325+
return PyErr_NoMemory();
1326+
}
1327+
if (PyObject_GetBuffer(fp, self->memview, PyBUF_SIMPLE) < 0) {
1328+
Py_DECREF(self);
1329+
return NULL;
1330+
}
1331+
self->buffer_size = self->memview->len;
1332+
self->input_buffer = self->memview->buf;
1333+
self->buffer_end = self->input_buffer + self->buffer_size;
1334+
self->all_bytes_read = 1;
13111335
}
13121336
self->current_pos = self->input_buffer;
1313-
self->buffer_end = self->current_pos;
13141337
self->_pos = 0;
13151338
self->_size = -1;
13161339
Py_INCREF(fp);
13171340
self->fp = fp;
13181341
self->stream_phase = GzipReader_HEADER;
1319-
self->all_bytes_read = 0;
13201342
self->closed = 0;
13211343
self->_last_mtime = 0;
13221344
self->lock = PyThread_allocate_lock();

0 commit comments

Comments
 (0)