diff --git a/.github/workflows/pypy.yml b/.github/workflows/pypy.yml index 1ea8942..18f75eb 100644 --- a/.github/workflows/pypy.yml +++ b/.github/workflows/pypy.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [pypy2, pypy3] + python-version: [pypy3.9, "pypy3.10"] name: ${{ matrix.python-version }} @@ -19,21 +19,18 @@ jobs: - uses: actions/checkout@v2 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} architecture: x64 - name: Install test dependencies - run: pip install cffi flake8 pytest wheel - - - name: Install libsnappy-dev - run: sudo apt-get install libsnappy-dev + run: pip install flake8 pytest wheel # Flake8 is already run in Source Distribution (sdist) workflow, so we don't run it here. - name: Install python-snappy from source - run: pip install -e . + run: python setup.py develop - name: Pytest - run: pytest --verbose test_snappy.py test_snappy_cffi.py + run: pytest --verbose test_snappy.py diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index e60cbf8..a72aa9e 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: "3.10" architecture: x64 @@ -31,9 +31,6 @@ jobs: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Install libsnappy-dev - run: sudo apt-get install libsnappy-dev - - name: Generate source distribution run: python setup.py sdist @@ -87,7 +84,7 @@ jobs: - uses: actions/checkout@v2 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: "3.10" architecture: ${{ matrix.architecture }} @@ -108,7 +105,8 @@ jobs: python -m pip install delvewheel==0.0.9 - name: Build wheels - uses: joerick/cibuildwheel@v2.1.3 + run: | + python -m pip wheel -w ./wheelhouse . - uses: actions/upload-artifact@v2 with: diff --git a/setup.py b/setup.py index 6b3c745..57e06e0 100644 --- a/setup.py +++ b/setup.py @@ -38,30 +38,9 @@ More details about Snappy library: http://google.github.io/snappy """ -library_dirs, include_dirs = [], [] -if os.environ.get("CIBUILDWHEEL", False) and sys.version_info[:2] == (3, 9) and sys.platform =="darwin": - library_dirs = ["/usr/local/lib/"] - include_dirs = ["/usr/local/include/"] - - -snappymodule = Extension('snappy._snappy', - libraries=['snappy'], - sources=['src/snappy/snappymodule.cc', 'src/snappy/crc32c.c'], - library_dirs=library_dirs, - include_dirs=include_dirs) - -ext_modules = [snappymodule] packages = ['snappy'] -install_requires = [] -setup_requires = [] -cffi_modules = [] - -if 'PyPy' in sys.version: - from setuptools import setup - ext_modules = [] - install_requires = ['cffi>=1.15.0'] - setup_requires = ['cffi>=1.15.0'] - cffi_modules = ['./src/snappy/snappy_cffi_builder.py:ffi'] +install_requires = ['cramjam>=2.6.0', 'crc32c'] +setup_requires = ['cramjam>=2.6.0', 'crc32c'] setup( name='python-snappy', @@ -93,10 +72,8 @@ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10' ], - ext_modules=ext_modules, packages=packages, install_requires=install_requires, setup_requires=setup_requires, - cffi_modules=cffi_modules, package_dir={'': 'src'}, ) diff --git a/src/snappy/crc32c.c b/src/snappy/crc32c.c deleted file mode 100644 index 9a607b0..0000000 --- a/src/snappy/crc32c.c +++ /dev/null @@ -1,130 +0,0 @@ -/** - * \file crc32c.c - * Functions and types for CRC checks. - * - * Generated on Wed Nov 7 16:14:50 2012, - * by pycrc v0.7.11, http://www.tty1.net/pycrc/ - * using the configuration: - * Width = 32 - * Poly = 0x1edc6f41 - * XorIn = 0xffffffff - * ReflectIn = True - * XorOut = 0xffffffff - * ReflectOut = True - * Algorithm = table-driven - *****************************************************************************/ -#include "crc32c.h" /* include the header file generated with pycrc */ -#include -#include - -/** - * Static table used for the table_driven implementation. - *****************************************************************************/ -static const crc_t crc_table[256] = { - 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, - 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, - 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, - 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, - 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, - 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, - 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, - 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, - 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, - 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, - 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, - 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, - 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, - 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, - 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, - 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, - 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, - 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, - 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, - 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, - 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, - 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, - 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, - 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, - 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, - 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, - 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, - 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, - 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, - 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, - 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, - 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, - 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, - 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, - 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, - 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, - 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, - 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, - 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, - 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, - 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, - 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, - 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, - 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, - 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, - 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, - 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, - 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, - 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, - 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, - 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, - 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, - 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, - 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, - 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, - 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, - 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, - 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, - 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, - 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, - 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, - 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, - 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, - 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351 -}; - -/** - * Reflect all bits of a \a data word of \a data_len bytes. - * - * \param data The data word to be reflected. - * \param data_len The width of \a data expressed in number of bits. - * \return The reflected data. - *****************************************************************************/ -crc_t crc_reflect(crc_t data, size_t data_len) -{ - unsigned int i; - crc_t ret; - - ret = data & 0x01; - for (i = 1; i < data_len; i++) { - data >>= 1; - ret = (ret << 1) | (data & 0x01); - } - return ret; -} - - -/** - * Update the crc value with new data. - * - * \param crc The current crc value. - * \param data Pointer to a buffer of \a data_len bytes. - * \param data_len Number of bytes in the \a data buffer. - * \return The updated crc value. - *****************************************************************************/ -crc_t crc_update(crc_t crc, const unsigned char *data, size_t data_len) -{ - unsigned int tbl_idx; - - while (data_len--) { - tbl_idx = (crc ^ *data) & 0xff; - crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff; - - data++; - } - return crc & 0xffffffff; -} diff --git a/src/snappy/crc32c.h b/src/snappy/crc32c.h deleted file mode 100644 index 415b7ff..0000000 --- a/src/snappy/crc32c.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * \file crc32c.h - * Functions and types for CRC checks. - * - * Generated on Wed Nov 7 16:14:52 2012, - * by pycrc v0.7.11, http://www.tty1.net/pycrc/ - * using the configuration: - * Width = 32 - * Poly = 0x1edc6f41 - * XorIn = 0xffffffff - * ReflectIn = True - * XorOut = 0xffffffff - * ReflectOut = True - * Algorithm = table-driven - *****************************************************************************/ -#ifndef __CRC32C_H__ -#define __CRC32C_H__ - -#include -#include - -#if defined(_MSC_VER) && !defined(__cplusplus) /* Visual Studio */ -#ifndef inline -#define inline __inline /* Visual C is not C99, but supports some kind of inline */ -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * The definition of the used algorithm. - *****************************************************************************/ -#define CRC_ALGO_TABLE_DRIVEN 1 - - -/** - * The type of the CRC values. - * - * This type must be big enough to contain at least 32 bits. - *****************************************************************************/ -typedef uint32_t crc_t; - - -/** - * Reflect all bits of a \a data word of \a data_len bytes. - * - * \param data The data word to be reflected. - * \param data_len The width of \a data expressed in number of bits. - * \return The reflected data. - *****************************************************************************/ -crc_t crc_reflect(crc_t data, size_t data_len); - - -/** - * Calculate the initial crc value. - * - * \return The initial crc value. - *****************************************************************************/ -static inline crc_t crc_init(void) -{ - return 0xffffffff; -} - - -/** - * Update the crc value with new data. - * - * \param crc The current crc value. - * \param data Pointer to a buffer of \a data_len bytes. - * \param data_len Number of bytes in the \a data buffer. - * \return The updated crc value. - *****************************************************************************/ -crc_t crc_update(crc_t crc, const unsigned char *data, size_t data_len); - - -/** - * Calculate the final crc value. - * - * \param crc The current crc value. - * \return The final crc value. - *****************************************************************************/ -static inline crc_t crc_finalize(crc_t crc) -{ - return crc ^ 0xffffffff; -} - - -#ifdef __cplusplus -} /* closing brace for extern "C" */ -#endif - -#endif /* __CRC32C_H__ */ diff --git a/src/snappy/pythoncapi_compat.h b/src/snappy/pythoncapi_compat.h deleted file mode 100644 index b4011d2..0000000 --- a/src/snappy/pythoncapi_compat.h +++ /dev/null @@ -1,393 +0,0 @@ -// Header file providing new functions of the Python C API to old Python -// versions. -// -// File distributed under the MIT license. -// Copyright Contributors to the pythoncapi_compat project. -// -// Homepage: -// https://github.com/pythoncapi/pythoncapi_compat -// -// Latest version: -// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h -// -// SPDX-License-Identifier: MIT - -#ifndef PYTHONCAPI_COMPAT -#define PYTHONCAPI_COMPAT - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "frameobject.h" // PyFrameObject, PyFrame_GetBack() - - -// Compatibility with Visual Studio 2013 and older which don't support -// the inline keyword in C (only in C++): use __inline instead. -#if (defined(_MSC_VER) && _MSC_VER < 1900 \ - && !defined(__cplusplus) && !defined(inline)) -# define inline __inline -# define PYTHONCAPI_COMPAT_MSC_INLINE - // These two macros are undefined at the end of this file -#endif - - -// Cast argument to PyObject* type. -#ifndef _PyObject_CAST -# define _PyObject_CAST(op) ((PyObject*)(op)) -#endif -#ifndef _PyObject_CAST_CONST -# define _PyObject_CAST_CONST(op) ((const PyObject*)(op)) -#endif - - -// bpo-42262 added Py_NewRef() to Python 3.10.0a3 -#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef) -static inline PyObject* _Py_NewRef(PyObject *obj) -{ - Py_INCREF(obj); - return obj; -} -#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) -#endif - - -// bpo-42262 added Py_XNewRef() to Python 3.10.0a3 -#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef) -static inline PyObject* _Py_XNewRef(PyObject *obj) -{ - Py_XINCREF(obj); - return obj; -} -#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) -#endif - - -// See https://bugs.python.org/issue42522 -#if !defined(_Py_StealRef) -static inline PyObject* __Py_StealRef(PyObject *obj) -{ - Py_DECREF(obj); - return obj; -} -#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj)) -#endif - - -// See https://bugs.python.org/issue42522 -#if !defined(_Py_XStealRef) -static inline PyObject* __Py_XStealRef(PyObject *obj) -{ - Py_XDECREF(obj); - return obj; -} -#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj)) -#endif - - -// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4 -#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT) -static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) -{ - ob->ob_refcnt = refcnt; -} -#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) -#endif - - -// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2. -// It is excluded from the limited C API. -#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API) -#define Py_SETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_DECREF(_py_tmp); \ - } while (0) - -#define Py_XSETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_XDECREF(_py_tmp); \ - } while (0) -#endif - - -// bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse() -// to Python 3.10.0b1. -#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is) -# define Py_Is(x, y) ((x) == (y)) -#endif -#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone) -# define Py_IsNone(x) Py_Is(x, Py_None) -#endif -#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue) -# define Py_IsTrue(x) Py_Is(x, Py_True) -#endif -#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse) -# define Py_IsFalse(x) Py_Is(x, Py_False) -#endif - - -// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4 -#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) -static inline void -_Py_SET_TYPE(PyObject *ob, PyTypeObject *type) -{ - ob->ob_type = type; -} -#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) -#endif - - -// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4 -#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) -static inline void -_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) -{ - ob->ob_size = size; -} -#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) -#endif - - -// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 -#if PY_VERSION_HEX < 0x030900B1 -static inline PyCodeObject* -PyFrame_GetCode(PyFrameObject *frame) -{ - assert(frame != NULL); - assert(frame->f_code != NULL); - return (PyCodeObject*)Py_NewRef(frame->f_code); -} -#endif - -static inline PyCodeObject* -_PyFrame_GetCodeBorrow(PyFrameObject *frame) -{ - return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame)); -} - - -// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 -#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) -static inline PyFrameObject* -PyFrame_GetBack(PyFrameObject *frame) -{ - assert(frame != NULL); - return (PyFrameObject*)Py_XNewRef(frame->f_back); -} -#endif - -#if !defined(PYPY_VERSION) -static inline PyFrameObject* -_PyFrame_GetBackBorrow(PyFrameObject *frame) -{ - return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame)); -} -#endif - - -// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5 -#if PY_VERSION_HEX < 0x030900A5 -static inline PyInterpreterState * -PyThreadState_GetInterpreter(PyThreadState *tstate) -{ - assert(tstate != NULL); - return tstate->interp; -} -#endif - - -// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1 -#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) -static inline PyFrameObject* -PyThreadState_GetFrame(PyThreadState *tstate) -{ - assert(tstate != NULL); - return (PyFrameObject *)Py_XNewRef(tstate->frame); -} -#endif - -#if !defined(PYPY_VERSION) -static inline PyFrameObject* -_PyThreadState_GetFrameBorrow(PyThreadState *tstate) -{ - return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate)); -} -#endif - - -// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5 -#if PY_VERSION_HEX < 0x030900A5 -static inline PyInterpreterState * -PyInterpreterState_Get(void) -{ - PyThreadState *tstate; - PyInterpreterState *interp; - - tstate = PyThreadState_GET(); - if (tstate == NULL) { - Py_FatalError("GIL released (tstate is NULL)"); - } - interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("no current interpreter"); - } - return interp; -} -#endif - - -// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6 -#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) -static inline uint64_t -PyThreadState_GetID(PyThreadState *tstate) -{ - assert(tstate != NULL); - return tstate->id; -} -#endif - -// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2 -#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) -static inline void PyThreadState_EnterTracing(PyThreadState *tstate) -{ - tstate->tracing++; -#if PY_VERSION_HEX >= 0x030A00A1 - tstate->cframe->use_tracing = 0; -#else - tstate->use_tracing = 0; -#endif -} -#endif - -// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2 -#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) -static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) -{ - tstate->tracing--; - int use_tracing = (tstate->c_tracefunc != NULL - || tstate->c_profilefunc != NULL); -#if PY_VERSION_HEX >= 0x030A00A1 - tstate->cframe->use_tracing = use_tracing; -#else - tstate->use_tracing = use_tracing; -#endif -} -#endif - - -// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1 -#if PY_VERSION_HEX < 0x030900A1 -static inline PyObject* -PyObject_CallNoArgs(PyObject *func) -{ - return PyObject_CallFunctionObjArgs(func, NULL); -} -#endif - - -// bpo-39245 made PyObject_CallOneArg() public (previously called -// _PyObject_CallOneArg) in Python 3.9.0a4 -#if PY_VERSION_HEX < 0x030900A4 -static inline PyObject* -PyObject_CallOneArg(PyObject *func, PyObject *arg) -{ - return PyObject_CallFunctionObjArgs(func, arg, NULL); -} -#endif - - -// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3 -#if PY_VERSION_HEX < 0x030A00A3 -static inline int -PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) -{ - int res; - Py_XINCREF(value); - res = PyModule_AddObject(module, name, value); - if (res < 0) { - Py_XDECREF(value); - } - return res; -} -#endif - - -// bpo-40024 added PyModule_AddType() to Python 3.9.0a5 -#if PY_VERSION_HEX < 0x030900A5 -static inline int -PyModule_AddType(PyObject *module, PyTypeObject *type) -{ - const char *name, *dot; - - if (PyType_Ready(type) < 0) { - return -1; - } - - // inline _PyType_Name() - name = type->tp_name; - assert(name != NULL); - dot = strrchr(name, '.'); - if (dot != NULL) { - name = dot + 1; - } - - return PyModule_AddObjectRef(module, name, (PyObject *)type); -} -#endif - - -// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6. -// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2. -#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) -static inline int -PyObject_GC_IsTracked(PyObject* obj) -{ - return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)); -} -#endif - -// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6. -// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final. -#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION) -static inline int -PyObject_GC_IsFinalized(PyObject *obj) -{ - return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1)); -} -#endif - - -// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4 -#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) -static inline int -_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { - return ob->ob_type == type; -} -#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type) -#endif - - -// Py_UNUSED() was added to Python 3.4.0b2. -#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED) -# if defined(__GNUC__) || defined(__clang__) -# define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) -# else -# define Py_UNUSED(name) _unused_ ## name -# endif -#endif - - -#ifdef PYTHONCAPI_COMPAT_MSC_INLINE -# undef inline -# undef PYTHONCAPI_COMPAT_MSC_INLINE -#endif - -#ifdef __cplusplus -} -#endif -#endif // PYTHONCAPI_COMPAT diff --git a/src/snappy/snappy.py b/src/snappy/snappy.py index b3031a7..7179a7a 100644 --- a/src/snappy/snappy.py +++ b/src/snappy/snappy.py @@ -44,12 +44,8 @@ import sys import struct -try: - from ._snappy import UncompressError, compress, decompress, \ - isValidCompressed, uncompress, _crc32c -except ImportError: - from .snappy_cffi import UncompressError, compress, decompress, \ - isValidCompressed, uncompress, _crc32c +import cramjam +import crc32c _CHUNK_MAX = 65536 _STREAM_TO_STREAM_BLOCK_SIZE = _CHUNK_MAX @@ -66,11 +62,15 @@ def _masked_crc32c(data): # see the framing format specification - crc = _crc32c(data) + crc = crc32c.crc32c(data) return (((crc >> 15) | (crc << 17)) + 0xa282ead8) & 0xffffffff -_compress = compress -_uncompress = uncompress +_compress = cramjam.snappy.compress_raw +_uncompress = cramjam.snappy.decompress_raw + + +class UncompressError(Exception): + pass py3k = False @@ -78,18 +78,36 @@ def _masked_crc32c(data): unicode = str py3k = True + +def isValidCompressed(data): + if isinstance(data, unicode): + data = data.encode('utf-8') + + ok = True + try: + decompress(data) + except UncompressError as err: + ok = False + return ok + + def compress(data, encoding='utf-8'): if isinstance(data, unicode): data = data.encode(encoding) - return _compress(data) + return bytes(_compress(data)) def uncompress(data, decoding=None): if isinstance(data, unicode): raise UncompressError("It's only possible to uncompress bytes") + try: + out = bytes(_uncompress(data)) + except cramjam.DecompressionError as err: + raise UncompressError from err if decoding: - return _uncompress(data).decode(decoding) - return _uncompress(data) + return out.decode(decoding) + return out + decompress = uncompress diff --git a/src/snappy/snappy_cffi.py b/src/snappy/snappy_cffi.py deleted file mode 100644 index f364e85..0000000 --- a/src/snappy/snappy_cffi.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import absolute_import - -from ._snappy_cffi import ffi, lib - -try: - unicode # Python 2 -except NameError: - unicode = str # Python 3 - - -class UncompressError(Exception): - pass - - -class SnappyBufferSmallError(Exception): - pass - - -def prepare(data): - _out_data = None - _out_size = None - - _out_data = ffi.from_buffer(data) - _out_size = ffi.cast('size_t', len(data)) - - return (_out_data, _out_size) - - -def compress(data): - if isinstance(data, unicode): - data = data.encode('utf-8') - - _input_data, _input_size = prepare(data) - - max_compressed = lib.snappy_max_compressed_length(_input_size) - - _out_data = ffi.new('char[]', max_compressed) - _out_size = ffi.new('size_t*', max_compressed) - - rc = lib.snappy_compress(_input_data, _input_size, _out_data, _out_size) - - if rc != lib.SNAPPY_OK: - raise SnappyBufferSmallError() - - value = ffi.buffer(ffi.cast('char*', _out_data), _out_size[0]) - - return value[:] - - -def uncompress(data): - _out_data, _out_size = prepare(data) - - result = ffi.new('size_t*', 0) - - rc = lib.snappy_validate_compressed_buffer(_out_data, _out_size) - - if not rc == lib.SNAPPY_OK: - raise UncompressError() - - rc = lib.snappy_uncompressed_length(_out_data, - _out_size, - result) - - if not rc == lib.SNAPPY_OK: - raise UncompressError() - - _uncompressed_data = ffi.new('char[]', result[0]) - - rc = lib.snappy_uncompress(_out_data, _out_size, _uncompressed_data, result) - - if rc != lib.SNAPPY_OK: - raise UncompressError() - - buf = ffi.buffer(ffi.cast('char*', _uncompressed_data), result[0]) - - return buf[:] - - -def isValidCompressed(data): - if isinstance(data, unicode): - data = data.encode('utf-8') - - _out_data, _out_size= prepare(data) - - rc = lib.snappy_validate_compressed_buffer(_out_data, _out_size) - - return rc == lib.SNAPPY_OK - -decompress = uncompress - -def _crc32c(data): - c_data = ffi.from_buffer(data) - size = ffi.cast('int', len(data)) - return int(lib._crc32c(c_data, size)) diff --git a/src/snappy/snappy_cffi_builder.py b/src/snappy/snappy_cffi_builder.py deleted file mode 100644 index 55889be..0000000 --- a/src/snappy/snappy_cffi_builder.py +++ /dev/null @@ -1,175 +0,0 @@ -import sys - -from cffi import FFI - -if sys.hexversion > 0x03000000: - unicode = str - -ffi = FFI() - -ffi.cdef(''' -typedef enum { - SNAPPY_OK = 0, - SNAPPY_INVALID_INPUT = 1, - SNAPPY_BUFFER_TOO_SMALL = 2 -} snappy_status; - -typedef uint32_t crc_t; - -int snappy_compress(const char* input, - size_t input_length, - char* compressed, - size_t* compressed_length); - -int snappy_uncompress(const char* compressed, - size_t compressed_length, - char* uncompressed, - size_t* uncompressed_length); - -size_t snappy_max_compressed_length(size_t source_length); - -int snappy_uncompressed_length(const char* compressed, - size_t compressed_length, - size_t* result); - -int snappy_validate_compressed_buffer(const char* compressed, - size_t compressed_length); - -crc_t crc_init(void); - -crc_t crc_finalize(crc_t crc); - -crc_t crc_reflect(crc_t data, size_t data_len); - -crc_t crc_update(crc_t crc, const unsigned char *data, size_t data_len); - -crc_t _crc32c(const char *input, int input_size); - -''') - -ffi.set_source('snappy._snappy_cffi', ''' -#include -#include -#include "snappy-c.h" - -/* - * COPY of crc32c - * This is allowed since all crc code is self contained - */ - -typedef uint32_t crc_t; - -uint32_t crc_table[256] = { - 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, - 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, - 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, - 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, - 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, - 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, - 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, - 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, - 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, - 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, - 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, - 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, - 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, - 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, - 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, - 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, - 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, - 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, - 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, - 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, - 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, - 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, - 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, - 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, - 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, - 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, - 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, - 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, - 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, - 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, - 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, - 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, - 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, - 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, - 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, - 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, - 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, - 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, - 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, - 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, - 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, - 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, - 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, - 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, - 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, - 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, - 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, - 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, - 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, - 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, - 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, - 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, - 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, - 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, - 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, - 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, - 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, - 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, - 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, - 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, - 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, - 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, - 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, - 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351 -}; - -crc_t crc_init(void) -{ - return 0xffffffff; -} - -crc_t crc_finalize(crc_t crc) -{ - return crc ^ 0xffffffff; -} - -crc_t crc_reflect(crc_t data, size_t data_len) -{ - unsigned int i; - crc_t ret; - - ret = data & 0x01; - for (i = 1; i < data_len; i++) { - data >>= 1; - ret = (ret << 1) | (data & 0x01); - } - return ret; -} - -crc_t crc_update(crc_t crc, const unsigned char *data, size_t data_len) -{ - unsigned int tbl_idx; - - while (data_len--) { - tbl_idx = (crc ^ *data) & 0xff; - crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff; - - data++; - } - return crc & 0xffffffff; -} - -uint32_t _crc32c(const char *input, int input_size) { - return crc_finalize(crc_update(crc_init(), input, input_size)); -} - -''', libraries=["snappy"]) - - - - -if __name__=='__main__': - ffi.compile() \ No newline at end of file diff --git a/src/snappy/snappymodule.cc b/src/snappy/snappymodule.cc deleted file mode 100644 index 5847ab1..0000000 --- a/src/snappy/snappymodule.cc +++ /dev/null @@ -1,311 +0,0 @@ -/* -Copyright (c) 2011, Andres Moreira - 2011, Felipe Cruz -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the authors nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ANDRES MOREIRA BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "pythoncapi_compat.h" -#include -#include -#include -#include "crc32c.h" - -#define RESIZE_TOLERATION 0.75 - -struct module_state { - PyObject *error; -}; - -#if PY_MAJOR_VERSION >= 3 -#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) -#else -#define GETSTATE(m) (&_state) -static struct module_state _state; -#endif - - -/* if support for Python 2.5 is dropped the bytesobject.h will do this for us */ -#if PY_MAJOR_VERSION < 3 -#define PyBytes_FromStringAndSize PyString_FromStringAndSize -#define _PyBytes_Resize _PyString_Resize -#define PyBytes_AS_STRING PyString_AS_STRING -#endif - -static PyObject *SnappyCompressError, - *SnappyUncompressError, - *SnappyInvalidCompressedInputError, - *SnappyCompressedLengthError; - -static inline PyObject * -maybe_resize(PyObject *str, size_t expected_size, size_t actual_size) -{ - // Tolerate up to 25% slop, to reduce the likelihood of - // reallocation and copying. - if (actual_size != expected_size) { - if (actual_size < expected_size * RESIZE_TOLERATION) { - _PyBytes_Resize(&str, actual_size); - return str; - } - Py_SET_SIZE(str, actual_size); - } - return str; -} - -static const char * -snappy_strerror(snappy_status status) -{ - switch (status) { - case SNAPPY_OK: - return "no error"; - case SNAPPY_INVALID_INPUT: - return "invalid input"; - case SNAPPY_BUFFER_TOO_SMALL: - return "buffer too small"; - default: - return "unknown error"; - } -} - -static PyObject * -snappy__compress(PyObject *self, PyObject *args) -{ - Py_buffer input; - size_t compressed_size, actual_size; - PyObject * result; - snappy_status status; - -#if PY_MAJOR_VERSION >= 3 - if (!PyArg_ParseTuple(args, "y*", &input)) -#else - if (!PyArg_ParseTuple(args, "s*", &input)) -#endif - return NULL; - - // Ask for the max size of the compressed object. - compressed_size = snappy_max_compressed_length(input.len); - - // Make snappy compression - result = PyBytes_FromStringAndSize(NULL, compressed_size); - if (result) { - actual_size = compressed_size; - Py_BEGIN_ALLOW_THREADS - status = snappy_compress((const char *) input.buf, input.len, - PyBytes_AS_STRING(result), &actual_size); - Py_END_ALLOW_THREADS - PyBuffer_Release(&input); - if (status == SNAPPY_OK) { - return maybe_resize(result, compressed_size, actual_size); - } - else { - Py_DECREF(result); - } - PyErr_Format(SnappyCompressError, - "Error while compressing: %s", snappy_strerror(status)); - } - else { - PyBuffer_Release(&input); - PyErr_Format(SnappyCompressError, - "Error while compressing: unable to acquire output string"); - } - return NULL; -} - -static PyObject * -snappy__uncompress(PyObject *self, PyObject *args) -{ - Py_buffer compressed; - size_t uncomp_size, actual_size; - PyObject * result; - snappy_status status; - -#if PY_MAJOR_VERSION >=3 - if (!PyArg_ParseTuple(args, "y*", &compressed)) -#else - if (!PyArg_ParseTuple(args, "s*", &compressed)) -#endif - return NULL; - - status = snappy_uncompressed_length((const char *) compressed.buf, compressed.len, - &uncomp_size); - if (status != SNAPPY_OK) { - PyBuffer_Release(&compressed); - PyErr_SetString(SnappyCompressedLengthError, - "Can not calculate uncompressed length"); - return NULL; - } - - result = PyBytes_FromStringAndSize(NULL, uncomp_size); - if (result) { - actual_size = uncomp_size; - Py_BEGIN_ALLOW_THREADS - status = snappy_uncompress((const char *) compressed.buf, compressed.len, - PyBytes_AS_STRING(result), &actual_size); - Py_END_ALLOW_THREADS - PyBuffer_Release(&compressed); - if (SNAPPY_OK == status) { - return maybe_resize(result, uncomp_size, actual_size); - } - else { - Py_DECREF(result); - PyErr_Format(SnappyUncompressError, - "Error while decompressing: %s", snappy_strerror(status)); - } - } - else { - PyBuffer_Release(&compressed); - } - return NULL; -} - - -static PyObject * -snappy__is_valid_compressed_buffer(PyObject *self, PyObject *args) -{ - const char * compressed; - Py_ssize_t comp_size; - snappy_status status; - -#if PY_MAJOR_VERSION >=3 - if (!PyArg_ParseTuple(args, "y#", &compressed, &comp_size)) -#else - if (!PyArg_ParseTuple(args, "s#", &compressed, &comp_size)) -#endif - return NULL; - - status = snappy_validate_compressed_buffer(compressed, comp_size); - if (status == SNAPPY_OK) - Py_RETURN_TRUE; - Py_RETURN_FALSE; -} - -static PyObject * -snappy__crc32c(PyObject *self, PyObject *args) -{ - Py_buffer input; - PyObject * result; - -#if PY_MAJOR_VERSION >= 3 - if (!PyArg_ParseTuple(args, "y*", &input)) -#else - if (!PyArg_ParseTuple(args, "s*", &input)) -#endif - return NULL; - - result = PyLong_FromUnsignedLong( - crc_finalize(crc_update(crc_init(), (const unsigned char *) input.buf, input.len))); - - PyBuffer_Release(&input); - - return result; -} - -static PyMethodDef snappy_methods[] = { - {"compress", snappy__compress, METH_VARARGS, - "Compress a string using the snappy library."}, - {"uncompress", snappy__uncompress, METH_VARARGS, - "Uncompress a string compressed with the snappy library."}, - {"decompress", snappy__uncompress, METH_VARARGS, - "Alias to Uncompress method, to be compatible with zlib."}, - {"isValidCompressed", snappy__is_valid_compressed_buffer, METH_VARARGS, - "Returns True if the compressed buffer is valid, False otherwise"}, - {"_crc32c", snappy__crc32c, METH_VARARGS, - "Generate an RFC3720, section 12.1 CRC-32C"}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -#if PY_MAJOR_VERSION >= 3 - -static int snappy_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(GETSTATE(m)->error); - return 0; -} - -static int snappy_clear(PyObject *m) { - Py_CLEAR(GETSTATE(m)->error); - return 0; -} - - -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_snappy", - NULL, - sizeof(struct module_state), - snappy_methods, - NULL, - snappy_traverse, - snappy_clear, - NULL -}; - - -#define INITERROR return NULL - -PyMODINIT_FUNC -PyInit__snappy(void) - -#else -#define INITERROR return - -PyMODINIT_FUNC -init_snappy(void) -#endif -{ - PyObject *m; - - #if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); - #else - m = Py_InitModule("_snappy", snappy_methods); - #endif - - if (m == NULL) - INITERROR; - - SnappyCompressError = PyErr_NewException((char*)"snappy.CompressError", - NULL, NULL); - SnappyUncompressError = PyErr_NewException((char*)"snappy.UncompressError", - NULL, NULL); - SnappyInvalidCompressedInputError = PyErr_NewException( - (char*)"snappy.InvalidCompressedInputError", NULL, NULL); - SnappyCompressedLengthError = PyErr_NewException( - (char*)"snappy.CompressedLengthError", NULL, NULL); - - Py_INCREF(SnappyCompressError); - Py_INCREF(SnappyUncompressError); - Py_INCREF(SnappyInvalidCompressedInputError); - Py_INCREF(SnappyCompressedLengthError); - - PyModule_AddObject(m, "CompressError", SnappyCompressError); - PyModule_AddObject(m, "UncompressError", SnappyUncompressError); - PyModule_AddObject(m, "InvalidCompressedInputError", - SnappyInvalidCompressedInputError); - PyModule_AddObject(m, "CompressedLengthError", SnappyCompressedLengthError); - -#if PY_MAJOR_VERSION >= 3 - return m; -#endif -} diff --git a/test_snappy_cffi.py b/test_snappy_cffi.py deleted file mode 100644 index af5a4e7..0000000 --- a/test_snappy_cffi.py +++ /dev/null @@ -1,54 +0,0 @@ -import sys - -py3k = False -if sys.hexversion > 0x02070000: - unicode = str - py3k = True - -def test_snappy_cffi_enum(): - from snappy.snappy_cffi import lib - - assert 0 == lib.SNAPPY_OK - assert 1 == lib.SNAPPY_INVALID_INPUT - assert 2 == lib.SNAPPY_BUFFER_TOO_SMALL - -def test_snappy_all_cffi(): - from snappy.snappy_cffi import ffi, lib - - import os - data = 'string to be compressed' - - _input_data = ffi.new('char[]', data.encode('utf-8')) - _input_size = ffi.cast('size_t', len(_input_data)) - - max_compressed = lib.snappy_max_compressed_length(_input_size) - - _out_data = ffi.new('char[]', max_compressed) - _out_size = ffi.new('size_t*', max_compressed) - - rc = lib.snappy_compress(_input_data, _input_size, _out_data, _out_size) - - assert lib.SNAPPY_OK == rc - - rc = lib.snappy_validate_compressed_buffer(_out_data, _out_size[0]) - - assert lib.SNAPPY_OK == rc - - result = ffi.new('size_t*', 0) - rc = lib.snappy_uncompressed_length(_out_data, - _out_size[0], - result) - - assert lib.SNAPPY_OK == rc - - _uncompressed_data = ffi.new('char[]', result[0]) - - rc = lib.snappy_uncompress(_out_data, _out_size[0], _uncompressed_data, result) - - assert lib.SNAPPY_OK == rc - - result = ffi.string(_uncompressed_data, result[0]) - if py3k: - result = result.decode('utf-8') - - assert data == result