19
19
from __future__ import absolute_import
21
from cpython.bytes cimport (
23
PyBytes_FromStringAndSize,
27
from cpython.long cimport (
30
from cpython.int cimport (
34
from cpython.tuple cimport (
37
from cpython.list cimport (
41
from cpython.dict cimport (
44
from cpython.bool cimport (
47
from cpython.mem cimport (
22
cdef extern from "stddef.h":
23
ctypedef unsigned int size_t
53
from libc.stdlib cimport (
56
from libc.string cimport (
25
60
cdef extern from "Python.h":
26
ctypedef int Py_ssize_t
27
int PyInt_CheckExact(object o)
28
int PyLong_CheckExact(object o)
29
int PyString_CheckExact(object o)
30
int PyTuple_CheckExact(object o)
31
int PyList_CheckExact(object o)
32
int PyDict_CheckExact(object o)
33
int PyBool_Check(object o)
34
object PyString_FromStringAndSize(char *v, Py_ssize_t len)
35
char *PyString_AS_STRING(object o) except NULL
36
Py_ssize_t PyString_GET_SIZE(object o) except -1
37
object PyInt_FromString(char *str, char **pend, int base)
61
# There is no cython module for ceval.h for some reason
38
62
int Py_GetRecursionLimit()
39
63
int Py_EnterRecursiveCall(char *)
40
64
void Py_LeaveRecursiveCall()
42
int PyList_Append(object, object) except -1
44
cdef extern from "stdlib.h":
45
void free(void *memblock)
46
void *malloc(size_t size)
47
void *realloc(void *memblock, size_t size)
48
long strtol(char *, char **, int)
50
cdef extern from "string.h":
51
void *memcpy(void *dest, void *src, size_t count)
53
66
cdef extern from "python-compat.h":
54
67
int snprintf(char* buffer, size_t nsize, char* fmt, ...)
78
91
"""Initialize decoder engine.
79
92
@param s: Python string.
81
if not PyString_CheckExact(s):
82
raise TypeError("String required")
94
if not PyBytes_CheckExact(s):
95
raise TypeError("bytes required")
85
self.tail = PyString_AS_STRING(s)
86
self.size = PyString_GET_SIZE(s)
98
self.tail = PyBytes_AS_STRING(s)
99
self.size = PyBytes_GET_SIZE(s)
87
100
self._yield_tuples = int(yield_tuples)
166
179
raise ValueError('leading zeros are not allowed')
167
180
D_UPDATE_TAIL(self, next_tail - self.tail + 1)
170
183
if n > self.size:
171
184
raise ValueError('stream underflow')
173
186
raise ValueError('string size below zero: %d' % n)
175
result = PyString_FromStringAndSize(self.tail, n)
188
result = PyBytes_FromStringAndSize(self.tail, n)
176
189
D_UPDATE_TAIL(self, n)
271
284
def __dealloc__(self):
285
PyMem_Free(self.buffer)
273
286
self.buffer = NULL
277
290
if self.buffer != NULL and self.size != 0:
278
return PyString_FromStringAndSize(self.buffer, self.size)
291
return PyBytes_FromStringAndSize(self.buffer, self.size)
282
294
cdef int _ensure_buffer(self, int required) except 0:
283
295
"""Ensure that tail of CharTail buffer has enough size.
310
322
self._ensure_buffer(INT_BUF_SIZE)
311
n = snprintf(self.tail, INT_BUF_SIZE, "i%de", x)
323
n = snprintf(self.tail, INT_BUF_SIZE, b"i%de", x)
313
325
raise MemoryError('int %d too big to encode' % x)
314
326
E_UPDATE_TAIL(self, n)
317
329
cdef int _encode_long(self, x) except 0:
318
return self._append_string(''.join(('i', str(x), 'e')))
330
return self._append_string(b'i%de' % x)
320
332
cdef int _append_string(self, s) except 0:
321
333
cdef Py_ssize_t n
322
n = PyString_GET_SIZE(s)
334
n = PyBytes_GET_SIZE(s)
323
335
self._ensure_buffer(n)
324
memcpy(self.tail, PyString_AS_STRING(s), n)
336
memcpy(self.tail, PyBytes_AS_STRING(s), n)
325
337
E_UPDATE_TAIL(self, n)
328
340
cdef int _encode_string(self, x) except 0:
330
342
cdef Py_ssize_t x_len
331
x_len = PyString_GET_SIZE(x)
343
x_len = PyBytes_GET_SIZE(x)
332
344
self._ensure_buffer(x_len + INT_BUF_SIZE)
333
n = snprintf(self.tail, INT_BUF_SIZE, '%d:', x_len)
345
n = snprintf(self.tail, INT_BUF_SIZE, b'%d:', x_len)
335
347
raise MemoryError('string %s too big to encode' % x)
336
memcpy(<void *>(self.tail+n), PyString_AS_STRING(x), x_len)
348
memcpy(<void *>(self.tail+n), PyBytes_AS_STRING(x), x_len)
337
349
E_UPDATE_TAIL(self, n + x_len)
372
382
if Py_EnterRecursiveCall("encode"):
373
383
raise RuntimeError("too deeply nested")
375
if PyString_CheckExact(x):
385
if PyBytes_CheckExact(x):
376
386
self._encode_string(x)
377
elif PyInt_CheckExact(x):
387
elif PyInt_CheckExact(x) and x.bit_length() < 32:
378
388
self._encode_int(x)
379
389
elif PyLong_CheckExact(x):
380
390
self._encode_long(x)
381
391
elif (PyList_CheckExact(x) or PyTuple_CheckExact(x)
382
or StaticTuple_CheckExact(x)):
392
or isinstance(x, StaticTuple)):
383
393
self._encode_list(x)
384
394
elif PyDict_CheckExact(x):
385
395
self._encode_dict(x)