blob: dded2c965be57a7c2bd9d1121dd7ca023a3d21a1 [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"
Antoine Pitroud0acb412012-03-22 14:42:18 +01003#include "accu.h"
4
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00005#ifdef __GNUC__
6#define UNUSED __attribute__((__unused__))
7#else
8#define UNUSED
9#endif
10
11#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType)
12#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType)
13#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType)
14#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType)
15
16static PyTypeObject PyScannerType;
17static PyTypeObject PyEncoderType;
18
19typedef struct _PyScannerObject {
20 PyObject_HEAD
21 PyObject *strict;
22 PyObject *object_hook;
23 PyObject *object_pairs_hook;
24 PyObject *parse_float;
25 PyObject *parse_int;
26 PyObject *parse_constant;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +000027 PyObject *memo;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +000028} PyScannerObject;
29
30static PyMemberDef scanner_members[] = {
31 {"strict", T_OBJECT, offsetof(PyScannerObject, strict), READONLY, "strict"},
32 {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"},
33 {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY},
34 {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"},
35 {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"},
36 {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"},
37 {NULL}
38};
39
40typedef struct _PyEncoderObject {
41 PyObject_HEAD
42 PyObject *markers;
43 PyObject *defaultfn;
44 PyObject *encoder;
45 PyObject *indent;
46 PyObject *key_separator;
47 PyObject *item_separator;
48 PyObject *sort_keys;
49 PyObject *skipkeys;
50 int fast_encode;
51 int allow_nan;
52} PyEncoderObject;
53
54static PyMemberDef encoder_members[] = {
55 {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"},
56 {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"},
57 {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"},
58 {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"},
59 {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"},
60 {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"},
61 {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
62 {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"},
63 {NULL}
64};
65
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +020066static PyObject *
67join_list_unicode(PyObject *lst)
68{
69 /* return u''.join(lst) */
70 static PyObject *sep = NULL;
71 if (sep == NULL) {
72 sep = PyUnicode_FromStringAndSize("", 0);
73 if (sep == NULL)
74 return NULL;
75 }
76 return PyUnicode_Join(sep, lst);
77}
78
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +020079/* Forward decls */
80
Benjamin Petersonc6b607d2009-05-02 12:36:44 +000081static PyObject *
82ascii_escape_unicode(PyObject *pystr);
83static PyObject *
84py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr);
85void init_json(void);
86static PyObject *
87scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
88static PyObject *
89_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
90static PyObject *
91scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
92static int
93scanner_init(PyObject *self, PyObject *args, PyObject *kwds);
94static void
95scanner_dealloc(PyObject *self);
96static int
97scanner_clear(PyObject *self);
98static PyObject *
99encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
100static int
101encoder_init(PyObject *self, PyObject *args, PyObject *kwds);
102static void
103encoder_dealloc(PyObject *self);
104static int
105encoder_clear(PyObject *self);
106static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +0200107encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000108static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +0200109encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000110static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +0200111encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000112static PyObject *
Hirokazu Yamamotofecf5d12009-05-02 15:55:19 +0000113_encoded_const(PyObject *obj);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000114static void
115raise_errmsg(char *msg, PyObject *s, Py_ssize_t end);
116static PyObject *
117encoder_encode_string(PyEncoderObject *s, PyObject *obj);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000118static PyObject *
Ethan Furmana4998a72013-08-10 13:01:45 -0700119encoder_encode_long(PyEncoderObject* s UNUSED, PyObject *obj);
120static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000121encoder_encode_float(PyEncoderObject *s, PyObject *obj);
122
Christian Heimes90540002008-05-08 14:29:10 +0000123#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000124#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
Christian Heimes90540002008-05-08 14:29:10 +0000125
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000126static Py_ssize_t
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200127ascii_escape_unichar(Py_UCS4 c, unsigned char *output, Py_ssize_t chars)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000128{
129 /* Escape unicode code point c to ASCII escape sequences
130 in char *output. output must have at least 12 bytes unused to
131 accommodate an escaped surrogate pair "\uXXXX\uXXXX" */
Christian Heimes90540002008-05-08 14:29:10 +0000132 output[chars++] = '\\';
133 switch (c) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000134 case '\\': output[chars++] = c; break;
135 case '"': output[chars++] = c; break;
Christian Heimes90540002008-05-08 14:29:10 +0000136 case '\b': output[chars++] = 'b'; break;
137 case '\f': output[chars++] = 'f'; break;
138 case '\n': output[chars++] = 'n'; break;
139 case '\r': output[chars++] = 'r'; break;
140 case '\t': output[chars++] = 't'; break;
141 default:
Christian Heimes90540002008-05-08 14:29:10 +0000142 if (c >= 0x10000) {
143 /* UTF-16 surrogate pair */
Victor Stinner76df43d2012-10-30 01:42:39 +0100144 Py_UCS4 v = Py_UNICODE_HIGH_SURROGATE(c);
Christian Heimes90540002008-05-08 14:29:10 +0000145 output[chars++] = 'u';
Victor Stinner76df43d2012-10-30 01:42:39 +0100146 output[chars++] = Py_hexdigits[(v >> 12) & 0xf];
147 output[chars++] = Py_hexdigits[(v >> 8) & 0xf];
148 output[chars++] = Py_hexdigits[(v >> 4) & 0xf];
149 output[chars++] = Py_hexdigits[(v ) & 0xf];
150 c = Py_UNICODE_LOW_SURROGATE(c);
Christian Heimes90540002008-05-08 14:29:10 +0000151 output[chars++] = '\\';
152 }
Christian Heimes90540002008-05-08 14:29:10 +0000153 output[chars++] = 'u';
Victor Stinnerf5cff562011-10-14 02:13:11 +0200154 output[chars++] = Py_hexdigits[(c >> 12) & 0xf];
155 output[chars++] = Py_hexdigits[(c >> 8) & 0xf];
156 output[chars++] = Py_hexdigits[(c >> 4) & 0xf];
157 output[chars++] = Py_hexdigits[(c ) & 0xf];
Christian Heimes90540002008-05-08 14:29:10 +0000158 }
159 return chars;
160}
161
162static PyObject *
163ascii_escape_unicode(PyObject *pystr)
164{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000165 /* Take a PyUnicode pystr and return a new ASCII-only escaped PyUnicode */
Christian Heimes90540002008-05-08 14:29:10 +0000166 Py_ssize_t i;
167 Py_ssize_t input_chars;
168 Py_ssize_t output_size;
169 Py_ssize_t chars;
170 PyObject *rval;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200171 void *input;
172 unsigned char *output;
173 int kind;
Christian Heimes90540002008-05-08 14:29:10 +0000174
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200175 if (PyUnicode_READY(pystr) == -1)
176 return NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000177
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200178 input_chars = PyUnicode_GET_LENGTH(pystr);
179 input = PyUnicode_DATA(pystr);
180 kind = PyUnicode_KIND(pystr);
181
182 /* Compute the output size */
183 for (i = 0, output_size = 2; i < input_chars; i++) {
184 Py_UCS4 c = PyUnicode_READ(kind, input, i);
Benjamin Petersone3bfe192015-02-01 17:53:53 -0500185 Py_ssize_t d;
186 if (S_CHAR(c)) {
187 d = 1;
188 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200189 else {
190 switch(c) {
Victor Stinnerd9c06312011-10-11 21:56:19 +0200191 case '\\': case '"': case '\b': case '\f':
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200192 case '\n': case '\r': case '\t':
Benjamin Petersone3bfe192015-02-01 17:53:53 -0500193 d = 2; break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200194 default:
Benjamin Petersone3bfe192015-02-01 17:53:53 -0500195 d = c >= 0x10000 ? 12 : 6;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200196 }
197 }
Benjamin Petersone3bfe192015-02-01 17:53:53 -0500198 if (output_size > PY_SSIZE_T_MAX - d) {
199 PyErr_SetString(PyExc_OverflowError, "string is too long to escape");
200 return NULL;
201 }
202 output_size += d;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200203 }
204
205 rval = PyUnicode_New(output_size, 127);
Christian Heimes90540002008-05-08 14:29:10 +0000206 if (rval == NULL) {
207 return NULL;
208 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200209 output = PyUnicode_1BYTE_DATA(rval);
Christian Heimes90540002008-05-08 14:29:10 +0000210 chars = 0;
211 output[chars++] = '"';
212 for (i = 0; i < input_chars; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200213 Py_UCS4 c = PyUnicode_READ(kind, input, i);
Christian Heimes90540002008-05-08 14:29:10 +0000214 if (S_CHAR(c)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000215 output[chars++] = c;
Christian Heimes90540002008-05-08 14:29:10 +0000216 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000217 else {
218 chars = ascii_escape_unichar(c, output, chars);
Christian Heimes90540002008-05-08 14:29:10 +0000219 }
Christian Heimes90540002008-05-08 14:29:10 +0000220 }
221 output[chars++] = '"';
Christian Heimesf402e922013-01-03 09:21:55 +0100222#ifdef Py_DEBUG
Victor Stinner8f825062012-04-27 13:55:39 +0200223 assert(_PyUnicode_CheckConsistency(rval, 1));
Christian Heimesf402e922013-01-03 09:21:55 +0100224#endif
Christian Heimes90540002008-05-08 14:29:10 +0000225 return rval;
226}
227
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000228static void
Christian Heimes90540002008-05-08 14:29:10 +0000229raise_errmsg(char *msg, PyObject *s, Py_ssize_t end)
230{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000231 /* Use the Python function json.decoder.errmsg to raise a nice
232 looking ValueError exception */
Christian Heimes90540002008-05-08 14:29:10 +0000233 static PyObject *errmsg_fn = NULL;
234 PyObject *pymsg;
235 if (errmsg_fn == NULL) {
236 PyObject *decoder = PyImport_ImportModule("json.decoder");
237 if (decoder == NULL)
238 return;
239 errmsg_fn = PyObject_GetAttrString(decoder, "errmsg");
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000240 Py_DECREF(decoder);
Christian Heimes90540002008-05-08 14:29:10 +0000241 if (errmsg_fn == NULL)
242 return;
Christian Heimes90540002008-05-08 14:29:10 +0000243 }
Antoine Pitroucbb02842012-12-01 19:34:16 +0100244 pymsg = PyObject_CallFunction(errmsg_fn, "(zOn)", msg, s, end);
Benjamin Petersona13d4752008-10-16 21:17:24 +0000245 if (pymsg) {
246 PyErr_SetObject(PyExc_ValueError, pymsg);
247 Py_DECREF(pymsg);
248 }
Christian Heimes90540002008-05-08 14:29:10 +0000249}
250
Ezio Melotti37623ab2013-01-03 08:44:15 +0200251static void
252raise_stop_iteration(Py_ssize_t idx)
253{
254 PyObject *value = PyLong_FromSsize_t(idx);
255 if (value != NULL) {
256 PyErr_SetObject(PyExc_StopIteration, value);
257 Py_DECREF(value);
258 }
259}
260
Christian Heimes90540002008-05-08 14:29:10 +0000261static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000262_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) {
263 /* return (rval, idx) tuple, stealing reference to rval */
264 PyObject *tpl;
265 PyObject *pyidx;
266 /*
267 steal a reference to rval, returns (rval, idx)
268 */
269 if (rval == NULL) {
Christian Heimes90540002008-05-08 14:29:10 +0000270 return NULL;
271 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000272 pyidx = PyLong_FromSsize_t(idx);
273 if (pyidx == NULL) {
274 Py_DECREF(rval);
275 return NULL;
276 }
277 tpl = PyTuple_New(2);
278 if (tpl == NULL) {
279 Py_DECREF(pyidx);
280 Py_DECREF(rval);
281 return NULL;
282 }
283 PyTuple_SET_ITEM(tpl, 0, rval);
284 PyTuple_SET_ITEM(tpl, 1, pyidx);
285 return tpl;
Christian Heimes90540002008-05-08 14:29:10 +0000286}
287
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000288#define APPEND_OLD_CHUNK \
289 if (chunk != NULL) { \
290 if (chunks == NULL) { \
291 chunks = PyList_New(0); \
292 if (chunks == NULL) { \
293 goto bail; \
294 } \
295 } \
296 if (PyList_Append(chunks, chunk)) { \
Victor Stinner31a3ec32014-09-10 23:31:42 +0200297 Py_CLEAR(chunk); \
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000298 goto bail; \
299 } \
300 Py_CLEAR(chunk); \
301 }
302
Christian Heimes90540002008-05-08 14:29:10 +0000303static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000304scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr)
Christian Heimes90540002008-05-08 14:29:10 +0000305{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000306 /* Read the JSON string from PyUnicode pystr.
307 end is the index of the first character after the quote.
308 if strict is zero then literal control characters are allowed
309 *next_end_ptr is a return-by-reference index of the character
310 after the end quote
Christian Heimes90540002008-05-08 14:29:10 +0000311
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000312 Return value is a new PyUnicode
313 */
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000314 PyObject *rval = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200315 Py_ssize_t len;
Christian Heimes90540002008-05-08 14:29:10 +0000316 Py_ssize_t begin = end - 1;
Brett Cannonb94767f2011-02-22 20:15:44 +0000317 Py_ssize_t next /* = begin */;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200318 const void *buf;
319 int kind;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000320 PyObject *chunks = NULL;
321 PyObject *chunk = NULL;
322
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200323 if (PyUnicode_READY(pystr) == -1)
324 return 0;
325
326 len = PyUnicode_GET_LENGTH(pystr);
327 buf = PyUnicode_DATA(pystr);
328 kind = PyUnicode_KIND(pystr);
329
Ezio Melotti37623ab2013-01-03 08:44:15 +0200330 if (end < 0 || len < end) {
Benjamin Peterson7af6eec2008-07-19 22:26:35 +0000331 PyErr_SetString(PyExc_ValueError, "end is out of bounds");
332 goto bail;
333 }
Christian Heimes90540002008-05-08 14:29:10 +0000334 while (1) {
335 /* Find the end of the string or the next escape */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200336 Py_UCS4 c = 0;
Christian Heimes90540002008-05-08 14:29:10 +0000337 for (next = end; next < len; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200338 c = PyUnicode_READ(kind, buf, next);
Christian Heimes90540002008-05-08 14:29:10 +0000339 if (c == '"' || c == '\\') {
340 break;
341 }
342 else if (strict && c <= 0x1f) {
Benjamin Peterson7af6eec2008-07-19 22:26:35 +0000343 raise_errmsg("Invalid control character at", pystr, next);
Christian Heimes90540002008-05-08 14:29:10 +0000344 goto bail;
345 }
346 }
347 if (!(c == '"' || c == '\\')) {
348 raise_errmsg("Unterminated string starting at", pystr, begin);
349 goto bail;
350 }
351 /* Pick up this chunk if it's not zero length */
352 if (next != end) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000353 APPEND_OLD_CHUNK
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200354 chunk = PyUnicode_FromKindAndData(
355 kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200356 (char*)buf + kind * end,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200357 next - end);
Christian Heimes90540002008-05-08 14:29:10 +0000358 if (chunk == NULL) {
359 goto bail;
360 }
Christian Heimes90540002008-05-08 14:29:10 +0000361 }
362 next++;
363 if (c == '"') {
364 end = next;
365 break;
366 }
367 if (next == len) {
368 raise_errmsg("Unterminated string starting at", pystr, begin);
369 goto bail;
370 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200371 c = PyUnicode_READ(kind, buf, next);
Christian Heimes90540002008-05-08 14:29:10 +0000372 if (c != 'u') {
373 /* Non-unicode backslash escapes */
374 end = next + 1;
375 switch (c) {
376 case '"': break;
377 case '\\': break;
378 case '/': break;
379 case 'b': c = '\b'; break;
380 case 'f': c = '\f'; break;
381 case 'n': c = '\n'; break;
382 case 'r': c = '\r'; break;
383 case 't': c = '\t'; break;
384 default: c = 0;
385 }
386 if (c == 0) {
387 raise_errmsg("Invalid \\escape", pystr, end - 2);
388 goto bail;
389 }
390 }
391 else {
392 c = 0;
393 next++;
394 end = next + 4;
395 if (end >= len) {
396 raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1);
397 goto bail;
398 }
399 /* Decode 4 hex digits */
400 for (; next < end; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200401 Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000402 c <<= 4;
Christian Heimes90540002008-05-08 14:29:10 +0000403 switch (digit) {
404 case '0': case '1': case '2': case '3': case '4':
405 case '5': case '6': case '7': case '8': case '9':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000406 c |= (digit - '0'); break;
Christian Heimes90540002008-05-08 14:29:10 +0000407 case 'a': case 'b': case 'c': case 'd': case 'e':
408 case 'f':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000409 c |= (digit - 'a' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000410 case 'A': case 'B': case 'C': case 'D': case 'E':
411 case 'F':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000412 c |= (digit - 'A' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000413 default:
414 raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
415 goto bail;
416 }
417 }
Christian Heimes90540002008-05-08 14:29:10 +0000418 /* Surrogate pair */
Serhiy Storchakac93329b2013-11-26 21:25:28 +0200419 if (Py_UNICODE_IS_HIGH_SURROGATE(c) && end + 6 < len &&
420 PyUnicode_READ(kind, buf, next++) == '\\' &&
421 PyUnicode_READ(kind, buf, next++) == 'u') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200422 Py_UCS4 c2 = 0;
Christian Heimes90540002008-05-08 14:29:10 +0000423 end += 6;
424 /* Decode 4 hex digits */
425 for (; next < end; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200426 Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
Antoine Pitrou5b0e9e82010-10-09 15:24:28 +0000427 c2 <<= 4;
Christian Heimes90540002008-05-08 14:29:10 +0000428 switch (digit) {
429 case '0': case '1': case '2': case '3': case '4':
430 case '5': case '6': case '7': case '8': case '9':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000431 c2 |= (digit - '0'); break;
Christian Heimes90540002008-05-08 14:29:10 +0000432 case 'a': case 'b': case 'c': case 'd': case 'e':
433 case 'f':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000434 c2 |= (digit - 'a' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000435 case 'A': case 'B': case 'C': case 'D': case 'E':
436 case 'F':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000437 c2 |= (digit - 'A' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000438 default:
439 raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
440 goto bail;
441 }
442 }
Serhiy Storchakac93329b2013-11-26 21:25:28 +0200443 if (Py_UNICODE_IS_LOW_SURROGATE(c2))
444 c = Py_UNICODE_JOIN_SURROGATES(c, c2);
445 else
446 end -= 6;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000447 }
Christian Heimes90540002008-05-08 14:29:10 +0000448 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000449 APPEND_OLD_CHUNK
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200450 chunk = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, &c, 1);
Christian Heimes90540002008-05-08 14:29:10 +0000451 if (chunk == NULL) {
452 goto bail;
453 }
Christian Heimes90540002008-05-08 14:29:10 +0000454 }
455
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000456 if (chunks == NULL) {
457 if (chunk != NULL)
458 rval = chunk;
459 else
460 rval = PyUnicode_FromStringAndSize("", 0);
Christian Heimes90540002008-05-08 14:29:10 +0000461 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000462 else {
463 APPEND_OLD_CHUNK
464 rval = join_list_unicode(chunks);
465 if (rval == NULL) {
466 goto bail;
467 }
468 Py_CLEAR(chunks);
469 }
470
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000471 *next_end_ptr = end;
472 return rval;
Christian Heimes90540002008-05-08 14:29:10 +0000473bail:
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000474 *next_end_ptr = -1;
Christian Heimes90540002008-05-08 14:29:10 +0000475 Py_XDECREF(chunks);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000476 Py_XDECREF(chunk);
Christian Heimes90540002008-05-08 14:29:10 +0000477 return NULL;
478}
479
480PyDoc_STRVAR(pydoc_scanstring,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000481 "scanstring(string, end, strict=True) -> (string, end)\n"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000482 "\n"
483 "Scan the string s for a JSON string. End is the index of the\n"
484 "character in s after the quote that started the JSON string.\n"
485 "Unescapes all valid JSON string escape sequences and raises ValueError\n"
486 "on attempt to decode an invalid string. If strict is False then literal\n"
487 "control characters are allowed in the string.\n"
488 "\n"
489 "Returns a tuple of the decoded string and the index of the character in s\n"
490 "after the end quote."
491);
Christian Heimes90540002008-05-08 14:29:10 +0000492
493static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000494py_scanstring(PyObject* self UNUSED, PyObject *args)
Christian Heimes90540002008-05-08 14:29:10 +0000495{
496 PyObject *pystr;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000497 PyObject *rval;
Christian Heimes90540002008-05-08 14:29:10 +0000498 Py_ssize_t end;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000499 Py_ssize_t next_end = -1;
500 int strict = 1;
Antoine Pitroucbb02842012-12-01 19:34:16 +0100501 if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) {
Christian Heimes90540002008-05-08 14:29:10 +0000502 return NULL;
503 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000504 if (PyUnicode_Check(pystr)) {
505 rval = scanstring_unicode(pystr, end, strict, &next_end);
Christian Heimes90540002008-05-08 14:29:10 +0000506 }
507 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 PyErr_Format(PyExc_TypeError,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000509 "first argument must be a string, not %.80s",
Christian Heimes90540002008-05-08 14:29:10 +0000510 Py_TYPE(pystr)->tp_name);
511 return NULL;
512 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000513 return _build_rval_index_tuple(rval, next_end);
Christian Heimes90540002008-05-08 14:29:10 +0000514}
515
516PyDoc_STRVAR(pydoc_encode_basestring_ascii,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000517 "encode_basestring_ascii(string) -> string\n"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000518 "\n"
519 "Return an ASCII-only JSON representation of a Python string"
520);
Christian Heimes90540002008-05-08 14:29:10 +0000521
522static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000523py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr)
Christian Heimes90540002008-05-08 14:29:10 +0000524{
525 PyObject *rval;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000526 /* Return an ASCII-only JSON representation of a Python string */
Christian Heimes90540002008-05-08 14:29:10 +0000527 /* METH_O */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000528 if (PyUnicode_Check(pystr)) {
Christian Heimes90540002008-05-08 14:29:10 +0000529 rval = ascii_escape_unicode(pystr);
530 }
531 else {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000532 PyErr_Format(PyExc_TypeError,
533 "first argument must be a string, not %.80s",
Christian Heimes90540002008-05-08 14:29:10 +0000534 Py_TYPE(pystr)->tp_name);
535 return NULL;
536 }
Christian Heimes90540002008-05-08 14:29:10 +0000537 return rval;
538}
539
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000540static void
541scanner_dealloc(PyObject *self)
542{
543 /* Deallocate scanner object */
544 scanner_clear(self);
545 Py_TYPE(self)->tp_free(self);
546}
547
548static int
549scanner_traverse(PyObject *self, visitproc visit, void *arg)
550{
551 PyScannerObject *s;
552 assert(PyScanner_Check(self));
553 s = (PyScannerObject *)self;
554 Py_VISIT(s->strict);
555 Py_VISIT(s->object_hook);
556 Py_VISIT(s->object_pairs_hook);
557 Py_VISIT(s->parse_float);
558 Py_VISIT(s->parse_int);
559 Py_VISIT(s->parse_constant);
560 return 0;
561}
562
563static int
564scanner_clear(PyObject *self)
565{
566 PyScannerObject *s;
567 assert(PyScanner_Check(self));
568 s = (PyScannerObject *)self;
569 Py_CLEAR(s->strict);
570 Py_CLEAR(s->object_hook);
571 Py_CLEAR(s->object_pairs_hook);
572 Py_CLEAR(s->parse_float);
573 Py_CLEAR(s->parse_int);
574 Py_CLEAR(s->parse_constant);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000575 Py_CLEAR(s->memo);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000576 return 0;
577}
578
579static PyObject *
580_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
581 /* Read a JSON object from PyUnicode pystr.
582 idx is the index of the first character after the opening curly brace.
583 *next_idx_ptr is a return-by-reference index to the first character after
584 the closing curly brace.
585
586 Returns a new PyObject (usually a dict, but object_hook can change that)
587 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200588 void *str;
589 int kind;
590 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000591 PyObject *val = NULL;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000592 PyObject *rval = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000593 PyObject *key = NULL;
594 int strict = PyObject_IsTrue(s->strict);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000595 int has_pairs_hook = (s->object_pairs_hook != Py_None);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000596 Py_ssize_t next_idx;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000597
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300598 if (strict < 0)
599 return NULL;
600
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200601 if (PyUnicode_READY(pystr) == -1)
602 return NULL;
603
604 str = PyUnicode_DATA(pystr);
605 kind = PyUnicode_KIND(pystr);
606 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
607
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000608 if (has_pairs_hook)
609 rval = PyList_New(0);
610 else
611 rval = PyDict_New();
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000612 if (rval == NULL)
613 return NULL;
614
615 /* skip whitespace after { */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200616 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000617
618 /* only loop if the object is non-empty */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200619 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') {
620 while (1) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000621 PyObject *memokey;
622
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000623 /* read key */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200624 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '"') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200625 raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000626 goto bail;
627 }
628 key = scanstring_unicode(pystr, idx + 1, strict, &next_idx);
629 if (key == NULL)
630 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000631 memokey = PyDict_GetItem(s->memo, key);
632 if (memokey != NULL) {
633 Py_INCREF(memokey);
634 Py_DECREF(key);
635 key = memokey;
636 }
637 else {
638 if (PyDict_SetItem(s->memo, key, key) < 0)
639 goto bail;
640 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000641 idx = next_idx;
642
643 /* skip whitespace between key and : delimiter, read :, skip whitespace */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200644 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
645 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200646 raise_errmsg("Expecting ':' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000647 goto bail;
648 }
649 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200650 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000651
652 /* read any JSON term */
653 val = scan_once_unicode(s, pystr, idx, &next_idx);
654 if (val == NULL)
655 goto bail;
656
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000657 if (has_pairs_hook) {
658 PyObject *item = PyTuple_Pack(2, key, val);
659 if (item == NULL)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000660 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000661 Py_CLEAR(key);
662 Py_CLEAR(val);
663 if (PyList_Append(rval, item) == -1) {
664 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000665 goto bail;
666 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000667 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000668 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000669 else {
670 if (PyDict_SetItem(rval, key, val) < 0)
671 goto bail;
672 Py_CLEAR(key);
673 Py_CLEAR(val);
674 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000675 idx = next_idx;
676
677 /* skip whitespace before } or , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200678 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000679
680 /* bail if the object is closed or we didn't get the , delimiter */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200681 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == '}')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000682 break;
Ezio Melotti37623ab2013-01-03 08:44:15 +0200683 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200684 raise_errmsg("Expecting ',' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000685 goto bail;
686 }
687 idx++;
688
689 /* skip whitespace after , delimiter */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200690 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000691 }
692 }
693
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000694 *next_idx_ptr = idx + 1;
695
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000696 if (has_pairs_hook) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000697 val = PyObject_CallFunctionObjArgs(s->object_pairs_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000698 Py_DECREF(rval);
699 return val;
700 }
701
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000702 /* if object_hook is not None: rval = object_hook(rval) */
703 if (s->object_hook != Py_None) {
704 val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000705 Py_DECREF(rval);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000706 return val;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000707 }
708 return rval;
709bail:
710 Py_XDECREF(key);
711 Py_XDECREF(val);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000712 Py_XDECREF(rval);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000713 return NULL;
714}
715
716static PyObject *
717_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
718 /* Read a JSON array from PyString pystr.
719 idx is the index of the first character after the opening brace.
720 *next_idx_ptr is a return-by-reference index to the first character after
721 the closing brace.
722
723 Returns a new PyList
724 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200725 void *str;
726 int kind;
727 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000728 PyObject *val = NULL;
729 PyObject *rval = PyList_New(0);
730 Py_ssize_t next_idx;
731 if (rval == NULL)
732 return NULL;
733
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200734 if (PyUnicode_READY(pystr) == -1)
735 return NULL;
736
737 str = PyUnicode_DATA(pystr);
738 kind = PyUnicode_KIND(pystr);
739 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
740
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000741 /* skip whitespace after [ */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200742 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000743
744 /* only loop if the array is non-empty */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200745 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
746 while (1) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000747
748 /* read any JSON term */
749 val = scan_once_unicode(s, pystr, idx, &next_idx);
750 if (val == NULL)
751 goto bail;
752
753 if (PyList_Append(rval, val) == -1)
754 goto bail;
755
756 Py_CLEAR(val);
757 idx = next_idx;
758
759 /* skip whitespace between term and , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200760 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000761
762 /* bail if the array is closed or we didn't get the , delimiter */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200763 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == ']')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000764 break;
Ezio Melotti37623ab2013-01-03 08:44:15 +0200765 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200766 raise_errmsg("Expecting ',' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000767 goto bail;
768 }
769 idx++;
770
771 /* skip whitespace after , */
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 }
775
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200776 /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */
777 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200778 raise_errmsg("Expecting value", pystr, end_idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000779 goto bail;
780 }
781 *next_idx_ptr = idx + 1;
782 return rval;
783bail:
784 Py_XDECREF(val);
785 Py_DECREF(rval);
786 return NULL;
787}
788
789static PyObject *
790_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
791 /* Read a JSON constant from PyString pystr.
792 constant is the constant string that was found
793 ("NaN", "Infinity", "-Infinity").
794 idx is the index of the first character of the constant
795 *next_idx_ptr is a return-by-reference index to the first character after
796 the constant.
797
798 Returns the result of parse_constant
799 */
800 PyObject *cstr;
801 PyObject *rval;
802 /* constant is "NaN", "Infinity", or "-Infinity" */
803 cstr = PyUnicode_InternFromString(constant);
804 if (cstr == NULL)
805 return NULL;
806
807 /* rval = parse_constant(constant) */
808 rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL);
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200809 idx += PyUnicode_GET_LENGTH(cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000810 Py_DECREF(cstr);
811 *next_idx_ptr = idx;
812 return rval;
813}
814
815static PyObject *
816_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) {
817 /* Read a JSON number from PyUnicode pystr.
818 idx is the index of the first character of the number
819 *next_idx_ptr is a return-by-reference index to the first character after
820 the number.
821
822 Returns a new PyObject representation of that number:
823 PyInt, PyLong, or PyFloat.
824 May return other types if parse_int or parse_float are set
825 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200826 void *str;
827 int kind;
828 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000829 Py_ssize_t idx = start;
830 int is_float = 0;
831 PyObject *rval;
Antoine Pitrouf6454512011-04-25 19:16:06 +0200832 PyObject *numstr = NULL;
833 PyObject *custom_func;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000834
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200835 if (PyUnicode_READY(pystr) == -1)
836 return NULL;
837
838 str = PyUnicode_DATA(pystr);
839 kind = PyUnicode_KIND(pystr);
840 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
841
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000842 /* 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 +0200843 if (PyUnicode_READ(kind, str, idx) == '-') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000844 idx++;
845 if (idx > end_idx) {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200846 raise_stop_iteration(start);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000847 return NULL;
848 }
849 }
850
851 /* 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 +0200852 if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000853 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200854 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000855 }
856 /* if it starts with 0 we only expect one integer digit */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200857 else if (PyUnicode_READ(kind, str, idx) == '0') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000858 idx++;
859 }
860 /* no integer digits, error */
861 else {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200862 raise_stop_iteration(start);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000863 return NULL;
864 }
865
866 /* if the next char is '.' followed by a digit then read all float digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200867 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 +0000868 is_float = 1;
869 idx += 2;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200870 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000871 }
872
873 /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200874 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000875 Py_ssize_t e_start = idx;
876 idx++;
877
878 /* read an exponent sign if present */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200879 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000880
881 /* read all digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200882 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000883
884 /* if we got a digit, then parse as float. if not, backtrack */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200885 if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000886 is_float = 1;
887 }
888 else {
889 idx = e_start;
890 }
891 }
892
Antoine Pitrouf6454512011-04-25 19:16:06 +0200893 if (is_float && s->parse_float != (PyObject *)&PyFloat_Type)
894 custom_func = s->parse_float;
895 else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type)
896 custom_func = s->parse_int;
897 else
898 custom_func = NULL;
899
900 if (custom_func) {
901 /* copy the section we determined to be a number */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200902 numstr = PyUnicode_FromKindAndData(kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200903 (char*)str + kind * start,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200904 idx - start);
Antoine Pitrouf6454512011-04-25 19:16:06 +0200905 if (numstr == NULL)
906 return NULL;
907 rval = PyObject_CallFunctionObjArgs(custom_func, numstr, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000908 }
909 else {
Antoine Pitrouf6454512011-04-25 19:16:06 +0200910 Py_ssize_t i, n;
911 char *buf;
912 /* Straight conversion to ASCII, to avoid costly conversion of
913 decimal unicode digits (which cannot appear here) */
914 n = idx - start;
915 numstr = PyBytes_FromStringAndSize(NULL, n);
916 if (numstr == NULL)
917 return NULL;
918 buf = PyBytes_AS_STRING(numstr);
919 for (i = 0; i < n; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200920 buf[i] = (char) PyUnicode_READ(kind, str, i + start);
Antoine Pitrouf6454512011-04-25 19:16:06 +0200921 }
922 if (is_float)
923 rval = PyFloat_FromString(numstr);
924 else
925 rval = PyLong_FromString(buf, NULL, 10);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000926 }
927 Py_DECREF(numstr);
928 *next_idx_ptr = idx;
929 return rval;
930}
931
932static PyObject *
933scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
934{
935 /* Read one JSON term (of any kind) from PyUnicode pystr.
936 idx is the index of the first character of the term
937 *next_idx_ptr is a return-by-reference index to the first character after
938 the number.
939
940 Returns a new PyObject representation of the term.
941 */
Ezio Melotti362b9512011-05-07 17:58:09 +0300942 PyObject *res;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200943 void *str;
944 int kind;
945 Py_ssize_t length;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300946 int strict;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200947
948 if (PyUnicode_READY(pystr) == -1)
949 return NULL;
950
951 str = PyUnicode_DATA(pystr);
952 kind = PyUnicode_KIND(pystr);
953 length = PyUnicode_GET_LENGTH(pystr);
954
Benjamin Peterson6ef2b362014-04-14 11:45:21 -0400955 if (idx < 0) {
Benjamin Peterson9beee042014-04-14 11:46:51 -0400956 PyErr_SetString(PyExc_ValueError, "idx cannot be negative");
Benjamin Peterson6ef2b362014-04-14 11:45:21 -0400957 return NULL;
958 }
959 if (idx >= length) {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200960 raise_stop_iteration(idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000961 return NULL;
962 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200963
964 switch (PyUnicode_READ(kind, str, idx)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000965 case '"':
966 /* string */
Serhiy Storchakafa494fd2015-05-30 17:45:22 +0300967 strict = PyObject_IsTrue(s->strict);
968 if (strict < 0)
969 return NULL;
970 return scanstring_unicode(pystr, idx + 1, strict, next_idx_ptr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000971 case '{':
972 /* object */
Ezio Melotti362b9512011-05-07 17:58:09 +0300973 if (Py_EnterRecursiveCall(" while decoding a JSON object "
974 "from a unicode string"))
975 return NULL;
976 res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
977 Py_LeaveRecursiveCall();
978 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000979 case '[':
980 /* array */
Ezio Melotti362b9512011-05-07 17:58:09 +0300981 if (Py_EnterRecursiveCall(" while decoding a JSON array "
982 "from a unicode string"))
983 return NULL;
984 res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
985 Py_LeaveRecursiveCall();
986 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000987 case 'n':
988 /* null */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200989 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 +0000990 Py_INCREF(Py_None);
991 *next_idx_ptr = idx + 4;
992 return Py_None;
993 }
994 break;
995 case 't':
996 /* true */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200997 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 +0000998 Py_INCREF(Py_True);
999 *next_idx_ptr = idx + 4;
1000 return Py_True;
1001 }
1002 break;
1003 case 'f':
1004 /* false */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001005 if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
1006 PyUnicode_READ(kind, str, idx + 2) == 'l' &&
1007 PyUnicode_READ(kind, str, idx + 3) == 's' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001008 PyUnicode_READ(kind, str, idx + 4) == 'e') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001009 Py_INCREF(Py_False);
1010 *next_idx_ptr = idx + 5;
1011 return Py_False;
1012 }
1013 break;
1014 case 'N':
1015 /* NaN */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001016 if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001017 PyUnicode_READ(kind, str, idx + 2) == 'N') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001018 return _parse_constant(s, "NaN", idx, next_idx_ptr);
1019 }
1020 break;
1021 case 'I':
1022 /* Infinity */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001023 if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' &&
1024 PyUnicode_READ(kind, str, idx + 2) == 'f' &&
1025 PyUnicode_READ(kind, str, idx + 3) == 'i' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001026 PyUnicode_READ(kind, str, idx + 4) == 'n' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001027 PyUnicode_READ(kind, str, idx + 5) == 'i' &&
1028 PyUnicode_READ(kind, str, idx + 6) == 't' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001029 PyUnicode_READ(kind, str, idx + 7) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001030 return _parse_constant(s, "Infinity", idx, next_idx_ptr);
1031 }
1032 break;
1033 case '-':
1034 /* -Infinity */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001035 if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001036 PyUnicode_READ(kind, str, idx + 2) == 'n' &&
1037 PyUnicode_READ(kind, str, idx + 3) == 'f' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001038 PyUnicode_READ(kind, str, idx + 4) == 'i' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001039 PyUnicode_READ(kind, str, idx + 5) == 'n' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001040 PyUnicode_READ(kind, str, idx + 6) == 'i' &&
1041 PyUnicode_READ(kind, str, idx + 7) == 't' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001042 PyUnicode_READ(kind, str, idx + 8) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001043 return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
1044 }
1045 break;
1046 }
1047 /* Didn't find a string, object, array, or named constant. Look for a number. */
1048 return _match_number_unicode(s, pystr, idx, next_idx_ptr);
1049}
1050
1051static PyObject *
1052scanner_call(PyObject *self, PyObject *args, PyObject *kwds)
1053{
1054 /* Python callable interface to scan_once_{str,unicode} */
1055 PyObject *pystr;
1056 PyObject *rval;
1057 Py_ssize_t idx;
1058 Py_ssize_t next_idx = -1;
1059 static char *kwlist[] = {"string", "idx", NULL};
1060 PyScannerObject *s;
1061 assert(PyScanner_Check(self));
1062 s = (PyScannerObject *)self;
Antoine Pitroucbb02842012-12-01 19:34:16 +01001063 if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001064 return NULL;
1065
1066 if (PyUnicode_Check(pystr)) {
1067 rval = scan_once_unicode(s, pystr, idx, &next_idx);
1068 }
1069 else {
1070 PyErr_Format(PyExc_TypeError,
1071 "first argument must be a string, not %.80s",
1072 Py_TYPE(pystr)->tp_name);
1073 return NULL;
1074 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001075 PyDict_Clear(s->memo);
1076 if (rval == NULL)
1077 return NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001078 return _build_rval_index_tuple(rval, next_idx);
1079}
1080
1081static PyObject *
1082scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1083{
1084 PyScannerObject *s;
1085 s = (PyScannerObject *)type->tp_alloc(type, 0);
1086 if (s != NULL) {
1087 s->strict = NULL;
1088 s->object_hook = NULL;
1089 s->object_pairs_hook = NULL;
1090 s->parse_float = NULL;
1091 s->parse_int = NULL;
1092 s->parse_constant = NULL;
1093 }
1094 return (PyObject *)s;
1095}
1096
1097static int
1098scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
1099{
1100 /* Initialize Scanner object */
1101 PyObject *ctx;
1102 static char *kwlist[] = {"context", NULL};
1103 PyScannerObject *s;
1104
1105 assert(PyScanner_Check(self));
1106 s = (PyScannerObject *)self;
1107
1108 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
1109 return -1;
1110
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001111 if (s->memo == NULL) {
1112 s->memo = PyDict_New();
1113 if (s->memo == NULL)
1114 goto bail;
1115 }
1116
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001117 /* All of these will fail "gracefully" so we don't need to verify them */
1118 s->strict = PyObject_GetAttrString(ctx, "strict");
1119 if (s->strict == NULL)
1120 goto bail;
1121 s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
1122 if (s->object_hook == NULL)
1123 goto bail;
1124 s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook");
1125 if (s->object_pairs_hook == NULL)
1126 goto bail;
1127 s->parse_float = PyObject_GetAttrString(ctx, "parse_float");
1128 if (s->parse_float == NULL)
1129 goto bail;
1130 s->parse_int = PyObject_GetAttrString(ctx, "parse_int");
1131 if (s->parse_int == NULL)
1132 goto bail;
1133 s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant");
1134 if (s->parse_constant == NULL)
1135 goto bail;
1136
1137 return 0;
1138
1139bail:
1140 Py_CLEAR(s->strict);
1141 Py_CLEAR(s->object_hook);
1142 Py_CLEAR(s->object_pairs_hook);
1143 Py_CLEAR(s->parse_float);
1144 Py_CLEAR(s->parse_int);
1145 Py_CLEAR(s->parse_constant);
1146 return -1;
1147}
1148
1149PyDoc_STRVAR(scanner_doc, "JSON scanner object");
1150
1151static
1152PyTypeObject PyScannerType = {
1153 PyVarObject_HEAD_INIT(NULL, 0)
1154 "_json.Scanner", /* tp_name */
1155 sizeof(PyScannerObject), /* tp_basicsize */
1156 0, /* tp_itemsize */
1157 scanner_dealloc, /* tp_dealloc */
1158 0, /* tp_print */
1159 0, /* tp_getattr */
1160 0, /* tp_setattr */
1161 0, /* tp_compare */
1162 0, /* tp_repr */
1163 0, /* tp_as_number */
1164 0, /* tp_as_sequence */
1165 0, /* tp_as_mapping */
1166 0, /* tp_hash */
1167 scanner_call, /* tp_call */
1168 0, /* tp_str */
1169 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */
1170 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */
1171 0, /* tp_as_buffer */
1172 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1173 scanner_doc, /* tp_doc */
1174 scanner_traverse, /* tp_traverse */
1175 scanner_clear, /* tp_clear */
1176 0, /* tp_richcompare */
1177 0, /* tp_weaklistoffset */
1178 0, /* tp_iter */
1179 0, /* tp_iternext */
1180 0, /* tp_methods */
1181 scanner_members, /* tp_members */
1182 0, /* tp_getset */
1183 0, /* tp_base */
1184 0, /* tp_dict */
1185 0, /* tp_descr_get */
1186 0, /* tp_descr_set */
1187 0, /* tp_dictoffset */
1188 scanner_init, /* tp_init */
1189 0,/* PyType_GenericAlloc, */ /* tp_alloc */
1190 scanner_new, /* tp_new */
1191 0,/* PyObject_GC_Del, */ /* tp_free */
1192};
1193
1194static PyObject *
1195encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1196{
1197 PyEncoderObject *s;
1198 s = (PyEncoderObject *)type->tp_alloc(type, 0);
1199 if (s != NULL) {
1200 s->markers = NULL;
1201 s->defaultfn = NULL;
1202 s->encoder = NULL;
1203 s->indent = NULL;
1204 s->key_separator = NULL;
1205 s->item_separator = NULL;
1206 s->sort_keys = NULL;
1207 s->skipkeys = NULL;
1208 }
1209 return (PyObject *)s;
1210}
1211
1212static int
1213encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
1214{
1215 /* initialize Encoder object */
1216 static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
1217
1218 PyEncoderObject *s;
Antoine Pitrou781eba72009-12-08 15:57:31 +00001219 PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001220 PyObject *item_separator, *sort_keys, *skipkeys;
1221 int allow_nan;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001222
1223 assert(PyEncoder_Check(self));
1224 s = (PyEncoderObject *)self;
1225
Serhiy Storchaka83236f72015-07-26 09:01:22 +03001226 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUOOp:make_encoder", kwlist,
1227 &markers, &defaultfn, &encoder, &indent,
1228 &key_separator, &item_separator,
Antoine Pitrou781eba72009-12-08 15:57:31 +00001229 &sort_keys, &skipkeys, &allow_nan))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001230 return -1;
1231
Serhiy Storchaka83236f72015-07-26 09:01:22 +03001232 if (markers != Py_None && !PyDict_Check(markers)) {
1233 PyErr_Format(PyExc_TypeError,
1234 "make_encoder() argument 1 must be dict or None, "
1235 "not %.200s", Py_TYPE(markers)->tp_name);
1236 return -1;
1237 }
1238
Antoine Pitrou781eba72009-12-08 15:57:31 +00001239 s->markers = markers;
1240 s->defaultfn = defaultfn;
1241 s->encoder = encoder;
1242 s->indent = indent;
1243 s->key_separator = key_separator;
1244 s->item_separator = item_separator;
1245 s->sort_keys = sort_keys;
1246 s->skipkeys = skipkeys;
1247 s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001248 s->allow_nan = allow_nan;
Antoine Pitrou781eba72009-12-08 15:57:31 +00001249
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001250 Py_INCREF(s->markers);
1251 Py_INCREF(s->defaultfn);
1252 Py_INCREF(s->encoder);
1253 Py_INCREF(s->indent);
1254 Py_INCREF(s->key_separator);
1255 Py_INCREF(s->item_separator);
1256 Py_INCREF(s->sort_keys);
1257 Py_INCREF(s->skipkeys);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001258 return 0;
1259}
1260
1261static PyObject *
1262encoder_call(PyObject *self, PyObject *args, PyObject *kwds)
1263{
1264 /* Python callable interface to encode_listencode_obj */
1265 static char *kwlist[] = {"obj", "_current_indent_level", NULL};
1266 PyObject *obj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001267 Py_ssize_t indent_level;
1268 PyEncoderObject *s;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001269 _PyAccu acc;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001270
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001271 assert(PyEncoder_Check(self));
1272 s = (PyEncoderObject *)self;
Antoine Pitroucbb02842012-12-01 19:34:16 +01001273 if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist,
1274 &obj, &indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001275 return NULL;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001276 if (_PyAccu_Init(&acc))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001277 return NULL;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001278 if (encoder_listencode_obj(s, &acc, obj, indent_level)) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001279 _PyAccu_Destroy(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001280 return NULL;
1281 }
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001282 return _PyAccu_FinishAsList(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001283}
1284
1285static PyObject *
1286_encoded_const(PyObject *obj)
1287{
1288 /* Return the JSON string representation of None, True, False */
1289 if (obj == Py_None) {
1290 static PyObject *s_null = NULL;
1291 if (s_null == NULL) {
1292 s_null = PyUnicode_InternFromString("null");
1293 }
1294 Py_INCREF(s_null);
1295 return s_null;
1296 }
1297 else if (obj == Py_True) {
1298 static PyObject *s_true = NULL;
1299 if (s_true == NULL) {
1300 s_true = PyUnicode_InternFromString("true");
1301 }
1302 Py_INCREF(s_true);
1303 return s_true;
1304 }
1305 else if (obj == Py_False) {
1306 static PyObject *s_false = NULL;
1307 if (s_false == NULL) {
1308 s_false = PyUnicode_InternFromString("false");
1309 }
1310 Py_INCREF(s_false);
1311 return s_false;
1312 }
1313 else {
1314 PyErr_SetString(PyExc_ValueError, "not a const");
1315 return NULL;
1316 }
1317}
1318
1319static PyObject *
Ethan Furmana4998a72013-08-10 13:01:45 -07001320encoder_encode_long(PyEncoderObject* s UNUSED, PyObject *obj)
1321{
1322 /* Return the JSON representation of a PyLong and PyLong subclasses.
1323 Calls int() on PyLong subclasses in case the str() was changed.
1324 Added specifically to deal with IntEnum. See Issue18264. */
1325 PyObject *encoded, *longobj;
1326 if (PyLong_CheckExact(obj)) {
1327 encoded = PyObject_Str(obj);
1328 }
1329 else {
1330 longobj = PyNumber_Long(obj);
1331 if (longobj == NULL) {
1332 PyErr_SetString(
1333 PyExc_ValueError,
1334 "Unable to coerce int subclass to int"
1335 );
1336 return NULL;
1337 }
1338 encoded = PyObject_Str(longobj);
1339 Py_DECREF(longobj);
1340 }
1341 return encoded;
1342}
1343
1344
1345static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001346encoder_encode_float(PyEncoderObject *s, PyObject *obj)
1347{
Ethan Furmana4998a72013-08-10 13:01:45 -07001348 /* Return the JSON representation of a PyFloat.
1349 Modified to call float() on float subclasses in case the subclass
1350 changes the repr. See Issue18264. */
1351 PyObject *encoded, *floatobj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001352 double i = PyFloat_AS_DOUBLE(obj);
1353 if (!Py_IS_FINITE(i)) {
1354 if (!s->allow_nan) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001355 PyErr_SetString(
1356 PyExc_ValueError,
1357 "Out of range float values are not JSON compliant"
1358 );
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001359 return NULL;
1360 }
1361 if (i > 0) {
1362 return PyUnicode_FromString("Infinity");
1363 }
1364 else if (i < 0) {
1365 return PyUnicode_FromString("-Infinity");
1366 }
1367 else {
1368 return PyUnicode_FromString("NaN");
1369 }
1370 }
Ethan Furmana4998a72013-08-10 13:01:45 -07001371 /* coerce float subclasses to float (primarily for Enum) */
1372 if (PyFloat_CheckExact(obj)) {
1373 /* Use a better float format here? */
1374 encoded = PyObject_Repr(obj);
1375 }
1376 else {
1377 floatobj = PyNumber_Float(obj);
1378 if (floatobj == NULL) {
1379 PyErr_SetString(
1380 PyExc_ValueError,
1381 "Unable to coerce float subclass to float"
1382 );
1383 return NULL;
1384 }
1385 encoded = PyObject_Repr(floatobj);
1386 Py_DECREF(floatobj);
1387 }
1388 return encoded;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001389}
1390
1391static PyObject *
1392encoder_encode_string(PyEncoderObject *s, PyObject *obj)
1393{
1394 /* Return the JSON representation of a string */
1395 if (s->fast_encode)
1396 return py_encode_basestring_ascii(NULL, obj);
1397 else
1398 return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
1399}
1400
1401static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001402_steal_accumulate(_PyAccu *acc, PyObject *stolen)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001403{
1404 /* Append stolen and then decrement its reference count */
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001405 int rval = _PyAccu_Accumulate(acc, stolen);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001406 Py_DECREF(stolen);
1407 return rval;
1408}
1409
1410static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001411encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001412 PyObject *obj, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001413{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001414 /* Encode Python object obj to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001415 PyObject *newobj;
1416 int rv;
1417
1418 if (obj == Py_None || obj == Py_True || obj == Py_False) {
1419 PyObject *cstr = _encoded_const(obj);
1420 if (cstr == NULL)
1421 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001422 return _steal_accumulate(acc, cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001423 }
1424 else if (PyUnicode_Check(obj))
1425 {
1426 PyObject *encoded = encoder_encode_string(s, obj);
1427 if (encoded == NULL)
1428 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001429 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001430 }
1431 else if (PyLong_Check(obj)) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001432 PyObject *encoded = encoder_encode_long(s, obj);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001433 if (encoded == NULL)
1434 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001435 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001436 }
1437 else if (PyFloat_Check(obj)) {
1438 PyObject *encoded = encoder_encode_float(s, obj);
1439 if (encoded == NULL)
1440 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001441 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001442 }
1443 else if (PyList_Check(obj) || PyTuple_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001444 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1445 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001446 rv = encoder_listencode_list(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001447 Py_LeaveRecursiveCall();
1448 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001449 }
1450 else if (PyDict_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001451 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1452 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001453 rv = encoder_listencode_dict(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001454 Py_LeaveRecursiveCall();
1455 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001456 }
1457 else {
1458 PyObject *ident = NULL;
1459 if (s->markers != Py_None) {
1460 int has_key;
1461 ident = PyLong_FromVoidPtr(obj);
1462 if (ident == NULL)
1463 return -1;
1464 has_key = PyDict_Contains(s->markers, ident);
1465 if (has_key) {
1466 if (has_key != -1)
1467 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1468 Py_DECREF(ident);
1469 return -1;
1470 }
1471 if (PyDict_SetItem(s->markers, ident, obj)) {
1472 Py_DECREF(ident);
1473 return -1;
1474 }
1475 }
1476 newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL);
1477 if (newobj == NULL) {
1478 Py_XDECREF(ident);
1479 return -1;
1480 }
Ezio Melotti13672652011-05-11 01:02:56 +03001481
1482 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1483 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001484 rv = encoder_listencode_obj(s, acc, newobj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001485 Py_LeaveRecursiveCall();
1486
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001487 Py_DECREF(newobj);
1488 if (rv) {
1489 Py_XDECREF(ident);
1490 return -1;
1491 }
1492 if (ident != NULL) {
1493 if (PyDict_DelItem(s->markers, ident)) {
1494 Py_XDECREF(ident);
1495 return -1;
1496 }
1497 Py_XDECREF(ident);
1498 }
1499 return rv;
1500 }
1501}
1502
1503static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001504encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001505 PyObject *dct, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001506{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001507 /* Encode Python dict dct a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001508 static PyObject *open_dict = NULL;
1509 static PyObject *close_dict = NULL;
1510 static PyObject *empty_dict = NULL;
1511 PyObject *kstr = NULL;
1512 PyObject *ident = NULL;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001513 PyObject *it = NULL;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001514 PyObject *items;
1515 PyObject *item = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001516 int skipkeys;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001517 int sortkeys;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001518 Py_ssize_t idx;
1519
1520 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
1521 open_dict = PyUnicode_InternFromString("{");
1522 close_dict = PyUnicode_InternFromString("}");
1523 empty_dict = PyUnicode_InternFromString("{}");
1524 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL)
1525 return -1;
1526 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001527 if (Py_SIZE(dct) == 0)
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001528 return _PyAccu_Accumulate(acc, empty_dict);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001529
1530 if (s->markers != Py_None) {
1531 int has_key;
1532 ident = PyLong_FromVoidPtr(dct);
1533 if (ident == NULL)
1534 goto bail;
1535 has_key = PyDict_Contains(s->markers, ident);
1536 if (has_key) {
1537 if (has_key != -1)
1538 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1539 goto bail;
1540 }
1541 if (PyDict_SetItem(s->markers, ident, dct)) {
1542 goto bail;
1543 }
1544 }
1545
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001546 if (_PyAccu_Accumulate(acc, open_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001547 goto bail;
1548
1549 if (s->indent != Py_None) {
1550 /* TODO: DOES NOT RUN */
1551 indent_level += 1;
1552 /*
1553 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1554 separator = _item_separator + newline_indent
1555 buf += newline_indent
1556 */
1557 }
1558
Benjamin Peterson501182a2015-05-02 22:28:04 -04001559 items = PyMapping_Items(dct);
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001560 if (items == NULL)
Raymond Hettinger491a4cb2009-05-27 11:19:02 +00001561 goto bail;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001562 sortkeys = PyObject_IsTrue(s->sort_keys);
1563 if (sortkeys < 0 || (sortkeys && PyList_Sort(items) < 0))
Benjamin Peterson501182a2015-05-02 22:28:04 -04001564 goto bail;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001565 it = PyObject_GetIter(items);
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001566 Py_DECREF(items);
1567 if (it == NULL)
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001568 goto bail;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001569 skipkeys = PyObject_IsTrue(s->skipkeys);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001570 if (skipkeys < 0)
1571 goto bail;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001572 idx = 0;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001573 while ((item = PyIter_Next(it)) != NULL) {
1574 PyObject *encoded, *key, *value;
1575 if (!PyTuple_Check(item) || Py_SIZE(item) != 2) {
1576 PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
1577 goto bail;
1578 }
1579 key = PyTuple_GET_ITEM(item, 0);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001580 if (PyUnicode_Check(key)) {
1581 Py_INCREF(key);
1582 kstr = key;
1583 }
1584 else if (PyFloat_Check(key)) {
1585 kstr = encoder_encode_float(s, key);
1586 if (kstr == NULL)
1587 goto bail;
1588 }
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001589 else if (key == Py_True || key == Py_False || key == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 /* This must come before the PyLong_Check because
1591 True and False are also 1 and 0.*/
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001592 kstr = _encoded_const(key);
1593 if (kstr == NULL)
1594 goto bail;
1595 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001596 else if (PyLong_Check(key)) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001597 kstr = encoder_encode_long(s, key);
1598 if (kstr == NULL) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001599 goto bail;
Ethan Furmana4998a72013-08-10 13:01:45 -07001600 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001601 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001602 else if (skipkeys) {
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001603 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001604 continue;
1605 }
1606 else {
1607 /* TODO: include repr of key */
Doug Hellmann1c524752010-07-21 12:29:04 +00001608 PyErr_SetString(PyExc_TypeError, "keys must be a string");
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001609 goto bail;
1610 }
1611
1612 if (idx) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001613 if (_PyAccu_Accumulate(acc, s->item_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001614 goto bail;
1615 }
1616
1617 encoded = encoder_encode_string(s, kstr);
1618 Py_CLEAR(kstr);
1619 if (encoded == NULL)
1620 goto bail;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001621 if (_PyAccu_Accumulate(acc, encoded)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001622 Py_DECREF(encoded);
1623 goto bail;
1624 }
1625 Py_DECREF(encoded);
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001626 if (_PyAccu_Accumulate(acc, s->key_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001627 goto bail;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001628
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001629 value = PyTuple_GET_ITEM(item, 1);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001630 if (encoder_listencode_obj(s, acc, value, indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001631 goto bail;
1632 idx += 1;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001633 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001634 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001635 if (PyErr_Occurred())
1636 goto bail;
1637 Py_CLEAR(it);
1638
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001639 if (ident != NULL) {
1640 if (PyDict_DelItem(s->markers, ident))
1641 goto bail;
1642 Py_CLEAR(ident);
1643 }
Brett Cannonb94767f2011-02-22 20:15:44 +00001644 /* TODO DOES NOT RUN; dead code
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001645 if (s->indent != Py_None) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001646 indent_level -= 1;
Brett Cannonb94767f2011-02-22 20:15:44 +00001647
1648 yield '\n' + (' ' * (_indent * _current_indent_level))
1649 }*/
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001650 if (_PyAccu_Accumulate(acc, close_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001651 goto bail;
1652 return 0;
1653
1654bail:
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001655 Py_XDECREF(it);
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001656 Py_XDECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001657 Py_XDECREF(kstr);
1658 Py_XDECREF(ident);
1659 return -1;
1660}
1661
1662
1663static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001664encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001665 PyObject *seq, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001666{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001667 /* Encode Python list seq to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001668 static PyObject *open_array = NULL;
1669 static PyObject *close_array = NULL;
1670 static PyObject *empty_array = NULL;
1671 PyObject *ident = NULL;
1672 PyObject *s_fast = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001673 Py_ssize_t i;
1674
1675 if (open_array == NULL || close_array == NULL || empty_array == NULL) {
1676 open_array = PyUnicode_InternFromString("[");
1677 close_array = PyUnicode_InternFromString("]");
1678 empty_array = PyUnicode_InternFromString("[]");
1679 if (open_array == NULL || close_array == NULL || empty_array == NULL)
1680 return -1;
1681 }
1682 ident = NULL;
1683 s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence");
1684 if (s_fast == NULL)
1685 return -1;
Antoine Pitrou9f69e792012-11-01 19:52:06 +01001686 if (PySequence_Fast_GET_SIZE(s_fast) == 0) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001687 Py_DECREF(s_fast);
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001688 return _PyAccu_Accumulate(acc, empty_array);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001689 }
1690
1691 if (s->markers != Py_None) {
1692 int has_key;
1693 ident = PyLong_FromVoidPtr(seq);
1694 if (ident == NULL)
1695 goto bail;
1696 has_key = PyDict_Contains(s->markers, ident);
1697 if (has_key) {
1698 if (has_key != -1)
1699 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1700 goto bail;
1701 }
1702 if (PyDict_SetItem(s->markers, ident, seq)) {
1703 goto bail;
1704 }
1705 }
1706
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001707 if (_PyAccu_Accumulate(acc, open_array))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001708 goto bail;
1709 if (s->indent != Py_None) {
1710 /* TODO: DOES NOT RUN */
1711 indent_level += 1;
1712 /*
1713 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1714 separator = _item_separator + newline_indent
1715 buf += newline_indent
1716 */
1717 }
Antoine Pitrou9f69e792012-11-01 19:52:06 +01001718 for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) {
1719 PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001720 if (i) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001721 if (_PyAccu_Accumulate(acc, s->item_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001722 goto bail;
1723 }
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001724 if (encoder_listencode_obj(s, acc, obj, indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001725 goto bail;
1726 }
1727 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
1733 /* TODO: DOES NOT RUN
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001734 if (s->indent != Py_None) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001735 indent_level -= 1;
Brett Cannonb94767f2011-02-22 20:15:44 +00001736
1737 yield '\n' + (' ' * (_indent * _current_indent_level))
1738 }*/
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001739 if (_PyAccu_Accumulate(acc, close_array))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001740 goto bail;
1741 Py_DECREF(s_fast);
1742 return 0;
1743
1744bail:
1745 Py_XDECREF(ident);
1746 Py_DECREF(s_fast);
1747 return -1;
1748}
1749
1750static void
1751encoder_dealloc(PyObject *self)
1752{
1753 /* Deallocate Encoder */
1754 encoder_clear(self);
1755 Py_TYPE(self)->tp_free(self);
1756}
1757
1758static int
1759encoder_traverse(PyObject *self, visitproc visit, void *arg)
1760{
1761 PyEncoderObject *s;
1762 assert(PyEncoder_Check(self));
1763 s = (PyEncoderObject *)self;
1764 Py_VISIT(s->markers);
1765 Py_VISIT(s->defaultfn);
1766 Py_VISIT(s->encoder);
1767 Py_VISIT(s->indent);
1768 Py_VISIT(s->key_separator);
1769 Py_VISIT(s->item_separator);
1770 Py_VISIT(s->sort_keys);
1771 Py_VISIT(s->skipkeys);
1772 return 0;
1773}
1774
1775static int
1776encoder_clear(PyObject *self)
1777{
1778 /* Deallocate Encoder */
1779 PyEncoderObject *s;
1780 assert(PyEncoder_Check(self));
1781 s = (PyEncoderObject *)self;
1782 Py_CLEAR(s->markers);
1783 Py_CLEAR(s->defaultfn);
1784 Py_CLEAR(s->encoder);
1785 Py_CLEAR(s->indent);
1786 Py_CLEAR(s->key_separator);
1787 Py_CLEAR(s->item_separator);
1788 Py_CLEAR(s->sort_keys);
1789 Py_CLEAR(s->skipkeys);
1790 return 0;
1791}
1792
1793PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable");
1794
1795static
1796PyTypeObject PyEncoderType = {
1797 PyVarObject_HEAD_INIT(NULL, 0)
1798 "_json.Encoder", /* tp_name */
1799 sizeof(PyEncoderObject), /* tp_basicsize */
1800 0, /* tp_itemsize */
1801 encoder_dealloc, /* tp_dealloc */
1802 0, /* tp_print */
1803 0, /* tp_getattr */
1804 0, /* tp_setattr */
1805 0, /* tp_compare */
1806 0, /* tp_repr */
1807 0, /* tp_as_number */
1808 0, /* tp_as_sequence */
1809 0, /* tp_as_mapping */
1810 0, /* tp_hash */
1811 encoder_call, /* tp_call */
1812 0, /* tp_str */
1813 0, /* tp_getattro */
1814 0, /* tp_setattro */
1815 0, /* tp_as_buffer */
1816 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1817 encoder_doc, /* tp_doc */
1818 encoder_traverse, /* tp_traverse */
1819 encoder_clear, /* tp_clear */
1820 0, /* tp_richcompare */
1821 0, /* tp_weaklistoffset */
1822 0, /* tp_iter */
1823 0, /* tp_iternext */
1824 0, /* tp_methods */
1825 encoder_members, /* tp_members */
1826 0, /* tp_getset */
1827 0, /* tp_base */
1828 0, /* tp_dict */
1829 0, /* tp_descr_get */
1830 0, /* tp_descr_set */
1831 0, /* tp_dictoffset */
1832 encoder_init, /* tp_init */
1833 0, /* tp_alloc */
1834 encoder_new, /* tp_new */
1835 0, /* tp_free */
1836};
1837
1838static PyMethodDef speedups_methods[] = {
1839 {"encode_basestring_ascii",
1840 (PyCFunction)py_encode_basestring_ascii,
1841 METH_O,
1842 pydoc_encode_basestring_ascii},
1843 {"scanstring",
1844 (PyCFunction)py_scanstring,
1845 METH_VARARGS,
1846 pydoc_scanstring},
Christian Heimes90540002008-05-08 14:29:10 +00001847 {NULL, NULL, 0, NULL}
1848};
1849
1850PyDoc_STRVAR(module_doc,
1851"json speedups\n");
1852
Martin v. Löwis1a214512008-06-11 05:26:20 +00001853static struct PyModuleDef jsonmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 PyModuleDef_HEAD_INIT,
1855 "_json",
1856 module_doc,
1857 -1,
1858 speedups_methods,
1859 NULL,
1860 NULL,
1861 NULL,
1862 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001863};
1864
1865PyObject*
1866PyInit__json(void)
Christian Heimes90540002008-05-08 14:29:10 +00001867{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001868 PyObject *m = PyModule_Create(&jsonmodule);
1869 if (!m)
1870 return NULL;
1871 PyScannerType.tp_new = PyType_GenericNew;
1872 if (PyType_Ready(&PyScannerType) < 0)
1873 goto fail;
1874 PyEncoderType.tp_new = PyType_GenericNew;
1875 if (PyType_Ready(&PyEncoderType) < 0)
1876 goto fail;
1877 Py_INCREF((PyObject*)&PyScannerType);
1878 if (PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType) < 0) {
1879 Py_DECREF((PyObject*)&PyScannerType);
1880 goto fail;
1881 }
1882 Py_INCREF((PyObject*)&PyEncoderType);
1883 if (PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType) < 0) {
1884 Py_DECREF((PyObject*)&PyEncoderType);
1885 goto fail;
1886 }
1887 return m;
1888 fail:
1889 Py_DECREF(m);
1890 return NULL;
Christian Heimes90540002008-05-08 14:29:10 +00001891}