blob: f87d680db63cef70ee4abee244e181950b23eaf0 [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
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200598 if (PyUnicode_READY(pystr) == -1)
599 return NULL;
600
601 str = PyUnicode_DATA(pystr);
602 kind = PyUnicode_KIND(pystr);
603 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
604
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000605 if (has_pairs_hook)
606 rval = PyList_New(0);
607 else
608 rval = PyDict_New();
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000609 if (rval == NULL)
610 return NULL;
611
612 /* skip whitespace after { */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200613 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000614
615 /* only loop if the object is non-empty */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200616 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') {
617 while (1) {
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000618 PyObject *memokey;
619
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000620 /* read key */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200621 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '"') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200622 raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000623 goto bail;
624 }
625 key = scanstring_unicode(pystr, idx + 1, strict, &next_idx);
626 if (key == NULL)
627 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000628 memokey = PyDict_GetItem(s->memo, key);
629 if (memokey != NULL) {
630 Py_INCREF(memokey);
631 Py_DECREF(key);
632 key = memokey;
633 }
634 else {
635 if (PyDict_SetItem(s->memo, key, key) < 0)
636 goto bail;
637 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000638 idx = next_idx;
639
640 /* skip whitespace between key and : delimiter, read :, skip whitespace */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200641 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
642 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200643 raise_errmsg("Expecting ':' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000644 goto bail;
645 }
646 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200647 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000648
649 /* read any JSON term */
650 val = scan_once_unicode(s, pystr, idx, &next_idx);
651 if (val == NULL)
652 goto bail;
653
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000654 if (has_pairs_hook) {
655 PyObject *item = PyTuple_Pack(2, key, val);
656 if (item == NULL)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000657 goto bail;
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000658 Py_CLEAR(key);
659 Py_CLEAR(val);
660 if (PyList_Append(rval, item) == -1) {
661 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000662 goto bail;
663 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000664 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000665 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000666 else {
667 if (PyDict_SetItem(rval, key, val) < 0)
668 goto bail;
669 Py_CLEAR(key);
670 Py_CLEAR(val);
671 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000672 idx = next_idx;
673
674 /* skip whitespace before } or , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200675 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000676
677 /* bail if the object is closed or we didn't get the , delimiter */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200678 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == '}')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000679 break;
Ezio Melotti37623ab2013-01-03 08:44:15 +0200680 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200681 raise_errmsg("Expecting ',' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000682 goto bail;
683 }
684 idx++;
685
686 /* skip whitespace after , delimiter */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200687 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000688 }
689 }
690
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000691 *next_idx_ptr = idx + 1;
692
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000693 if (has_pairs_hook) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000694 val = PyObject_CallFunctionObjArgs(s->object_pairs_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000695 Py_DECREF(rval);
696 return val;
697 }
698
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000699 /* if object_hook is not None: rval = object_hook(rval) */
700 if (s->object_hook != Py_None) {
701 val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000702 Py_DECREF(rval);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000703 return val;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000704 }
705 return rval;
706bail:
707 Py_XDECREF(key);
708 Py_XDECREF(val);
Antoine Pitrou7d6e0762010-09-04 20:16:53 +0000709 Py_XDECREF(rval);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000710 return NULL;
711}
712
713static PyObject *
714_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
715 /* Read a JSON array from PyString pystr.
716 idx is the index of the first character after the opening brace.
717 *next_idx_ptr is a return-by-reference index to the first character after
718 the closing brace.
719
720 Returns a new PyList
721 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200722 void *str;
723 int kind;
724 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000725 PyObject *val = NULL;
726 PyObject *rval = PyList_New(0);
727 Py_ssize_t next_idx;
728 if (rval == NULL)
729 return NULL;
730
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200731 if (PyUnicode_READY(pystr) == -1)
732 return NULL;
733
734 str = PyUnicode_DATA(pystr);
735 kind = PyUnicode_KIND(pystr);
736 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
737
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000738 /* skip whitespace after [ */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200739 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000740
741 /* only loop if the array is non-empty */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200742 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
743 while (1) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000744
745 /* read any JSON term */
746 val = scan_once_unicode(s, pystr, idx, &next_idx);
747 if (val == NULL)
748 goto bail;
749
750 if (PyList_Append(rval, val) == -1)
751 goto bail;
752
753 Py_CLEAR(val);
754 idx = next_idx;
755
756 /* skip whitespace between term and , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200757 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000758
759 /* bail if the array is closed or we didn't get the , delimiter */
Ezio Melotti37623ab2013-01-03 08:44:15 +0200760 if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == ']')
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000761 break;
Ezio Melotti37623ab2013-01-03 08:44:15 +0200762 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
Antoine Pitrou2d24e942012-06-29 01:58:26 +0200763 raise_errmsg("Expecting ',' delimiter", pystr, idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000764 goto bail;
765 }
766 idx++;
767
768 /* skip whitespace after , */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200769 while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000770 }
771 }
772
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200773 /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */
774 if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200775 raise_errmsg("Expecting value", pystr, end_idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000776 goto bail;
777 }
778 *next_idx_ptr = idx + 1;
779 return rval;
780bail:
781 Py_XDECREF(val);
782 Py_DECREF(rval);
783 return NULL;
784}
785
786static PyObject *
787_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
788 /* Read a JSON constant from PyString pystr.
789 constant is the constant string that was found
790 ("NaN", "Infinity", "-Infinity").
791 idx is the index of the first character of the constant
792 *next_idx_ptr is a return-by-reference index to the first character after
793 the constant.
794
795 Returns the result of parse_constant
796 */
797 PyObject *cstr;
798 PyObject *rval;
799 /* constant is "NaN", "Infinity", or "-Infinity" */
800 cstr = PyUnicode_InternFromString(constant);
801 if (cstr == NULL)
802 return NULL;
803
804 /* rval = parse_constant(constant) */
805 rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL);
Victor Stinnerc4f281e2011-10-11 22:11:42 +0200806 idx += PyUnicode_GET_LENGTH(cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000807 Py_DECREF(cstr);
808 *next_idx_ptr = idx;
809 return rval;
810}
811
812static PyObject *
813_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) {
814 /* Read a JSON number from PyUnicode pystr.
815 idx is the index of the first character of the number
816 *next_idx_ptr is a return-by-reference index to the first character after
817 the number.
818
819 Returns a new PyObject representation of that number:
820 PyInt, PyLong, or PyFloat.
821 May return other types if parse_int or parse_float are set
822 */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200823 void *str;
824 int kind;
825 Py_ssize_t end_idx;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000826 Py_ssize_t idx = start;
827 int is_float = 0;
828 PyObject *rval;
Antoine Pitrouf6454512011-04-25 19:16:06 +0200829 PyObject *numstr = NULL;
830 PyObject *custom_func;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000831
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200832 if (PyUnicode_READY(pystr) == -1)
833 return NULL;
834
835 str = PyUnicode_DATA(pystr);
836 kind = PyUnicode_KIND(pystr);
837 end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
838
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000839 /* 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 +0200840 if (PyUnicode_READ(kind, str, idx) == '-') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000841 idx++;
842 if (idx > end_idx) {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200843 raise_stop_iteration(start);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000844 return NULL;
845 }
846 }
847
848 /* 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 +0200849 if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000850 idx++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200851 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000852 }
853 /* if it starts with 0 we only expect one integer digit */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200854 else if (PyUnicode_READ(kind, str, idx) == '0') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000855 idx++;
856 }
857 /* no integer digits, error */
858 else {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200859 raise_stop_iteration(start);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000860 return NULL;
861 }
862
863 /* if the next char is '.' followed by a digit then read all float digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200864 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 +0000865 is_float = 1;
866 idx += 2;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200867 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000868 }
869
870 /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200871 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000872 Py_ssize_t e_start = idx;
873 idx++;
874
875 /* read an exponent sign if present */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200876 if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000877
878 /* read all digits */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200879 while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000880
881 /* if we got a digit, then parse as float. if not, backtrack */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200882 if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000883 is_float = 1;
884 }
885 else {
886 idx = e_start;
887 }
888 }
889
Antoine Pitrouf6454512011-04-25 19:16:06 +0200890 if (is_float && s->parse_float != (PyObject *)&PyFloat_Type)
891 custom_func = s->parse_float;
892 else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type)
893 custom_func = s->parse_int;
894 else
895 custom_func = NULL;
896
897 if (custom_func) {
898 /* copy the section we determined to be a number */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200899 numstr = PyUnicode_FromKindAndData(kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200900 (char*)str + kind * start,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200901 idx - start);
Antoine Pitrouf6454512011-04-25 19:16:06 +0200902 if (numstr == NULL)
903 return NULL;
904 rval = PyObject_CallFunctionObjArgs(custom_func, numstr, NULL);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000905 }
906 else {
Antoine Pitrouf6454512011-04-25 19:16:06 +0200907 Py_ssize_t i, n;
908 char *buf;
909 /* Straight conversion to ASCII, to avoid costly conversion of
910 decimal unicode digits (which cannot appear here) */
911 n = idx - start;
912 numstr = PyBytes_FromStringAndSize(NULL, n);
913 if (numstr == NULL)
914 return NULL;
915 buf = PyBytes_AS_STRING(numstr);
916 for (i = 0; i < n; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200917 buf[i] = (char) PyUnicode_READ(kind, str, i + start);
Antoine Pitrouf6454512011-04-25 19:16:06 +0200918 }
919 if (is_float)
920 rval = PyFloat_FromString(numstr);
921 else
922 rval = PyLong_FromString(buf, NULL, 10);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000923 }
924 Py_DECREF(numstr);
925 *next_idx_ptr = idx;
926 return rval;
927}
928
929static PyObject *
930scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
931{
932 /* Read one JSON term (of any kind) from PyUnicode pystr.
933 idx is the index of the first character of the term
934 *next_idx_ptr is a return-by-reference index to the first character after
935 the number.
936
937 Returns a new PyObject representation of the term.
938 */
Ezio Melotti362b9512011-05-07 17:58:09 +0300939 PyObject *res;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200940 void *str;
941 int kind;
942 Py_ssize_t length;
943
944 if (PyUnicode_READY(pystr) == -1)
945 return NULL;
946
947 str = PyUnicode_DATA(pystr);
948 kind = PyUnicode_KIND(pystr);
949 length = PyUnicode_GET_LENGTH(pystr);
950
Benjamin Peterson6ef2b362014-04-14 11:45:21 -0400951 if (idx < 0) {
Benjamin Peterson9beee042014-04-14 11:46:51 -0400952 PyErr_SetString(PyExc_ValueError, "idx cannot be negative");
Benjamin Peterson6ef2b362014-04-14 11:45:21 -0400953 return NULL;
954 }
955 if (idx >= length) {
Ezio Melotti37623ab2013-01-03 08:44:15 +0200956 raise_stop_iteration(idx);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000957 return NULL;
958 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200959
960 switch (PyUnicode_READ(kind, str, idx)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000961 case '"':
962 /* string */
963 return scanstring_unicode(pystr, idx + 1,
964 PyObject_IsTrue(s->strict),
965 next_idx_ptr);
966 case '{':
967 /* object */
Ezio Melotti362b9512011-05-07 17:58:09 +0300968 if (Py_EnterRecursiveCall(" while decoding a JSON object "
969 "from a unicode string"))
970 return NULL;
971 res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
972 Py_LeaveRecursiveCall();
973 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000974 case '[':
975 /* array */
Ezio Melotti362b9512011-05-07 17:58:09 +0300976 if (Py_EnterRecursiveCall(" while decoding a JSON array "
977 "from a unicode string"))
978 return NULL;
979 res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
980 Py_LeaveRecursiveCall();
981 return res;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +0000982 case 'n':
983 /* null */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200984 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 +0000985 Py_INCREF(Py_None);
986 *next_idx_ptr = idx + 4;
987 return Py_None;
988 }
989 break;
990 case 't':
991 /* true */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200992 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 +0000993 Py_INCREF(Py_True);
994 *next_idx_ptr = idx + 4;
995 return Py_True;
996 }
997 break;
998 case 'f':
999 /* false */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001000 if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
1001 PyUnicode_READ(kind, str, idx + 2) == 'l' &&
1002 PyUnicode_READ(kind, str, idx + 3) == 's' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001003 PyUnicode_READ(kind, str, idx + 4) == 'e') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001004 Py_INCREF(Py_False);
1005 *next_idx_ptr = idx + 5;
1006 return Py_False;
1007 }
1008 break;
1009 case 'N':
1010 /* NaN */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001011 if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001012 PyUnicode_READ(kind, str, idx + 2) == 'N') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001013 return _parse_constant(s, "NaN", idx, next_idx_ptr);
1014 }
1015 break;
1016 case 'I':
1017 /* Infinity */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001018 if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' &&
1019 PyUnicode_READ(kind, str, idx + 2) == 'f' &&
1020 PyUnicode_READ(kind, str, idx + 3) == 'i' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001021 PyUnicode_READ(kind, str, idx + 4) == 'n' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001022 PyUnicode_READ(kind, str, idx + 5) == 'i' &&
1023 PyUnicode_READ(kind, str, idx + 6) == 't' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001024 PyUnicode_READ(kind, str, idx + 7) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001025 return _parse_constant(s, "Infinity", idx, next_idx_ptr);
1026 }
1027 break;
1028 case '-':
1029 /* -Infinity */
Victor Stinnerd9c06312011-10-11 21:56:19 +02001030 if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001031 PyUnicode_READ(kind, str, idx + 2) == 'n' &&
1032 PyUnicode_READ(kind, str, idx + 3) == 'f' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001033 PyUnicode_READ(kind, str, idx + 4) == 'i' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001034 PyUnicode_READ(kind, str, idx + 5) == 'n' &&
Victor Stinnerd9c06312011-10-11 21:56:19 +02001035 PyUnicode_READ(kind, str, idx + 6) == 'i' &&
1036 PyUnicode_READ(kind, str, idx + 7) == 't' &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001037 PyUnicode_READ(kind, str, idx + 8) == 'y') {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001038 return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
1039 }
1040 break;
1041 }
1042 /* Didn't find a string, object, array, or named constant. Look for a number. */
1043 return _match_number_unicode(s, pystr, idx, next_idx_ptr);
1044}
1045
1046static PyObject *
1047scanner_call(PyObject *self, PyObject *args, PyObject *kwds)
1048{
1049 /* Python callable interface to scan_once_{str,unicode} */
1050 PyObject *pystr;
1051 PyObject *rval;
1052 Py_ssize_t idx;
1053 Py_ssize_t next_idx = -1;
1054 static char *kwlist[] = {"string", "idx", NULL};
1055 PyScannerObject *s;
1056 assert(PyScanner_Check(self));
1057 s = (PyScannerObject *)self;
Antoine Pitroucbb02842012-12-01 19:34:16 +01001058 if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001059 return NULL;
1060
1061 if (PyUnicode_Check(pystr)) {
1062 rval = scan_once_unicode(s, pystr, idx, &next_idx);
1063 }
1064 else {
1065 PyErr_Format(PyExc_TypeError,
1066 "first argument must be a string, not %.80s",
1067 Py_TYPE(pystr)->tp_name);
1068 return NULL;
1069 }
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001070 PyDict_Clear(s->memo);
1071 if (rval == NULL)
1072 return NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001073 return _build_rval_index_tuple(rval, next_idx);
1074}
1075
1076static PyObject *
1077scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1078{
1079 PyScannerObject *s;
1080 s = (PyScannerObject *)type->tp_alloc(type, 0);
1081 if (s != NULL) {
1082 s->strict = NULL;
1083 s->object_hook = NULL;
1084 s->object_pairs_hook = NULL;
1085 s->parse_float = NULL;
1086 s->parse_int = NULL;
1087 s->parse_constant = NULL;
1088 }
1089 return (PyObject *)s;
1090}
1091
1092static int
1093scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
1094{
1095 /* Initialize Scanner object */
1096 PyObject *ctx;
1097 static char *kwlist[] = {"context", NULL};
1098 PyScannerObject *s;
1099
1100 assert(PyScanner_Check(self));
1101 s = (PyScannerObject *)self;
1102
1103 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
1104 return -1;
1105
Antoine Pitrou7d6e0762010-09-04 20:16:53 +00001106 if (s->memo == NULL) {
1107 s->memo = PyDict_New();
1108 if (s->memo == NULL)
1109 goto bail;
1110 }
1111
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001112 /* All of these will fail "gracefully" so we don't need to verify them */
1113 s->strict = PyObject_GetAttrString(ctx, "strict");
1114 if (s->strict == NULL)
1115 goto bail;
1116 s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
1117 if (s->object_hook == NULL)
1118 goto bail;
1119 s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook");
1120 if (s->object_pairs_hook == NULL)
1121 goto bail;
1122 s->parse_float = PyObject_GetAttrString(ctx, "parse_float");
1123 if (s->parse_float == NULL)
1124 goto bail;
1125 s->parse_int = PyObject_GetAttrString(ctx, "parse_int");
1126 if (s->parse_int == NULL)
1127 goto bail;
1128 s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant");
1129 if (s->parse_constant == NULL)
1130 goto bail;
1131
1132 return 0;
1133
1134bail:
1135 Py_CLEAR(s->strict);
1136 Py_CLEAR(s->object_hook);
1137 Py_CLEAR(s->object_pairs_hook);
1138 Py_CLEAR(s->parse_float);
1139 Py_CLEAR(s->parse_int);
1140 Py_CLEAR(s->parse_constant);
1141 return -1;
1142}
1143
1144PyDoc_STRVAR(scanner_doc, "JSON scanner object");
1145
1146static
1147PyTypeObject PyScannerType = {
1148 PyVarObject_HEAD_INIT(NULL, 0)
1149 "_json.Scanner", /* tp_name */
1150 sizeof(PyScannerObject), /* tp_basicsize */
1151 0, /* tp_itemsize */
1152 scanner_dealloc, /* tp_dealloc */
1153 0, /* tp_print */
1154 0, /* tp_getattr */
1155 0, /* tp_setattr */
1156 0, /* tp_compare */
1157 0, /* tp_repr */
1158 0, /* tp_as_number */
1159 0, /* tp_as_sequence */
1160 0, /* tp_as_mapping */
1161 0, /* tp_hash */
1162 scanner_call, /* tp_call */
1163 0, /* tp_str */
1164 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */
1165 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */
1166 0, /* tp_as_buffer */
1167 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1168 scanner_doc, /* tp_doc */
1169 scanner_traverse, /* tp_traverse */
1170 scanner_clear, /* tp_clear */
1171 0, /* tp_richcompare */
1172 0, /* tp_weaklistoffset */
1173 0, /* tp_iter */
1174 0, /* tp_iternext */
1175 0, /* tp_methods */
1176 scanner_members, /* tp_members */
1177 0, /* tp_getset */
1178 0, /* tp_base */
1179 0, /* tp_dict */
1180 0, /* tp_descr_get */
1181 0, /* tp_descr_set */
1182 0, /* tp_dictoffset */
1183 scanner_init, /* tp_init */
1184 0,/* PyType_GenericAlloc, */ /* tp_alloc */
1185 scanner_new, /* tp_new */
1186 0,/* PyObject_GC_Del, */ /* tp_free */
1187};
1188
1189static PyObject *
1190encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1191{
1192 PyEncoderObject *s;
1193 s = (PyEncoderObject *)type->tp_alloc(type, 0);
1194 if (s != NULL) {
1195 s->markers = NULL;
1196 s->defaultfn = NULL;
1197 s->encoder = NULL;
1198 s->indent = NULL;
1199 s->key_separator = NULL;
1200 s->item_separator = NULL;
1201 s->sort_keys = NULL;
1202 s->skipkeys = NULL;
1203 }
1204 return (PyObject *)s;
1205}
1206
1207static int
1208encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
1209{
1210 /* initialize Encoder object */
1211 static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
1212
1213 PyEncoderObject *s;
Antoine Pitrou781eba72009-12-08 15:57:31 +00001214 PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
1215 PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001216
1217 assert(PyEncoder_Check(self));
1218 s = (PyEncoderObject *)self;
1219
1220 if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist,
Antoine Pitrou781eba72009-12-08 15:57:31 +00001221 &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator,
1222 &sort_keys, &skipkeys, &allow_nan))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001223 return -1;
1224
Antoine Pitrou781eba72009-12-08 15:57:31 +00001225 s->markers = markers;
1226 s->defaultfn = defaultfn;
1227 s->encoder = encoder;
1228 s->indent = indent;
1229 s->key_separator = key_separator;
1230 s->item_separator = item_separator;
1231 s->sort_keys = sort_keys;
1232 s->skipkeys = skipkeys;
1233 s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii);
1234 s->allow_nan = PyObject_IsTrue(allow_nan);
1235
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001236 Py_INCREF(s->markers);
1237 Py_INCREF(s->defaultfn);
1238 Py_INCREF(s->encoder);
1239 Py_INCREF(s->indent);
1240 Py_INCREF(s->key_separator);
1241 Py_INCREF(s->item_separator);
1242 Py_INCREF(s->sort_keys);
1243 Py_INCREF(s->skipkeys);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001244 return 0;
1245}
1246
1247static PyObject *
1248encoder_call(PyObject *self, PyObject *args, PyObject *kwds)
1249{
1250 /* Python callable interface to encode_listencode_obj */
1251 static char *kwlist[] = {"obj", "_current_indent_level", NULL};
1252 PyObject *obj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001253 Py_ssize_t indent_level;
1254 PyEncoderObject *s;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001255 _PyAccu acc;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001256
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001257 assert(PyEncoder_Check(self));
1258 s = (PyEncoderObject *)self;
Antoine Pitroucbb02842012-12-01 19:34:16 +01001259 if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist,
1260 &obj, &indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001261 return NULL;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001262 if (_PyAccu_Init(&acc))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001263 return NULL;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001264 if (encoder_listencode_obj(s, &acc, obj, indent_level)) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001265 _PyAccu_Destroy(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001266 return NULL;
1267 }
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001268 return _PyAccu_FinishAsList(&acc);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001269}
1270
1271static PyObject *
1272_encoded_const(PyObject *obj)
1273{
1274 /* Return the JSON string representation of None, True, False */
1275 if (obj == Py_None) {
1276 static PyObject *s_null = NULL;
1277 if (s_null == NULL) {
1278 s_null = PyUnicode_InternFromString("null");
1279 }
1280 Py_INCREF(s_null);
1281 return s_null;
1282 }
1283 else if (obj == Py_True) {
1284 static PyObject *s_true = NULL;
1285 if (s_true == NULL) {
1286 s_true = PyUnicode_InternFromString("true");
1287 }
1288 Py_INCREF(s_true);
1289 return s_true;
1290 }
1291 else if (obj == Py_False) {
1292 static PyObject *s_false = NULL;
1293 if (s_false == NULL) {
1294 s_false = PyUnicode_InternFromString("false");
1295 }
1296 Py_INCREF(s_false);
1297 return s_false;
1298 }
1299 else {
1300 PyErr_SetString(PyExc_ValueError, "not a const");
1301 return NULL;
1302 }
1303}
1304
1305static PyObject *
Ethan Furmana4998a72013-08-10 13:01:45 -07001306encoder_encode_long(PyEncoderObject* s UNUSED, PyObject *obj)
1307{
1308 /* Return the JSON representation of a PyLong and PyLong subclasses.
1309 Calls int() on PyLong subclasses in case the str() was changed.
1310 Added specifically to deal with IntEnum. See Issue18264. */
1311 PyObject *encoded, *longobj;
1312 if (PyLong_CheckExact(obj)) {
1313 encoded = PyObject_Str(obj);
1314 }
1315 else {
1316 longobj = PyNumber_Long(obj);
1317 if (longobj == NULL) {
1318 PyErr_SetString(
1319 PyExc_ValueError,
1320 "Unable to coerce int subclass to int"
1321 );
1322 return NULL;
1323 }
1324 encoded = PyObject_Str(longobj);
1325 Py_DECREF(longobj);
1326 }
1327 return encoded;
1328}
1329
1330
1331static PyObject *
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001332encoder_encode_float(PyEncoderObject *s, PyObject *obj)
1333{
Ethan Furmana4998a72013-08-10 13:01:45 -07001334 /* Return the JSON representation of a PyFloat.
1335 Modified to call float() on float subclasses in case the subclass
1336 changes the repr. See Issue18264. */
1337 PyObject *encoded, *floatobj;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001338 double i = PyFloat_AS_DOUBLE(obj);
1339 if (!Py_IS_FINITE(i)) {
1340 if (!s->allow_nan) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001341 PyErr_SetString(
1342 PyExc_ValueError,
1343 "Out of range float values are not JSON compliant"
1344 );
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001345 return NULL;
1346 }
1347 if (i > 0) {
1348 return PyUnicode_FromString("Infinity");
1349 }
1350 else if (i < 0) {
1351 return PyUnicode_FromString("-Infinity");
1352 }
1353 else {
1354 return PyUnicode_FromString("NaN");
1355 }
1356 }
Ethan Furmana4998a72013-08-10 13:01:45 -07001357 /* coerce float subclasses to float (primarily for Enum) */
1358 if (PyFloat_CheckExact(obj)) {
1359 /* Use a better float format here? */
1360 encoded = PyObject_Repr(obj);
1361 }
1362 else {
1363 floatobj = PyNumber_Float(obj);
1364 if (floatobj == NULL) {
1365 PyErr_SetString(
1366 PyExc_ValueError,
1367 "Unable to coerce float subclass to float"
1368 );
1369 return NULL;
1370 }
1371 encoded = PyObject_Repr(floatobj);
1372 Py_DECREF(floatobj);
1373 }
1374 return encoded;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001375}
1376
1377static PyObject *
1378encoder_encode_string(PyEncoderObject *s, PyObject *obj)
1379{
1380 /* Return the JSON representation of a string */
1381 if (s->fast_encode)
1382 return py_encode_basestring_ascii(NULL, obj);
1383 else
1384 return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL);
1385}
1386
1387static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001388_steal_accumulate(_PyAccu *acc, PyObject *stolen)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001389{
1390 /* Append stolen and then decrement its reference count */
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001391 int rval = _PyAccu_Accumulate(acc, stolen);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001392 Py_DECREF(stolen);
1393 return rval;
1394}
1395
1396static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001397encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001398 PyObject *obj, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001399{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001400 /* Encode Python object obj to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001401 PyObject *newobj;
1402 int rv;
1403
1404 if (obj == Py_None || obj == Py_True || obj == Py_False) {
1405 PyObject *cstr = _encoded_const(obj);
1406 if (cstr == NULL)
1407 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001408 return _steal_accumulate(acc, cstr);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001409 }
1410 else if (PyUnicode_Check(obj))
1411 {
1412 PyObject *encoded = encoder_encode_string(s, obj);
1413 if (encoded == NULL)
1414 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001415 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001416 }
1417 else if (PyLong_Check(obj)) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001418 PyObject *encoded = encoder_encode_long(s, obj);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001419 if (encoded == NULL)
1420 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001421 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001422 }
1423 else if (PyFloat_Check(obj)) {
1424 PyObject *encoded = encoder_encode_float(s, obj);
1425 if (encoded == NULL)
1426 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001427 return _steal_accumulate(acc, encoded);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001428 }
1429 else if (PyList_Check(obj) || PyTuple_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_list(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 if (PyDict_Check(obj)) {
Ezio Melotti13672652011-05-11 01:02:56 +03001437 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1438 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001439 rv = encoder_listencode_dict(s, acc, obj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001440 Py_LeaveRecursiveCall();
1441 return rv;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001442 }
1443 else {
1444 PyObject *ident = NULL;
1445 if (s->markers != Py_None) {
1446 int has_key;
1447 ident = PyLong_FromVoidPtr(obj);
1448 if (ident == NULL)
1449 return -1;
1450 has_key = PyDict_Contains(s->markers, ident);
1451 if (has_key) {
1452 if (has_key != -1)
1453 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1454 Py_DECREF(ident);
1455 return -1;
1456 }
1457 if (PyDict_SetItem(s->markers, ident, obj)) {
1458 Py_DECREF(ident);
1459 return -1;
1460 }
1461 }
1462 newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL);
1463 if (newobj == NULL) {
1464 Py_XDECREF(ident);
1465 return -1;
1466 }
Ezio Melotti13672652011-05-11 01:02:56 +03001467
1468 if (Py_EnterRecursiveCall(" while encoding a JSON object"))
1469 return -1;
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001470 rv = encoder_listencode_obj(s, acc, newobj, indent_level);
Ezio Melotti13672652011-05-11 01:02:56 +03001471 Py_LeaveRecursiveCall();
1472
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001473 Py_DECREF(newobj);
1474 if (rv) {
1475 Py_XDECREF(ident);
1476 return -1;
1477 }
1478 if (ident != NULL) {
1479 if (PyDict_DelItem(s->markers, ident)) {
1480 Py_XDECREF(ident);
1481 return -1;
1482 }
1483 Py_XDECREF(ident);
1484 }
1485 return rv;
1486 }
1487}
1488
1489static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001490encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001491 PyObject *dct, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001492{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001493 /* Encode Python dict dct a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001494 static PyObject *open_dict = NULL;
1495 static PyObject *close_dict = NULL;
1496 static PyObject *empty_dict = NULL;
1497 PyObject *kstr = NULL;
1498 PyObject *ident = NULL;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001499 PyObject *it = NULL;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001500 PyObject *items;
1501 PyObject *item = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001502 int skipkeys;
1503 Py_ssize_t idx;
1504
1505 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
1506 open_dict = PyUnicode_InternFromString("{");
1507 close_dict = PyUnicode_InternFromString("}");
1508 empty_dict = PyUnicode_InternFromString("{}");
1509 if (open_dict == NULL || close_dict == NULL || empty_dict == NULL)
1510 return -1;
1511 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001512 if (Py_SIZE(dct) == 0)
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001513 return _PyAccu_Accumulate(acc, empty_dict);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001514
1515 if (s->markers != Py_None) {
1516 int has_key;
1517 ident = PyLong_FromVoidPtr(dct);
1518 if (ident == NULL)
1519 goto bail;
1520 has_key = PyDict_Contains(s->markers, ident);
1521 if (has_key) {
1522 if (has_key != -1)
1523 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1524 goto bail;
1525 }
1526 if (PyDict_SetItem(s->markers, ident, dct)) {
1527 goto bail;
1528 }
1529 }
1530
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001531 if (_PyAccu_Accumulate(acc, open_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001532 goto bail;
1533
1534 if (s->indent != Py_None) {
1535 /* TODO: DOES NOT RUN */
1536 indent_level += 1;
1537 /*
1538 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1539 separator = _item_separator + newline_indent
1540 buf += newline_indent
1541 */
1542 }
1543
Benjamin Peterson501182a2015-05-02 22:28:04 -04001544 items = PyMapping_Items(dct);
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001545 if (items == NULL)
Raymond Hettinger491a4cb2009-05-27 11:19:02 +00001546 goto bail;
Benjamin Peterson501182a2015-05-02 22:28:04 -04001547 if (PyObject_IsTrue(s->sort_keys) && PyList_Sort(items) < 0)
1548 goto bail;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001549 it = PyObject_GetIter(items);
Antoine Pitrou2397dd52010-11-04 16:51:32 +00001550 Py_DECREF(items);
1551 if (it == NULL)
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001552 goto bail;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001553 skipkeys = PyObject_IsTrue(s->skipkeys);
1554 idx = 0;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001555 while ((item = PyIter_Next(it)) != NULL) {
1556 PyObject *encoded, *key, *value;
1557 if (!PyTuple_Check(item) || Py_SIZE(item) != 2) {
1558 PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
1559 goto bail;
1560 }
1561 key = PyTuple_GET_ITEM(item, 0);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001562 if (PyUnicode_Check(key)) {
1563 Py_INCREF(key);
1564 kstr = key;
1565 }
1566 else if (PyFloat_Check(key)) {
1567 kstr = encoder_encode_float(s, key);
1568 if (kstr == NULL)
1569 goto bail;
1570 }
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001571 else if (key == Py_True || key == Py_False || key == Py_None) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 /* This must come before the PyLong_Check because
1573 True and False are also 1 and 0.*/
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001574 kstr = _encoded_const(key);
1575 if (kstr == NULL)
1576 goto bail;
1577 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001578 else if (PyLong_Check(key)) {
Ethan Furmana4998a72013-08-10 13:01:45 -07001579 kstr = encoder_encode_long(s, key);
1580 if (kstr == NULL) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001581 goto bail;
Ethan Furmana4998a72013-08-10 13:01:45 -07001582 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001583 }
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001584 else if (skipkeys) {
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001585 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001586 continue;
1587 }
1588 else {
1589 /* TODO: include repr of key */
Doug Hellmann1c524752010-07-21 12:29:04 +00001590 PyErr_SetString(PyExc_TypeError, "keys must be a string");
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001591 goto bail;
1592 }
1593
1594 if (idx) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001595 if (_PyAccu_Accumulate(acc, s->item_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001596 goto bail;
1597 }
1598
1599 encoded = encoder_encode_string(s, kstr);
1600 Py_CLEAR(kstr);
1601 if (encoded == NULL)
1602 goto bail;
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001603 if (_PyAccu_Accumulate(acc, encoded)) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001604 Py_DECREF(encoded);
1605 goto bail;
1606 }
1607 Py_DECREF(encoded);
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001608 if (_PyAccu_Accumulate(acc, s->key_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001609 goto bail;
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001610
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001611 value = PyTuple_GET_ITEM(item, 1);
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001612 if (encoder_listencode_obj(s, acc, value, indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001613 goto bail;
1614 idx += 1;
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001615 Py_DECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001616 }
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001617 if (PyErr_Occurred())
1618 goto bail;
1619 Py_CLEAR(it);
1620
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001621 if (ident != NULL) {
1622 if (PyDict_DelItem(s->markers, ident))
1623 goto bail;
1624 Py_CLEAR(ident);
1625 }
Brett Cannonb94767f2011-02-22 20:15:44 +00001626 /* TODO DOES NOT RUN; dead code
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001627 if (s->indent != Py_None) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001628 indent_level -= 1;
Brett Cannonb94767f2011-02-22 20:15:44 +00001629
1630 yield '\n' + (' ' * (_indent * _current_indent_level))
1631 }*/
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001632 if (_PyAccu_Accumulate(acc, close_dict))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001633 goto bail;
1634 return 0;
1635
1636bail:
Raymond Hettingerc8d952d2009-05-27 06:50:31 +00001637 Py_XDECREF(it);
Raymond Hettingerbcf6f922009-05-27 09:58:34 +00001638 Py_XDECREF(item);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001639 Py_XDECREF(kstr);
1640 Py_XDECREF(ident);
1641 return -1;
1642}
1643
1644
1645static int
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001646encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc,
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001647 PyObject *seq, Py_ssize_t indent_level)
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001648{
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001649 /* Encode Python list seq to a JSON term */
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001650 static PyObject *open_array = NULL;
1651 static PyObject *close_array = NULL;
1652 static PyObject *empty_array = NULL;
1653 PyObject *ident = NULL;
1654 PyObject *s_fast = NULL;
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001655 Py_ssize_t i;
1656
1657 if (open_array == NULL || close_array == NULL || empty_array == NULL) {
1658 open_array = PyUnicode_InternFromString("[");
1659 close_array = PyUnicode_InternFromString("]");
1660 empty_array = PyUnicode_InternFromString("[]");
1661 if (open_array == NULL || close_array == NULL || empty_array == NULL)
1662 return -1;
1663 }
1664 ident = NULL;
1665 s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence");
1666 if (s_fast == NULL)
1667 return -1;
Antoine Pitrou9f69e792012-11-01 19:52:06 +01001668 if (PySequence_Fast_GET_SIZE(s_fast) == 0) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001669 Py_DECREF(s_fast);
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001670 return _PyAccu_Accumulate(acc, empty_array);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001671 }
1672
1673 if (s->markers != Py_None) {
1674 int has_key;
1675 ident = PyLong_FromVoidPtr(seq);
1676 if (ident == NULL)
1677 goto bail;
1678 has_key = PyDict_Contains(s->markers, ident);
1679 if (has_key) {
1680 if (has_key != -1)
1681 PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1682 goto bail;
1683 }
1684 if (PyDict_SetItem(s->markers, ident, seq)) {
1685 goto bail;
1686 }
1687 }
1688
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001689 if (_PyAccu_Accumulate(acc, open_array))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001690 goto bail;
1691 if (s->indent != Py_None) {
1692 /* TODO: DOES NOT RUN */
1693 indent_level += 1;
1694 /*
1695 newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1696 separator = _item_separator + newline_indent
1697 buf += newline_indent
1698 */
1699 }
Antoine Pitrou9f69e792012-11-01 19:52:06 +01001700 for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) {
1701 PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i);
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001702 if (i) {
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001703 if (_PyAccu_Accumulate(acc, s->item_separator))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001704 goto bail;
1705 }
Antoine Pitroudf7fc9d2011-08-19 18:03:14 +02001706 if (encoder_listencode_obj(s, acc, obj, indent_level))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001707 goto bail;
1708 }
1709 if (ident != NULL) {
1710 if (PyDict_DelItem(s->markers, ident))
1711 goto bail;
1712 Py_CLEAR(ident);
1713 }
Brett Cannonb94767f2011-02-22 20:15:44 +00001714
1715 /* TODO: DOES NOT RUN
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001716 if (s->indent != Py_None) {
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001717 indent_level -= 1;
Brett Cannonb94767f2011-02-22 20:15:44 +00001718
1719 yield '\n' + (' ' * (_indent * _current_indent_level))
1720 }*/
Antoine Pitrou90c30e82011-10-06 19:09:51 +02001721 if (_PyAccu_Accumulate(acc, close_array))
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001722 goto bail;
1723 Py_DECREF(s_fast);
1724 return 0;
1725
1726bail:
1727 Py_XDECREF(ident);
1728 Py_DECREF(s_fast);
1729 return -1;
1730}
1731
1732static void
1733encoder_dealloc(PyObject *self)
1734{
1735 /* Deallocate Encoder */
1736 encoder_clear(self);
1737 Py_TYPE(self)->tp_free(self);
1738}
1739
1740static int
1741encoder_traverse(PyObject *self, visitproc visit, void *arg)
1742{
1743 PyEncoderObject *s;
1744 assert(PyEncoder_Check(self));
1745 s = (PyEncoderObject *)self;
1746 Py_VISIT(s->markers);
1747 Py_VISIT(s->defaultfn);
1748 Py_VISIT(s->encoder);
1749 Py_VISIT(s->indent);
1750 Py_VISIT(s->key_separator);
1751 Py_VISIT(s->item_separator);
1752 Py_VISIT(s->sort_keys);
1753 Py_VISIT(s->skipkeys);
1754 return 0;
1755}
1756
1757static int
1758encoder_clear(PyObject *self)
1759{
1760 /* Deallocate Encoder */
1761 PyEncoderObject *s;
1762 assert(PyEncoder_Check(self));
1763 s = (PyEncoderObject *)self;
1764 Py_CLEAR(s->markers);
1765 Py_CLEAR(s->defaultfn);
1766 Py_CLEAR(s->encoder);
1767 Py_CLEAR(s->indent);
1768 Py_CLEAR(s->key_separator);
1769 Py_CLEAR(s->item_separator);
1770 Py_CLEAR(s->sort_keys);
1771 Py_CLEAR(s->skipkeys);
1772 return 0;
1773}
1774
1775PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable");
1776
1777static
1778PyTypeObject PyEncoderType = {
1779 PyVarObject_HEAD_INIT(NULL, 0)
1780 "_json.Encoder", /* tp_name */
1781 sizeof(PyEncoderObject), /* tp_basicsize */
1782 0, /* tp_itemsize */
1783 encoder_dealloc, /* tp_dealloc */
1784 0, /* tp_print */
1785 0, /* tp_getattr */
1786 0, /* tp_setattr */
1787 0, /* tp_compare */
1788 0, /* tp_repr */
1789 0, /* tp_as_number */
1790 0, /* tp_as_sequence */
1791 0, /* tp_as_mapping */
1792 0, /* tp_hash */
1793 encoder_call, /* tp_call */
1794 0, /* tp_str */
1795 0, /* tp_getattro */
1796 0, /* tp_setattro */
1797 0, /* tp_as_buffer */
1798 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1799 encoder_doc, /* tp_doc */
1800 encoder_traverse, /* tp_traverse */
1801 encoder_clear, /* tp_clear */
1802 0, /* tp_richcompare */
1803 0, /* tp_weaklistoffset */
1804 0, /* tp_iter */
1805 0, /* tp_iternext */
1806 0, /* tp_methods */
1807 encoder_members, /* tp_members */
1808 0, /* tp_getset */
1809 0, /* tp_base */
1810 0, /* tp_dict */
1811 0, /* tp_descr_get */
1812 0, /* tp_descr_set */
1813 0, /* tp_dictoffset */
1814 encoder_init, /* tp_init */
1815 0, /* tp_alloc */
1816 encoder_new, /* tp_new */
1817 0, /* tp_free */
1818};
1819
1820static PyMethodDef speedups_methods[] = {
1821 {"encode_basestring_ascii",
1822 (PyCFunction)py_encode_basestring_ascii,
1823 METH_O,
1824 pydoc_encode_basestring_ascii},
1825 {"scanstring",
1826 (PyCFunction)py_scanstring,
1827 METH_VARARGS,
1828 pydoc_scanstring},
Christian Heimes90540002008-05-08 14:29:10 +00001829 {NULL, NULL, 0, NULL}
1830};
1831
1832PyDoc_STRVAR(module_doc,
1833"json speedups\n");
1834
Martin v. Löwis1a214512008-06-11 05:26:20 +00001835static struct PyModuleDef jsonmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 PyModuleDef_HEAD_INIT,
1837 "_json",
1838 module_doc,
1839 -1,
1840 speedups_methods,
1841 NULL,
1842 NULL,
1843 NULL,
1844 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001845};
1846
1847PyObject*
1848PyInit__json(void)
Christian Heimes90540002008-05-08 14:29:10 +00001849{
Benjamin Petersonc6b607d2009-05-02 12:36:44 +00001850 PyObject *m = PyModule_Create(&jsonmodule);
1851 if (!m)
1852 return NULL;
1853 PyScannerType.tp_new = PyType_GenericNew;
1854 if (PyType_Ready(&PyScannerType) < 0)
1855 goto fail;
1856 PyEncoderType.tp_new = PyType_GenericNew;
1857 if (PyType_Ready(&PyEncoderType) < 0)
1858 goto fail;
1859 Py_INCREF((PyObject*)&PyScannerType);
1860 if (PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType) < 0) {
1861 Py_DECREF((PyObject*)&PyScannerType);
1862 goto fail;
1863 }
1864 Py_INCREF((PyObject*)&PyEncoderType);
1865 if (PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType) < 0) {
1866 Py_DECREF((PyObject*)&PyEncoderType);
1867 goto fail;
1868 }
1869 return m;
1870 fail:
1871 Py_DECREF(m);
1872 return NULL;
Christian Heimes90540002008-05-08 14:29:10 +00001873}