blob: 863a30f41196222492263b0328d8477b06c209e1 [file] [log] [blame]
Christian Heimes90540002008-05-08 14:29:10 +00001#include "Python.h"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00002#include "structmember.h"
3#if PY_VERSION_HEX < 0x02060000 && !defined(Py_TYPE)
4#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
5#endif
6#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
7typedef int Py_ssize_t;
8#define PY_SSIZE_T_MAX INT_MAX
9#define PY_SSIZE_T_MIN INT_MIN
10#define PyInt_FromSsize_t PyInt_FromLong
11#define PyInt_AsSsize_t PyInt_AsLong
12#endif
13#ifndef Py_IS_FINITE
14#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
15#endif
Christian Heimes90540002008-05-08 14:29:10 +000016
Benjamin Petersonc6b607d2009-05-02 12:36:44 +000017#ifdef __GNUC__
18#define UNUSED __attribute__((__unused__))
19#else
20#define UNUSED
21#endif
22
23#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType)
24#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType)
25#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType)
26#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType)
27
28static PyTypeObject PyScannerType;
29static PyTypeObject PyEncoderType;
30
31typedef struct _PyScannerObject {
32 PyObject_HEAD
33 PyObject *strict;
34 PyObject *object_hook;
35 PyObject *object_pairs_hook;
36 PyObject *parse_float;
37 PyObject *parse_int;
38 PyObject *parse_constant;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +000039 PyObject *memo;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +000040} PyScannerObject;
41
42static PyMemberDef scanner_members[] = {
43 {"strict", T_OBJECT, offsetof(PyScannerObject, strict), READONLY, "strict"},
44 {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"},
45 {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY},
46 {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"},
47 {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"},
48 {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"},
49 {NULL}
50};
51
52typedef struct _PyEncoderObject {
53 PyObject_HEAD
54 PyObject *markers;
55 PyObject *defaultfn;
56 PyObject *encoder;
57 PyObject *indent;
58 PyObject *key_separator;
59 PyObject *item_separator;
60 PyObject *sort_keys;
61 PyObject *skipkeys;
62 int fast_encode;
63 int allow_nan;
64} PyEncoderObject;
65
66static PyMemberDef encoder_members[] = {
67 {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"},
68 {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"},
69 {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"},
70 {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"},
71 {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"},
72 {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"},
73 {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
74 {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"},
75 {NULL}
76};
77
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +020078/*
79 * A two-level accumulator of unicode objects that avoids both the overhead
80 * of keeping a huge number of small separate objects, and the quadratic
81 * behaviour of using a naive repeated concatenation scheme.
82 */
83
84typedef struct {
85 PyObject *large; /* A list of previously accumulated large strings */
86 PyObject *small; /* Pending small strings */
87} accumulator;
88
89static PyObject *
90join_list_unicode(PyObject *lst)
91{
92 /* return u''.join(lst) */
93 static PyObject *sep = NULL;
94 if (sep == NULL) {
95 sep = PyUnicode_FromStringAndSize("", 0);
96 if (sep == NULL)
97 return NULL;
98 }
99 return PyUnicode_Join(sep, lst);
100}
101
102static int
103init_accumulator(accumulator *acc)
104{
105 acc->large = PyList_New(0);
106 if (acc->large == NULL)
107 return -1;
108 acc->small = PyList_New(0);
109 if (acc->small == NULL) {
110 Py_CLEAR(acc->large);
111 return -1;
112 }
113 return 0;
114}
115
116static int
117flush_accumulator(accumulator *acc)
118{
119 Py_ssize_t nsmall = PyList_GET_SIZE(acc->small);
120 if (nsmall) {
121 int ret;
122 PyObject *joined = join_list_unicode(acc->small);
123 if (joined == NULL)
124 return -1;
125 if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) {
126 Py_DECREF(joined);
127 return -1;
128 }
129 ret = PyList_Append(acc->large, joined);
130 Py_DECREF(joined);
131 return ret;
132 }
133 return 0;
134}
135
136static int
137accumulate_unicode(accumulator *acc, PyObject *obj)
138{
139 int ret;
140 Py_ssize_t nsmall;
Antoine Pitrou18bb3302011-08-20 03:19:34 +0200141 PyObject *joined;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +0200142 assert(PyUnicode_Check(obj));
143
144 if (PyList_Append(acc->small, obj))
145 return -1;
146 nsmall = PyList_GET_SIZE(acc->small);
147 /* Each item in a list of unicode objects has an overhead (in 64-bit
148 * builds) of:
149 * - 8 bytes for the list slot
150 * - 56 bytes for the header of the unicode object
151 * that is, 64 bytes. 100000 such objects waste more than 6MB
152 * compared to a single concatenated string.
153 */
154 if (nsmall < 100000)
155 return 0;
Antoine Pitrou18bb3302011-08-20 03:19:34 +0200156 joined = join_list_unicode(acc->small);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +0200157 if (joined == NULL)
158 return -1;
159 if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) {
160 Py_DECREF(joined);
161 return -1;
162 }
163 ret = PyList_Append(acc->large, joined);
164 Py_DECREF(joined);
165 return ret;
166}
167
168static PyObject *
169finish_accumulator(accumulator *acc)
170{
171 int ret;
172 PyObject *res;
173
174 ret = flush_accumulator(acc);
175 Py_CLEAR(acc->small);
176 if (ret) {
177 Py_CLEAR(acc->large);
178 return NULL;
179 }
180 res = acc->large;
181 acc->large = NULL;
182 return res;
183}
184
185static void
186destroy_accumulator(accumulator *acc)
187{
188 Py_CLEAR(acc->small);
189 Py_CLEAR(acc->large);
190}
191
192/* Forward decls */
193
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000194static PyObject *
195ascii_escape_unicode(PyObject *pystr);
196static PyObject *
197py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr);
198void init_json(void);
199static PyObject *
200scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
201static PyObject *
202_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
203static PyObject *
204scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
205static int
206scanner_init(PyObject *self, PyObject *args, PyObject *kwds);
207static void
208scanner_dealloc(PyObject *self);
209static int
210scanner_clear(PyObject *self);
211static PyObject *
212encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
213static int
214encoder_init(PyObject *self, PyObject *args, PyObject *kwds);
215static void
216encoder_dealloc(PyObject *self);
217static int
218encoder_clear(PyObject *self);
219static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +0200220encoder_listencode_list(PyEncoderObject *s, accumulator *acc, PyObject *seq, Py_ssize_t indent_level);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000221static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +0200222encoder_listencode_obj(PyEncoderObject *s, accumulator *acc, PyObject *obj, Py_ssize_t indent_level);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000223static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +0200224encoder_listencode_dict(PyEncoderObject *s, accumulator *acc, PyObject *dct, Py_ssize_t indent_level);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000225static PyObject *
Hirokazu Yamamotofecf5d12009-05-02 15:55:19 +0000226_encoded_const(PyObject *obj);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000227static void
228raise_errmsg(char *msg, PyObject *s, Py_ssize_t end);
229static PyObject *
230encoder_encode_string(PyEncoderObject *s, PyObject *obj);
231static int
232_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr);
233static PyObject *
234_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr);
235static PyObject *
236encoder_encode_float(PyEncoderObject *s, PyObject *obj);
237
Christian Heimes90540002008-05-08 14:29:10 +0000238#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000239#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
Christian Heimes90540002008-05-08 14:29:10 +0000240
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000241static int
242_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr)
Christian Heimes90540002008-05-08 14:29:10 +0000243{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000244 /* PyObject to Py_ssize_t converter */
245 *size_ptr = PyLong_AsSsize_t(o);
Georg Brandl59682052009-05-05 07:52:05 +0000246 if (*size_ptr == -1 && PyErr_Occurred())
247 return 0;
248 return 1;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000249}
250
251static PyObject *
252_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr)
253{
254 /* Py_ssize_t to PyObject converter */
255 return PyLong_FromSsize_t(*size_ptr);
256}
257
258static Py_ssize_t
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200259ascii_escape_unichar(Py_UCS4 c, unsigned char *output, Py_ssize_t chars)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000260{
261 /* Escape unicode code point c to ASCII escape sequences
262 in char *output. output must have at least 12 bytes unused to
263 accommodate an escaped surrogate pair "\uXXXX\uXXXX" */
Christian Heimes90540002008-05-08 14:29:10 +0000264 output[chars++] = '\\';
265 switch (c) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000266 case '\\': output[chars++] = c; break;
267 case '"': output[chars++] = c; break;
Christian Heimes90540002008-05-08 14:29:10 +0000268 case '\b': output[chars++] = 'b'; break;
269 case '\f': output[chars++] = 'f'; break;
270 case '\n': output[chars++] = 'n'; break;
271 case '\r': output[chars++] = 'r'; break;
272 case '\t': output[chars++] = 't'; break;
273 default:
Christian Heimes90540002008-05-08 14:29:10 +0000274 if (c >= 0x10000) {
275 /* UTF-16 surrogate pair */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200276 Py_UCS4 v = c - 0x10000;
Christian Heimes90540002008-05-08 14:29:10 +0000277 c = 0xd800 | ((v >> 10) & 0x3ff);
278 output[chars++] = 'u';
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000279 output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf];
280 output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf];
281 output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf];
282 output[chars++] = "0123456789abcdef"[(c ) & 0xf];
Christian Heimes90540002008-05-08 14:29:10 +0000283 c = 0xdc00 | (v & 0x3ff);
284 output[chars++] = '\\';
285 }
Christian Heimes90540002008-05-08 14:29:10 +0000286 output[chars++] = 'u';
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000287 output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf];
288 output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf];
289 output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf];
290 output[chars++] = "0123456789abcdef"[(c ) & 0xf];
Christian Heimes90540002008-05-08 14:29:10 +0000291 }
292 return chars;
293}
294
295static PyObject *
296ascii_escape_unicode(PyObject *pystr)
297{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000298 /* Take a PyUnicode pystr and return a new ASCII-only escaped PyUnicode */
Christian Heimes90540002008-05-08 14:29:10 +0000299 Py_ssize_t i;
300 Py_ssize_t input_chars;
301 Py_ssize_t output_size;
302 Py_ssize_t chars;
303 PyObject *rval;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200304 void *input;
305 unsigned char *output;
306 int kind;
Christian Heimes90540002008-05-08 14:29:10 +0000307
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200308 if (PyUnicode_READY(pystr) == -1)
309 return NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000310
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200311 input_chars = PyUnicode_GET_LENGTH(pystr);
312 input = PyUnicode_DATA(pystr);
313 kind = PyUnicode_KIND(pystr);
314
315 /* Compute the output size */
316 for (i = 0, output_size = 2; i < input_chars; i++) {
317 Py_UCS4 c = PyUnicode_READ(kind, input, i);
318 if (S_CHAR(c))
319 output_size++;
320 else {
321 switch(c) {
322 case '\\': case '"': case '\b': case '\f':
323 case '\n': case '\r': case '\t':
324 output_size += 2; break;
325 default:
326 output_size += c >= 0x10000 ? 12 : 6;
327 }
328 }
329 }
330
331 rval = PyUnicode_New(output_size, 127);
Christian Heimes90540002008-05-08 14:29:10 +0000332 if (rval == NULL) {
333 return NULL;
334 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200335 output = PyUnicode_1BYTE_DATA(rval);
Christian Heimes90540002008-05-08 14:29:10 +0000336 chars = 0;
337 output[chars++] = '"';
338 for (i = 0; i < input_chars; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200339 Py_UCS4 c = PyUnicode_READ(kind, input, i);
Christian Heimes90540002008-05-08 14:29:10 +0000340 if (S_CHAR(c)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000341 output[chars++] = c;
Christian Heimes90540002008-05-08 14:29:10 +0000342 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000343 else {
344 chars = ascii_escape_unichar(c, output, chars);
Christian Heimes90540002008-05-08 14:29:10 +0000345 }
Christian Heimes90540002008-05-08 14:29:10 +0000346 }
347 output[chars++] = '"';
Christian Heimes90540002008-05-08 14:29:10 +0000348 return rval;
349}
350
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000351static void
Christian Heimes90540002008-05-08 14:29:10 +0000352raise_errmsg(char *msg, PyObject *s, Py_ssize_t end)
353{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000354 /* Use the Python function json.decoder.errmsg to raise a nice
355 looking ValueError exception */
Christian Heimes90540002008-05-08 14:29:10 +0000356 static PyObject *errmsg_fn = NULL;
357 PyObject *pymsg;
358 if (errmsg_fn == NULL) {
359 PyObject *decoder = PyImport_ImportModule("json.decoder");
360 if (decoder == NULL)
361 return;
362 errmsg_fn = PyObject_GetAttrString(decoder, "errmsg");
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000363 Py_DECREF(decoder);
Christian Heimes90540002008-05-08 14:29:10 +0000364 if (errmsg_fn == NULL)
365 return;
Christian Heimes90540002008-05-08 14:29:10 +0000366 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000367 pymsg = PyObject_CallFunction(errmsg_fn, "(zOO&)", msg, s, _convertPyInt_FromSsize_t, &end);
Benjamin Petersona13d4752008-10-16 21:17:24 +0000368 if (pymsg) {
369 PyErr_SetObject(PyExc_ValueError, pymsg);
370 Py_DECREF(pymsg);
371 }
Christian Heimes90540002008-05-08 14:29:10 +0000372}
373
374static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000375_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) {
376 /* return (rval, idx) tuple, stealing reference to rval */
377 PyObject *tpl;
378 PyObject *pyidx;
379 /*
380 steal a reference to rval, returns (rval, idx)
381 */
382 if (rval == NULL) {
Christian Heimes90540002008-05-08 14:29:10 +0000383 return NULL;
384 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000385 pyidx = PyLong_FromSsize_t(idx);
386 if (pyidx == NULL) {
387 Py_DECREF(rval);
388 return NULL;
389 }
390 tpl = PyTuple_New(2);
391 if (tpl == NULL) {
392 Py_DECREF(pyidx);
393 Py_DECREF(rval);
394 return NULL;
395 }
396 PyTuple_SET_ITEM(tpl, 0, rval);
397 PyTuple_SET_ITEM(tpl, 1, pyidx);
398 return tpl;
Christian Heimes90540002008-05-08 14:29:10 +0000399}
400
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000401#define APPEND_OLD_CHUNK \
402 if (chunk != NULL) { \
403 if (chunks == NULL) { \
404 chunks = PyList_New(0); \
405 if (chunks == NULL) { \
406 goto bail; \
407 } \
408 } \
409 if (PyList_Append(chunks, chunk)) { \
410 Py_DECREF(chunk); \
411 goto bail; \
412 } \
413 Py_CLEAR(chunk); \
414 }
415
Christian Heimes90540002008-05-08 14:29:10 +0000416static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000417scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr)
Christian Heimes90540002008-05-08 14:29:10 +0000418{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000419 /* Read the JSON string from PyUnicode pystr.
420 end is the index of the first character after the quote.
421 if strict is zero then literal control characters are allowed
422 *next_end_ptr is a return-by-reference index of the character
423 after the end quote
Christian Heimes90540002008-05-08 14:29:10 +0000424
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000425 Return value is a new PyUnicode
426 */
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000427 PyObject *rval = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200428 Py_ssize_t len;
Christian Heimes90540002008-05-08 14:29:10 +0000429 Py_ssize_t begin = end - 1;
Brett Cannonb94767f2011-02-22 20:15:44 +0000430 Py_ssize_t next /* = begin */;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200431 const void *buf;
432 int kind;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000433 PyObject *chunks = NULL;
434 PyObject *chunk = NULL;
435
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200436 if (PyUnicode_READY(pystr) == -1)
437 return 0;
438
439 len = PyUnicode_GET_LENGTH(pystr);
440 buf = PyUnicode_DATA(pystr);
441 kind = PyUnicode_KIND(pystr);
442
Benjamin Peterson7af6eec2008-07-19 22:26:35 +0000443 if (end < 0 || len <= end) {
444 PyErr_SetString(PyExc_ValueError, "end is out of bounds");
445 goto bail;
446 }
Christian Heimes90540002008-05-08 14:29:10 +0000447 while (1) {
448 /* Find the end of the string or the next escape */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200449 Py_UCS4 c = 0;
Christian Heimes90540002008-05-08 14:29:10 +0000450 for (next = end; next < len; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200451 c = PyUnicode_READ(kind, buf, next);
Christian Heimes90540002008-05-08 14:29:10 +0000452 if (c == '"' || c == '\\') {
453 break;
454 }
455 else if (strict && c <= 0x1f) {
Benjamin Peterson7af6eec2008-07-19 22:26:35 +0000456 raise_errmsg("Invalid control character at", pystr, next);
Christian Heimes90540002008-05-08 14:29:10 +0000457 goto bail;
458 }
459 }
460 if (!(c == '"' || c == '\\')) {
461 raise_errmsg("Unterminated string starting at", pystr, begin);
462 goto bail;
463 }
464 /* Pick up this chunk if it's not zero length */
465 if (next != end) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000466 APPEND_OLD_CHUNK
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200467 chunk = PyUnicode_FromKindAndData(
468 kind,
469 (char*)buf + PyUnicode_KIND_SIZE(kind, end),
470 next - end);
Christian Heimes90540002008-05-08 14:29:10 +0000471 if (chunk == NULL) {
472 goto bail;
473 }
Christian Heimes90540002008-05-08 14:29:10 +0000474 }
475 next++;
476 if (c == '"') {
477 end = next;
478 break;
479 }
480 if (next == len) {
481 raise_errmsg("Unterminated string starting at", pystr, begin);
482 goto bail;
483 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200484 c = PyUnicode_READ(kind, buf, next);
Christian Heimes90540002008-05-08 14:29:10 +0000485 if (c != 'u') {
486 /* Non-unicode backslash escapes */
487 end = next + 1;
488 switch (c) {
489 case '"': break;
490 case '\\': break;
491 case '/': break;
492 case 'b': c = '\b'; break;
493 case 'f': c = '\f'; break;
494 case 'n': c = '\n'; break;
495 case 'r': c = '\r'; break;
496 case 't': c = '\t'; break;
497 default: c = 0;
498 }
499 if (c == 0) {
500 raise_errmsg("Invalid \\escape", pystr, end - 2);
501 goto bail;
502 }
503 }
504 else {
505 c = 0;
506 next++;
507 end = next + 4;
508 if (end >= len) {
509 raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1);
510 goto bail;
511 }
512 /* Decode 4 hex digits */
513 for (; next < end; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200514 Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000515 c <<= 4;
Christian Heimes90540002008-05-08 14:29:10 +0000516 switch (digit) {
517 case '0': case '1': case '2': case '3': case '4':
518 case '5': case '6': case '7': case '8': case '9':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000519 c |= (digit - '0'); break;
Christian Heimes90540002008-05-08 14:29:10 +0000520 case 'a': case 'b': case 'c': case 'd': case 'e':
521 case 'f':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000522 c |= (digit - 'a' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000523 case 'A': case 'B': case 'C': case 'D': case 'E':
524 case 'F':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000525 c |= (digit - 'A' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000526 default:
527 raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
528 goto bail;
529 }
530 }
Christian Heimes90540002008-05-08 14:29:10 +0000531 /* Surrogate pair */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000532 if ((c & 0xfc00) == 0xd800) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200533 Py_UCS4 c2 = 0;
Christian Heimes90540002008-05-08 14:29:10 +0000534 if (end + 6 >= len) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000535 raise_errmsg("Unpaired high surrogate", pystr, end - 5);
536 goto bail;
Christian Heimes90540002008-05-08 14:29:10 +0000537 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200538 if (PyUnicode_READ(kind, buf, next++) != '\\' ||
539 PyUnicode_READ(kind, buf, next++) != 'u') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000540 raise_errmsg("Unpaired high surrogate", pystr, end - 5);
541 goto bail;
Christian Heimes90540002008-05-08 14:29:10 +0000542 }
543 end += 6;
544 /* Decode 4 hex digits */
545 for (; next < end; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200546 Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
Antoine Pitrou5b0e9e82010-10-09 15:24:28 +0000547 c2 <<= 4;
Christian Heimes90540002008-05-08 14:29:10 +0000548 switch (digit) {
549 case '0': case '1': case '2': case '3': case '4':
550 case '5': case '6': case '7': case '8': case '9':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000551 c2 |= (digit - '0'); break;
Christian Heimes90540002008-05-08 14:29:10 +0000552 case 'a': case 'b': case 'c': case 'd': case 'e':
553 case 'f':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000554 c2 |= (digit - 'a' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000555 case 'A': case 'B': case 'C': case 'D': case 'E':
556 case 'F':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000557 c2 |= (digit - 'A' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000558 default:
559 raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
560 goto bail;
561 }
562 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000563 if ((c2 & 0xfc00) != 0xdc00) {
564 raise_errmsg("Unpaired high surrogate", pystr, end - 5);
565 goto bail;
566 }
Christian Heimes90540002008-05-08 14:29:10 +0000567 c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00));
568 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000569 else if ((c & 0xfc00) == 0xdc00) {
570 raise_errmsg("Unpaired low surrogate", pystr, end - 5);
571 goto bail;
572 }
Christian Heimes90540002008-05-08 14:29:10 +0000573 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000574 APPEND_OLD_CHUNK
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200575 chunk = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, &c, 1);
Christian Heimes90540002008-05-08 14:29:10 +0000576 if (chunk == NULL) {
577 goto bail;
578 }
Christian Heimes90540002008-05-08 14:29:10 +0000579 }
580
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000581 if (chunks == NULL) {
582 if (chunk != NULL)
583 rval = chunk;
584 else
585 rval = PyUnicode_FromStringAndSize("", 0);
Christian Heimes90540002008-05-08 14:29:10 +0000586 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000587 else {
588 APPEND_OLD_CHUNK
589 rval = join_list_unicode(chunks);
590 if (rval == NULL) {
591 goto bail;
592 }
593 Py_CLEAR(chunks);
594 }
595
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000596 *next_end_ptr = end;
597 return rval;
Christian Heimes90540002008-05-08 14:29:10 +0000598bail:
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000599 *next_end_ptr = -1;
Christian Heimes90540002008-05-08 14:29:10 +0000600 Py_XDECREF(chunks);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000601 Py_XDECREF(chunk);
Christian Heimes90540002008-05-08 14:29:10 +0000602 return NULL;
603}
604
605PyDoc_STRVAR(pydoc_scanstring,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000606 "scanstring(string, end, strict=True) -> (string, end)\n"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000607 "\n"
608 "Scan the string s for a JSON string. End is the index of the\n"
609 "character in s after the quote that started the JSON string.\n"
610 "Unescapes all valid JSON string escape sequences and raises ValueError\n"
611 "on attempt to decode an invalid string. If strict is False then literal\n"
612 "control characters are allowed in the string.\n"
613 "\n"
614 "Returns a tuple of the decoded string and the index of the character in s\n"
615 "after the end quote."
616);
Christian Heimes90540002008-05-08 14:29:10 +0000617
618static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000619py_scanstring(PyObject* self UNUSED, PyObject *args)
Christian Heimes90540002008-05-08 14:29:10 +0000620{
621 PyObject *pystr;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000622 PyObject *rval;
Christian Heimes90540002008-05-08 14:29:10 +0000623 Py_ssize_t end;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000624 Py_ssize_t next_end = -1;
625 int strict = 1;
626 if (!PyArg_ParseTuple(args, "OO&|i:scanstring", &pystr, _convertPyInt_AsSsize_t, &end, &strict)) {
Christian Heimes90540002008-05-08 14:29:10 +0000627 return NULL;
628 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000629 if (PyUnicode_Check(pystr)) {
630 rval = scanstring_unicode(pystr, end, strict, &next_end);
Christian Heimes90540002008-05-08 14:29:10 +0000631 }
632 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 PyErr_Format(PyExc_TypeError,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000634 "first argument must be a string, not %.80s",
Christian Heimes90540002008-05-08 14:29:10 +0000635 Py_TYPE(pystr)->tp_name);
636 return NULL;
637 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000638 return _build_rval_index_tuple(rval, next_end);
Christian Heimes90540002008-05-08 14:29:10 +0000639}
640
641PyDoc_STRVAR(pydoc_encode_basestring_ascii,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000642 "encode_basestring_ascii(string) -> string\n"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000643 "\n"
644 "Return an ASCII-only JSON representation of a Python string"
645);
Christian Heimes90540002008-05-08 14:29:10 +0000646
647static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000648py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr)
Christian Heimes90540002008-05-08 14:29:10 +0000649{
650 PyObject *rval;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000651 /* Return an ASCII-only JSON representation of a Python string */
Christian Heimes90540002008-05-08 14:29:10 +0000652 /* METH_O */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000653 if (PyUnicode_Check(pystr)) {
Christian Heimes90540002008-05-08 14:29:10 +0000654 rval = ascii_escape_unicode(pystr);
655 }
656 else {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000657 PyErr_Format(PyExc_TypeError,
658 "first argument must be a string, not %.80s",
Christian Heimes90540002008-05-08 14:29:10 +0000659 Py_TYPE(pystr)->tp_name);
660 return NULL;
661 }
Christian Heimes90540002008-05-08 14:29:10 +0000662 return rval;
663}
664
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000665static void
666scanner_dealloc(PyObject *self)
667{
668 /* Deallocate scanner object */
669 scanner_clear(self);
670 Py_TYPE(self)->tp_free(self);
671}
672
673static int
674scanner_traverse(PyObject *self, visitproc visit, void *arg)
675{
676 PyScannerObject *s;
677 assert(PyScanner_Check(self));
678 s = (PyScannerObject *)self;
679 Py_VISIT(s->strict);
680 Py_VISIT(s->object_hook);
681 Py_VISIT(s->object_pairs_hook);
682 Py_VISIT(s->parse_float);
683 Py_VISIT(s->parse_int);
684 Py_VISIT(s->parse_constant);
685 return 0;
686}
687
688static int
689scanner_clear(PyObject *self)
690{
691 PyScannerObject *s;
692 assert(PyScanner_Check(self));
693 s = (PyScannerObject *)self;
694 Py_CLEAR(s->strict);
695 Py_CLEAR(s->object_hook);
696 Py_CLEAR(s->object_pairs_hook);
697 Py_CLEAR(s->parse_float);
698 Py_CLEAR(s->parse_int);
699 Py_CLEAR(s->parse_constant);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000700 Py_CLEAR(s->memo);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000701 return 0;
702}
703
704static PyObject *
705_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
706 /* Read a JSON object from PyUnicode pystr.
707 idx is the index of the first character after the opening curly brace.
708 *next_idx_ptr is a return-by-reference index to the first character after
709 the closing curly brace.
710
711 Returns a new PyObject (usually a dict, but object_hook can change that)
712 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200713 void *str;
714 int kind;
715 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000716 PyObject *val = NULL;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000717 PyObject *rval = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000718 PyObject *key = NULL;
719 int strict = PyObject_IsTrue(s->strict);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000720 int has_pairs_hook = (s->object_pairs_hook != Py_None);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000721 Py_ssize_t next_idx;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000722
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200723 if (PyUnicode_READY(pystr) == -1)
724 return NULL;
725
726 str = PyUnicode_DATA(pystr);
727 kind = PyUnicode_KIND(pystr);
728 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
729
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000730 if (has_pairs_hook)
731 rval = PyList_New(0);
732 else
733 rval = PyDict_New();
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000734 if (rval == NULL)
735 return NULL;
736
737 /* skip whitespace after { */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200738 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000739
740 /* only loop if the object is non-empty */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200741 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) != '}') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000742 while (idx <= end_idx) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000743 PyObject *memokey;
744
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000745 /* read key */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200746 if (PyUnicode_READ(kind, str, idx) != '"') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000747 raise_errmsg("Expecting property name", pystr, idx);
748 goto bail;
749 }
750 key = scanstring_unicode(pystr, idx + 1, strict, &next_idx);
751 if (key == NULL)
752 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000753 memokey = PyDict_GetItem(s->memo, key);
754 if (memokey != NULL) {
755 Py_INCREF(memokey);
756 Py_DECREF(key);
757 key = memokey;
758 }
759 else {
760 if (PyDict_SetItem(s->memo, key, key) < 0)
761 goto bail;
762 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000763 idx = next_idx;
764
765 /* skip whitespace between key and : delimiter, read :, skip whitespace */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200766 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
767 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000768 raise_errmsg("Expecting : delimiter", pystr, idx);
769 goto bail;
770 }
771 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200772 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000773
774 /* read any JSON term */
775 val = scan_once_unicode(s, pystr, idx, &next_idx);
776 if (val == NULL)
777 goto bail;
778
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000779 if (has_pairs_hook) {
780 PyObject *item = PyTuple_Pack(2, key, val);
781 if (item == NULL)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000782 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000783 Py_CLEAR(key);
784 Py_CLEAR(val);
785 if (PyList_Append(rval, item) == -1) {
786 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000787 goto bail;
788 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000789 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000790 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000791 else {
792 if (PyDict_SetItem(rval, key, val) < 0)
793 goto bail;
794 Py_CLEAR(key);
795 Py_CLEAR(val);
796 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000797 idx = next_idx;
798
799 /* skip whitespace before } or , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200800 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000801
802 /* bail if the object is closed or we didn't get the , delimiter */
803 if (idx > end_idx) break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200804 if (PyUnicode_READ(kind, str, idx) == '}') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000805 break;
806 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200807 else if (PyUnicode_READ(kind, str, idx) != ',') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000808 raise_errmsg("Expecting , delimiter", pystr, idx);
809 goto bail;
810 }
811 idx++;
812
813 /* skip whitespace after , delimiter */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200814 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000815 }
816 }
817
818 /* verify that idx < end_idx, str[idx] should be '}' */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200819 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000820 raise_errmsg("Expecting object", pystr, end_idx);
821 goto bail;
822 }
823
824 *next_idx_ptr = idx + 1;
825
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000826 if (has_pairs_hook) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000827 val = PyObject_CallFunctionObjArgs(s->object_pairs_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000828 Py_DECREF(rval);
829 return val;
830 }
831
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000832 /* if object_hook is not None: rval = object_hook(rval) */
833 if (s->object_hook != Py_None) {
834 val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000835 Py_DECREF(rval);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000836 return val;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000837 }
838 return rval;
839bail:
840 Py_XDECREF(key);
841 Py_XDECREF(val);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000842 Py_XDECREF(rval);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000843 return NULL;
844}
845
846static PyObject *
847_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
848 /* Read a JSON array from PyString pystr.
849 idx is the index of the first character after the opening brace.
850 *next_idx_ptr is a return-by-reference index to the first character after
851 the closing brace.
852
853 Returns a new PyList
854 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200855 void *str;
856 int kind;
857 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000858 PyObject *val = NULL;
859 PyObject *rval = PyList_New(0);
860 Py_ssize_t next_idx;
861 if (rval == NULL)
862 return NULL;
863
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200864 if (PyUnicode_READY(pystr) == -1)
865 return NULL;
866
867 str = PyUnicode_DATA(pystr);
868 kind = PyUnicode_KIND(pystr);
869 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
870
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000871 /* skip whitespace after [ */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200872 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000873
874 /* only loop if the array is non-empty */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200875 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) != ']') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000876 while (idx <= end_idx) {
877
878 /* read any JSON term */
879 val = scan_once_unicode(s, pystr, idx, &next_idx);
880 if (val == NULL)
881 goto bail;
882
883 if (PyList_Append(rval, val) == -1)
884 goto bail;
885
886 Py_CLEAR(val);
887 idx = next_idx;
888
889 /* skip whitespace between term and , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200890 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000891
892 /* bail if the array is closed or we didn't get the , delimiter */
893 if (idx > end_idx) break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200894 if (PyUnicode_READ(kind, str, idx) == ']') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000895 break;
896 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200897 else if (PyUnicode_READ(kind, str, idx) != ',') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000898 raise_errmsg("Expecting , delimiter", pystr, idx);
899 goto bail;
900 }
901 idx++;
902
903 /* skip whitespace after , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200904 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000905 }
906 }
907
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200908 /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */
909 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000910 raise_errmsg("Expecting object", pystr, end_idx);
911 goto bail;
912 }
913 *next_idx_ptr = idx + 1;
914 return rval;
915bail:
916 Py_XDECREF(val);
917 Py_DECREF(rval);
918 return NULL;
919}
920
921static PyObject *
922_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
923 /* Read a JSON constant from PyString pystr.
924 constant is the constant string that was found
925 ("NaN", "Infinity", "-Infinity").
926 idx is the index of the first character of the constant
927 *next_idx_ptr is a return-by-reference index to the first character after
928 the constant.
929
930 Returns the result of parse_constant
931 */
932 PyObject *cstr;
933 PyObject *rval;
934 /* constant is "NaN", "Infinity", or "-Infinity" */
935 cstr = PyUnicode_InternFromString(constant);
936 if (cstr == NULL)
937 return NULL;
938
939 /* rval = parse_constant(constant) */
940 rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL);
941 idx += PyUnicode_GET_SIZE(cstr);
942 Py_DECREF(cstr);
943 *next_idx_ptr = idx;
944 return rval;
945}
946
947static PyObject *
948_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) {
949 /* Read a JSON number from PyUnicode pystr.
950 idx is the index of the first character of the number
951 *next_idx_ptr is a return-by-reference index to the first character after
952 the number.
953
954 Returns a new PyObject representation of that number:
955 PyInt, PyLong, or PyFloat.
956 May return other types if parse_int or parse_float are set
957 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200958 void *str;
959 int kind;
960 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000961 Py_ssize_t idx = start;
962 int is_float = 0;
963 PyObject *rval;
Antoine Pitrouf6454512011-04-25 19:16:06 +0200964 PyObject *numstr = NULL;
965 PyObject *custom_func;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000966
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200967 if (PyUnicode_READY(pystr) == -1)
968 return NULL;
969
970 str = PyUnicode_DATA(pystr);
971 kind = PyUnicode_KIND(pystr);
972 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
973
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000974 /* read a sign if it's there, make sure it's not the end of the string */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200975 if (PyUnicode_READ(kind, str, idx) == '-') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000976 idx++;
977 if (idx > end_idx) {
978 PyErr_SetNone(PyExc_StopIteration);
979 return NULL;
980 }
981 }
982
983 /* read as many integer digits as we find as long as it doesn't start with 0 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200984 if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000985 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200986 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000987 }
988 /* if it starts with 0 we only expect one integer digit */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200989 else if (PyUnicode_READ(kind, str, idx) == '0') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000990 idx++;
991 }
992 /* no integer digits, error */
993 else {
994 PyErr_SetNone(PyExc_StopIteration);
995 return NULL;
996 }
997
998 /* if the next char is '.' followed by a digit then read all float digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200999 if (idx < end_idx && PyUnicode_READ(kind, str, idx) == '.' && PyUnicode_READ(kind, str, idx + 1) >= '0' && PyUnicode_READ(kind, str, idx + 1) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001000 is_float = 1;
1001 idx += 2;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001002 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001003 }
1004
1005 /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001006 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001007 Py_ssize_t e_start = idx;
1008 idx++;
1009
1010 /* read an exponent sign if present */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001011 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001012
1013 /* read all digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001014 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001015
1016 /* if we got a digit, then parse as float. if not, backtrack */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001017 if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001018 is_float = 1;
1019 }
1020 else {
1021 idx = e_start;
1022 }
1023 }
1024
Antoine Pitrouf6454512011-04-25 19:16:06 +02001025 if (is_float && s->parse_float != (PyObject *)&PyFloat_Type)
1026 custom_func = s->parse_float;
1027 else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type)
1028 custom_func = s->parse_int;
1029 else
1030 custom_func = NULL;
1031
1032 if (custom_func) {
1033 /* copy the section we determined to be a number */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001034 numstr = PyUnicode_FromKindAndData(kind,
1035 (char*)str + PyUnicode_KIND_SIZE(kind, start),
1036 idx - start);
Antoine Pitrouf6454512011-04-25 19:16:06 +02001037 if (numstr == NULL)
1038 return NULL;
1039 rval = PyObject_CallFunctionObjArgs(custom_func, numstr, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001040 }
1041 else {
Antoine Pitrouf6454512011-04-25 19:16:06 +02001042 Py_ssize_t i, n;
1043 char *buf;
1044 /* Straight conversion to ASCII, to avoid costly conversion of
1045 decimal unicode digits (which cannot appear here) */
1046 n = idx - start;
1047 numstr = PyBytes_FromStringAndSize(NULL, n);
1048 if (numstr == NULL)
1049 return NULL;
1050 buf = PyBytes_AS_STRING(numstr);
1051 for (i = 0; i < n; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001052 buf[i] = (char) PyUnicode_READ(kind, str, i + start);
Antoine Pitrouf6454512011-04-25 19:16:06 +02001053 }
1054 if (is_float)
1055 rval = PyFloat_FromString(numstr);
1056 else
1057 rval = PyLong_FromString(buf, NULL, 10);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001058 }
1059 Py_DECREF(numstr);
1060 *next_idx_ptr = idx;
1061 return rval;
1062}
1063
1064static PyObject *
1065scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
1066{
1067 /* Read one JSON term (of any kind) from PyUnicode pystr.
1068 idx is the index of the first character of the term
1069 *next_idx_ptr is a return-by-reference index to the first character after
1070 the number.
1071
1072 Returns a new PyObject representation of the term.
1073 */
Ezio Melotti362b9512011-05-07 17:58:09 +03001074 PyObject *res;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001075 void *str;
1076 int kind;
1077 Py_ssize_t length;
1078
1079 if (PyUnicode_READY(pystr) == -1)
1080 return NULL;
1081
1082 str = PyUnicode_DATA(pystr);
1083 kind = PyUnicode_KIND(pystr);
1084 length = PyUnicode_GET_LENGTH(pystr);
1085
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001086 if (idx >= length) {
1087 PyErr_SetNone(PyExc_StopIteration);
1088 return NULL;
1089 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001090
1091 switch (PyUnicode_READ(kind, str, idx)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001092 case '"':
1093 /* string */
1094 return scanstring_unicode(pystr, idx + 1,
1095 PyObject_IsTrue(s->strict),
1096 next_idx_ptr);
1097 case '{':
1098 /* object */
Ezio Melotti362b9512011-05-07 17:58:09 +03001099 if (Py_EnterRecursiveCall(" while decoding a JSON object "
1100 "from a unicode string"))
1101 return NULL;
1102 res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
1103 Py_LeaveRecursiveCall();
1104 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001105 case '[':
1106 /* array */
Ezio Melotti362b9512011-05-07 17:58:09 +03001107 if (Py_EnterRecursiveCall(" while decoding a JSON array "
1108 "from a unicode string"))
1109 return NULL;
1110 res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
1111 Py_LeaveRecursiveCall();
1112 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001113 case 'n':
1114 /* null */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001115 if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'u' && PyUnicode_READ(kind, str, idx + 2) == 'l' && PyUnicode_READ(kind, str, idx + 3) == 'l') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001116 Py_INCREF(Py_None);
1117 *next_idx_ptr = idx + 4;
1118 return Py_None;
1119 }
1120 break;
1121 case 't':
1122 /* true */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001123 if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'r' && PyUnicode_READ(kind, str, idx + 2) == 'u' && PyUnicode_READ(kind, str, idx + 3) == 'e') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001124 Py_INCREF(Py_True);
1125 *next_idx_ptr = idx + 4;
1126 return Py_True;
1127 }
1128 break;
1129 case 'f':
1130 /* false */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001131 if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
1132 PyUnicode_READ(kind, str, idx + 2) == 'l' &&
1133 PyUnicode_READ(kind, str, idx + 3) == 's' &&
1134 PyUnicode_READ(kind, str, idx + 4) == 'e') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001135 Py_INCREF(Py_False);
1136 *next_idx_ptr = idx + 5;
1137 return Py_False;
1138 }
1139 break;
1140 case 'N':
1141 /* NaN */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001142 if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
1143 PyUnicode_READ(kind, str, idx + 2) == 'N') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001144 return _parse_constant(s, "NaN", idx, next_idx_ptr);
1145 }
1146 break;
1147 case 'I':
1148 /* Infinity */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001149 if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' &&
1150 PyUnicode_READ(kind, str, idx + 2) == 'f' &&
1151 PyUnicode_READ(kind, str, idx + 3) == 'i' &&
1152 PyUnicode_READ(kind, str, idx + 4) == 'n' &&
1153 PyUnicode_READ(kind, str, idx + 5) == 'i' &&
1154 PyUnicode_READ(kind, str, idx + 6) == 't' &&
1155 PyUnicode_READ(kind, str, idx + 7) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001156 return _parse_constant(s, "Infinity", idx, next_idx_ptr);
1157 }
1158 break;
1159 case '-':
1160 /* -Infinity */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001161 if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' &&
1162 PyUnicode_READ(kind, str, idx + 2) == 'n' &&
1163 PyUnicode_READ(kind, str, idx + 3) == 'f' &&
1164 PyUnicode_READ(kind, str, idx + 4) == 'i' &&
1165 PyUnicode_READ(kind, str, idx + 5) == 'n' &&
1166 PyUnicode_READ(kind, str, idx + 6) == 'i' &&
1167 PyUnicode_READ(kind, str, idx + 7) == 't' &&
1168 PyUnicode_READ(kind, str, idx + 8) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001169 return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
1170 }
1171 break;
1172 }
1173 /* Didn't find a string, object, array, or named constant. Look for a number. */
1174 return _match_number_unicode(s, pystr, idx, next_idx_ptr);
1175}
1176
1177static PyObject *
1178scanner_call(PyObject *self, PyObject *args, PyObject *kwds)
1179{
1180 /* Python callable interface to scan_once_{str,unicode} */
1181 PyObject *pystr;
1182 PyObject *rval;
1183 Py_ssize_t idx;
1184 Py_ssize_t next_idx = -1;
1185 static char *kwlist[] = {"string", "idx", NULL};
1186 PyScannerObject *s;
1187 assert(PyScanner_Check(self));
1188 s = (PyScannerObject *)self;
1189 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:scan_once", kwlist, &pystr, _convertPyInt_AsSsize_t, &idx))
1190 return NULL;
1191
1192 if (PyUnicode_Check(pystr)) {
1193 rval = scan_once_unicode(s, pystr, idx, &next_idx);
1194 }
1195 else {
1196 PyErr_Format(PyExc_TypeError,
1197 "first argument must be a string, not %.80s",
1198 Py_TYPE(pystr)->tp_name);
1199 return NULL;
1200 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001201 PyDict_Clear(s->memo);
1202 if (rval == NULL)
1203 return NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001204 return _build_rval_index_tuple(rval, next_idx);
1205}
1206
1207static PyObject *
1208scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1209{
1210 PyScannerObject *s;
1211 s = (PyScannerObject *)type->tp_alloc(type, 0);
1212 if (s != NULL) {
1213 s->strict = NULL;
1214 s->object_hook = NULL;
1215 s->object_pairs_hook = NULL;
1216 s->parse_float = NULL;
1217 s->parse_int = NULL;
1218 s->parse_constant = NULL;
1219 }
1220 return (PyObject *)s;
1221}
1222
1223static int
1224scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
1225{
1226 /* Initialize Scanner object */
1227 PyObject *ctx;
1228 static char *kwlist[] = {"context", NULL};
1229 PyScannerObject *s;
1230
1231 assert(PyScanner_Check(self));
1232 s = (PyScannerObject *)self;
1233
1234 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
1235 return -1;
1236
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001237 if (s->memo == NULL) {
1238 s->memo = PyDict_New();
1239 if (s->memo == NULL)
1240 goto bail;
1241 }
1242
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001243 /* All of these will fail "gracefully" so we don't need to verify them */
1244 s->strict = PyObject_GetAttrString(ctx, "strict");
1245 if (s->strict == NULL)
1246 goto bail;
1247 s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
1248 if (s->object_hook == NULL)
1249 goto bail;
1250 s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook");
1251 if (s->object_pairs_hook == NULL)
1252 goto bail;
1253 s->parse_float = PyObject_GetAttrString(ctx, "parse_float");
1254 if (s->parse_float == NULL)
1255 goto bail;
1256 s->parse_int = PyObject_GetAttrString(ctx, "parse_int");
1257 if (s->parse_int == NULL)
1258 goto bail;
1259 s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant");
1260 if (s->parse_constant == NULL)
1261 goto bail;
1262
1263 return 0;
1264
1265bail:
1266 Py_CLEAR(s->strict);
1267 Py_CLEAR(s->object_hook);
1268 Py_CLEAR(s->object_pairs_hook);
1269 Py_CLEAR(s->parse_float);
1270 Py_CLEAR(s->parse_int);
1271 Py_CLEAR(s->parse_constant);
1272 return -1;
1273}
1274
1275PyDoc_STRVAR(scanner_doc, "JSON scanner object");
1276
1277static
1278PyTypeObject PyScannerType = {
1279 PyVarObject_HEAD_INIT(NULL, 0)
1280 "_json.Scanner", /* tp_name */
1281 sizeof(PyScannerObject), /* tp_basicsize */
1282 0, /* tp_itemsize */
1283 scanner_dealloc, /* tp_dealloc */
1284 0, /* tp_print */
1285 0, /* tp_getattr */
1286 0, /* tp_setattr */
1287 0, /* tp_compare */
1288 0, /* tp_repr */
1289 0, /* tp_as_number */
1290 0, /* tp_as_sequence */
1291 0, /* tp_as_mapping */
1292 0, /* tp_hash */
1293 scanner_call, /* tp_call */
1294 0, /* tp_str */
1295 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */
1296 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */
1297 0, /* tp_as_buffer */
1298 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1299 scanner_doc, /* tp_doc */
1300 scanner_traverse, /* tp_traverse */
1301 scanner_clear, /* tp_clear */
1302 0, /* tp_richcompare */
1303 0, /* tp_weaklistoffset */
1304 0, /* tp_iter */
1305 0, /* tp_iternext */
1306 0, /* tp_methods */
1307 scanner_members, /* tp_members */
1308 0, /* tp_getset */
1309 0, /* tp_base */
1310 0, /* tp_dict */
1311 0, /* tp_descr_get */
1312 0, /* tp_descr_set */
1313 0, /* tp_dictoffset */
1314 scanner_init, /* tp_init */
1315 0,/* PyType_GenericAlloc, */ /* tp_alloc */
1316 scanner_new, /* tp_new */
1317 0,/* PyObject_GC_Del, */ /* tp_free */
1318};
1319
1320static PyObject *
1321encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1322{
1323 PyEncoderObject *s;
1324 s = (PyEncoderObject *)type->tp_alloc(type, 0);
1325 if (s != NULL) {
1326 s->markers = NULL;
1327 s->defaultfn = NULL;
1328 s->encoder = NULL;
1329 s->indent = NULL;
1330 s->key_separator = NULL;
1331 s->item_separator = NULL;
1332 s->sort_keys = NULL;
1333 s->skipkeys = NULL;
1334 }
1335 return (PyObject *)s;
1336}
1337
1338static int
1339encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
1340{
1341 /* initialize Encoder object */
1342 static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
1343
1344 PyEncoderObject *s;
Antoine Pitrou781eba72009-12-08 15:57:31 +00001345 PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
1346 PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001347
1348 assert(PyEncoder_Check(self));
1349 s = (PyEncoderObject *)self;
1350
1351 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist,
Antoine Pitrou781eba72009-12-08 15:57:31 +00001352 &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator,
1353 &sort_keys, &skipkeys, &allow_nan))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001354 return -1;
1355
Antoine Pitrou781eba72009-12-08 15:57:31 +00001356 s->markers = markers;
1357 s->defaultfn = defaultfn;
1358 s->encoder = encoder;
1359 s->indent = indent;
1360 s->key_separator = key_separator;
1361 s->item_separator = item_separator;
1362 s->sort_keys = sort_keys;
1363 s->skipkeys = skipkeys;
1364 s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii);
1365 s->allow_nan = PyObject_IsTrue(allow_nan);
1366
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001367 Py_INCREF(s->markers);
1368 Py_INCREF(s->defaultfn);
1369 Py_INCREF(s->encoder);
1370 Py_INCREF(s->indent);
1371 Py_INCREF(s->key_separator);
1372 Py_INCREF(s->item_separator);
1373 Py_INCREF(s->sort_keys);
1374 Py_INCREF(s->skipkeys);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001375 return 0;
1376}
1377
1378static PyObject *
1379encoder_call(PyObject *self, PyObject *args, PyObject *kwds)
1380{
1381 /* Python callable interface to encode_listencode_obj */
1382 static char *kwlist[] = {"obj", "_current_indent_level", NULL};
1383 PyObject *obj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001384 Py_ssize_t indent_level;
1385 PyEncoderObject *s;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001386 accumulator acc;
1387
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001388 assert(PyEncoder_Check(self));
1389 s = (PyEncoderObject *)self;
1390 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:_iterencode", kwlist,
1391 &obj, _convertPyInt_AsSsize_t, &indent_level))
1392 return NULL;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001393 if (init_accumulator(&acc))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001394 return NULL;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001395 if (encoder_listencode_obj(s, &acc, obj, indent_level)) {
1396 destroy_accumulator(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001397 return NULL;
1398 }
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001399 return finish_accumulator(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001400}
1401
1402static PyObject *
1403_encoded_const(PyObject *obj)
1404{
1405 /* Return the JSON string representation of None, True, False */
1406 if (obj == Py_None) {
1407 static PyObject *s_null = NULL;
1408 if (s_null == NULL) {
1409 s_null = PyUnicode_InternFromString("null");
1410 }
1411 Py_INCREF(s_null);
1412 return s_null;
1413 }
1414 else if (obj == Py_True) {
1415 static PyObject *s_true = NULL;
1416 if (s_true == NULL) {
1417 s_true = PyUnicode_InternFromString("true");
1418 }
1419 Py_INCREF(s_true);
1420 return s_true;
1421 }
1422 else if (obj == Py_False) {
1423 static PyObject *s_false = NULL;
1424 if (s_false == NULL) {
1425 s_false = PyUnicode_InternFromString("false");
1426 }
1427 Py_INCREF(s_false);
1428 return s_false;
1429 }
1430 else {
1431 PyErr_SetString(PyExc_ValueError, "not a const");
1432 return NULL;
1433 }
1434}
1435
1436static PyObject *
1437encoder_encode_float(PyEncoderObject *s, PyObject *obj)
1438{
1439 /* Return the JSON representation of a PyFloat */
1440 double i = PyFloat_AS_DOUBLE(obj);
1441 if (!Py_IS_FINITE(i)) {
1442 if (!s->allow_nan) {
1443 PyErr_SetString(PyExc_ValueError, "Out of range float values are not JSON compliant");
1444 return NULL;
1445 }
1446 if (i > 0) {
1447 return PyUnicode_FromString("Infinity");
1448 }
1449 else if (i < 0) {
1450 return PyUnicode_FromString("-Infinity");
1451 }
1452 else {
1453 return PyUnicode_FromString("NaN");
1454 }
1455 }
1456 /* Use a better float format here? */
1457 return PyObject_Repr(obj);
1458}
1459
1460static PyObject *
1461encoder_encode_string(PyEncoderObject *s, PyObject *obj)
1462{
1463 /* Return the JSON representation of a string */
1464 if (s->fast_encode)
1465 return py_encode_basestring_ascii(NULL, obj);
1466 else
1467 return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
1468}
1469
1470static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001471_steal_accumulate(accumulator *acc, PyObject *stolen)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001472{
1473 /* Append stolen and then decrement its reference count */
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001474 int rval = accumulate_unicode(acc, stolen);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001475 Py_DECREF(stolen);
1476 return rval;
1477}
1478
1479static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001480encoder_listencode_obj(PyEncoderObject *s, accumulator *acc,
1481 PyObject *obj, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001482{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001483 /* Encode Python object obj to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001484 PyObject *newobj;
1485 int rv;
1486
1487 if (obj == Py_None || obj == Py_True || obj == Py_False) {
1488 PyObject *cstr = _encoded_const(obj);
1489 if (cstr == NULL)
1490 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001491 return _steal_accumulate(acc, cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001492 }
1493 else if (PyUnicode_Check(obj))
1494 {
1495 PyObject *encoded = encoder_encode_string(s, obj);
1496 if (encoded == NULL)
1497 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001498 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001499 }
1500 else if (PyLong_Check(obj)) {
1501 PyObject *encoded = PyObject_Str(obj);
1502 if (encoded == NULL)
1503 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001504 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001505 }
1506 else if (PyFloat_Check(obj)) {
1507 PyObject *encoded = encoder_encode_float(s, obj);
1508 if (encoded == NULL)
1509 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001510 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001511 }
1512 else if (PyList_Check(obj) || PyTuple_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001513 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1514 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001515 rv = encoder_listencode_list(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001516 Py_LeaveRecursiveCall();
1517 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001518 }
1519 else if (PyDict_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001520 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1521 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001522 rv = encoder_listencode_dict(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001523 Py_LeaveRecursiveCall();
1524 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001525 }
1526 else {
1527 PyObject *ident = NULL;
1528 if (s->markers != Py_None) {
1529 int has_key;
1530 ident = PyLong_FromVoidPtr(obj);
1531 if (ident == NULL)
1532 return -1;
1533 has_key = PyDict_Contains(s->markers, ident);
1534 if (has_key) {
1535 if (has_key != -1)
1536 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1537 Py_DECREF(ident);
1538 return -1;
1539 }
1540 if (PyDict_SetItem(s->markers, ident, obj)) {
1541 Py_DECREF(ident);
1542 return -1;
1543 }
1544 }
1545 newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL);
1546 if (newobj == NULL) {
1547 Py_XDECREF(ident);
1548 return -1;
1549 }
Ezio Melotti13672652011-05-11 01:02:56 +03001550
1551 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1552 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001553 rv = encoder_listencode_obj(s, acc, newobj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001554 Py_LeaveRecursiveCall();
1555
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001556 Py_DECREF(newobj);
1557 if (rv) {
1558 Py_XDECREF(ident);
1559 return -1;
1560 }
1561 if (ident != NULL) {
1562 if (PyDict_DelItem(s->markers, ident)) {
1563 Py_XDECREF(ident);
1564 return -1;
1565 }
1566 Py_XDECREF(ident);
1567 }
1568 return rv;
1569 }
1570}
1571
1572static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001573encoder_listencode_dict(PyEncoderObject *s, accumulator *acc,
1574 PyObject *dct, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001575{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001576 /* Encode Python dict dct a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001577 static PyObject *open_dict = NULL;
1578 static PyObject *close_dict = NULL;
1579 static PyObject *empty_dict = NULL;
1580 PyObject *kstr = NULL;
1581 PyObject *ident = NULL;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001582 PyObject *it = NULL;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001583 PyObject *items;
1584 PyObject *item = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001585 int skipkeys;
1586 Py_ssize_t idx;
1587
1588 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
1589 open_dict = PyUnicode_InternFromString("{");
1590 close_dict = PyUnicode_InternFromString("}");
1591 empty_dict = PyUnicode_InternFromString("{}");
1592 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL)
1593 return -1;
1594 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001595 if (Py_SIZE(dct) == 0)
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001596 return accumulate_unicode(acc, empty_dict);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001597
1598 if (s->markers != Py_None) {
1599 int has_key;
1600 ident = PyLong_FromVoidPtr(dct);
1601 if (ident == NULL)
1602 goto bail;
1603 has_key = PyDict_Contains(s->markers, ident);
1604 if (has_key) {
1605 if (has_key != -1)
1606 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1607 goto bail;
1608 }
1609 if (PyDict_SetItem(s->markers, ident, dct)) {
1610 goto bail;
1611 }
1612 }
1613
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001614 if (accumulate_unicode(acc, open_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001615 goto bail;
1616
1617 if (s->indent != Py_None) {
1618 /* TODO: DOES NOT RUN */
1619 indent_level += 1;
1620 /*
1621 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1622 separator = _item_separator + newline_indent
1623 buf += newline_indent
1624 */
1625 }
1626
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001627 if (PyObject_IsTrue(s->sort_keys)) {
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001628 /* First sort the keys then replace them with (key, value) tuples. */
1629 Py_ssize_t i, nitems;
1630 items = PyMapping_Keys(dct);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 if (items == NULL)
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001632 goto bail;
1633 if (!PyList_Check(items)) {
1634 PyErr_SetString(PyExc_ValueError, "keys must return list");
1635 goto bail;
1636 }
1637 if (PyList_Sort(items) < 0)
1638 goto bail;
1639 nitems = PyList_GET_SIZE(items);
1640 for (i = 0; i < nitems; i++) {
1641 PyObject *key, *value;
1642 key = PyList_GET_ITEM(items, i);
1643 value = PyDict_GetItem(dct, key);
1644 item = PyTuple_Pack(2, key, value);
1645 if (item == NULL)
1646 goto bail;
1647 PyList_SET_ITEM(items, i, item);
1648 Py_DECREF(key);
1649 }
1650 }
1651 else {
1652 items = PyMapping_Items(dct);
1653 }
1654 if (items == NULL)
Raymond Hettinger491a4cb2009-05-27 11:19:02 +00001655 goto bail;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001656 it = PyObject_GetIter(items);
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001657 Py_DECREF(items);
1658 if (it == NULL)
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001659 goto bail;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001660 skipkeys = PyObject_IsTrue(s->skipkeys);
1661 idx = 0;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001662 while ((item = PyIter_Next(it)) != NULL) {
1663 PyObject *encoded, *key, *value;
1664 if (!PyTuple_Check(item) || Py_SIZE(item) != 2) {
1665 PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
1666 goto bail;
1667 }
1668 key = PyTuple_GET_ITEM(item, 0);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001669 if (PyUnicode_Check(key)) {
1670 Py_INCREF(key);
1671 kstr = key;
1672 }
1673 else if (PyFloat_Check(key)) {
1674 kstr = encoder_encode_float(s, key);
1675 if (kstr == NULL)
1676 goto bail;
1677 }
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001678 else if (key == Py_True || key == Py_False || key == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 /* This must come before the PyLong_Check because
1680 True and False are also 1 and 0.*/
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001681 kstr = _encoded_const(key);
1682 if (kstr == NULL)
1683 goto bail;
1684 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001685 else if (PyLong_Check(key)) {
1686 kstr = PyObject_Str(key);
1687 if (kstr == NULL)
1688 goto bail;
1689 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001690 else if (skipkeys) {
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001691 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001692 continue;
1693 }
1694 else {
1695 /* TODO: include repr of key */
Doug Hellmann1c524752010-07-21 12:29:04 +00001696 PyErr_SetString(PyExc_TypeError, "keys must be a string");
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001697 goto bail;
1698 }
1699
1700 if (idx) {
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001701 if (accumulate_unicode(acc, s->item_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001702 goto bail;
1703 }
1704
1705 encoded = encoder_encode_string(s, kstr);
1706 Py_CLEAR(kstr);
1707 if (encoded == NULL)
1708 goto bail;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001709 if (accumulate_unicode(acc, encoded)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001710 Py_DECREF(encoded);
1711 goto bail;
1712 }
1713 Py_DECREF(encoded);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001714 if (accumulate_unicode(acc, s->key_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001715 goto bail;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001716
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001717 value = PyTuple_GET_ITEM(item, 1);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001718 if (encoder_listencode_obj(s, acc, value, indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001719 goto bail;
1720 idx += 1;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001721 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001722 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001723 if (PyErr_Occurred())
1724 goto bail;
1725 Py_CLEAR(it);
1726
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001727 if (ident != NULL) {
1728 if (PyDict_DelItem(s->markers, ident))
1729 goto bail;
1730 Py_CLEAR(ident);
1731 }
Brett Cannonb94767f2011-02-22 20:15:44 +00001732 /* TODO DOES NOT RUN; dead code
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001733 if (s->indent != Py_None) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001734 indent_level -= 1;
Brett Cannonb94767f2011-02-22 20:15:44 +00001735
1736 yield '\n' + (' ' * (_indent * _current_indent_level))
1737 }*/
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001738 if (accumulate_unicode(acc, close_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001739 goto bail;
1740 return 0;
1741
1742bail:
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001743 Py_XDECREF(it);
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001744 Py_XDECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001745 Py_XDECREF(kstr);
1746 Py_XDECREF(ident);
1747 return -1;
1748}
1749
1750
1751static int
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001752encoder_listencode_list(PyEncoderObject *s, accumulator *acc,
1753 PyObject *seq, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001754{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001755 /* Encode Python list seq to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001756 static PyObject *open_array = NULL;
1757 static PyObject *close_array = NULL;
1758 static PyObject *empty_array = NULL;
1759 PyObject *ident = NULL;
1760 PyObject *s_fast = NULL;
1761 Py_ssize_t num_items;
1762 PyObject **seq_items;
1763 Py_ssize_t i;
1764
1765 if (open_array == NULL || close_array == NULL || empty_array == NULL) {
1766 open_array = PyUnicode_InternFromString("[");
1767 close_array = PyUnicode_InternFromString("]");
1768 empty_array = PyUnicode_InternFromString("[]");
1769 if (open_array == NULL || close_array == NULL || empty_array == NULL)
1770 return -1;
1771 }
1772 ident = NULL;
1773 s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence");
1774 if (s_fast == NULL)
1775 return -1;
1776 num_items = PySequence_Fast_GET_SIZE(s_fast);
1777 if (num_items == 0) {
1778 Py_DECREF(s_fast);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001779 return accumulate_unicode(acc, empty_array);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001780 }
1781
1782 if (s->markers != Py_None) {
1783 int has_key;
1784 ident = PyLong_FromVoidPtr(seq);
1785 if (ident == NULL)
1786 goto bail;
1787 has_key = PyDict_Contains(s->markers, ident);
1788 if (has_key) {
1789 if (has_key != -1)
1790 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1791 goto bail;
1792 }
1793 if (PyDict_SetItem(s->markers, ident, seq)) {
1794 goto bail;
1795 }
1796 }
1797
1798 seq_items = PySequence_Fast_ITEMS(s_fast);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001799 if (accumulate_unicode(acc, open_array))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001800 goto bail;
1801 if (s->indent != Py_None) {
1802 /* TODO: DOES NOT RUN */
1803 indent_level += 1;
1804 /*
1805 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1806 separator = _item_separator + newline_indent
1807 buf += newline_indent
1808 */
1809 }
1810 for (i = 0; i < num_items; i++) {
1811 PyObject *obj = seq_items[i];
1812 if (i) {
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001813 if (accumulate_unicode(acc, s->item_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001814 goto bail;
1815 }
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001816 if (encoder_listencode_obj(s, acc, obj, indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001817 goto bail;
1818 }
1819 if (ident != NULL) {
1820 if (PyDict_DelItem(s->markers, ident))
1821 goto bail;
1822 Py_CLEAR(ident);
1823 }
Brett Cannonb94767f2011-02-22 20:15:44 +00001824
1825 /* TODO: DOES NOT RUN
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001826 if (s->indent != Py_None) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001827 indent_level -= 1;
Brett Cannonb94767f2011-02-22 20:15:44 +00001828
1829 yield '\n' + (' ' * (_indent * _current_indent_level))
1830 }*/
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001831 if (accumulate_unicode(acc, close_array))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001832 goto bail;
1833 Py_DECREF(s_fast);
1834 return 0;
1835
1836bail:
1837 Py_XDECREF(ident);
1838 Py_DECREF(s_fast);
1839 return -1;
1840}
1841
1842static void
1843encoder_dealloc(PyObject *self)
1844{
1845 /* Deallocate Encoder */
1846 encoder_clear(self);
1847 Py_TYPE(self)->tp_free(self);
1848}
1849
1850static int
1851encoder_traverse(PyObject *self, visitproc visit, void *arg)
1852{
1853 PyEncoderObject *s;
1854 assert(PyEncoder_Check(self));
1855 s = (PyEncoderObject *)self;
1856 Py_VISIT(s->markers);
1857 Py_VISIT(s->defaultfn);
1858 Py_VISIT(s->encoder);
1859 Py_VISIT(s->indent);
1860 Py_VISIT(s->key_separator);
1861 Py_VISIT(s->item_separator);
1862 Py_VISIT(s->sort_keys);
1863 Py_VISIT(s->skipkeys);
1864 return 0;
1865}
1866
1867static int
1868encoder_clear(PyObject *self)
1869{
1870 /* Deallocate Encoder */
1871 PyEncoderObject *s;
1872 assert(PyEncoder_Check(self));
1873 s = (PyEncoderObject *)self;
1874 Py_CLEAR(s->markers);
1875 Py_CLEAR(s->defaultfn);
1876 Py_CLEAR(s->encoder);
1877 Py_CLEAR(s->indent);
1878 Py_CLEAR(s->key_separator);
1879 Py_CLEAR(s->item_separator);
1880 Py_CLEAR(s->sort_keys);
1881 Py_CLEAR(s->skipkeys);
1882 return 0;
1883}
1884
1885PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable");
1886
1887static
1888PyTypeObject PyEncoderType = {
1889 PyVarObject_HEAD_INIT(NULL, 0)
1890 "_json.Encoder", /* tp_name */
1891 sizeof(PyEncoderObject), /* tp_basicsize */
1892 0, /* tp_itemsize */
1893 encoder_dealloc, /* tp_dealloc */
1894 0, /* tp_print */
1895 0, /* tp_getattr */
1896 0, /* tp_setattr */
1897 0, /* tp_compare */
1898 0, /* tp_repr */
1899 0, /* tp_as_number */
1900 0, /* tp_as_sequence */
1901 0, /* tp_as_mapping */
1902 0, /* tp_hash */
1903 encoder_call, /* tp_call */
1904 0, /* tp_str */
1905 0, /* tp_getattro */
1906 0, /* tp_setattro */
1907 0, /* tp_as_buffer */
1908 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1909 encoder_doc, /* tp_doc */
1910 encoder_traverse, /* tp_traverse */
1911 encoder_clear, /* tp_clear */
1912 0, /* tp_richcompare */
1913 0, /* tp_weaklistoffset */
1914 0, /* tp_iter */
1915 0, /* tp_iternext */
1916 0, /* tp_methods */
1917 encoder_members, /* tp_members */
1918 0, /* tp_getset */
1919 0, /* tp_base */
1920 0, /* tp_dict */
1921 0, /* tp_descr_get */
1922 0, /* tp_descr_set */
1923 0, /* tp_dictoffset */
1924 encoder_init, /* tp_init */
1925 0, /* tp_alloc */
1926 encoder_new, /* tp_new */
1927 0, /* tp_free */
1928};
1929
1930static PyMethodDef speedups_methods[] = {
1931 {"encode_basestring_ascii",
1932 (PyCFunction)py_encode_basestring_ascii,
1933 METH_O,
1934 pydoc_encode_basestring_ascii},
1935 {"scanstring",
1936 (PyCFunction)py_scanstring,
1937 METH_VARARGS,
1938 pydoc_scanstring},
Christian Heimes90540002008-05-08 14:29:10 +00001939 {NULL, NULL, 0, NULL}
1940};
1941
1942PyDoc_STRVAR(module_doc,
1943"json speedups\n");
1944
Martin v. Löwis1a214512008-06-11 05:26:20 +00001945static struct PyModuleDef jsonmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 PyModuleDef_HEAD_INIT,
1947 "_json",
1948 module_doc,
1949 -1,
1950 speedups_methods,
1951 NULL,
1952 NULL,
1953 NULL,
1954 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001955};
1956
1957PyObject*
1958PyInit__json(void)
Christian Heimes90540002008-05-08 14:29:10 +00001959{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001960 PyObject *m = PyModule_Create(&jsonmodule);
1961 if (!m)
1962 return NULL;
1963 PyScannerType.tp_new = PyType_GenericNew;
1964 if (PyType_Ready(&PyScannerType) < 0)
1965 goto fail;
1966 PyEncoderType.tp_new = PyType_GenericNew;
1967 if (PyType_Ready(&PyEncoderType) < 0)
1968 goto fail;
1969 Py_INCREF((PyObject*)&PyScannerType);
1970 if (PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType) < 0) {
1971 Py_DECREF((PyObject*)&PyScannerType);
1972 goto fail;
1973 }
1974 Py_INCREF((PyObject*)&PyEncoderType);
1975 if (PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType) < 0) {
1976 Py_DECREF((PyObject*)&PyEncoderType);
1977 goto fail;
1978 }
1979 return m;
1980 fail:
1981 Py_DECREF(m);
1982 return NULL;
Christian Heimes90540002008-05-08 14:29:10 +00001983}