Commit aaa67d43 authored by Julien Muchembled's avatar Julien Muchembled

Initial revision

parents
*.pyc
*.pyo
*.c
*.so
/build/
/dist/
from distutils.core import setup
from distutils.extension import Extension
kw = dict(name="zstd._bindings", libraries=["zstd"])
try:
from Cython.Build import cythonize
except ImportError:
ext_modules = [Extension(sources=["zstd/_bindings.c"], **kw)]
else:
ext_modules = cythonize([Extension(sources=["zstd/_bindings.pyx"], **kw)])
classifiers = """\
License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
Programming Language :: Cython
Programming Language :: Python :: 2
Programming Language :: Python :: 3
"""
setup(
name = 'cython-zstd',
version = '0.1',
description = 'Zstd bindings for Python',
author = 'Nexedi',
author_email = 'jm@nexedi.com',
url = 'https://lab.nexedi.com/nexedi/cython-zstd',
license = 'GPL 2+',
classifiers=classifiers.splitlines(),
packages = ['zstd'],
ext_modules = ext_modules,
)
from ._bindings import *
class error(Exception):
_strerror = None
def __init__(self, code):
self.code = code
@property
def strerror(self):
strerror = self._strerror
if strerror is None:
strerror = self._strerror = getErrorName(-self.code)
return strerror
def __str__(self):
return "[error %s] %s" % (self.code, self.strerror)
from . import _bindings
_bindings.error = error
del _bindings
from cpython cimport (PyObject, PY_LONG_LONG,
PyBytes_FromStringAndSize as _PyBytes_FromStringAndSize,
PyBytes_AS_STRING as _PyBytes_AS_STRING)
cdef extern from "Python.h":
# Although the following are in cpython, we want `PyObject*` instead of
# `object` type for correct reference counting with _PyBytes_Resize
# (all this because Cython refuses to "take address of Python variable").
void Py_DECREF(PyObject *o)
PyObject *PyBytes_FromStringAndSize(char *v, Py_ssize_t len) except NULL
int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1
char *PyBytes_AS_STRING(PyObject *string)
cdef extern from "zstd.h":
# To simplify implementation, we use signed types (and detect errors with
# negative values). Anyway, that's what `bytes` uses for its length.
ssize_t ZSTD_compressBound(ssize_t srcSize)
const char * ZSTD_getErrorName(ssize_t code)
int ZSTD_maxCLevel()
PY_LONG_LONG ZSTD_getFrameContentSize(const void *src, ssize_t srcSize)
ssize_t ZSTD_compress(void *dst, ssize_t dstCapacity,
const void *src, ssize_t srcSize,
int compressionLevel)
ssize_t ZSTD_decompress(void *dst, ssize_t dstCapacity,
const void *src, ssize_t compressedSize)
def maxCLevel():
return ZSTD_maxCLevel()
cdef PY_LONG_LONG _getFrameContentSize(const void *src, ssize_t srcSize) except -1:
cdef PY_LONG_LONG size = ZSTD_getFrameContentSize(src, srcSize)
if size < 0:
raise RuntimeError("ZSTD_getFrameContentSize returned %s" % size)
return size
def getFrameContentSize(bytes string not None):
return _getFrameContentSize(_PyBytes_AS_STRING(string), len(string))
def getErrorName(code):
# why can't I just cast to str ?
IF str is bytes:
return ZSTD_getErrorName(code)
return ZSTD_getErrorName(code).decode()
error = None
def compress(bytes string not None, int level=0):
cdef:
ssize_t srcSize = len(string)
ssize_t dstCapacity = ZSTD_compressBound(srcSize)
PyObject *dst = PyBytes_FromStringAndSize(NULL, dstCapacity)
int x = ZSTD_compress(PyBytes_AS_STRING(dst), dstCapacity,
_PyBytes_AS_STRING(string), srcSize,
level)
if x < 0:
Py_DECREF(dst)
raise error(-x)
_PyBytes_Resize(&dst, x)
r = <object>dst
Py_DECREF(dst) # revert the unwanted incref on the previous line
return r
def decompress(bytes string not None):
cdef:
ssize_t compressedSize = len(string)
void *src = _PyBytes_AS_STRING(string)
PY_LONG_LONG dstCapacity = _getFrameContentSize(src, compressedSize)
dst = _PyBytes_FromStringAndSize(NULL, dstCapacity)
cdef int x = ZSTD_decompress(_PyBytes_AS_STRING(dst), dstCapacity,
src, compressedSize)
if x < 0:
raise error(-x)
return dst
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment