blob: 1580ee6b658d3f91453562e69e9704486aec04a0 [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);
185 if (S_CHAR(c))
186 output_size++;
187 else {
188 switch(c) {
Victor Stinnerd9c06312011-10-11 21:56:19 +0200189 case '\\': case '"': case '\b': case '\f':
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200190 case '\n': case '\r': case '\t':
191 output_size += 2; break;
192 default:
193 output_size += c >= 0x10000 ? 12 : 6;
194 }
195 }
196 }
197
198 rval = PyUnicode_New(output_size, 127);
Christian Heimes90540002008-05-08 14:29:10 +0000199 if (rval == NULL) {
200 return NULL;
201 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200202 output = PyUnicode_1BYTE_DATA(rval);
Christian Heimes90540002008-05-08 14:29:10 +0000203 chars = 0;
204 output[chars++] = '"';
205 for (i = 0; i < input_chars; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200206 Py_UCS4 c = PyUnicode_READ(kind, input, i);
Christian Heimes90540002008-05-08 14:29:10 +0000207 if (S_CHAR(c)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000208 output[chars++] = c;
Christian Heimes90540002008-05-08 14:29:10 +0000209 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000210 else {
211 chars = ascii_escape_unichar(c, output, chars);
Christian Heimes90540002008-05-08 14:29:10 +0000212 }
Christian Heimes90540002008-05-08 14:29:10 +0000213 }
214 output[chars++] = '"';
Christian Heimesf402e922013-01-03 09:21:55 +0100215#ifdef Py_DEBUG
Victor Stinner8f825062012-04-27 13:55:39 +0200216 assert(_PyUnicode_CheckConsistency(rval, 1));
Christian Heimesf402e922013-01-03 09:21:55 +0100217#endif
Christian Heimes90540002008-05-08 14:29:10 +0000218 return rval;
219}
220
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000221static void
Christian Heimes90540002008-05-08 14:29:10 +0000222raise_errmsg(char *msg, PyObject *s, Py_ssize_t end)
223{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000224 /* Use the Python function json.decoder.errmsg to raise a nice
225 looking ValueError exception */
Christian Heimes90540002008-05-08 14:29:10 +0000226 static PyObject *errmsg_fn = NULL;
227 PyObject *pymsg;
228 if (errmsg_fn == NULL) {
229 PyObject *decoder = PyImport_ImportModule("json.decoder");
230 if (decoder == NULL)
231 return;
232 errmsg_fn = PyObject_GetAttrString(decoder, "errmsg");
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000233 Py_DECREF(decoder);
Christian Heimes90540002008-05-08 14:29:10 +0000234 if (errmsg_fn == NULL)
235 return;
Christian Heimes90540002008-05-08 14:29:10 +0000236 }
Antoine Pitroucbb02842012-12-01 19:34:16 +0100237 pymsg = PyObject_CallFunction(errmsg_fn, "(zOn)", msg, s, end);
Benjamin Petersona13d4752008-10-16 21:17:24 +0000238 if (pymsg) {
239 PyErr_SetObject(PyExc_ValueError, pymsg);
240 Py_DECREF(pymsg);
241 }
Christian Heimes90540002008-05-08 14:29:10 +0000242}
243
Ezio Melotti37623ab2013-01-03 08:44:15 +0200244static void
245raise_stop_iteration(Py_ssize_t idx)
246{
247 PyObject *value = PyLong_FromSsize_t(idx);
248 if (value != NULL) {
249 PyErr_SetObject(PyExc_StopIteration, value);
250 Py_DECREF(value);
251 }
252}
253
Christian Heimes90540002008-05-08 14:29:10 +0000254static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000255_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) {
256 /* return (rval, idx) tuple, stealing reference to rval */
257 PyObject *tpl;
258 PyObject *pyidx;
259 /*
260 steal a reference to rval, returns (rval, idx)
261 */
262 if (rval == NULL) {
Christian Heimes90540002008-05-08 14:29:10 +0000263 return NULL;
264 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000265 pyidx = PyLong_FromSsize_t(idx);
266 if (pyidx == NULL) {
267 Py_DECREF(rval);
268 return NULL;
269 }
270 tpl = PyTuple_New(2);
271 if (tpl == NULL) {
272 Py_DECREF(pyidx);
273 Py_DECREF(rval);
274 return NULL;
275 }
276 PyTuple_SET_ITEM(tpl, 0, rval);
277 PyTuple_SET_ITEM(tpl, 1, pyidx);
278 return tpl;
Christian Heimes90540002008-05-08 14:29:10 +0000279}
280
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000281#define APPEND_OLD_CHUNK \
282 if (chunk != NULL) { \
283 if (chunks == NULL) { \
284 chunks = PyList_New(0); \
285 if (chunks == NULL) { \
286 goto bail; \
287 } \
288 } \
289 if (PyList_Append(chunks, chunk)) { \
Victor Stinner31a3ec32014-09-10 23:31:42 +0200290 Py_CLEAR(chunk); \
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000291 goto bail; \
292 } \
293 Py_CLEAR(chunk); \
294 }
295
Christian Heimes90540002008-05-08 14:29:10 +0000296static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000297scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr)
Christian Heimes90540002008-05-08 14:29:10 +0000298{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000299 /* Read the JSON string from PyUnicode pystr.
300 end is the index of the first character after the quote.
301 if strict is zero then literal control characters are allowed
302 *next_end_ptr is a return-by-reference index of the character
303 after the end quote
Christian Heimes90540002008-05-08 14:29:10 +0000304
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000305 Return value is a new PyUnicode
306 */
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000307 PyObject *rval = NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200308 Py_ssize_t len;
Christian Heimes90540002008-05-08 14:29:10 +0000309 Py_ssize_t begin = end - 1;
Brett Cannonb94767f2011-02-22 20:15:44 +0000310 Py_ssize_t next /* = begin */;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200311 const void *buf;
312 int kind;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000313 PyObject *chunks = NULL;
314 PyObject *chunk = NULL;
315
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200316 if (PyUnicode_READY(pystr) == -1)
317 return 0;
318
319 len = PyUnicode_GET_LENGTH(pystr);
320 buf = PyUnicode_DATA(pystr);
321 kind = PyUnicode_KIND(pystr);
322
Ezio Melotti37623ab2013-01-03 08:44:15 +0200323 if (end < 0 || len < end) {
Benjamin Peterson7af6eec2008-07-19 22:26:35 +0000324 PyErr_SetString(PyExc_ValueError, "end is out of bounds");
325 goto bail;
326 }
Christian Heimes90540002008-05-08 14:29:10 +0000327 while (1) {
328 /* Find the end of the string or the next escape */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200329 Py_UCS4 c = 0;
Christian Heimes90540002008-05-08 14:29:10 +0000330 for (next = end; next < len; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200331 c = PyUnicode_READ(kind, buf, next);
Christian Heimes90540002008-05-08 14:29:10 +0000332 if (c == '"' || c == '\\') {
333 break;
334 }
335 else if (strict && c <= 0x1f) {
Benjamin Peterson7af6eec2008-07-19 22:26:35 +0000336 raise_errmsg("Invalid control character at", pystr, next);
Christian Heimes90540002008-05-08 14:29:10 +0000337 goto bail;
338 }
339 }
340 if (!(c == '"' || c == '\\')) {
341 raise_errmsg("Unterminated string starting at", pystr, begin);
342 goto bail;
343 }
344 /* Pick up this chunk if it's not zero length */
345 if (next != end) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000346 APPEND_OLD_CHUNK
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200347 chunk = PyUnicode_FromKindAndData(
348 kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200349 (char*)buf + kind * end,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200350 next - end);
Christian Heimes90540002008-05-08 14:29:10 +0000351 if (chunk == NULL) {
352 goto bail;
353 }
Christian Heimes90540002008-05-08 14:29:10 +0000354 }
355 next++;
356 if (c == '"') {
357 end = next;
358 break;
359 }
360 if (next == len) {
361 raise_errmsg("Unterminated string starting at", pystr, begin);
362 goto bail;
363 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200364 c = PyUnicode_READ(kind, buf, next);
Christian Heimes90540002008-05-08 14:29:10 +0000365 if (c != 'u') {
366 /* Non-unicode backslash escapes */
367 end = next + 1;
368 switch (c) {
369 case '"': break;
370 case '\\': break;
371 case '/': break;
372 case 'b': c = '\b'; break;
373 case 'f': c = '\f'; break;
374 case 'n': c = '\n'; break;
375 case 'r': c = '\r'; break;
376 case 't': c = '\t'; break;
377 default: c = 0;
378 }
379 if (c == 0) {
380 raise_errmsg("Invalid \\escape", pystr, end - 2);
381 goto bail;
382 }
383 }
384 else {
385 c = 0;
386 next++;
387 end = next + 4;
388 if (end >= len) {
389 raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1);
390 goto bail;
391 }
392 /* Decode 4 hex digits */
393 for (; next < end; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200394 Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000395 c <<= 4;
Christian Heimes90540002008-05-08 14:29:10 +0000396 switch (digit) {
397 case '0': case '1': case '2': case '3': case '4':
398 case '5': case '6': case '7': case '8': case '9':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000399 c |= (digit - '0'); break;
Christian Heimes90540002008-05-08 14:29:10 +0000400 case 'a': case 'b': case 'c': case 'd': case 'e':
401 case 'f':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000402 c |= (digit - 'a' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000403 case 'A': case 'B': case 'C': case 'D': case 'E':
404 case 'F':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000405 c |= (digit - 'A' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000406 default:
407 raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
408 goto bail;
409 }
410 }
Christian Heimes90540002008-05-08 14:29:10 +0000411 /* Surrogate pair */
Serhiy Storchakac93329b2013-11-26 21:25:28 +0200412 if (Py_UNICODE_IS_HIGH_SURROGATE(c) && end + 6 < len &&
413 PyUnicode_READ(kind, buf, next++) == '\\' &&
414 PyUnicode_READ(kind, buf, next++) == 'u') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200415 Py_UCS4 c2 = 0;
Christian Heimes90540002008-05-08 14:29:10 +0000416 end += 6;
417 /* Decode 4 hex digits */
418 for (; next < end; next++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200419 Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
Antoine Pitrou5b0e9e82010-10-09 15:24:28 +0000420 c2 <<= 4;
Christian Heimes90540002008-05-08 14:29:10 +0000421 switch (digit) {
422 case '0': case '1': case '2': case '3': case '4':
423 case '5': case '6': case '7': case '8': case '9':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000424 c2 |= (digit - '0'); break;
Christian Heimes90540002008-05-08 14:29:10 +0000425 case 'a': case 'b': case 'c': case 'd': case 'e':
426 case 'f':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000427 c2 |= (digit - 'a' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000428 case 'A': case 'B': case 'C': case 'D': case 'E':
429 case 'F':
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000430 c2 |= (digit - 'A' + 10); break;
Christian Heimes90540002008-05-08 14:29:10 +0000431 default:
432 raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
433 goto bail;
434 }
435 }
Serhiy Storchakac93329b2013-11-26 21:25:28 +0200436 if (Py_UNICODE_IS_LOW_SURROGATE(c2))
437 c = Py_UNICODE_JOIN_SURROGATES(c, c2);
438 else
439 end -= 6;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000440 }
Christian Heimes90540002008-05-08 14:29:10 +0000441 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000442 APPEND_OLD_CHUNK
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200443 chunk = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, &c, 1);
Christian Heimes90540002008-05-08 14:29:10 +0000444 if (chunk == NULL) {
445 goto bail;
446 }
Christian Heimes90540002008-05-08 14:29:10 +0000447 }
448
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000449 if (chunks == NULL) {
450 if (chunk != NULL)
451 rval = chunk;
452 else
453 rval = PyUnicode_FromStringAndSize("", 0);
Christian Heimes90540002008-05-08 14:29:10 +0000454 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000455 else {
456 APPEND_OLD_CHUNK
457 rval = join_list_unicode(chunks);
458 if (rval == NULL) {
459 goto bail;
460 }
461 Py_CLEAR(chunks);
462 }
463
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000464 *next_end_ptr = end;
465 return rval;
Christian Heimes90540002008-05-08 14:29:10 +0000466bail:
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000467 *next_end_ptr = -1;
Christian Heimes90540002008-05-08 14:29:10 +0000468 Py_XDECREF(chunks);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000469 Py_XDECREF(chunk);
Christian Heimes90540002008-05-08 14:29:10 +0000470 return NULL;
471}
472
473PyDoc_STRVAR(pydoc_scanstring,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000474 "scanstring(string, end, strict=True) -> (string, end)\n"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000475 "\n"
476 "Scan the string s for a JSON string. End is the index of the\n"
477 "character in s after the quote that started the JSON string.\n"
478 "Unescapes all valid JSON string escape sequences and raises ValueError\n"
479 "on attempt to decode an invalid string. If strict is False then literal\n"
480 "control characters are allowed in the string.\n"
481 "\n"
482 "Returns a tuple of the decoded string and the index of the character in s\n"
483 "after the end quote."
484);
Christian Heimes90540002008-05-08 14:29:10 +0000485
486static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000487py_scanstring(PyObject* self UNUSED, PyObject *args)
Christian Heimes90540002008-05-08 14:29:10 +0000488{
489 PyObject *pystr;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000490 PyObject *rval;
Christian Heimes90540002008-05-08 14:29:10 +0000491 Py_ssize_t end;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000492 Py_ssize_t next_end = -1;
493 int strict = 1;
Antoine Pitroucbb02842012-12-01 19:34:16 +0100494 if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) {
Christian Heimes90540002008-05-08 14:29:10 +0000495 return NULL;
496 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000497 if (PyUnicode_Check(pystr)) {
498 rval = scanstring_unicode(pystr, end, strict, &next_end);
Christian Heimes90540002008-05-08 14:29:10 +0000499 }
500 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 PyErr_Format(PyExc_TypeError,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000502 "first argument must be a string, not %.80s",
Christian Heimes90540002008-05-08 14:29:10 +0000503 Py_TYPE(pystr)->tp_name);
504 return NULL;
505 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000506 return _build_rval_index_tuple(rval, next_end);
Christian Heimes90540002008-05-08 14:29:10 +0000507}
508
509PyDoc_STRVAR(pydoc_encode_basestring_ascii,
Georg Brandlc8284cf2010-08-02 20:16:18 +0000510 "encode_basestring_ascii(string) -> string\n"
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000511 "\n"
512 "Return an ASCII-only JSON representation of a Python string"
513);
Christian Heimes90540002008-05-08 14:29:10 +0000514
515static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000516py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr)
Christian Heimes90540002008-05-08 14:29:10 +0000517{
518 PyObject *rval;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000519 /* Return an ASCII-only JSON representation of a Python string */
Christian Heimes90540002008-05-08 14:29:10 +0000520 /* METH_O */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000521 if (PyUnicode_Check(pystr)) {
Christian Heimes90540002008-05-08 14:29:10 +0000522 rval = ascii_escape_unicode(pystr);
523 }
524 else {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000525 PyErr_Format(PyExc_TypeError,
526 "first argument must be a string, not %.80s",
Christian Heimes90540002008-05-08 14:29:10 +0000527 Py_TYPE(pystr)->tp_name);
528 return NULL;
529 }
Christian Heimes90540002008-05-08 14:29:10 +0000530 return rval;
531}
532
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000533static void
534scanner_dealloc(PyObject *self)
535{
536 /* Deallocate scanner object */
537 scanner_clear(self);
538 Py_TYPE(self)->tp_free(self);
539}
540
541static int
542scanner_traverse(PyObject *self, visitproc visit, void *arg)
543{
544 PyScannerObject *s;
545 assert(PyScanner_Check(self));
546 s = (PyScannerObject *)self;
547 Py_VISIT(s->strict);
548 Py_VISIT(s->object_hook);
549 Py_VISIT(s->object_pairs_hook);
550 Py_VISIT(s->parse_float);
551 Py_VISIT(s->parse_int);
552 Py_VISIT(s->parse_constant);
553 return 0;
554}
555
556static int
557scanner_clear(PyObject *self)
558{
559 PyScannerObject *s;
560 assert(PyScanner_Check(self));
561 s = (PyScannerObject *)self;
562 Py_CLEAR(s->strict);
563 Py_CLEAR(s->object_hook);
564 Py_CLEAR(s->object_pairs_hook);
565 Py_CLEAR(s->parse_float);
566 Py_CLEAR(s->parse_int);
567 Py_CLEAR(s->parse_constant);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000568 Py_CLEAR(s->memo);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000569 return 0;
570}
571
572static PyObject *
573_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
574 /* Read a JSON object from PyUnicode pystr.
575 idx is the index of the first character after the opening curly brace.
576 *next_idx_ptr is a return-by-reference index to the first character after
577 the closing curly brace.
578
579 Returns a new PyObject (usually a dict, but object_hook can change that)
580 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200581 void *str;
582 int kind;
583 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000584 PyObject *val = NULL;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000585 PyObject *rval = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000586 PyObject *key = NULL;
587 int strict = PyObject_IsTrue(s->strict);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000588 int has_pairs_hook = (s->object_pairs_hook != Py_None);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000589 Py_ssize_t next_idx;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000590
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200591 if (PyUnicode_READY(pystr) == -1)
592 return NULL;
593
594 str = PyUnicode_DATA(pystr);
595 kind = PyUnicode_KIND(pystr);
596 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
597
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000598 if (has_pairs_hook)
599 rval = PyList_New(0);
600 else
601 rval = PyDict_New();
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000602 if (rval == NULL)
603 return NULL;
604
605 /* skip whitespace after { */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000607
608 /* only loop if the object is non-empty */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200609 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') {
610 while (1) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000611 PyObject *memokey;
612
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000613 /* read key */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200614 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '"') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200615 raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000616 goto bail;
617 }
618 key = scanstring_unicode(pystr, idx + 1, strict, &next_idx);
619 if (key == NULL)
620 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000621 memokey = PyDict_GetItem(s->memo, key);
622 if (memokey != NULL) {
623 Py_INCREF(memokey);
624 Py_DECREF(key);
625 key = memokey;
626 }
627 else {
628 if (PyDict_SetItem(s->memo, key, key) < 0)
629 goto bail;
630 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000631 idx = next_idx;
632
633 /* skip whitespace between key and : delimiter, read :, skip whitespace */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200634 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
635 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200636 raise_errmsg("Expecting ':' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000637 goto bail;
638 }
639 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200640 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000641
642 /* read any JSON term */
643 val = scan_once_unicode(s, pystr, idx, &next_idx);
644 if (val == NULL)
645 goto bail;
646
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000647 if (has_pairs_hook) {
648 PyObject *item = PyTuple_Pack(2, key, val);
649 if (item == NULL)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000650 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000651 Py_CLEAR(key);
652 Py_CLEAR(val);
653 if (PyList_Append(rval, item) == -1) {
654 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000655 goto bail;
656 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000657 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000658 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000659 else {
660 if (PyDict_SetItem(rval, key, val) < 0)
661 goto bail;
662 Py_CLEAR(key);
663 Py_CLEAR(val);
664 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000665 idx = next_idx;
666
667 /* skip whitespace before } or , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200668 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000669
670 /* bail if the object is closed or we didn't get the , delimiter */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200671 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == '}')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000672 break;
Ezio Melotti37623ab2013-01-03 08:44:15 +0200673 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200674 raise_errmsg("Expecting ',' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000675 goto bail;
676 }
677 idx++;
678
679 /* skip whitespace after , delimiter */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200680 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000681 }
682 }
683
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000684 *next_idx_ptr = idx + 1;
685
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000686 if (has_pairs_hook) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000687 val = PyObject_CallFunctionObjArgs(s->object_pairs_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000688 Py_DECREF(rval);
689 return val;
690 }
691
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000692 /* if object_hook is not None: rval = object_hook(rval) */
693 if (s->object_hook != Py_None) {
694 val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000695 Py_DECREF(rval);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000696 return val;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000697 }
698 return rval;
699bail:
700 Py_XDECREF(key);
701 Py_XDECREF(val);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000702 Py_XDECREF(rval);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000703 return NULL;
704}
705
706static PyObject *
707_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
708 /* Read a JSON array from PyString pystr.
709 idx is the index of the first character after the opening brace.
710 *next_idx_ptr is a return-by-reference index to the first character after
711 the closing brace.
712
713 Returns a new PyList
714 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200715 void *str;
716 int kind;
717 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000718 PyObject *val = NULL;
719 PyObject *rval = PyList_New(0);
720 Py_ssize_t next_idx;
721 if (rval == NULL)
722 return NULL;
723
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200724 if (PyUnicode_READY(pystr) == -1)
725 return NULL;
726
727 str = PyUnicode_DATA(pystr);
728 kind = PyUnicode_KIND(pystr);
729 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
730
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000731 /* skip whitespace after [ */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200732 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000733
734 /* only loop if the array is non-empty */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200735 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
736 while (1) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000737
738 /* read any JSON term */
739 val = scan_once_unicode(s, pystr, idx, &next_idx);
740 if (val == NULL)
741 goto bail;
742
743 if (PyList_Append(rval, val) == -1)
744 goto bail;
745
746 Py_CLEAR(val);
747 idx = next_idx;
748
749 /* skip whitespace between term and , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200750 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000751
752 /* bail if the array is closed or we didn't get the , delimiter */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200753 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == ']')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000754 break;
Ezio Melotti37623ab2013-01-03 08:44:15 +0200755 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200756 raise_errmsg("Expecting ',' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000757 goto bail;
758 }
759 idx++;
760
761 /* skip whitespace after , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200762 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000763 }
764 }
765
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200766 /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */
767 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200768 raise_errmsg("Expecting value", pystr, end_idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000769 goto bail;
770 }
771 *next_idx_ptr = idx + 1;
772 return rval;
773bail:
774 Py_XDECREF(val);
775 Py_DECREF(rval);
776 return NULL;
777}
778
779static PyObject *
780_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
781 /* Read a JSON constant from PyString pystr.
782 constant is the constant string that was found
783 ("NaN", "Infinity", "-Infinity").
784 idx is the index of the first character of the constant
785 *next_idx_ptr is a return-by-reference index to the first character after
786 the constant.
787
788 Returns the result of parse_constant
789 */
790 PyObject *cstr;
791 PyObject *rval;
792 /* constant is "NaN", "Infinity", or "-Infinity" */
793 cstr = PyUnicode_InternFromString(constant);
794 if (cstr == NULL)
795 return NULL;
796
797 /* rval = parse_constant(constant) */
798 rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL);
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200799 idx += PyUnicode_GET_LENGTH(cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000800 Py_DECREF(cstr);
801 *next_idx_ptr = idx;
802 return rval;
803}
804
805static PyObject *
806_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) {
807 /* Read a JSON number from PyUnicode pystr.
808 idx is the index of the first character of the number
809 *next_idx_ptr is a return-by-reference index to the first character after
810 the number.
811
812 Returns a new PyObject representation of that number:
813 PyInt, PyLong, or PyFloat.
814 May return other types if parse_int or parse_float are set
815 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200816 void *str;
817 int kind;
818 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000819 Py_ssize_t idx = start;
820 int is_float = 0;
821 PyObject *rval;
Antoine Pitrouf6454512011-04-25 19:16:06 +0200822 PyObject *numstr = NULL;
823 PyObject *custom_func;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000824
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200825 if (PyUnicode_READY(pystr) == -1)
826 return NULL;
827
828 str = PyUnicode_DATA(pystr);
829 kind = PyUnicode_KIND(pystr);
830 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
831
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000832 /* 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 +0200833 if (PyUnicode_READ(kind, str, idx) == '-') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000834 idx++;
835 if (idx > end_idx) {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200836 raise_stop_iteration(start);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000837 return NULL;
838 }
839 }
840
841 /* 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 +0200842 if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000843 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200844 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000845 }
846 /* if it starts with 0 we only expect one integer digit */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200847 else if (PyUnicode_READ(kind, str, idx) == '0') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000848 idx++;
849 }
850 /* no integer digits, error */
851 else {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200852 raise_stop_iteration(start);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000853 return NULL;
854 }
855
856 /* if the next char is '.' followed by a digit then read all float digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200857 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 +0000858 is_float = 1;
859 idx += 2;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200860 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000861 }
862
863 /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200864 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000865 Py_ssize_t e_start = idx;
866 idx++;
867
868 /* read an exponent sign if present */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200869 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000870
871 /* read all digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200872 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000873
874 /* if we got a digit, then parse as float. if not, backtrack */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200875 if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000876 is_float = 1;
877 }
878 else {
879 idx = e_start;
880 }
881 }
882
Antoine Pitrouf6454512011-04-25 19:16:06 +0200883 if (is_float && s->parse_float != (PyObject *)&PyFloat_Type)
884 custom_func = s->parse_float;
885 else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type)
886 custom_func = s->parse_int;
887 else
888 custom_func = NULL;
889
890 if (custom_func) {
891 /* copy the section we determined to be a number */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200892 numstr = PyUnicode_FromKindAndData(kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200893 (char*)str + kind * start,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200894 idx - start);
Antoine Pitrouf6454512011-04-25 19:16:06 +0200895 if (numstr == NULL)
896 return NULL;
897 rval = PyObject_CallFunctionObjArgs(custom_func, numstr, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000898 }
899 else {
Antoine Pitrouf6454512011-04-25 19:16:06 +0200900 Py_ssize_t i, n;
901 char *buf;
902 /* Straight conversion to ASCII, to avoid costly conversion of
903 decimal unicode digits (which cannot appear here) */
904 n = idx - start;
905 numstr = PyBytes_FromStringAndSize(NULL, n);
906 if (numstr == NULL)
907 return NULL;
908 buf = PyBytes_AS_STRING(numstr);
909 for (i = 0; i < n; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200910 buf[i] = (char) PyUnicode_READ(kind, str, i + start);
Antoine Pitrouf6454512011-04-25 19:16:06 +0200911 }
912 if (is_float)
913 rval = PyFloat_FromString(numstr);
914 else
915 rval = PyLong_FromString(buf, NULL, 10);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000916 }
917 Py_DECREF(numstr);
918 *next_idx_ptr = idx;
919 return rval;
920}
921
922static PyObject *
923scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
924{
925 /* Read one JSON term (of any kind) from PyUnicode pystr.
926 idx is the index of the first character of the term
927 *next_idx_ptr is a return-by-reference index to the first character after
928 the number.
929
930 Returns a new PyObject representation of the term.
931 */
Ezio Melotti362b9512011-05-07 17:58:09 +0300932 PyObject *res;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200933 void *str;
934 int kind;
935 Py_ssize_t length;
936
937 if (PyUnicode_READY(pystr) == -1)
938 return NULL;
939
940 str = PyUnicode_DATA(pystr);
941 kind = PyUnicode_KIND(pystr);
942 length = PyUnicode_GET_LENGTH(pystr);
943
Benjamin Peterson6ef2b362014-04-14 11:45:21 -0400944 if (idx < 0) {
Benjamin Peterson9beee042014-04-14 11:46:51 -0400945 PyErr_SetString(PyExc_ValueError, "idx cannot be negative");
Benjamin Peterson6ef2b362014-04-14 11:45:21 -0400946 return NULL;
947 }
948 if (idx >= length) {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200949 raise_stop_iteration(idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000950 return NULL;
951 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200952
953 switch (PyUnicode_READ(kind, str, idx)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000954 case '"':
955 /* string */
956 return scanstring_unicode(pystr, idx + 1,
957 PyObject_IsTrue(s->strict),
958 next_idx_ptr);
959 case '{':
960 /* object */
Ezio Melotti362b9512011-05-07 17:58:09 +0300961 if (Py_EnterRecursiveCall(" while decoding a JSON object "
962 "from a unicode string"))
963 return NULL;
964 res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
965 Py_LeaveRecursiveCall();
966 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000967 case '[':
968 /* array */
Ezio Melotti362b9512011-05-07 17:58:09 +0300969 if (Py_EnterRecursiveCall(" while decoding a JSON array "
970 "from a unicode string"))
971 return NULL;
972 res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
973 Py_LeaveRecursiveCall();
974 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000975 case 'n':
976 /* null */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200977 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 +0000978 Py_INCREF(Py_None);
979 *next_idx_ptr = idx + 4;
980 return Py_None;
981 }
982 break;
983 case 't':
984 /* true */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200985 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 +0000986 Py_INCREF(Py_True);
987 *next_idx_ptr = idx + 4;
988 return Py_True;
989 }
990 break;
991 case 'f':
992 /* false */
Victor Stinnerd9c06312011-10-11 21:56:19 +0200993 if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
994 PyUnicode_READ(kind, str, idx + 2) == 'l' &&
995 PyUnicode_READ(kind, str, idx + 3) == 's' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200996 PyUnicode_READ(kind, str, idx + 4) == 'e') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000997 Py_INCREF(Py_False);
998 *next_idx_ptr = idx + 5;
999 return Py_False;
1000 }
1001 break;
1002 case 'N':
1003 /* NaN */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001004 if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001005 PyUnicode_READ(kind, str, idx + 2) == 'N') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001006 return _parse_constant(s, "NaN", idx, next_idx_ptr);
1007 }
1008 break;
1009 case 'I':
1010 /* Infinity */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001011 if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' &&
1012 PyUnicode_READ(kind, str, idx + 2) == 'f' &&
1013 PyUnicode_READ(kind, str, idx + 3) == 'i' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001014 PyUnicode_READ(kind, str, idx + 4) == 'n' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001015 PyUnicode_READ(kind, str, idx + 5) == 'i' &&
1016 PyUnicode_READ(kind, str, idx + 6) == 't' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001017 PyUnicode_READ(kind, str, idx + 7) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001018 return _parse_constant(s, "Infinity", idx, next_idx_ptr);
1019 }
1020 break;
1021 case '-':
1022 /* -Infinity */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001023 if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001024 PyUnicode_READ(kind, str, idx + 2) == 'n' &&
1025 PyUnicode_READ(kind, str, idx + 3) == 'f' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001026 PyUnicode_READ(kind, str, idx + 4) == 'i' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001027 PyUnicode_READ(kind, str, idx + 5) == 'n' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001028 PyUnicode_READ(kind, str, idx + 6) == 'i' &&
1029 PyUnicode_READ(kind, str, idx + 7) == 't' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001030 PyUnicode_READ(kind, str, idx + 8) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001031 return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
1032 }
1033 break;
1034 }
1035 /* Didn't find a string, object, array, or named constant. Look for a number. */
1036 return _match_number_unicode(s, pystr, idx, next_idx_ptr);
1037}
1038
1039static PyObject *
1040scanner_call(PyObject *self, PyObject *args, PyObject *kwds)
1041{
1042 /* Python callable interface to scan_once_{str,unicode} */
1043 PyObject *pystr;
1044 PyObject *rval;
1045 Py_ssize_t idx;
1046 Py_ssize_t next_idx = -1;
1047 static char *kwlist[] = {"string", "idx", NULL};
1048 PyScannerObject *s;
1049 assert(PyScanner_Check(self));
1050 s = (PyScannerObject *)self;
Antoine Pitroucbb02842012-12-01 19:34:16 +01001051 if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001052 return NULL;
1053
1054 if (PyUnicode_Check(pystr)) {
1055 rval = scan_once_unicode(s, pystr, idx, &next_idx);
1056 }
1057 else {
1058 PyErr_Format(PyExc_TypeError,
1059 "first argument must be a string, not %.80s",
1060 Py_TYPE(pystr)->tp_name);
1061 return NULL;
1062 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001063 PyDict_Clear(s->memo);
1064 if (rval == NULL)
1065 return NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001066 return _build_rval_index_tuple(rval, next_idx);
1067}
1068
1069static PyObject *
1070scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1071{
1072 PyScannerObject *s;
1073 s = (PyScannerObject *)type->tp_alloc(type, 0);
1074 if (s != NULL) {
1075 s->strict = NULL;
1076 s->object_hook = NULL;
1077 s->object_pairs_hook = NULL;
1078 s->parse_float = NULL;
1079 s->parse_int = NULL;
1080 s->parse_constant = NULL;
1081 }
1082 return (PyObject *)s;
1083}
1084
1085static int
1086scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
1087{
1088 /* Initialize Scanner object */
1089 PyObject *ctx;
1090 static char *kwlist[] = {"context", NULL};
1091 PyScannerObject *s;
1092
1093 assert(PyScanner_Check(self));
1094 s = (PyScannerObject *)self;
1095
1096 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
1097 return -1;
1098
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001099 if (s->memo == NULL) {
1100 s->memo = PyDict_New();
1101 if (s->memo == NULL)
1102 goto bail;
1103 }
1104
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001105 /* All of these will fail "gracefully" so we don't need to verify them */
1106 s->strict = PyObject_GetAttrString(ctx, "strict");
1107 if (s->strict == NULL)
1108 goto bail;
1109 s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
1110 if (s->object_hook == NULL)
1111 goto bail;
1112 s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook");
1113 if (s->object_pairs_hook == NULL)
1114 goto bail;
1115 s->parse_float = PyObject_GetAttrString(ctx, "parse_float");
1116 if (s->parse_float == NULL)
1117 goto bail;
1118 s->parse_int = PyObject_GetAttrString(ctx, "parse_int");
1119 if (s->parse_int == NULL)
1120 goto bail;
1121 s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant");
1122 if (s->parse_constant == NULL)
1123 goto bail;
1124
1125 return 0;
1126
1127bail:
1128 Py_CLEAR(s->strict);
1129 Py_CLEAR(s->object_hook);
1130 Py_CLEAR(s->object_pairs_hook);
1131 Py_CLEAR(s->parse_float);
1132 Py_CLEAR(s->parse_int);
1133 Py_CLEAR(s->parse_constant);
1134 return -1;
1135}
1136
1137PyDoc_STRVAR(scanner_doc, "JSON scanner object");
1138
1139static
1140PyTypeObject PyScannerType = {
1141 PyVarObject_HEAD_INIT(NULL, 0)
1142 "_json.Scanner", /* tp_name */
1143 sizeof(PyScannerObject), /* tp_basicsize */
1144 0, /* tp_itemsize */
1145 scanner_dealloc, /* tp_dealloc */
1146 0, /* tp_print */
1147 0, /* tp_getattr */
1148 0, /* tp_setattr */
1149 0, /* tp_compare */
1150 0, /* tp_repr */
1151 0, /* tp_as_number */
1152 0, /* tp_as_sequence */
1153 0, /* tp_as_mapping */
1154 0, /* tp_hash */
1155 scanner_call, /* tp_call */
1156 0, /* tp_str */
1157 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */
1158 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */
1159 0, /* tp_as_buffer */
1160 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1161 scanner_doc, /* tp_doc */
1162 scanner_traverse, /* tp_traverse */
1163 scanner_clear, /* tp_clear */
1164 0, /* tp_richcompare */
1165 0, /* tp_weaklistoffset */
1166 0, /* tp_iter */
1167 0, /* tp_iternext */
1168 0, /* tp_methods */
1169 scanner_members, /* tp_members */
1170 0, /* tp_getset */
1171 0, /* tp_base */
1172 0, /* tp_dict */
1173 0, /* tp_descr_get */
1174 0, /* tp_descr_set */
1175 0, /* tp_dictoffset */
1176 scanner_init, /* tp_init */
1177 0,/* PyType_GenericAlloc, */ /* tp_alloc */
1178 scanner_new, /* tp_new */
1179 0,/* PyObject_GC_Del, */ /* tp_free */
1180};
1181
1182static PyObject *
1183encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1184{
1185 PyEncoderObject *s;
1186 s = (PyEncoderObject *)type->tp_alloc(type, 0);
1187 if (s != NULL) {
1188 s->markers = NULL;
1189 s->defaultfn = NULL;
1190 s->encoder = NULL;
1191 s->indent = NULL;
1192 s->key_separator = NULL;
1193 s->item_separator = NULL;
1194 s->sort_keys = NULL;
1195 s->skipkeys = NULL;
1196 }
1197 return (PyObject *)s;
1198}
1199
1200static int
1201encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
1202{
1203 /* initialize Encoder object */
1204 static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
1205
1206 PyEncoderObject *s;
Antoine Pitrou781eba72009-12-08 15:57:31 +00001207 PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
1208 PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001209
1210 assert(PyEncoder_Check(self));
1211 s = (PyEncoderObject *)self;
1212
1213 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist,
Antoine Pitrou781eba72009-12-08 15:57:31 +00001214 &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator,
1215 &sort_keys, &skipkeys, &allow_nan))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001216 return -1;
1217
Antoine Pitrou781eba72009-12-08 15:57:31 +00001218 s->markers = markers;
1219 s->defaultfn = defaultfn;
1220 s->encoder = encoder;
1221 s->indent = indent;
1222 s->key_separator = key_separator;
1223 s->item_separator = item_separator;
1224 s->sort_keys = sort_keys;
1225 s->skipkeys = skipkeys;
1226 s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii);
1227 s->allow_nan = PyObject_IsTrue(allow_nan);
1228
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001229 Py_INCREF(s->markers);
1230 Py_INCREF(s->defaultfn);
1231 Py_INCREF(s->encoder);
1232 Py_INCREF(s->indent);
1233 Py_INCREF(s->key_separator);
1234 Py_INCREF(s->item_separator);
1235 Py_INCREF(s->sort_keys);
1236 Py_INCREF(s->skipkeys);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001237 return 0;
1238}
1239
1240static PyObject *
1241encoder_call(PyObject *self, PyObject *args, PyObject *kwds)
1242{
1243 /* Python callable interface to encode_listencode_obj */
1244 static char *kwlist[] = {"obj", "_current_indent_level", NULL};
1245 PyObject *obj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001246 Py_ssize_t indent_level;
1247 PyEncoderObject *s;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001248 _PyAccu acc;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001249
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001250 assert(PyEncoder_Check(self));
1251 s = (PyEncoderObject *)self;
Antoine Pitroucbb02842012-12-01 19:34:16 +01001252 if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist,
1253 &obj, &indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001254 return NULL;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001255 if (_PyAccu_Init(&acc))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001256 return NULL;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001257 if (encoder_listencode_obj(s, &acc, obj, indent_level)) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001258 _PyAccu_Destroy(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001259 return NULL;
1260 }
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001261 return _PyAccu_FinishAsList(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001262}
1263
1264static PyObject *
1265_encoded_const(PyObject *obj)
1266{
1267 /* Return the JSON string representation of None, True, False */
1268 if (obj == Py_None) {
1269 static PyObject *s_null = NULL;
1270 if (s_null == NULL) {
1271 s_null = PyUnicode_InternFromString("null");
1272 }
1273 Py_INCREF(s_null);
1274 return s_null;
1275 }
1276 else if (obj == Py_True) {
1277 static PyObject *s_true = NULL;
1278 if (s_true == NULL) {
1279 s_true = PyUnicode_InternFromString("true");
1280 }
1281 Py_INCREF(s_true);
1282 return s_true;
1283 }
1284 else if (obj == Py_False) {
1285 static PyObject *s_false = NULL;
1286 if (s_false == NULL) {
1287 s_false = PyUnicode_InternFromString("false");
1288 }
1289 Py_INCREF(s_false);
1290 return s_false;
1291 }
1292 else {
1293 PyErr_SetString(PyExc_ValueError, "not a const");
1294 return NULL;
1295 }
1296}
1297
1298static PyObject *
Ethan Furmana4998a72013-08-10 13:01:45 -07001299encoder_encode_long(PyEncoderObject* s UNUSED, PyObject *obj)
1300{
1301 /* Return the JSON representation of a PyLong and PyLong subclasses.
1302 Calls int() on PyLong subclasses in case the str() was changed.
1303 Added specifically to deal with IntEnum. See Issue18264. */
1304 PyObject *encoded, *longobj;
1305 if (PyLong_CheckExact(obj)) {
1306 encoded = PyObject_Str(obj);
1307 }
1308 else {
1309 longobj = PyNumber_Long(obj);
1310 if (longobj == NULL) {
1311 PyErr_SetString(
1312 PyExc_ValueError,
1313 "Unable to coerce int subclass to int"
1314 );
1315 return NULL;
1316 }
1317 encoded = PyObject_Str(longobj);
1318 Py_DECREF(longobj);
1319 }
1320 return encoded;
1321}
1322
1323
1324static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001325encoder_encode_float(PyEncoderObject *s, PyObject *obj)
1326{
Ethan Furmana4998a72013-08-10 13:01:45 -07001327 /* Return the JSON representation of a PyFloat.
1328 Modified to call float() on float subclasses in case the subclass
1329 changes the repr. See Issue18264. */
1330 PyObject *encoded, *floatobj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001331 double i = PyFloat_AS_DOUBLE(obj);
1332 if (!Py_IS_FINITE(i)) {
1333 if (!s->allow_nan) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001334 PyErr_SetString(
1335 PyExc_ValueError,
1336 "Out of range float values are not JSON compliant"
1337 );
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001338 return NULL;
1339 }
1340 if (i > 0) {
1341 return PyUnicode_FromString("Infinity");
1342 }
1343 else if (i < 0) {
1344 return PyUnicode_FromString("-Infinity");
1345 }
1346 else {
1347 return PyUnicode_FromString("NaN");
1348 }
1349 }
Ethan Furmana4998a72013-08-10 13:01:45 -07001350 /* coerce float subclasses to float (primarily for Enum) */
1351 if (PyFloat_CheckExact(obj)) {
1352 /* Use a better float format here? */
1353 encoded = PyObject_Repr(obj);
1354 }
1355 else {
1356 floatobj = PyNumber_Float(obj);
1357 if (floatobj == NULL) {
1358 PyErr_SetString(
1359 PyExc_ValueError,
1360 "Unable to coerce float subclass to float"
1361 );
1362 return NULL;
1363 }
1364 encoded = PyObject_Repr(floatobj);
1365 Py_DECREF(floatobj);
1366 }
1367 return encoded;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001368}
1369
1370static PyObject *
1371encoder_encode_string(PyEncoderObject *s, PyObject *obj)
1372{
1373 /* Return the JSON representation of a string */
1374 if (s->fast_encode)
1375 return py_encode_basestring_ascii(NULL, obj);
1376 else
1377 return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
1378}
1379
1380static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001381_steal_accumulate(_PyAccu *acc, PyObject *stolen)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001382{
1383 /* Append stolen and then decrement its reference count */
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001384 int rval = _PyAccu_Accumulate(acc, stolen);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001385 Py_DECREF(stolen);
1386 return rval;
1387}
1388
1389static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001390encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001391 PyObject *obj, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001392{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001393 /* Encode Python object obj to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001394 PyObject *newobj;
1395 int rv;
1396
1397 if (obj == Py_None || obj == Py_True || obj == Py_False) {
1398 PyObject *cstr = _encoded_const(obj);
1399 if (cstr == NULL)
1400 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001401 return _steal_accumulate(acc, cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001402 }
1403 else if (PyUnicode_Check(obj))
1404 {
1405 PyObject *encoded = encoder_encode_string(s, obj);
1406 if (encoded == NULL)
1407 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001408 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001409 }
1410 else if (PyLong_Check(obj)) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001411 PyObject *encoded = encoder_encode_long(s, obj);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001412 if (encoded == NULL)
1413 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001414 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001415 }
1416 else if (PyFloat_Check(obj)) {
1417 PyObject *encoded = encoder_encode_float(s, obj);
1418 if (encoded == NULL)
1419 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001420 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001421 }
1422 else if (PyList_Check(obj) || PyTuple_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001423 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1424 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001425 rv = encoder_listencode_list(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001426 Py_LeaveRecursiveCall();
1427 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001428 }
1429 else if (PyDict_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001430 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1431 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001432 rv = encoder_listencode_dict(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001433 Py_LeaveRecursiveCall();
1434 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001435 }
1436 else {
1437 PyObject *ident = NULL;
1438 if (s->markers != Py_None) {
1439 int has_key;
1440 ident = PyLong_FromVoidPtr(obj);
1441 if (ident == NULL)
1442 return -1;
1443 has_key = PyDict_Contains(s->markers, ident);
1444 if (has_key) {
1445 if (has_key != -1)
1446 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1447 Py_DECREF(ident);
1448 return -1;
1449 }
1450 if (PyDict_SetItem(s->markers, ident, obj)) {
1451 Py_DECREF(ident);
1452 return -1;
1453 }
1454 }
1455 newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL);
1456 if (newobj == NULL) {
1457 Py_XDECREF(ident);
1458 return -1;
1459 }
Ezio Melotti13672652011-05-11 01:02:56 +03001460
1461 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1462 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001463 rv = encoder_listencode_obj(s, acc, newobj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001464 Py_LeaveRecursiveCall();
1465
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001466 Py_DECREF(newobj);
1467 if (rv) {
1468 Py_XDECREF(ident);
1469 return -1;
1470 }
1471 if (ident != NULL) {
1472 if (PyDict_DelItem(s->markers, ident)) {
1473 Py_XDECREF(ident);
1474 return -1;
1475 }
1476 Py_XDECREF(ident);
1477 }
1478 return rv;
1479 }
1480}
1481
1482static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001483encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001484 PyObject *dct, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001485{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001486 /* Encode Python dict dct a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001487 static PyObject *open_dict = NULL;
1488 static PyObject *close_dict = NULL;
1489 static PyObject *empty_dict = NULL;
1490 PyObject *kstr = NULL;
1491 PyObject *ident = NULL;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001492 PyObject *it = NULL;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001493 PyObject *items;
1494 PyObject *item = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001495 int skipkeys;
1496 Py_ssize_t idx;
1497
1498 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
1499 open_dict = PyUnicode_InternFromString("{");
1500 close_dict = PyUnicode_InternFromString("}");
1501 empty_dict = PyUnicode_InternFromString("{}");
1502 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL)
1503 return -1;
1504 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001505 if (Py_SIZE(dct) == 0)
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001506 return _PyAccu_Accumulate(acc, empty_dict);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001507
1508 if (s->markers != Py_None) {
1509 int has_key;
1510 ident = PyLong_FromVoidPtr(dct);
1511 if (ident == NULL)
1512 goto bail;
1513 has_key = PyDict_Contains(s->markers, ident);
1514 if (has_key) {
1515 if (has_key != -1)
1516 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1517 goto bail;
1518 }
1519 if (PyDict_SetItem(s->markers, ident, dct)) {
1520 goto bail;
1521 }
1522 }
1523
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001524 if (_PyAccu_Accumulate(acc, open_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001525 goto bail;
1526
1527 if (s->indent != Py_None) {
1528 /* TODO: DOES NOT RUN */
1529 indent_level += 1;
1530 /*
1531 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1532 separator = _item_separator + newline_indent
1533 buf += newline_indent
1534 */
1535 }
1536
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001537 if (PyObject_IsTrue(s->sort_keys)) {
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001538 /* First sort the keys then replace them with (key, value) tuples. */
1539 Py_ssize_t i, nitems;
1540 items = PyMapping_Keys(dct);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 if (items == NULL)
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001542 goto bail;
1543 if (!PyList_Check(items)) {
1544 PyErr_SetString(PyExc_ValueError, "keys must return list");
1545 goto bail;
1546 }
1547 if (PyList_Sort(items) < 0)
1548 goto bail;
1549 nitems = PyList_GET_SIZE(items);
1550 for (i = 0; i < nitems; i++) {
1551 PyObject *key, *value;
1552 key = PyList_GET_ITEM(items, i);
1553 value = PyDict_GetItem(dct, key);
1554 item = PyTuple_Pack(2, key, value);
1555 if (item == NULL)
1556 goto bail;
1557 PyList_SET_ITEM(items, i, item);
Victor Stinner31a3ec32014-09-10 23:31:42 +02001558 item = NULL;
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001559 Py_DECREF(key);
1560 }
1561 }
1562 else {
1563 items = PyMapping_Items(dct);
1564 }
1565 if (items == NULL)
Raymond Hettinger491a4cb2009-05-27 11:19:02 +00001566 goto bail;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001567 it = PyObject_GetIter(items);
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001568 Py_DECREF(items);
1569 if (it == NULL)
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001570 goto bail;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001571 skipkeys = PyObject_IsTrue(s->skipkeys);
1572 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}