Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 420 lines (377 sloc) 13.367 kb
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
1 /*
01cb3f1 @rtyler Properly escape unicode characters to their proper code points
authored
2 * Copyright 2010, R. Tyler Ballance <tyler@monkeypox.org>
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
3 *
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
7 *
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
10 *
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
15 *
d0fa568 @rtyler Update the yajl submodule reference
authored
16 * 3. Neither the name of R. Tyler Ballance nor the names of its
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
19 *
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
31 */
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
32 #include <Python.h>
33
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
34 #include <yajl/yajl_parse.h>
35 #include <yajl/yajl_gen.h>
dd6edb3 @rtyler Properly handle unicode() objects in the parser
authored
36 #include <yajl_alloc.h>
37 #include <yajl_buf.h>
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
38
d6c33a1 Add encoder/decoder.c to contain the methods for the YajlEncoder/Decoder...
R. Tyler Ballance authored
39 #include "py_yajl.h"
40
01cb3f1 @rtyler Properly escape unicode characters to their proper code points
authored
41 static const char *hexdigit = "0123456789abcdef";
42
85f3aa5 @rtyler Properly handle multiple unicode keys inside of a dictionary
authored
43 /* Located in yajl_hacks.c */
1c276f4 @rtyler When dealing with PyLong objects, pull them out as long long's and use y...
authored
44 extern yajl_gen_status yajl_gen_raw_string(yajl_gen g,
85f3aa5 @rtyler Properly handle multiple unicode keys inside of a dictionary
authored
45 const unsigned char * str, unsigned int len);
46
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
47 static yajl_gen_status ProcessObject(_YajlEncoder *self, PyObject *object)
48 {
49 yajl_gen handle = (yajl_gen)(self->_generator);
50 yajl_gen_status status = yajl_gen_in_error_state;
51 PyObject *iterator, *item;
52
53 if (object == Py_None) {
54 return yajl_gen_null(handle);
55 }
56 if (object == Py_True) {
57 return yajl_gen_bool(handle, 1);
58 }
59 if (object == Py_False) {
60 return yajl_gen_bool(handle, 0);
61 }
dd6edb3 @rtyler Properly handle unicode() objects in the parser
authored
62 if (PyUnicode_Check(object)) {
01cb3f1 @rtyler Properly escape unicode characters to their proper code points
authored
63 Py_ssize_t length = PyUnicode_GET_SIZE(object);
64 Py_UNICODE *raw_unicode = PyUnicode_AS_UNICODE(object);
65 /*
66 * Create a buffer with enough space for code-points, preceeding and
67 * following quotes and a null termination character
68 */
85f3aa5 @rtyler Properly handle multiple unicode keys inside of a dictionary
authored
69 char *buffer = (char *)(malloc(sizeof(char) * (1 + length * 6)));
01cb3f1 @rtyler Properly escape unicode characters to their proper code points
authored
70 unsigned int offset = 0;
71
72 while (length-- > 0) {
73 Py_UNICODE ch = *raw_unicode++;
74
75 /* Escape escape characters */
76 switch (ch) {
77 case '\t':
78 buffer[offset++] = '\\';
79 buffer[offset++] = 't';
80 continue;
81 break;
82 case '\n':
83 buffer[offset++] = '\\';
84 buffer[offset++] = 'n';
85 continue;
86 break;
87 case '\r':
88 buffer[offset++] = '\\';
89 buffer[offset++] = 'r';
90 continue;
91 break;
92 case '\f':
93 buffer[offset++] = '\\';
94 buffer[offset++] = 'f';
95 continue;
96 break;
97 case '\b':
98 buffer[offset++] = '\\';
99 buffer[offset++] = 'b';
100 continue;
101 break;
c619aea @rtyler Properly escape inbound slashes and double-quotes
authored
102 case '\\':
103 buffer[offset++] = '\\';
104 buffer[offset++] = '\\';
105 continue;
106 break;
107 case '\"':
108 buffer[offset++] = '\\';
109 buffer[offset++] = '\"';
110 continue;
111 break;
01cb3f1 @rtyler Properly escape unicode characters to their proper code points
authored
112 default:
113 break;
114 }
115
116 /* Map 16-bit characters to '\uxxxx' */
117 if (ch >= 256) {
118 buffer[offset++] = '\\';
119 buffer[offset++] = 'u';
120 buffer[offset++] = hexdigit[(ch >> 12) & 0x000F];
121 buffer[offset++] = hexdigit[(ch >> 8) & 0x000F];
122 buffer[offset++] = hexdigit[(ch >> 4) & 0x000F];
123 buffer[offset++] = hexdigit[ch & 0x000F];
124 continue;
125 }
126
127 /* Map non-printable US ASCII to '\u00hh' */
128 if ( (ch < 0x20) || (ch >= 0x7F) ) {
129 buffer[offset++] = '\\';
130 buffer[offset++] = 'u';
131 buffer[offset++] = '0';
132 buffer[offset++] = '0';
133 buffer[offset++] = hexdigit[(ch >> 4) & 0x0F];
134 buffer[offset++] = hexdigit[ch & 0x0F];
135 continue;
136 }
137
138 /* Handle proper ascii chars */
139 if ( (ch >= 0x20) && (ch < 0x7F) ) {
140 buffer[offset++] = (char)(ch);
141 continue;
142 }
143 }
85f3aa5 @rtyler Properly handle multiple unicode keys inside of a dictionary
authored
144 buffer[offset] = '\0';
a652ad0 Fix memory leaks in ProcessObject.
Eric Peden authored
145 status = yajl_gen_raw_string(handle, (const unsigned char *)(buffer), (unsigned int)(offset));
146 free(buffer);
147 return status;
dd6edb3 @rtyler Properly handle unicode() objects in the parser
authored
148 }
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
149 #ifdef IS_PYTHON3
150 if (PyBytes_Check(object)) {
151 #else
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
152 if (PyString_Check(object)) {
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
153 #endif
7ace2df @rtyler Cleanup some memory leaks and missed reference decrements
authored
154 const unsigned char *buffer = NULL;
0de3bbf @alphabetum int -> Py_ssize_t
alphabetum authored
155 Py_ssize_t length;
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
156 #ifdef IS_PYTHON3
157 PyBytes_AsStringAndSize(object, (char **)&buffer, &length);
158 #else
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
159 PyString_AsStringAndSize(object, (char **)&buffer, &length);
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
160 #endif
01cb3f1 @rtyler Properly escape unicode characters to their proper code points
authored
161 return yajl_gen_string(handle, buffer, (unsigned int)(length));
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
162 }
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
163 #ifndef IS_PYTHON3
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
164 if (PyInt_Check(object)) {
1c276f4 @rtyler When dealing with PyLong objects, pull them out as long long's and use y...
authored
165 long number = PyInt_AsLong(object);
166 if ( (number == -1) && (PyErr_Occurred()) ) {
167 return yajl_gen_in_error_state;
168 }
169 return yajl_gen_integer(handle, number);
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
170 }
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
171 #endif
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
172 if (PyLong_Check(object)) {
1c276f4 @rtyler When dealing with PyLong objects, pull them out as long long's and use y...
authored
173 long long number = PyLong_AsLongLong(object);
174 char *buffer = NULL;
175
176 if ( (number == -1) && (PyErr_Occurred()) ) {
177 return yajl_gen_in_error_state;;
178 }
179
180 /*
181 * Nifty trick for getting the buffer length of a long long, going
182 * to convert this long long into a buffer to be handled by
183 * yajl_gen_number()
184 */
185 unsigned int length = (unsigned int)(snprintf(NULL, 0, "%lld", number)) + 1;
186 buffer = (char *)(malloc(length));
187 snprintf(buffer, length, "%lld", number);
188 return yajl_gen_number(handle, buffer, length - 1);
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
189 }
190 if (PyFloat_Check(object)) {
191 return yajl_gen_double(handle, PyFloat_AsDouble(object));
192 }
ac1469e change ProcessObject to treat lists, tuple and generators as iterators w...
Igor authored
193 if (PyList_Check(object)||PyGen_Check(object)||PyTuple_Check(object)) {
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
194 /*
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
195 * Recurse and handle the list
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
196 */
197 iterator = PyObject_GetIter(object);
198 if (iterator == NULL)
199 goto exit;
7ace2df @rtyler Cleanup some memory leaks and missed reference decrements
authored
200 status = yajl_gen_array_open(handle);
e250426 @teepark Prevent SIGSEGV when encoding objects that refer to themselves
teepark authored
201 if (status == yajl_max_depth_exceeded) {
202 Py_XDECREF(iterator);
203 goto exit;
204 }
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
205 while ((item = PyIter_Next(iterator))) {
206 status = ProcessObject(self, item);
207 Py_XDECREF(item);
208 }
209 Py_XDECREF(iterator);
9d8d1a4 @rtyler Raise a TypeError when encountering objects that cannot be serialized
authored
210 yajl_gen_status close_status = yajl_gen_array_close(handle);
211 if (status == yajl_gen_in_error_state)
212 return status;
213 return close_status;
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
214 }
215 if (PyDict_Check(object)) {
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
216 PyObject *key, *value;
0de3bbf @alphabetum int -> Py_ssize_t
alphabetum authored
217 Py_ssize_t position = 0;
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
218
219 status = yajl_gen_map_open(handle);
e250426 @teepark Prevent SIGSEGV when encoding objects that refer to themselves
teepark authored
220 if (status == yajl_max_depth_exceeded) goto exit;
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
221 while (PyDict_Next(object, &position, &key, &value)) {
f40427c @rtyler When dealing with numbered keys in dictionaries, convert them to strings
authored
222 PyObject *newKey = key;
223
224 if ( (PyFloat_Check(key)) ||
225 #ifndef IS_PYTHON3
226 (PyInt_Check(key)) ||
227 #endif
228 (PyLong_Check(key)) ) {
9fbc542 @rtyler Encode keys properly for Python 3
authored
229
230 /*
231 * Performing the conversion separately for Python 2
232 * and Python 3 to ensure we consistently generate
233 * unicode strings in both versions
234 */
235 #ifdef IS_PYTHON3
236 newKey = PyObject_Str(key);
237 #else
f40427c @rtyler When dealing with numbered keys in dictionaries, convert them to strings
authored
238 newKey = PyObject_Unicode(key);
9fbc542 @rtyler Encode keys properly for Python 3
authored
239 #endif
f40427c @rtyler When dealing with numbered keys in dictionaries, convert them to strings
authored
240 }
241
242 status = ProcessObject(self, newKey);
a652ad0 Fix memory leaks in ProcessObject.
Eric Peden authored
243 if (key != newKey) {
244 Py_XDECREF(newKey);
245 }
e250426 @teepark Prevent SIGSEGV when encoding objects that refer to themselves
teepark authored
246 if (status == yajl_gen_in_error_state) return status;
247 if (status == yajl_max_depth_exceeded) goto exit;
248
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
249 status = ProcessObject(self, value);
e250426 @teepark Prevent SIGSEGV when encoding objects that refer to themselves
teepark authored
250 if (status == yajl_gen_in_error_state) return status;
251 if (status == yajl_max_depth_exceeded) goto exit;
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
252 }
253 return yajl_gen_map_close(handle);
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
254 }
001ba95 make yajl.(De|En)coder subclassable. Add default methode to Encoder and
Igor authored
255 else {
256 object = PyObject_CallMethod((PyObject *)self, "default", "O", object);
257 if (object==NULL)
258 goto exit;
259 status = ProcessObject(self, object);
260 return status;
261 }
262
263
c3c6853 Finish up encoding of dictionaries and strings
R. Tyler Ballance authored
264
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
265 exit:
266 return yajl_gen_in_error_state;
267 }
268
7ace2df @rtyler Cleanup some memory leaks and missed reference decrements
authored
269 yajl_alloc_funcs *y_allocs = NULL;
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
270 /* a structure used to pass context to our printer function */
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
271 struct StringAndUsedCount
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
272 {
273 PyObject * str;
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
274 size_t used;
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
275 };
276
277 static void py_yajl_printer(void * ctx,
278 const char * str,
279 unsigned int len)
280 {
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
281 struct StringAndUsedCount * sauc = (struct StringAndUsedCount *) ctx;
f82b133 @lloyd check that sauc->str is not NULL *before* dereferencing it
lloyd authored
282 size_t newsize;
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
283
284 if (!sauc || !sauc->str) return;
285
286 /* resize our string if necc */
f82b133 @lloyd check that sauc->str is not NULL *before* dereferencing it
lloyd authored
287 newsize = Py_SIZE(sauc->str);
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
288 while (sauc->used + len > newsize) newsize *= 2;
289 if (newsize != Py_SIZE(sauc->str)) {
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
290 #ifdef IS_PYTHON3
291 _PyBytes_Resize(&(sauc->str), newsize);
292 #else
6197b7f @rtyler Clean-up some irritating extra whitespace
authored
293 _PyString_Resize(&(sauc->str), newsize);
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
294 #endif
295 if (!sauc->str)
296 return;
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
297 }
298
299 /* and append data if available */
300 if (len && str) {
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
301 #ifdef IS_PYTHON3
302 memcpy((void *)(((PyBytesObject *)sauc->str)->ob_sval + sauc->used), str, len);
303 #else
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
304 memcpy((void *) (((PyStringObject *) sauc->str)->ob_sval + sauc->used), str, len);
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
305 #endif
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
306 sauc->used += len;
307 }
308 }
309
310 /* Efficiently allocate a python string of a fixed size containing uninitialized memory */
311 static PyObject * lowLevelStringAlloc(Py_ssize_t size)
312 {
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
313 #ifdef IS_PYTHON3
314 PyBytesObject * op = (PyBytesObject *)PyObject_MALLOC(sizeof(PyBytesObject) + size);
315 if (op) {
316 PyObject_INIT_VAR(op, &PyBytes_Type, size);
317 }
318 #else
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
319 PyStringObject * op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
320 if (op) {
321 PyObject_INIT_VAR(op, &PyString_Type, size);
322 op->ob_shash = -1;
323 op->ob_sstate = SSTATE_NOT_INTERNED;
324 }
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
325 #endif
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
326 return (PyObject *) op;
327 }
328
adeeb98 @rtyler Add the `indent` kwarg to yajl.dump() and yajl.dumps()
authored
329 PyObject *_internal_encode(_YajlEncoder *self, PyObject *obj, yajl_gen_config genconfig)
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
330 {
331 yajl_gen generator = NULL;
332 yajl_gen_status status;
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
333 struct StringAndUsedCount sauc;
ac438e9 @rtyler Prevent unused variable warning on Python2
authored
334 #ifdef IS_PYTHON3
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
335 PyObject *result = NULL;
ac438e9 @rtyler Prevent unused variable warning on Python2
authored
336 #endif
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
337
338 /* initialize context for our printer function which
339 * performs low level string appending, using the python
340 * string implementation as a chunked growth buffer */
341 sauc.used = 0;
342 sauc.str = lowLevelStringAlloc(PY_YAJL_CHUNK_SZ);
343
344 generator = yajl_gen_alloc2(py_yajl_printer, &genconfig, NULL, (void *) &sauc);
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
345
e485132 @rtyler Implement _internal_encode to prevent a Python method invocation
authored
346 self->_generator = generator;
347
348 status = ProcessObject(self, obj);
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
349
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
350 yajl_gen_free(generator);
351 self->_generator = NULL;
352
353 /* if resize failed inside our printer function we'll have a null sauc.str */
354 if (!sauc.str) {
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
355 PyErr_SetObject(PyExc_ValueError, PyUnicode_FromString("Allocation failure"));
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
356 return NULL;
357 }
358
9d8d1a4 @rtyler Raise a TypeError when encountering objects that cannot be serialized
authored
359 if ( (status == yajl_gen_in_error_state) ||
360 (status != yajl_gen_status_ok) ) {
215f62f @rtyler If ProcessObject() gives us a bad status, check to see if we have a Pyth...
authored
361 /*
362 * If we have an exception underneath the covers, let's raise that
363 * instead
364 */
365 if (!PyErr_Occurred()) {
366 PyErr_SetObject(PyExc_TypeError, PyUnicode_FromString("Object is not JSON serializable"));
367 }
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
368 Py_XDECREF(sauc.str);
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
369 return NULL;
370 }
371
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
372 #ifdef IS_PYTHON3
373 result = PyUnicode_DecodeUTF8(((PyBytesObject *)sauc.str)->ob_sval, sauc.used, "strict");
374 Py_XDECREF(sauc.str);
375 return result;
376 #else
7e92d48 @lloyd 5%-10% perf improvement during json encoding - use yajl's new custom pri...
lloyd authored
377 /* truncate to used size, and resize will handle the null plugging */
378 _PyString_Resize(&sauc.str, sauc.used);
379 return sauc.str;
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
380 #endif
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
381 }
382
001ba95 make yajl.(De|En)coder subclassable. Add default methode to Encoder and
Igor authored
383 PyObject *py_yajlencoder_default(PYARGS)
384 {
385 PyObject *value;
386 if (!PyArg_ParseTuple(args, "O", &value))
387 return NULL;
388 PyErr_SetObject(PyExc_TypeError, PyUnicode_FromString("Not serializable to JSON"));
389 return NULL;
390 }
391
e485132 @rtyler Implement _internal_encode to prevent a Python method invocation
authored
392 PyObject *py_yajlencoder_encode(PYARGS)
393 {
394 _YajlEncoder *encoder = (_YajlEncoder *)(self);
adeeb98 @rtyler Add the `indent` kwarg to yajl.dump() and yajl.dumps()
authored
395 yajl_gen_config config = {0, NULL};
e485132 @rtyler Implement _internal_encode to prevent a Python method invocation
authored
396 PyObject *value;
397
398 if (!PyArg_ParseTuple(args, "O", &value))
399 return NULL;
adeeb98 @rtyler Add the `indent` kwarg to yajl.dump() and yajl.dumps()
authored
400 return _internal_encode(encoder, value, config);
e485132 @rtyler Implement _internal_encode to prevent a Python method invocation
authored
401 }
402
075cdcf Beginnings of encoder support, adding some tests to ensure we're doing i...
R. Tyler Ballance authored
403 int yajlencoder_init(PYARGS)
404 {
405 _YajlEncoder *me = (_YajlEncoder *)(self);
406
407 if (!me)
408 return 1;
409 return 0;
410 }
e5adf0a @rtyler Add proper dealloc methods
authored
411
412 void yajlencoder_dealloc(_YajlEncoder *self)
413 {
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
414 #ifdef IS_PYTHON3
415 Py_TYPE(self)->tp_free((PyObject*)self);
416 #else
e5adf0a @rtyler Add proper dealloc methods
authored
417 self->ob_type->tp_free((PyObject*)self);
99e9126 @rtyler Allow yajl to be compiled out of the box for Python 2.x and 3.x
authored
418 #endif
e5adf0a @rtyler Add proper dealloc methods
authored
419 }
Something went wrong with that request. Please try again.