17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h" 27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "structmember.h" 37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if PY_VERSION_HEX < 0x02060000 && !defined(Py_TYPE) 47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) 77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef int Py_ssize_t; 87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PY_SSIZE_T_MAX INT_MAX 97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PY_SSIZE_T_MIN INT_MIN 107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyInt_FromSsize_t PyInt_FromLong 117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyInt_AsSsize_t PyInt_AsLong 127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_IS_FINITE 147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) 157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef __GNUC__ 187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define UNUSED __attribute__((__unused__)) 197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define UNUSED 217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define DEFAULT_ENCODING "utf-8" 247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) 267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType) 277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) 287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType) 297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject PyScannerType; 317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject PyEncoderType; 327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct _PyScannerObject { 347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_HEAD 357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *encoding; 367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *strict; 377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *object_hook; 387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pairs_hook; 397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *parse_float; 407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *parse_int; 417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *parse_constant; 427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} PyScannerObject; 437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMemberDef scanner_members[] = { 457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"encoding", T_OBJECT, offsetof(PyScannerObject, encoding), READONLY, "encoding"}, 467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"strict", T_OBJECT, offsetof(PyScannerObject, strict), READONLY, "strict"}, 477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"}, 487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, pairs_hook), READONLY, "object_pairs_hook"}, 497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"}, 507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"}, 517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"}, 527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {NULL} 537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct _PyEncoderObject { 567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_HEAD 577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *markers; 587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *defaultfn; 597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *encoder; 607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *indent; 617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *key_separator; 627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *item_separator; 637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *sort_keys; 647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *skipkeys; 657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int fast_encode; 667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int allow_nan; 677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} PyEncoderObject; 687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMemberDef encoder_members[] = { 707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"}, 717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"}, 727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"}, 737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"}, 747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"}, 757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"}, 767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"}, 777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"}, 787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {NULL} 797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic Py_ssize_t 827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars); 837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielascii_escape_unicode(PyObject *pystr); 857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielascii_escape_str(PyObject *pystr); 877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielpy_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr); 897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvoid init_json(void); 907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); 927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); 947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); 967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); 987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_init(PyObject *self, PyObject *args, PyObject *kwds); 1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_dealloc(PyObject *self); 1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_clear(PyObject *self); 1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); 1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_init(PyObject *self, PyObject *args, PyObject *kwds); 1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_dealloc(PyObject *self); 1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_clear(PyObject *self); 1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_listencode_list(PyEncoderObject *s, PyObject *rval, PyObject *seq, Py_ssize_t indent_level); 1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssize_t indent_level); 1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ssize_t indent_level); 1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_encoded_const(PyObject *obj); 1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielraise_errmsg(char *msg, PyObject *s, Py_ssize_t end); 1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_encode_string(PyEncoderObject *s, PyObject *obj); 1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr); 1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr); 1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_encode_float(PyEncoderObject *s, PyObject *obj); 1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"') 1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) 1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MIN_EXPANSION 6 1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_UNICODE_WIDE 1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MAX_EXPANSION (2 * MIN_EXPANSION) 1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MAX_EXPANSION MIN_EXPANSION 1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr) 1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* PyObject to Py_ssize_t converter */ 1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *size_ptr = PyInt_AsSsize_t(o); 1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (*size_ptr == -1 && PyErr_Occurred()) 1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 1; 1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr) 1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Py_ssize_t to PyObject converter */ 1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyInt_FromSsize_t(*size_ptr); 1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic Py_ssize_t 1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars) 1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Escape unicode code point c to ASCII escape sequences 1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel in char *output. output must have at least 12 bytes unused to 1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel accommodate an escaped surrogate pair "\uXXXX\uXXXX" */ 1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = '\\'; 1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (c) { 1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\\': output[chars++] = (char)c; break; 1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '"': output[chars++] = (char)c; break; 1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\b': output[chars++] = 'b'; break; 1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\f': output[chars++] = 'f'; break; 1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\n': output[chars++] = 'n'; break; 1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\r': output[chars++] = 'r'; break; 1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\t': output[chars++] = 't'; break; 1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: 1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_UNICODE_WIDE 1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c >= 0x10000) { 1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* UTF-16 surrogate pair */ 1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE v = c - 0x10000; 1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = 0xd800 | ((v >> 10) & 0x3ff); 1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = 'u'; 1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf]; 1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf]; 1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf]; 1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c ) & 0xf]; 1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = 0xdc00 | (v & 0x3ff); 1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = '\\'; 1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = 'u'; 1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf]; 1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf]; 1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf]; 1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = "0123456789abcdef"[(c ) & 0xf]; 1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return chars; 1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielascii_escape_unicode(PyObject *pystr) 1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Take a PyUnicode pystr and return a new ASCII-only escaped PyString */ 2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t i; 2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t input_chars; 2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t output_size; 2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t max_output_size; 2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t chars; 2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *output; 2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *input_unicode; 2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel input_chars = PyUnicode_GET_SIZE(pystr); 2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel input_unicode = PyUnicode_AS_UNICODE(pystr); 2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* One char input can be up to 6 chars output, estimate 4 of these */ 2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output_size = 2 + (MIN_EXPANSION * 4) + input_chars; 2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel max_output_size = 2 + (input_chars * MAX_EXPANSION); 2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyString_FromStringAndSize(NULL, output_size); 2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) { 2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output = PyString_AS_STRING(rval); 2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chars = 0; 2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = '"'; 2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (i = 0; i < input_chars; i++) { 2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c = input_unicode[i]; 2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (S_CHAR(c)) { 2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = (char)c; 2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chars = ascii_escape_char(c, output, chars); 2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (output_size - chars < (1 + MAX_EXPANSION)) { 2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* There's more than four, so let's resize by a lot */ 2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t new_output_size = output_size * 2; 2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* This is an upper bound */ 2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (new_output_size > max_output_size) { 2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel new_output_size = max_output_size; 2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Make sure that the output size changed before resizing */ 2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (new_output_size != output_size) { 2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output_size = new_output_size; 2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (_PyString_Resize(&rval, output_size) == -1) { 2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output = PyString_AS_STRING(rval); 2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = '"'; 2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (_PyString_Resize(&rval, chars) == -1) { 2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielascii_escape_str(PyObject *pystr) 2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Take a PyString pystr and return a new ASCII-only escaped PyString */ 2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t i; 2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t input_chars; 2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t output_size; 2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t chars; 2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *output; 2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *input_str; 2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel input_chars = PyString_GET_SIZE(pystr); 2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel input_str = PyString_AS_STRING(pystr); 2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Fast path for a string that's already ASCII */ 2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (i = 0; i < input_chars; i++) { 2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c = (Py_UNICODE)(unsigned char)input_str[i]; 2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!S_CHAR(c)) { 2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* If we have to escape something, scan the string for unicode */ 2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t j; 2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (j = i; j < input_chars; j++) { 2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = (Py_UNICODE)(unsigned char)input_str[j]; 2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c > 0x7f) { 2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* We hit a non-ASCII character, bail to unicode mode */ 2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *uni; 2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel uni = PyUnicode_DecodeUTF8(input_str, input_chars, "strict"); 2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (uni == NULL) { 2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = ascii_escape_unicode(uni); 2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(uni); 2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (i == input_chars) { 2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Input is already ASCII */ 2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output_size = 2 + input_chars; 2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* One char input can be up to 6 chars output, estimate 4 of these */ 3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output_size = 2 + (MIN_EXPANSION * 4) + input_chars; 3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyString_FromStringAndSize(NULL, output_size); 3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) { 3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output = PyString_AS_STRING(rval); 3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[0] = '"'; 3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* We know that everything up to i is ASCII already */ 3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chars = i + 1; 3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel memcpy(&output[1], input_str, i); 3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (; i < input_chars; i++) { 3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c = (Py_UNICODE)(unsigned char)input_str[i]; 3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (S_CHAR(c)) { 3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = (char)c; 3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chars = ascii_escape_char(c, output, chars); 3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* An ASCII char can't possibly expand to a surrogate! */ 3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (output_size - chars < (1 + MIN_EXPANSION)) { 3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* There's more than four, so let's resize by a lot */ 3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output_size *= 2; 3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (output_size > 2 + (input_chars * MIN_EXPANSION)) { 3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output_size = 2 + (input_chars * MIN_EXPANSION); 3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (_PyString_Resize(&rval, output_size) == -1) { 3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output = PyString_AS_STRING(rval); 3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output[chars++] = '"'; 3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (_PyString_Resize(&rval, chars) == -1) { 3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielraise_errmsg(char *msg, PyObject *s, Py_ssize_t end) 3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Use the Python function json.decoder.errmsg to raise a nice 3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel looking ValueError exception */ 3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *errmsg_fn = NULL; 3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pymsg; 3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (errmsg_fn == NULL) { 3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *decoder = PyImport_ImportModule("json.decoder"); 3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (decoder == NULL) 3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return; 3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel errmsg_fn = PyObject_GetAttrString(decoder, "errmsg"); 3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(decoder); 3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (errmsg_fn == NULL) 3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return; 3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pymsg = PyObject_CallFunction(errmsg_fn, "(zOO&)", msg, s, _convertPyInt_FromSsize_t, &end); 3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pymsg) { 3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetObject(PyExc_ValueError, pymsg); 3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(pymsg); 3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieljoin_list_unicode(PyObject *lst) 3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* return u''.join(lst) */ 3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *joinfn = NULL; 3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (joinfn == NULL) { 3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *ustr = PyUnicode_FromUnicode(NULL, 0); 3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ustr == NULL) 3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel joinfn = PyObject_GetAttrString(ustr, "join"); 3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(ustr); 3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (joinfn == NULL) 3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyObject_CallFunctionObjArgs(joinfn, lst, NULL); 3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { 3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* return (rval, idx) tuple, stealing reference to rval */ 3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *tpl; 3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pyidx; 3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* 3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel steal a reference to rval, returns (rval, idx) 3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) { 3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pyidx = PyInt_FromSsize_t(idx); 3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pyidx == NULL) { 3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel tpl = PyTuple_New(2); 3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (tpl == NULL) { 4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(pyidx); 4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyTuple_SET_ITEM(tpl, 0, rval); 4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyTuple_SET_ITEM(tpl, 1, pyidx); 4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return tpl; 4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_ssize_t *next_end_ptr) 4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read the JSON string from PyString pystr. 4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end is the index of the first character after the quote. 4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoding is the encoding of pystr (must be an ASCII superset) 4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if strict is zero then literal control characters are allowed 4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_end_ptr is a return-by-reference index of the character 4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel after the end quote 4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Return value is a new PyString (if ASCII-only) or PyUnicode 4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t len = PyString_GET_SIZE(pystr); 4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t begin = end - 1; 4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next; 4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *buf = PyString_AS_STRING(pystr); 4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *chunks = PyList_New(0); 4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (chunks == NULL) { 4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (end < 0 || len <= end) { 4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "end is out of bounds"); 4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (1) { 4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Find the end of the string or the next escape */ 4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c = 0; 4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *chunk = NULL; 4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (next = end; next < len; next++) { 4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = (unsigned char)buf[next]; 4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c == '"' || c == '\\') { 4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (strict && c <= 0x1f) { 4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid control character at", pystr, next); 4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!(c == '"' || c == '\\')) { 4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Unterminated string starting at", pystr, begin); 4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Pick up this chunk if it's not zero length */ 4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (next != end) { 4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *strchunk = PyString_FromStringAndSize(&buf[end], next - end); 4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strchunk == NULL) { 4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chunk = PyUnicode_FromEncodedObject(strchunk, encoding, NULL); 4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(strchunk); 4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (chunk == NULL) { 4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(chunks, chunk)) { 4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next++; 4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c == '"') { 4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = next; 4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (next == len) { 4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Unterminated string starting at", pystr, begin); 4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = buf[next]; 4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c != 'u') { 4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Non-unicode backslash escapes */ 4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = next + 1; 4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (c) { 4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '"': break; 4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\\': break; 4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '/': break; 4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'b': c = '\b'; break; 4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': c = '\f'; break; 4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'n': c = '\n'; break; 4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'r': c = '\r'; break; 4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 't': c = '\t'; break; 4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: c = 0; 4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c == 0) { 4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\escape", pystr, end - 2); 4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = 0; 5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next++; 5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = next + 4; 5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (end >= len) { 5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); 5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Decode 4 hex digits */ 5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (; next < end; next++) { 5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE digit = buf[next]; 5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c <<= 4; 5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (digit) { 5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '0': case '1': case '2': case '3': case '4': 5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '5': case '6': case '7': case '8': case '9': 5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c |= (digit - '0'); break; 5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'a': case 'b': case 'c': case 'd': case 'e': 5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': 5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c |= (digit - 'a' + 10); break; 5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'A': case 'B': case 'C': case 'D': case 'E': 5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'F': 5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c |= (digit - 'A' + 10); break; 5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: 5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); 5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_UNICODE_WIDE 5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Surrogate pair */ 5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((c & 0xfc00) == 0xd800 && end + 6 < len && 5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buf[next++] == '\\' && 5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buf[next++] == 'u') { 5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c2 = 0; 5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end += 6; 5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Decode 4 hex digits */ 5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (; next < end; next++) { 5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE digit = buf[next]; 5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 <<= 4; 5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (digit) { 5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '0': case '1': case '2': case '3': case '4': 5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '5': case '6': case '7': case '8': case '9': 5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 |= (digit - '0'); break; 5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'a': case 'b': case 'c': case 'd': case 'e': 5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': 5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 |= (digit - 'a' + 10); break; 5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'A': case 'B': case 'C': case 'D': case 'E': 5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'F': 5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 |= (digit - 'A' + 10); break; 5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: 5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); 5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((c2 & 0xfc00) == 0xdc00) 5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); 5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else 5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end -= 6; 5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chunk = PyUnicode_FromUnicode(&c, 1); 5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (chunk == NULL) { 5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(chunks, chunk)) { 5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = join_list_unicode(chunks); 5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) { 5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(chunks); 5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_end_ptr = end; 5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_end_ptr = -1; 5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(chunks); 5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr) 5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read the JSON string from PyUnicode pystr. 5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end is the index of the first character after the quote. 5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if strict is zero then literal control characters are allowed 5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_end_ptr is a return-by-reference index of the character 5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel after the end quote 5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Return value is a new PyUnicode 5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t len = PyUnicode_GET_SIZE(pystr); 5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t begin = end - 1; 5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next; 5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel const Py_UNICODE *buf = PyUnicode_AS_UNICODE(pystr); 5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *chunks = PyList_New(0); 6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (chunks == NULL) { 6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (end < 0 || len <= end) { 6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "end is out of bounds"); 6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (1) { 6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Find the end of the string or the next escape */ 6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c = 0; 6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *chunk = NULL; 6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (next = end; next < len; next++) { 6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = buf[next]; 6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c == '"' || c == '\\') { 6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (strict && c <= 0x1f) { 6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid control character at", pystr, next); 6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!(c == '"' || c == '\\')) { 6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Unterminated string starting at", pystr, begin); 6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Pick up this chunk if it's not zero length */ 6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (next != end) { 6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chunk = PyUnicode_FromUnicode(&buf[end], next - end); 6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (chunk == NULL) { 6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(chunks, chunk)) { 6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next++; 6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c == '"') { 6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = next; 6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (next == len) { 6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Unterminated string starting at", pystr, begin); 6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = buf[next]; 6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c != 'u') { 6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Non-unicode backslash escapes */ 6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = next + 1; 6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (c) { 6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '"': break; 6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '\\': break; 6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '/': break; 6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'b': c = '\b'; break; 6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': c = '\f'; break; 6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'n': c = '\n'; break; 6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'r': c = '\r'; break; 6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 't': c = '\t'; break; 6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: c = 0; 6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (c == 0) { 6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\escape", pystr, end - 2); 6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = 0; 6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next++; 6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end = next + 4; 6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (end >= len) { 6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); 6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Decode 4 hex digits */ 6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (; next < end; next++) { 6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE digit = buf[next]; 6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c <<= 4; 6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (digit) { 6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '0': case '1': case '2': case '3': case '4': 6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '5': case '6': case '7': case '8': case '9': 6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c |= (digit - '0'); break; 6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'a': case 'b': case 'c': case 'd': case 'e': 6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': 6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c |= (digit - 'a' + 10); break; 6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'A': case 'B': case 'C': case 'D': case 'E': 6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'F': 6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c |= (digit - 'A' + 10); break; 6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: 6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); 6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_UNICODE_WIDE 6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Surrogate pair */ 6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((c & 0xfc00) == 0xd800 && end + 6 < len && 6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buf[next++] == '\\' && buf[next++] == 'u') { 6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE c2 = 0; 6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end += 6; 6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Decode 4 hex digits */ 7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (; next < end; next++) { 7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE digit = buf[next]; 7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 <<= 4; 7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (digit) { 7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '0': case '1': case '2': case '3': case '4': 7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '5': case '6': case '7': case '8': case '9': 7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 |= (digit - '0'); break; 7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'a': case 'b': case 'c': case 'd': case 'e': 7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': 7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 |= (digit - 'a' + 10); break; 7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'A': case 'B': case 'C': case 'D': case 'E': 7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'F': 7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c2 |= (digit - 'A' + 10); break; 7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: 7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); 7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((c2 & 0xfc00) == 0xdc00) 7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); 7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else 7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel end -= 6; 7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel chunk = PyUnicode_FromUnicode(&c, 1); 7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (chunk == NULL) { 7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(chunks, chunk)) { 7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunk); 7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = join_list_unicode(chunks); 7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) { 7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(chunks); 7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_end_ptr = end; 7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_end_ptr = -1; 7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(chunks); 7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(pydoc_scanstring, 7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "scanstring(basestring, end, encoding, strict=True) -> (str, end)\n" 7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Scan the string s for a JSON string. End is the index of the\n" 7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "character in s after the quote that started the JSON string.\n" 7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Unescapes all valid JSON string escape sequences and raises ValueError\n" 7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "on attempt to decode an invalid string. If strict is False then literal\n" 7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "control characters are allowed in the string.\n" 7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Returns a tuple of the decoded string and the index of the character in s\n" 7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "after the end quote." 7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel); 7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielpy_scanstring(PyObject* self UNUSED, PyObject *args) 7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pystr; 7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end; 7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next_end = -1; 7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *encoding = NULL; 7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int strict = 1; 7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTuple(args, "OO&|zi:scanstring", &pystr, _convertPyInt_AsSsize_t, &end, &encoding, &strict)) { 7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoding == NULL) { 7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoding = DEFAULT_ENCODING; 7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyString_Check(pystr)) { 7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = scanstring_str(pystr, end, encoding, strict, &next_end); 7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyUnicode_Check(pystr)) { 7817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = scanstring_unicode(pystr, end, strict, &next_end); 7827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 7847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 7857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "first argument must be a string, not %.80s", 7867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(pystr)->tp_name); 7877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 7887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _build_rval_index_tuple(rval, next_end); 7907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 7917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(pydoc_encode_basestring_ascii, 7937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "encode_basestring_ascii(basestring) -> str\n" 7947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "\n" 7957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "Return an ASCII-only JSON representation of a Python string" 7967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel); 7977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 7987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 7997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielpy_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) 8007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Return an ASCII-only JSON representation of a Python string */ 8027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* METH_O */ 8037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyString_Check(pystr)) { 8047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return ascii_escape_str(pystr); 8057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyUnicode_Check(pystr)) { 8077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return ascii_escape_unicode(pystr); 8087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 8107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 8117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "first argument must be a string, not %.80s", 8127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(pystr)->tp_name); 8137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 8147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 8187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_dealloc(PyObject *self) 8197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Deallocate scanner object */ 8217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_clear(self); 8227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(self)->tp_free(self); 8237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 8267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_traverse(PyObject *self, visitproc visit, void *arg) 8277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyScannerObject *s; 8297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyScanner_Check(self)); 8307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyScannerObject *)self; 8317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->encoding); 8327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->strict); 8337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->object_hook); 8347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->pairs_hook); 8357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->parse_float); 8367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->parse_int); 8377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->parse_constant); 8387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 8397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 8427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_clear(PyObject *self) 8437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 8447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyScannerObject *s; 8457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyScanner_Check(self)); 8467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyScannerObject *)self; 8477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->encoding); 8487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->strict); 8497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->object_hook); 8507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->pairs_hook); 8517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->parse_float); 8527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->parse_int); 8537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->parse_constant); 8547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 8557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 8567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 8587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_parse_object_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { 8597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON object from PyString pystr. 8607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character after the opening curly brace. 8617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 8627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the closing curly brace. 8637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyObject (usually a dict, but object_hook can change that) 8657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 8667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *str = PyString_AS_STRING(pystr); 8677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; 8687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 8697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pairs; 8707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *item; 8717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *key = NULL; 8727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *val = NULL; 8737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *encoding = PyString_AS_STRING(s->encoding); 8747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int strict = PyObject_IsTrue(s->strict); 8757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next_idx; 8767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pairs = PyList_New(0); 8787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pairs == NULL) 8797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 8807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after { */ 8827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 8837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* only loop if the object is non-empty */ 8857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx <= end_idx && str[idx] != '}') { 8867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx) { 8877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read key */ 8887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] != '"') { 8897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting property name", pystr, idx); 8907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 8917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel key = scanstring_str(pystr, idx + 1, encoding, strict, &next_idx); 8937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (key == NULL) 8947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 8957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = next_idx; 8967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 8977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace between key and : delimiter, read :, skip whitespace */ 8987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 8997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx || str[idx] != ':') { 9007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting : delimiter", pystr, idx); 9017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 9047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 9057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read any JSON data type */ 9077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = scan_once_str(s, pystr, idx, &next_idx); 9087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 9097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel item = PyTuple_Pack(2, key, val); 9127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (item == NULL) 9137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(key); 9157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(val); 9167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(pairs, item) == -1) { 9177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(item); 9187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(item); 9217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = next_idx; 9227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace before } or , */ 9247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 9257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* bail if the object is closed or we didn't get the , delimiter */ 9277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx) break; 9287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] == '}') { 9297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 9307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (str[idx] != ',') { 9327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting , delimiter", pystr, idx); 9337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 9367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after , delimiter */ 9387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 9397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* verify that idx < end_idx, str[idx] should be '}' */ 9427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx || str[idx] != '}') { 9437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting object", pystr, end_idx); 9447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if pairs_hook is not None: rval = object_pairs_hook(pairs) */ 9487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->pairs_hook != Py_None) { 9497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = PyObject_CallFunctionObjArgs(s->pairs_hook, pairs, NULL); 9507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 9517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(pairs); 9537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 1; 9547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return val; 9557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs((PyObject *)(&PyDict_Type), 9587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pairs, NULL); 9597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) 9607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(pairs); 9627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if object_hook is not None: rval = object_hook(rval) */ 9647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->object_hook != Py_None) { 9657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL); 9667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 9677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 9687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 9697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = val; 9707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = NULL; 9717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 1; 9737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 9747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 9757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(key); 9767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(val); 9777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(pairs); 9787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 9797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 9807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 9827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { 9837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON object from PyUnicode pystr. 9847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character after the opening curly brace. 9857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 9867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the closing curly brace. 9877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyObject (usually a dict, but object_hook can change that) 9897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 9907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); 9917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1; 9927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 9937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pairs; 9947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *item; 9957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *key = NULL; 9967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *val = NULL; 9977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int strict = PyObject_IsTrue(s->strict); 9987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next_idx; 9997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pairs = PyList_New(0); 10017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (pairs == NULL) 10027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 10037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after { */ 10057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 10067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* only loop if the object is non-empty */ 10087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx <= end_idx && str[idx] != '}') { 10097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx) { 10107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read key */ 10117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] != '"') { 10127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx); 10137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel key = scanstring_unicode(pystr, idx + 1, strict, &next_idx); 10167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (key == NULL) 10177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = next_idx; 10197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace between key and : delimiter, read :, skip whitespace */ 10217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 10227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx || str[idx] != ':') { 10237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting ':' delimiter", pystr, idx); 10247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 10277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 10287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read any JSON term */ 10307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = scan_once_unicode(s, pystr, idx, &next_idx); 10317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 10327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel item = PyTuple_Pack(2, key, val); 10357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (item == NULL) 10367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(key); 10387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(val); 10397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(pairs, item) == -1) { 10407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(item); 10417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(item); 10447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = next_idx; 10457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace before } or , */ 10477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 10487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* bail if the object is closed or we didn't get the , delimiter */ 10507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx) break; 10517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] == '}') { 10527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (str[idx] != ',') { 10557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting ',' delimiter", pystr, idx); 10567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 10597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after , delimiter */ 10617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 10627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* verify that idx < end_idx, str[idx] should be '}' */ 10667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx || str[idx] != '}') { 10677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting object", pystr, end_idx); 10687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if pairs_hook is not None: rval = object_pairs_hook(pairs) */ 10727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->pairs_hook != Py_None) { 10737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = PyObject_CallFunctionObjArgs(s->pairs_hook, pairs, NULL); 10747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 10757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(pairs); 10777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 1; 10787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return val; 10797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs((PyObject *)(&PyDict_Type), 10827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pairs, NULL); 10837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) 10847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(pairs); 10867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 10877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if object_hook is not None: rval = object_hook(rval) */ 10887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->object_hook != Py_None) { 10897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL); 10907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 10917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 10927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 10937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = val; 10947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = NULL; 10957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 1; 10977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 10987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 10997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(key); 11007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(val); 11017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(pairs); 11027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 11037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 11047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 11067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_parse_array_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { 11077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON array from PyString pystr. 11087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character after the opening brace. 11097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 11107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the closing brace. 11117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyList 11137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 11147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *str = PyString_AS_STRING(pystr); 11157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; 11167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *val = NULL; 11177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval = PyList_New(0); 11187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next_idx; 11197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) 11207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 11217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after [ */ 11237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 11247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* only loop if the array is non-empty */ 11267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx <= end_idx && str[idx] != ']') { 11277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx) { 11287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read any JSON term and de-tuplefy the (rval, idx) */ 11307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = scan_once_str(s, pystr, idx, &next_idx); 11317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 11327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 11337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, val) == -1) 11357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 11367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(val); 11387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = next_idx; 11397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace between term and , */ 11417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 11427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* bail if the array is closed or we didn't get the , delimiter */ 11447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx) break; 11457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] == ']') { 11467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (str[idx] != ',') { 11497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting , delimiter", pystr, idx); 11507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 11517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 11537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after , */ 11557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 11567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* verify that idx < end_idx, str[idx] should be ']' */ 11607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx || str[idx] != ']') { 11617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting object", pystr, end_idx); 11627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 11637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 1; 11657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 11667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 11677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(val); 11687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 11697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 11707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 11717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 11737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { 11747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON array from PyString pystr. 11757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character after the opening brace. 11767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 11777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the closing brace. 11787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyList 11807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 11817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); 11827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1; 11837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *val = NULL; 11847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval = PyList_New(0); 11857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next_idx; 11867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) 11877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 11887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after [ */ 11907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 11917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* only loop if the array is non-empty */ 11937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx <= end_idx && str[idx] != ']') { 11947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx) { 11957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 11967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read any JSON term */ 11977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel val = scan_once_unicode(s, pystr, idx, &next_idx); 11987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (val == NULL) 11997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 12007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, val) == -1) 12027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 12037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(val); 12057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = next_idx; 12067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace between term and , */ 12087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 12097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* bail if the array is closed or we didn't get the , delimiter */ 12117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx) break; 12127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] == ']') { 12137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 12147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (str[idx] != ',') { 12167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting ',' delimiter", pystr, idx); 12177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 12187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 12207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* skip whitespace after , */ 12227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; 12237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* verify that idx < end_idx, str[idx] should be ']' */ 12277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx || str[idx] != ']') { 12287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel raise_errmsg("Expecting object", pystr, end_idx); 12297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 12307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 1; 12327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 12337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 12347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(val); 12357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 12367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 12377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 12387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 12407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { 12417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON constant from PyString pystr. 12427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel constant is the constant string that was found 12437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ("NaN", "Infinity", "-Infinity"). 12447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character of the constant 12457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 12467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the constant. 12477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns the result of parse_constant 12497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 12507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *cstr; 12517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 12527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* constant is "NaN", "Infinity", or "-Infinity" */ 12537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel cstr = PyString_InternFromString(constant); 12547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (cstr == NULL) 12557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 12567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* rval = parse_constant(constant) */ 12587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL); 12597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx += PyString_GET_SIZE(cstr); 12607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(cstr); 12617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx; 12627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 12637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 12647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 12667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_match_number_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) { 12677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON number from PyString pystr. 12687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character of the number 12697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 12707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the number. 12717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyObject representation of that number: 12737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyInt, PyLong, or PyFloat. 12747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel May return other types if parse_int or parse_float are set 12757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 12767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *str = PyString_AS_STRING(pystr); 12777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; 12787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t idx = start; 12797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int is_float = 0; 12807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 12817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *numstr; 12827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read a sign if it's there, make sure it's not the end of the string */ 12847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] == '-') { 12857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 12867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx) { 12877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetNone(PyExc_StopIteration); 12887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 12897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read as many integer digits as we find as long as it doesn't start with 0 */ 12937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] >= '1' && str[idx] <= '9') { 12947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 12957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; 12967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if it starts with 0 we only expect one integer digit */ 12987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (str[idx] == '0') { 12997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 13007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* no integer digits, error */ 13027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 13037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetNone(PyExc_StopIteration); 13047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 13057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if the next char is '.' followed by a digit then read all float digits */ 13087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < end_idx && str[idx] == '.' && str[idx + 1] >= '0' && str[idx + 1] <= '9') { 13097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is_float = 1; 13107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx += 2; 13117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; 13127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */ 13157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < end_idx && (str[idx] == 'e' || str[idx] == 'E')) { 13167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* save the index of the 'e' or 'E' just in case we need to backtrack */ 13187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t e_start = idx; 13197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 13207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read an exponent sign if present */ 13227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < end_idx && (str[idx] == '-' || str[idx] == '+')) idx++; 13237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read all digits */ 13257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; 13267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if we got a digit, then parse as float. if not, backtrack */ 13287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx - 1] >= '0' && str[idx - 1] <= '9') { 13297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is_float = 1; 13307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 13327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = e_start; 13337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* copy the section we determined to be a number */ 13377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel numstr = PyString_FromStringAndSize(&str[start], idx - start); 13387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (numstr == NULL) 13397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 13407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (is_float) { 13417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* parse as a float using a fast path if available, otherwise call user defined method */ 13427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->parse_float != (PyObject *)&PyFloat_Type) { 13437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs(s->parse_float, numstr, NULL); 13447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 13467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel double d = PyOS_string_to_double(PyString_AS_STRING(numstr), 13477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NULL, NULL); 13487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (d == -1.0 && PyErr_Occurred()) 13497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 13507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyFloat_FromDouble(d); 13517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 13547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* parse as an int using a fast path if available, otherwise call user defined method */ 13557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->parse_int != (PyObject *)&PyInt_Type) { 13567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs(s->parse_int, numstr, NULL); 13577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 13597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyInt_FromString(PyString_AS_STRING(numstr), NULL, 10); 13607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(numstr); 13637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx; 13647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 13657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 13667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 13687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) { 13697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read a JSON number from PyUnicode pystr. 13707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character of the number 13717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 13727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the number. 13737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyObject representation of that number: 13757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyInt, PyLong, or PyFloat. 13767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel May return other types if parse_int or parse_float are set 13777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 13787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); 13797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1; 13807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t idx = start; 13817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int is_float = 0; 13827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 13837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *numstr; 13847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read a sign if it's there, make sure it's not the end of the string */ 13867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] == '-') { 13877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 13887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx > end_idx) { 13897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetNone(PyExc_StopIteration); 13907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 13917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read as many integer digits as we find as long as it doesn't start with 0 */ 13957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx] >= '1' && str[idx] <= '9') { 13967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 13977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; 13987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if it starts with 0 we only expect one integer digit */ 14007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (str[idx] == '0') { 14017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 14027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* no integer digits, error */ 14047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 14057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetNone(PyExc_StopIteration); 14067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 14077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if the next char is '.' followed by a digit then read all float digits */ 14107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < end_idx && str[idx] == '.' && str[idx + 1] >= '0' && str[idx + 1] <= '9') { 14117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is_float = 1; 14127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx += 2; 14137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; 14147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */ 14177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < end_idx && (str[idx] == 'e' || str[idx] == 'E')) { 14187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t e_start = idx; 14197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx++; 14207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read an exponent sign if present */ 14227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < end_idx && (str[idx] == '-' || str[idx] == '+')) idx++; 14237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* read all digits */ 14257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; 14267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if we got a digit, then parse as float. if not, backtrack */ 14287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (str[idx - 1] >= '0' && str[idx - 1] <= '9') { 14297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is_float = 1; 14307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 14327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = e_start; 14337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* copy the section we determined to be a number */ 14377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel numstr = PyUnicode_FromUnicode(&str[start], idx - start); 14387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (numstr == NULL) 14397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 14407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (is_float) { 14417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* parse as a float using a fast path if available, otherwise call user defined method */ 14427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->parse_float != (PyObject *)&PyFloat_Type) { 14437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs(s->parse_float, numstr, NULL); 14447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 14467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyFloat_FromString(numstr, NULL); 14477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 14507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* no fast path for unicode -> int, just call */ 14517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyObject_CallFunctionObjArgs(s->parse_int, numstr, NULL); 14527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(numstr); 14547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx; 14557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 14567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 14577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 14597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) 14607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 14617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read one JSON term (of any kind) from PyString pystr. 14627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character of the term 14637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 14647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the number. 14657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyObject representation of the term. 14677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 14687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *res; 14697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel char *str = PyString_AS_STRING(pystr); 14707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t length = PyString_GET_SIZE(pystr); 14717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < 0) { 14727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "idx cannot be negative"); 14737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 14747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx >= length) { 14767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetNone(PyExc_StopIteration); 14777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 14787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (str[idx]) { 14807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '"': 14817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* string */ 14827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return scanstring_str(pystr, idx + 1, 14837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyString_AS_STRING(s->encoding), 14847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_IsTrue(s->strict), 14857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next_idx_ptr); 14867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '{': 14877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* object */ 14887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while decoding a JSON object " 14897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "from a byte string")) 14907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 14917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel res = _parse_object_str(s, pystr, idx + 1, next_idx_ptr); 14927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 14937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return res; 14947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '[': 14957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* array */ 14967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while decoding a JSON array " 14977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "from a byte string")) 14987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 14997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel res = _parse_array_str(s, pystr, idx + 1, next_idx_ptr); 15007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 15017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return res; 15027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'n': 15037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* null */ 15047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') { 15057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_None); 15067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 4; 15077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Py_None; 15087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 15107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 't': 15117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* true */ 15127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') { 15137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_True); 15147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 4; 15157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Py_True; 15167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 15187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': 15197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* false */ 15207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') { 15217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_False); 15227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 5; 15237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Py_False; 15247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 15267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'N': 15277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* NaN */ 15287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') { 15297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _parse_constant(s, "NaN", idx, next_idx_ptr); 15307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 15327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'I': 15337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Infinity */ 15347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') { 15357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _parse_constant(s, "Infinity", idx, next_idx_ptr); 15367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 15387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '-': 15397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* -Infinity */ 15407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') { 15417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _parse_constant(s, "-Infinity", idx, next_idx_ptr); 15427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 15447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Didn't find a string, object, array, or named constant. Look for a number. */ 15467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _match_number_str(s, pystr, idx, next_idx_ptr); 15477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 15487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 15497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 15507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) 15517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 15527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Read one JSON term (of any kind) from PyUnicode pystr. 15537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx is the index of the first character of the term 15547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr is a return-by-reference index to the first character after 15557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the number. 15567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 15577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns a new PyObject representation of the term. 15587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 15597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *res; 15607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); 15617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t length = PyUnicode_GET_SIZE(pystr); 15627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx < 0) { 15637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "idx cannot be negative"); 15647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 15657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx >= length) { 15677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetNone(PyExc_StopIteration); 15687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 15697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (str[idx]) { 15717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '"': 15727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* string */ 15737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return scanstring_unicode(pystr, idx + 1, 15747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_IsTrue(s->strict), 15757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next_idx_ptr); 15767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '{': 15777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* object */ 15787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while decoding a JSON object " 15797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "from a unicode string")) 15807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 15817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); 15827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 15837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return res; 15847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '[': 15857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* array */ 15867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while decoding a JSON array " 15877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "from a unicode string")) 15887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 15897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); 15907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 15917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return res; 15927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'n': 15937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* null */ 15947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') { 15957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_None); 15967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 4; 15977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Py_None; 15987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 15997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 16007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 't': 16017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* true */ 16027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') { 16037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_True); 16047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 4; 16057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Py_True; 16067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 16087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'f': 16097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* false */ 16107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') { 16117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(Py_False); 16127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *next_idx_ptr = idx + 5; 16137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Py_False; 16147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 16167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'N': 16177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* NaN */ 16187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') { 16197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _parse_constant(s, "NaN", idx, next_idx_ptr); 16207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 16227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 'I': 16237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Infinity */ 16247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') { 16257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _parse_constant(s, "Infinity", idx, next_idx_ptr); 16267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 16287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case '-': 16297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* -Infinity */ 16307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') { 16317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _parse_constant(s, "-Infinity", idx, next_idx_ptr); 16327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 16347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Didn't find a string, object, array, or named constant. Look for a number. */ 16367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _match_number_unicode(s, pystr, idx, next_idx_ptr); 16377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 16387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 16397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 16407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_call(PyObject *self, PyObject *args, PyObject *kwds) 16417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 16427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Python callable interface to scan_once_{str,unicode} */ 16437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *pystr; 16447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 16457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t idx; 16467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t next_idx = -1; 16477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static char *kwlist[] = {"string", "idx", NULL}; 16487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyScannerObject *s; 16497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyScanner_Check(self)); 16507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyScannerObject *)self; 16517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:scan_once", kwlist, &pystr, _convertPyInt_AsSsize_t, &idx)) 16527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 16537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 16547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyString_Check(pystr)) { 16557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = scan_once_str(s, pystr, idx, &next_idx); 16567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyUnicode_Check(pystr)) { 16587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = scan_once_unicode(s, pystr, idx, &next_idx); 16597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 16617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 16627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "first argument must be a string, not %.80s", 16637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(pystr)->tp_name); 16647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 16657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _build_rval_index_tuple(rval, next_idx); 16677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 16687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 16697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 16707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 16717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 16727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyScannerObject *s; 16737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyScannerObject *)type->tp_alloc(type, 0); 16747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s != NULL) { 16757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->encoding = NULL; 16767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->strict = NULL; 16777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->object_hook = NULL; 16787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->pairs_hook = NULL; 16797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->parse_float = NULL; 16807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->parse_int = NULL; 16817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->parse_constant = NULL; 16827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 16837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return (PyObject *)s; 16847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 16857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 16867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 16877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielscanner_init(PyObject *self, PyObject *args, PyObject *kwds) 16887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 16897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Initialize Scanner object */ 16907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *ctx; 16917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static char *kwlist[] = {"context", NULL}; 16927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyScannerObject *s; 16937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 16947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyScanner_Check(self)); 16957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyScannerObject *)self; 16967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 16977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) 16987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 16997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* PyString_AS_STRING is used on encoding */ 17017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->encoding = PyObject_GetAttrString(ctx, "encoding"); 17027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->encoding == NULL) 17037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->encoding == Py_None) { 17057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(Py_None); 17067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->encoding = PyString_InternFromString(DEFAULT_ENCODING); 17077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 17087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyUnicode_Check(s->encoding)) { 17097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *tmp = PyUnicode_AsEncodedString(s->encoding, NULL, NULL); 17107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(s->encoding); 17117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->encoding = tmp; 17127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 17137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->encoding == NULL) 17147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyString_Check(s->encoding)) { 17167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_Format(PyExc_TypeError, 17177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "encoding must be a string, not %.80s", 17187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(s->encoding)->tp_name); 17197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 17217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* All of these will fail "gracefully" so we don't need to verify them */ 17247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->strict = PyObject_GetAttrString(ctx, "strict"); 17257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->strict == NULL) 17267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->object_hook = PyObject_GetAttrString(ctx, "object_hook"); 17287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->object_hook == NULL) 17297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook"); 17317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->pairs_hook == NULL) 17327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->parse_float = PyObject_GetAttrString(ctx, "parse_float"); 17347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->parse_float == NULL) 17357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->parse_int = PyObject_GetAttrString(ctx, "parse_int"); 17377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->parse_int == NULL) 17387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant"); 17407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->parse_constant == NULL) 17417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 17427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 17447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 17467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->encoding); 17477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->strict); 17487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->object_hook); 17497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->pairs_hook); 17507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->parse_float); 17517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->parse_int); 17527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->parse_constant); 17537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 17547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 17557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(scanner_doc, "JSON scanner object"); 17577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 17587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic 17597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyTypeObject PyScannerType = { 17607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_HEAD_INIT(NULL) 17617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_internal */ 17627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "_json.Scanner", /* tp_name */ 17637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel sizeof(PyScannerObject), /* tp_basicsize */ 17647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_itemsize */ 17657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_dealloc, /* tp_dealloc */ 17667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_print */ 17677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_getattr */ 17687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_setattr */ 17697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_compare */ 17707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_repr */ 17717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_number */ 17727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_sequence */ 17737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_mapping */ 17747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_hash */ 17757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_call, /* tp_call */ 17767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_str */ 17777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */ 17787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */ 17797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_buffer */ 17807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 17817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_doc, /* tp_doc */ 17827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_traverse, /* tp_traverse */ 17837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_clear, /* tp_clear */ 17847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_richcompare */ 17857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_weaklistoffset */ 17867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_iter */ 17877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_iternext */ 17887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_methods */ 17897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_members, /* tp_members */ 17907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_getset */ 17917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_base */ 17927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_dict */ 17937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_descr_get */ 17947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_descr_set */ 17957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_dictoffset */ 17967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_init, /* tp_init */ 17977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0,/* PyType_GenericAlloc, */ /* tp_alloc */ 17987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel scanner_new, /* tp_new */ 17997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0,/* PyObject_GC_Del, */ /* tp_free */ 18007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 18017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 18037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 18047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 18057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyEncoderObject *s; 18067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyEncoderObject *)type->tp_alloc(type, 0); 18077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s != NULL) { 18087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->markers = NULL; 18097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->defaultfn = NULL; 18107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->encoder = NULL; 18117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->indent = NULL; 18127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->key_separator = NULL; 18137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->item_separator = NULL; 18147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->sort_keys = NULL; 18157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->skipkeys = NULL; 18167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 18177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return (PyObject *)s; 18187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 18197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 18217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_init(PyObject *self, PyObject *args, PyObject *kwds) 18227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 18237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* initialize Encoder object */ 18247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; 18257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyEncoderObject *s; 18277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; 18287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan; 18297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyEncoder_Check(self)); 18317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyEncoderObject *)self; 18327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, 18347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, 18357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &sort_keys, &skipkeys, &allow_nan)) 18367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 18377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->markers = markers; 18397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->defaultfn = defaultfn; 18407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->encoder = encoder; 18417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->indent = indent; 18427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->key_separator = key_separator; 18437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->item_separator = item_separator; 18447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->sort_keys = sort_keys; 18457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->skipkeys = skipkeys; 18467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); 18477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s->allow_nan = PyObject_IsTrue(allow_nan); 18487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->markers); 18507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->defaultfn); 18517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->encoder); 18527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->indent); 18537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->key_separator); 18547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->item_separator); 18557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->sort_keys); 18567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s->skipkeys); 18577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 18587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 18597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 18617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_call(PyObject *self, PyObject *args, PyObject *kwds) 18627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 18637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Python callable interface to encode_listencode_obj */ 18647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static char *kwlist[] = {"obj", "_current_indent_level", NULL}; 18657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *obj; 18667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *rval; 18677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t indent_level; 18687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyEncoderObject *s; 18697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyEncoder_Check(self)); 18707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyEncoderObject *)self; 18717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:_iterencode", kwlist, 18727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &obj, _convertPyInt_AsSsize_t, &indent_level)) 18737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 18747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rval = PyList_New(0); 18757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rval == NULL) 18767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 18777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoder_listencode_obj(s, rval, obj, indent_level)) { 18787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(rval); 18797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 18807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 18817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 18827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 18837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 18847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 18857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_encoded_const(PyObject *obj) 18867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 18877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Return the JSON string representation of None, True, False */ 18887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (obj == Py_None) { 18897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *s_null = NULL; 18907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s_null == NULL) { 18917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s_null = PyString_InternFromString("null"); 18927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 18937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s_null); 18947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return s_null; 18957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 18967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (obj == Py_True) { 18977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *s_true = NULL; 18987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s_true == NULL) { 18997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s_true = PyString_InternFromString("true"); 19007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s_true); 19027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return s_true; 19037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (obj == Py_False) { 19057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *s_false = NULL; 19067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s_false == NULL) { 19077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s_false = PyString_InternFromString("false"); 19087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(s_false); 19107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return s_false; 19117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 19137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "not a const"); 19147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 19157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 19177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 19187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 19197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_encode_float(PyEncoderObject *s, PyObject *obj) 19207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 19217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Return the JSON representation of a PyFloat */ 19227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel double i = PyFloat_AS_DOUBLE(obj); 19237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!Py_IS_FINITE(i)) { 19247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!s->allow_nan) { 19257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "Out of range float values are not JSON compliant"); 19267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return NULL; 19277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (i > 0) { 19297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyString_FromString("Infinity"); 19307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (i < 0) { 19327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyString_FromString("-Infinity"); 19337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 19357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyString_FromString("NaN"); 19367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Use a better float format here? */ 19397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyObject_Repr(obj); 19407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 19417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 19427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject * 19437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_encode_string(PyEncoderObject *s, PyObject *obj) 19447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 19457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Return the JSON representation of a string */ 19467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->fast_encode) 19477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return py_encode_basestring_ascii(NULL, obj); 19487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else 19497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); 19507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 19517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 19527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 19537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel_steal_list_append(PyObject *lst, PyObject *stolen) 19547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 19557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Append stolen and then decrement its reference count */ 19567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int rval = PyList_Append(lst, stolen); 19577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(stolen); 19587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rval; 19597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 19607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 19617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 19627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssize_t indent_level) 19637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 19647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Encode Python object obj to a JSON term, rval is a PyList */ 19657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *newobj; 19667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int rv; 19677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 19687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (obj == Py_None || obj == Py_True || obj == Py_False) { 19697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *cstr = _encoded_const(obj); 19707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (cstr == NULL) 19717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 19727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _steal_list_append(rval, cstr); 19737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyString_Check(obj) || PyUnicode_Check(obj)) 19757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel { 19767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *encoded = encoder_encode_string(s, obj); 19777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoded == NULL) 19787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 19797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _steal_list_append(rval, encoded); 19807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyInt_Check(obj) || PyLong_Check(obj)) { 19827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *encoded = PyObject_Str(obj); 19837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoded == NULL) 19847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 19857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _steal_list_append(rval, encoded); 19867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyFloat_Check(obj)) { 19887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *encoded = encoder_encode_float(s, obj); 19897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoded == NULL) 19907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 19917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return _steal_list_append(rval, encoded); 19927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 19937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyList_Check(obj) || PyTuple_Check(obj)) { 19947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while encoding a JSON object")) 19957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 19967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rv = encoder_listencode_list(s, rval, obj, indent_level); 19977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 19987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rv; 19997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyDict_Check(obj)) { 20017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while encoding a JSON object")) 20027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rv = encoder_listencode_dict(s, rval, obj, indent_level); 20047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 20057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rv; 20067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 20087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *ident = NULL; 20097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->markers != Py_None) { 20107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int has_key; 20117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ident = PyLong_FromVoidPtr(obj); 20127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ident == NULL) 20137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel has_key = PyDict_Contains(s->markers, ident); 20157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (has_key) { 20167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (has_key != -1) 20177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "Circular reference detected"); 20187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(ident); 20197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_SetItem(s->markers, ident, obj)) { 20227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(ident); 20237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL); 20277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (newobj == NULL) { 20287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(ident); 20297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_EnterRecursiveCall(" while encoding a JSON object")) 20337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel rv = encoder_listencode_obj(s, rval, newobj, indent_level); 20357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_LeaveRecursiveCall(); 20367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(newobj); 20387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (rv) { 20397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(ident); 20407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ident != NULL) { 20437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_DelItem(s->markers, ident)) { 20447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(ident); 20457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(ident); 20487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return rv; 20507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 20527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 20547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ssize_t indent_level) 20557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 20567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Encode Python dict dct a JSON term, rval is a PyList */ 20577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *open_dict = NULL; 20587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *close_dict = NULL; 20597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *empty_dict = NULL; 20607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *kstr = NULL; 20617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *ident = NULL; 20627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *key = NULL; 20637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *value = NULL; 20647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *it = NULL; 20657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int skipkeys; 20667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t idx; 20677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { 20697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel open_dict = PyString_InternFromString("{"); 20707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel close_dict = PyString_InternFromString("}"); 20717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel empty_dict = PyString_InternFromString("{}"); 20727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) 20737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 20747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (Py_SIZE(dct) == 0) 20767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyList_Append(rval, empty_dict); 20777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->markers != Py_None) { 20797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int has_key; 20807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ident = PyLong_FromVoidPtr(dct); 20817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ident == NULL) 20827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 20837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel has_key = PyDict_Contains(s->markers, ident); 20847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (has_key) { 20857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (has_key != -1) 20867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "Circular reference detected"); 20877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 20887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_SetItem(s->markers, ident, dct)) { 20907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 20917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 20937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, open_dict)) 20957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 20967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 20977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->indent != Py_None) { 20987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* TODO: DOES NOT RUN */ 20997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel indent_level += 1; 21007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* 21017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) 21027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel separator = _item_separator + newline_indent 21037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buf += newline_indent 21047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 21057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* TODO: C speedup not implemented for sort_keys */ 21087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel it = PyObject_GetIter(dct); 21107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (it == NULL) 21117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel skipkeys = PyObject_IsTrue(s->skipkeys); 21137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx = 0; 21147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while ((key = PyIter_Next(it)) != NULL) { 21157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *encoded; 21167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyString_Check(key) || PyUnicode_Check(key)) { 21187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF(key); 21197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel kstr = key; 21207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyFloat_Check(key)) { 21227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel kstr = encoder_encode_float(s, key); 21237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (kstr == NULL) 21247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (PyInt_Check(key) || PyLong_Check(key)) { 21277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel kstr = PyObject_Str(key); 21287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (kstr == NULL) 21297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (key == Py_True || key == Py_False || key == Py_None) { 21327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel kstr = _encoded_const(key); 21337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (kstr == NULL) 21347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (skipkeys) { 21377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(key); 21387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel continue; 21397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 21417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* TODO: include repr of key */ 21427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_TypeError, "keys must be a string"); 21437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (idx) { 21477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, s->item_separator)) 21487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel value = PyObject_GetItem(dct, key); 21527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (value == NULL) 21537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoded = encoder_encode_string(s, kstr); 21567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(kstr); 21577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoded == NULL) 21587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, encoded)) { 21607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(encoded); 21617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(encoded); 21647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, s->key_separator)) 21657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoder_listencode_obj(s, rval, value, indent_level)) 21677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel idx += 1; 21697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(value); 21707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(key); 21717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyErr_Occurred()) 21737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(it); 21757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ident != NULL) { 21777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_DelItem(s->markers, ident)) 21787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(ident); 21807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->indent != Py_None) { 21827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* TODO: DOES NOT RUN */ 21837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* 21847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel indent_level -= 1; 21857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel yield '\n' + (' ' * (_indent * _current_indent_level)) 21877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 21887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 21897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, close_dict)) 21907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 21917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 21927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 21937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 21947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(it); 21957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(key); 21967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(value); 21977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(kstr); 21987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(ident); 21997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 22007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 22017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 22047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_listencode_list(PyEncoderObject *s, PyObject *rval, PyObject *seq, Py_ssize_t indent_level) 22057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 22067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Encode Python list seq to a JSON term, rval is a PyList */ 22077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *open_array = NULL; 22087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *close_array = NULL; 22097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static PyObject *empty_array = NULL; 22107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *ident = NULL; 22117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *s_fast = NULL; 22127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_ssize_t i; 22137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (open_array == NULL || close_array == NULL || empty_array == NULL) { 22157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel open_array = PyString_InternFromString("["); 22167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel close_array = PyString_InternFromString("]"); 22177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel empty_array = PyString_InternFromString("[]"); 22187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (open_array == NULL || close_array == NULL || empty_array == NULL) 22197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 22207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ident = NULL; 22227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); 22237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s_fast == NULL) 22247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 22257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PySequence_Fast_GET_SIZE(s_fast) == 0) { 22267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(s_fast); 22277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return PyList_Append(rval, empty_array); 22287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->markers != Py_None) { 22317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int has_key; 22327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ident = PyLong_FromVoidPtr(seq); 22337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ident == NULL) 22347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel has_key = PyDict_Contains(s->markers, ident); 22367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (has_key) { 22377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (has_key != -1) 22387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyErr_SetString(PyExc_ValueError, "Circular reference detected"); 22397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_SetItem(s->markers, ident, seq)) { 22427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, open_array)) 22477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->indent != Py_None) { 22497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* TODO: DOES NOT RUN */ 22507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel indent_level += 1; 22517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* 22527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) 22537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel separator = _item_separator + newline_indent 22547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buf += newline_indent 22557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 22567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { 22587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); 22597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (i) { 22607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, s->item_separator)) 22617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (encoder_listencode_obj(s, rval, obj, indent_level)) 22647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ident != NULL) { 22677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyDict_DelItem(s->markers, ident)) 22687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(ident); 22707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (s->indent != Py_None) { 22727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* TODO: DOES NOT RUN */ 22737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* 22747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel indent_level -= 1; 22757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel yield '\n' + (' ' * (_indent * _current_indent_level)) 22777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 22787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 22797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyList_Append(rval, close_array)) 22807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto bail; 22817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(s_fast); 22827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 22837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielbail: 22857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_XDECREF(ident); 22867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_DECREF(s_fast); 22877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return -1; 22887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 22897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void 22917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_dealloc(PyObject *self) 22927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 22937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Deallocate Encoder */ 22947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_clear(self); 22957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TYPE(self)->tp_free(self); 22967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 22977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 22987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 22997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_traverse(PyObject *self, visitproc visit, void *arg) 23007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 23017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyEncoderObject *s; 23027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyEncoder_Check(self)); 23037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyEncoderObject *)self; 23047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->markers); 23057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->defaultfn); 23067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->encoder); 23077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->indent); 23087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->key_separator); 23097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->item_separator); 23107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->sort_keys); 23117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_VISIT(s->skipkeys); 23127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 23137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 23147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 23157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int 23167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielencoder_clear(PyObject *self) 23177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 23187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* Deallocate Encoder */ 23197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyEncoderObject *s; 23207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel assert(PyEncoder_Check(self)); 23217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel s = (PyEncoderObject *)self; 23227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->markers); 23237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->defaultfn); 23247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->encoder); 23257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->indent); 23267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->key_separator); 23277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->item_separator); 23287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->sort_keys); 23297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_CLEAR(s->skipkeys); 23307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 23317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 23327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 23337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable"); 23347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 23357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic 23367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyTypeObject PyEncoderType = { 23377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject_HEAD_INIT(NULL) 23387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_internal */ 23397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "_json.Encoder", /* tp_name */ 23407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel sizeof(PyEncoderObject), /* tp_basicsize */ 23417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_itemsize */ 23427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_dealloc, /* tp_dealloc */ 23437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_print */ 23447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_getattr */ 23457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_setattr */ 23467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_compare */ 23477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_repr */ 23487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_number */ 23497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_sequence */ 23507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_mapping */ 23517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_hash */ 23527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_call, /* tp_call */ 23537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_str */ 23547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_getattro */ 23557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_setattro */ 23567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_as_buffer */ 23577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 23587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_doc, /* tp_doc */ 23597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_traverse, /* tp_traverse */ 23607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_clear, /* tp_clear */ 23617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_richcompare */ 23627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_weaklistoffset */ 23637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_iter */ 23647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_iternext */ 23657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_methods */ 23667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_members, /* tp_members */ 23677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_getset */ 23687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_base */ 23697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_dict */ 23707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_descr_get */ 23717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_descr_set */ 23727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_dictoffset */ 23737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_init, /* tp_init */ 23747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_alloc */ 23757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel encoder_new, /* tp_new */ 23767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 0, /* tp_free */ 23777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 23787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 23797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyMethodDef speedups_methods[] = { 23807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"encode_basestring_ascii", 23817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (PyCFunction)py_encode_basestring_ascii, 23827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel METH_O, 23837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pydoc_encode_basestring_ascii}, 23847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {"scanstring", 23857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (PyCFunction)py_scanstring, 23867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel METH_VARARGS, 23877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pydoc_scanstring}, 23887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {NULL, NULL, 0, NULL} 23897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}; 23907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 23917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(module_doc, 23927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"json speedups\n"); 23937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 23947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvoid 23957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinit_json(void) 23967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 23977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyObject *m; 23987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyScannerType.tp_new = PyType_GenericNew; 23997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyType_Ready(&PyScannerType) < 0) 24007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return; 24017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyEncoderType.tp_new = PyType_GenericNew; 24027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (PyType_Ready(&PyEncoderType) < 0) 24037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return; 24047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel m = Py_InitModule3("_json", speedups_methods, module_doc); 24057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF((PyObject*)&PyScannerType); 24067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType); 24077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Py_INCREF((PyObject*)&PyEncoderType); 24087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType); 24097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2410