29
29
object PyString_FromStringAndSize(char *v, Py_ssize_t len)
30
30
char *PyString_AS_STRING(object o) except NULL
31
31
Py_ssize_t PyString_GET_SIZE(object o) except -1
33
32
object PyLong_FromString(char *str, char **pend, int base)
35
34
cdef extern from "stddef.h":
39
38
void free(void *memblock)
40
39
void *malloc(size_t size)
41
40
void *realloc(void *memblock, size_t size)
41
long strtol(char *, char **, int)
43
43
cdef extern from "string.h":
44
44
void *memcpy(void *dest, void *src, size_t count)
45
char *strndup(char *src, size_t count)
46
47
cdef extern from "python-compat.h":
47
48
int snprintf(char* buffer, size_t nsize, char* fmt, ...)
106
100
self.size = self.size - n
107
101
self.tail = &self.tail[n]
103
cdef char *_read_digits(self, char stop_char) except NULL:
106
while ((self.tail[i] >= c'0' and self.tail[i] <= c'9') or
107
self.tail[i] == c'-') and i < self.size:
110
if self.tail[i] != stop_char:
111
raise ValueError("Stop character %c not found: %c" %
112
(stop_char, self.tail[i]))
113
if (self.tail[0] == c'0' or
114
(self.tail[0] == c'-' and self.tail[1] == c'0')):
116
self._update_tail(i+1)
117
return strndup("0", 1)
119
raise ValueError # leading zeroes are not allowed
120
ret = <char*>strndup(self.tail, i)
123
self._update_tail(i+1)
109
126
cdef object _decode_int(self):
111
result = self._decode_int_until(c'e')
112
if result != self._MAXINT:
117
cdef int _decode_int_until(self, char stop_char) except? -1:
118
"""Decode int from stream until stop_char encountered"""
125
for n from 0 <= n < self.size:
126
if self.tail[n] == stop_char:
132
if c'-' == self.tail[0]:
136
raise ValueError # ie / i-e
138
if self.tail[sign] == c'0': # special check for zero
140
raise ValueError # i-0e
142
raise ValueError # i00e / i01e
143
self._update_tail(n+1)
146
if n-sign < self._MAXN:
149
for i from sign <= i < n:
151
if c'0' <= digit <= c'9':
152
result = result * 10 + (digit - c'0')
157
self._update_tail(n+1)
160
result = self._MAXINT
161
longstr = <char*>malloc(n+1)
164
memcpy(longstr, self.tail, n)
166
self._longint = PyLong_FromString(longstr, NULL, 10)
168
self._update_tail(n+1)
127
cdef char *longstr, *tail
128
longstr = self._read_digits(c'e')
129
result = PyLong_FromString(longstr, &tail, 10)
172
133
cdef object _decode_string(self):
134
cdef char *longstr, *tail
175
n = self._decode_int_until(c':')
136
longstr = self._read_digits(c':')
138
n = strtol(longstr, &tail, 10)
140
raise ValueError("Tail invalid: %s" % longstr)
178
if n == self._MAXINT:
179
# strings longer than 1GB is not supported
180
raise ValueError('too long string')
181
144
if n > self.size:
182
145
raise ValueError('stream underflow')