Commit 86fc4428 authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 0.5.2

parents
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
This source diff could not be displayed because it is too large. You can view the blob instead.
include MANIFEST.in ChangeLog COPYING THANKS README NEWS liblzma*.h python-liblzma.spec setup.cfg
recursive-include tests *.py
recursive-include tests/data *
Version 0.5.2 - 26 Feb 2009, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Synchronize code with bz2module.c from python upstream.
o fixes various minor issues and bugs.
o support the context manager protocol (adds __enter__() & __enter__()).
o use Py_buffer.
o make code more in sync with bz2module.c for easier maintenance etc..
Version 0.5.1 - 26 Jan 2009, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Fix huge memleaks in LZMADecompress() and also fix broken flush() and reset()
functions.
- Fix various minor memleaks and bugs.
- This will be the last version supporting python versions older than 2.6.
Version 0.5.0 - 25 Jan 2009, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Add support for xz format (is now default format, xz/liblzma >= 4.999.8beta required).
- Add support for extreme preset.
- Add support for setting decoder memlimit.
- Lots of fixes and cleanups.
- Compression options are now passed as dictionary with keywords rather than
as keyword arguments directly.
Version 0.4.1 - 12 Nov 2008, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Migrate code to use new and final(?) liblzma api (lzma_utils >= 4.999.6).
Version 0.4.0 - 11 Sep 2008, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Add liblzma_file.[ch] implementing lzma_FILE*. (code much based on RPM's
lzdio.c)
- renamed functions, classes, variables from liblzma* to lzma*.
- Implement LZMAFile object. (as with much of the existing code, most of the
code is derived from Gustavo Niemeyer's bz2.c and adapted to lzma)
- Repository has now been migrated from git to bzr and is now hosted and
publically available at http://launchpad.net/pyliblzma.
Version 0.3.4 - 10 Sep 2008, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Add portability fixes for BSD. (from Anders F. Björklund)
Version 0.3.3 - 10 Sep 2008, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Rename python module name from 'liblzma' to 'lzma' as giving the module same
name as the library would result in problems if the library were to be found
in $PWD or $PYTHONPATH.
Rationale behind module being named PylibLZMA and not PyLZMA is due to a
different PyLZMA already exists, it's python module name is 'pylzma',
so 'lzma' is available. :)
- fix code formatting that was quite messed up due to mixed usage of tab
expansion and various tab length.
- clean out compiler flag craziness.
Version 0.3.2 - 28 May 2008, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Fix build with pre-C99.
- Fix url.
- Add some background to README.
Version 0.3.1 - 23 May 2008, by Per Øyvind Karlsen <peroyvind@mandriva.org>
- Fix so that destructor actually gets called when (de)compressor objects are
no longer used.
- Add format option.
- Improve setup.py so that proper source tarball can be generated with sdist.
- Various minor fixes.
Metadata-Version: 1.0
Name: pyliblzma
Version: 0.5.2
Summary: Python bindings for liblzma
Home-page: https://launchpad.net/pyliblzma
Author: Per Øyvind Karlsen
Author-email: peroyvind@mandriva.org
License: LGPL 3
Description: PylibLZMA provides a python interface for the liblzma library
to read and write data that has been compressed or can be decompressed
by Lasse Collin's xz / lzma utils.
Keywords: xz lzma compression
Platform: linux2
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Operating System :: POSIX :: Linux
PylibLZMA
---------
PylibLZMA is a python module that implements the liblzma API.
You need the new lzma utils for this available through git at:
git://ctrl.tukaani.org/lzma-utils.git
Project homepage: http://sourceforge.net/projects/lzmautils
I initially wrote this python module was initially written by as a project
assignment in the course "INF5660 - Advanced problem solving with high level
languages" at the University of Oslo, May 2008. It was written as a first
attempt of both writing a proper python module and also as first proper project
written in the C language, so any obscurities or just plain retardness is
expected, and any help at correcting such will be greatfully accepted. :)
- Per Øyvind Karlsen <peroyvind@mandriva.org>
Thanks
------
This module would be a whole lot harder to write if it weren't for help and
inspiration by others. So I'd like to thank the following people:
* Lasse Collin, the author of lzma utils and liblzma, providing me with a lot
of help, understanding and insight on LZMA.
* Gustavo Niemeyer, for help and advice on C/Python and also benefitting a lot
from his python bz2 module which helped me out a lot as a reference.
* Whoever wrote the python zlib module which also helped as a reference.
* Joachim Bauch, author of pylzma (different format, different language),
for much the same as well his his regression tests that I based some of mine
on.
Thx!
#include "liblzma.h"
#include "liblzma_compressobj.h"
#include "liblzma_decompressobj.h"
#include "liblzma_options.h"
#include "liblzma_util.h"
static const char __author__[] =
"The lzma python module was written by:\n\
\n\
Per Øyvind Karlsen <peroyvind@mandriva.org>\n\
";
PyDoc_STRVAR(LZMA_compress__doc__,
"compress(string [, "DEFAULT_OPTIONS_STRING"]) -> string\n\
\n\
Compress data using the given parameters, returning a string\n\
containing the compressed data.");
static PyObject *
LZMA_compress(__attribute__((unused)) PyObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *ret = NULL, *options_dict = NULL;
Py_buffer pdata;
uint8_t *data;
Py_ssize_t datasize, bufsize;
lzma_ret lzuerror;
lzma_stream _lzus;
lzma_stream *lzus = &_lzus;
lzma_filter filters[LZMA_FILTERS_MAX + 2];
lzma_options_lzma options;
static char *kwlist[] = {"input", "options", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|O:compress", kwlist,
&pdata, &options_dict))
return NULL;
filters[0].options = &options;
if(!init_lzma_options("compress", options_dict, filters))
return NULL;
data = pdata.buf;
datasize = pdata.len;
lzma_stream tmp = LZMA_STREAM_INIT;
*lzus = tmp;
bufsize = lzma_stream_buffer_bound(datasize);
/* TODO: if(bufsize == 0) goto error; */
if (!(ret = PyString_FromStringAndSize(NULL, bufsize)))
return NULL;
if(filters[0].id == LZMA_FILTER_LZMA2)
{
size_t loc = 0;
Py_BEGIN_ALLOW_THREADS
lzuerror = lzma_stream_buffer_encode(filters, filters[LZMA_FILTERS_MAX + 1].id,
NULL, data, (size_t)datasize,
(uint8_t *)PyString_AS_STRING(ret), &loc, (size_t)bufsize);
Py_END_ALLOW_THREADS
_PyString_Resize(&ret, (Py_ssize_t)loc);
}
else if(filters[0].id == LZMA_FILTER_LZMA1)
{
lzuerror = lzma_alone_encoder(lzus, filters[0].options);
if(!Util_CatchLZMAError(lzuerror, lzus, true))
goto error;
lzus->avail_in = (size_t)datasize;
lzus->next_in = data;
lzus->next_out = (uint8_t *)PyString_AS_STRING(ret);
lzus->avail_out = (size_t)bufsize;
Py_BEGIN_ALLOW_THREADS
lzuerror = lzma_code(lzus, LZMA_FINISH);
Py_END_ALLOW_THREADS
if(!Util_CatchLZMAError(lzuerror, lzus, true))
goto error;
lzma_end(lzus);
if (lzuerror == LZMA_STREAM_END)
_PyString_Resize(&ret, (Py_ssize_t)lzus->total_out);
}
PyBuffer_Release(&pdata);
return ret;
error:
if(lzuerror != LZMA_MEM_ERROR && lzuerror != LZMA_PROG_ERROR)
lzma_end(lzus);
Py_XDECREF(ret);
PyBuffer_Release(&pdata);
return NULL;
}
PyDoc_STRVAR(LZMA_decompress__doc__,
"decompress(string[, bufsize=8192, memlimit=-1]) -> string\n\
\n\
Decompress data in one shot. If you want to decompress data sequentially,\n\
use an instance of LZMADecompressor instead.\n\
\n\
Optional arg 'bufsize' is the initial output buffer size.\n\
Optional arg 'memlimit' is the maximum amount of memory the decoder may use,\n\
-1 means no limit.");
static PyObject *
LZMA_decompress(__attribute__((unused)) PyObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *ret = NULL;
Py_buffer pdata;
uint8_t *data;
Py_ssize_t datasize, bufsize = SMALLCHUNK;
uint64_t memlimit = -1;
lzma_ret lzuerror;
lzma_stream _lzus;
lzma_stream *lzus = &_lzus;
static char *kwlist[] = {"input", "bufsize", "memlimit", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|lK:decompress", kwlist,
&pdata, &bufsize, &memlimit))
return NULL;
data = pdata.buf;
datasize = pdata.len;
if (datasize == 0) {
PyBuffer_Release(&pdata);
return PyString_FromString("");
}
ret = PyString_FromStringAndSize(NULL, bufsize);
if (!ret) {
PyBuffer_Release(&pdata);
return NULL;
}
lzma_stream tmp = LZMA_STREAM_INIT;
*lzus = tmp;
lzus->avail_in = (size_t)datasize;
lzus->avail_out = (size_t)bufsize;
lzus->next_out = (uint8_t *)PyString_AS_STRING(ret);
lzus->next_in = (uint8_t *)data;
lzuerror = lzma_auto_decoder(lzus, memlimit, 0);
if(!Util_CatchLZMAError(lzuerror, lzus, false))
goto error;
while (lzuerror != LZMA_STREAM_END){
Py_BEGIN_ALLOW_THREADS
lzuerror=lzma_code(lzus, LZMA_RUN);
Py_END_ALLOW_THREADS
if(!Util_CatchLZMAError(lzuerror, lzus, false))
goto error;
if(lzuerror == LZMA_STREAM_END)
break;
if(lzuerror == LZMA_OK){
if (_PyString_Resize(&ret, bufsize << 1) < 0) {
goto error;
}
lzus->next_out = (uint8_t *)PyString_AS_STRING(ret) + bufsize;
lzus->avail_out = (size_t)bufsize;
bufsize = bufsize << 1;
}
}
_PyString_Resize(&ret, (Py_ssize_t)lzus->total_out);
lzma_end(lzus);
PyBuffer_Release(&pdata);
return ret;
error:
if(lzuerror != LZMA_MEM_ERROR && lzuerror != LZMA_PROG_ERROR)
lzma_end(lzus);
Py_XDECREF(ret);
PyBuffer_Release(&pdata);
return NULL;
}
PyDoc_STRVAR(LZMA_crc32__doc__,
"crc32(string[, start]) -> int\n\
\n\
Compute a CRC-32 checksum of string.\n\
\n\
An optional starting value 'start' can be specified.");
static PyObject *
LZMA_crc32(__attribute__((unused)) PyObject *self, PyObject *args)
{
uint32_t crc32val = lzma_crc32(NULL, (size_t)0, (uint32_t)0);
uint8_t *buf;
Py_ssize_t size;
if (!PyArg_ParseTuple(args, "s#|I:crc32", &buf, &size, &crc32val))
return NULL;
crc32val = lzma_crc32(buf, (size_t)size, crc32val);
return PyInt_FromLong((long)crc32val);
}
PyDoc_STRVAR(LZMA_crc64__doc__,
"crc64(string[, start]) -> int\n\
\n\
Compute a CRC-64 checksum of string.\n\
\n\
An optional starting value 'start' can be specified.");
static PyObject *
LZMA_crc64(__attribute__((unused)) PyObject *self, PyObject *args)
{
uint64_t crc64val = lzma_crc64(NULL, (size_t)0, (uint64_t)0);
uint8_t *buf;
Py_ssize_t size;
if (!PyArg_ParseTuple(args, "s#|K:crc64", &buf, &size, &crc64val))
return NULL;
crc64val = lzma_crc64(buf, (size_t)size, crc64val);
return PyLong_FromUnsignedLongLong(crc64val);
}
static PyMethodDef lzma_methods[] = {
{"compress", (PyCFunction)LZMA_compress,
METH_VARARGS|METH_KEYWORDS, LZMA_compress__doc__},
{"crc32", (PyCFunction)LZMA_crc32,
METH_VARARGS, LZMA_crc32__doc__},
{"crc64", (PyCFunction)LZMA_crc64,
METH_VARARGS, LZMA_crc64__doc__},
{"decompress", (PyCFunction)LZMA_decompress,
METH_VARARGS|METH_KEYWORDS, LZMA_decompress__doc__},
{0, 0, 0, 0}
};
PyDoc_STRVAR(lzma_module_documentation,
"The python lzma module provides a comprehensive interface for\n\
the lzma compression library. It implements one shot (de)compression\n\
functions, CRC-32 & CRC-64 checksum copmutations, types for sequential\n\
(de)compression, and advanced options for lzma compression.\n\
");
/* declare function before defining it to avoid compile warnings */
PyMODINIT_FUNC initlzma(void);
PyMODINIT_FUNC
initlzma(void)
{
PyObject *ver, *optionsSingleton;
char verstring[10], major, minor[5], revision[5], s[8];
Py_TYPE(&LZMAComp_Type) = &PyType_Type;
Py_TYPE(&LZMADecomp_Type) = &PyType_Type;
Py_TYPE(&LZMAFile_Type) = &PyType_Type;
module = Py_InitModule3("lzma", lzma_methods,
lzma_module_documentation);
if (module == NULL)
return;
optionsSingleton = PyType_GenericNew(&LZMAOptions_Type, NULL, NULL);
if(PyType_Ready(&LZMAOptions_Type) < 0)
return;
LZMAError = PyErr_NewException("LZMA.error", NULL, NULL);
if (LZMAError != NULL) {
Py_INCREF(LZMAError);
PyModule_AddObject(module, "error", LZMAError);
}
Py_INCREF(&LZMAOptions_Type);
PyModule_AddObject(module, "LZMAOptions", (PyObject *)&LZMAOptions_Type);
Py_INCREF(&LZMAComp_Type);
PyModule_AddObject(module, "LZMACompressor", (PyObject *)&LZMAComp_Type);
Py_INCREF(&LZMADecomp_Type);
PyModule_AddObject(module, "LZMADecompressor", (PyObject *)&LZMADecomp_Type);
Py_INCREF(&LZMAFile_Type);
PyModule_AddObject(module, "LZMAFile", (PyObject *)&LZMAFile_Type);
PyModule_AddObject(module, "options", optionsSingleton);
PyModule_AddIntConstant(module, "LZMA_RUN", (ulong)LZMA_RUN);
PyModule_AddIntConstant(module, "LZMA_SYNC_FLUSH", (ulong)LZMA_SYNC_FLUSH);
PyModule_AddIntConstant(module, "LZMA_FULL_FLUSH", (ulong)LZMA_FULL_FLUSH);
PyModule_AddIntConstant(module, "LZMA_FINISH", (ulong)LZMA_FINISH);
PyModule_AddObject(module, "__author__", PyString_FromString(__author__));
/* A bit ugly, but what the hell.. */
snprintf(verstring, 9, "%d", LZMA_VERSION);
verstring[9] = 0;
major = verstring[0];
sprintf(minor, "%c%c%c", verstring[1], verstring[2], verstring[3]);
sprintf(revision, "%c%c%c", verstring[4], verstring[5], verstring[6]);
if(verstring[7] == '0')
sprintf(s, "alpha");
else if(verstring[7] == '1')
sprintf(s, "beta");
else
sprintf(s, "stable");
ver = PyString_FromFormat("%c.%d.%d%s", major, atoi(minor), atoi(revision), s);
if (ver != NULL)
PyModule_AddObject(module, "LZMA_VERSION", ver);
PyModule_AddStringConstant(module, "__version__", VERSION);
}
#ifndef LIBLZMA_H
#define LIBLZMA_H 1
/* To handle length as ssize_t in stead of int, otherwise we'd either have to
* use the internal _PyArg_ParseTuple_SizeT function to avoid screwups
*/
#define PY_SSIZE_T_CLEAN 1
#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#if defined (__APPLE__) || defined(__FreeBSD__) || \
defined(__OpenBSD__) || defined(__NetBSD__) || \
defined (__sun) || defined (__svr4__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <string.h>
#include <inttypes.h>
#if !defined(linux) && !defined(__sun) && !defined(__svr4__)
typedef unsigned long ulong;
#endif
#include <sys/types.h>
#include <lzma.h>
#ifdef WITH_THREAD
#include <pythread.h>
#define ACQUIRE_LOCK(obj) PyThread_acquire_lock(obj->lock, 1)
#define RELEASE_LOCK(obj) PyThread_release_lock(obj->lock)
#else
#define ACQUIRE_LOCK(obj)
#define RELEASE_LOCK(obj)
#endif
#ifdef __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#endif
#elif defined(__C99FEATURES__)
#include <stdbool.h>
#else
#define bool uint8_t
#define true 1
#define false 0
#ifndef inline
#define inline __inline__
#endif
#endif
#define INITCHECK if (!self->is_initialised) { PyErr_Format(PyExc_RuntimeError, "%s object not initialised!", self->ob_type->tp_name); return NULL; }
PyObject *module;
#endif /* LIBLZMA_H */
#!/usr/bin/env python
from lzma import *
from warnings import warn
warn("'liblzma' has been renamed to 'lzma'!\n Please update code to import 'lzma'!", DeprecationWarning, stacklevel=1)
#include "liblzma_compressobj.h"
#include "liblzma_options.h"
#include "liblzma_util.h"
PyDoc_STRVAR(LZMAComp_compress__doc__,
"compress(data) -> string\n\
\n\
Feed the compressor object with data to compress sequently.\n\
This function will return the header for the compressed string for the first\n\
input provided, this header will be needed to concatenate with the rest of\n\
the stream when flushing to have a proper stream able to be decompressed\n\
again.\n");
static PyObject *
LZMAComp_compress(LZMACompObject *self, PyObject *args)
{
Py_buffer pdata;
Py_ssize_t datasize, bufsize = SMALLCHUNK;
uint8_t *data;
uint64_t start_total_out;
PyObject *ret = NULL;
lzma_stream *lzus = &self->lzus;
lzma_ret lzuerror;
INITCHECK
if (!PyArg_ParseTuple(args, "s*:compress", &pdata))
return NULL;
data = pdata.buf;
datasize = pdata.len;
ACQUIRE_LOCK(self);
if (!self->running) {
PyErr_SetString(PyExc_ValueError,
"this object was already flushed");
goto error;
}
if (!(ret = PyString_FromStringAndSize(NULL, bufsize)))
goto error;
start_total_out = lzus->total_out;
lzus->avail_in = (size_t)datasize;
lzus->next_in = data;
lzus->avail_out = (size_t)bufsize;
lzus->next_out = (uint8_t *)PyString_AS_STRING(ret);
for (;;) {
Py_BEGIN_ALLOW_THREADS
lzuerror = lzma_code(lzus, LZMA_RUN);
Py_END_ALLOW_THREADS
if (lzus->avail_in == 0 || lzus->avail_out != 0)
break;
if (_PyString_Resize(&ret, bufsize << 1) < 0)
goto error;
lzus->next_out = (uint8_t *)PyString_AS_STRING(ret) + datasize;
lzus->avail_out = (size_t)bufsize;
bufsize = bufsize << 1;
if(!Util_CatchLZMAError(lzuerror, lzus, true))
goto error;
}
_PyString_Resize(&ret, (Py_ssize_t)lzus->total_out - (Py_ssize_t)start_total_out);
RELEASE_LOCK(self);
PyBuffer_Release(&pdata);
return ret;
error:
RELEASE_LOCK(self);
PyBuffer_Release(&pdata);
Py_XDECREF(ret);
return NULL;
}
PyDoc_STRVAR(LZMAComp_flush__doc__,
"flush( [mode] ) -> string\n\
\n\
Returns a string containing any remaining compressed data.\n\
\n\
'mode' can be one of the constants LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FINISH; the\n\
default value used when mode is not specified is LZMA_FINISH.\n\
If mode == LZMA_FINISH, the compressor object can no longer be used after\n\
calling the flush() method. Otherwise, more data can still be compressed.\n");
static PyObject *
LZMAComp_flush(LZMACompObject *self, PyObject *args)
{
Py_ssize_t bufsize = SMALLCHUNK;
PyObject *ret = NULL;