Crossfire Server, Branches 1.12  R18729
cjson.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2007 Dan Pascu.
3  * Author: Dan Pascu <dan@ag-projects.com>
4  *
5  * Fast JSON encoder/decoder implementation for Python
6  * This file is under GPL licence
7  */
8 
9 #include <Python.h>
10 #include <stddef.h>
11 #include <stdio.h>
12 #include <ctype.h>
13 #include <math.h>
14 
15 typedef struct JSONData {
16  char *str; /* the actual json string */
17  char *end; /* pointer to the string end */
18  char *ptr; /* pointer to the current parsing position */
19  int all_unicode; /* make all output strings unicode if true */
20 } JSONData;
21 
22 static PyObject *encode_object(PyObject *object);
23 static PyObject *encode_string(PyObject *object);
24 static PyObject *encode_unicode(PyObject *object);
25 static PyObject *encode_tuple(PyObject *object);
26 static PyObject *encode_list(PyObject *object);
27 static PyObject *encode_dict(PyObject *object);
28 
29 static PyObject *decode_json(JSONData *jsondata);
30 static PyObject *decode_null(JSONData *jsondata);
31 static PyObject *decode_bool(JSONData *jsondata);
32 static PyObject *decode_string(JSONData *jsondata);
33 static PyObject *decode_inf(JSONData *jsondata);
34 static PyObject *decode_nan(JSONData *jsondata);
35 static PyObject *decode_number(JSONData *jsondata);
36 static PyObject *decode_array(JSONData *jsondata);
37 static PyObject *decode_object(JSONData *jsondata);
38 
39 static PyObject *JSON_Error;
40 static PyObject *JSON_EncodeError;
41 static PyObject *JSON_DecodeError;
42 
43 #if PY_VERSION_HEX < 0x02050000
44 typedef int Py_ssize_t;
45 
46 #define PY_SSIZE_T_MAX INT_MAX
47 #define PY_SSIZE_T_MIN INT_MIN
48 
49 #define SSIZE_T_F "%d"
50 #else
51 #define SSIZE_T_F "%zd"
52 #endif
53 
54 #define True 1
55 #define False 0
56 
57 #ifndef INFINITY
58 #define INFINITY HUGE_VAL
59 #endif
60 
61 #ifndef NAN
62 #define NAN (HUGE_VAL-HUGE_VAL)
63 #endif
64 
65 #ifndef Py_IS_NAN
66 #define Py_IS_NAN(X) ((X) != (X))
67 #endif
68 
69 #define skipSpaces(d) while (*((d)->ptr) && isspace(*((d)->ptr))) (d)->ptr++
70 
71 /* ------------------------------ Decoding ----------------------------- */
72 
73 static void getRowAndCol(char *begin, char *current, int *row, int *col) {
74  *col = 1;
75  *row = 1;
76  while (current > begin) {
77  if (*current == '\n')
78  (*row)++;
79  if (*row < 2)
80  (*col)++;
81  current--;
82  }
83 }
84 static PyObject *decode_null(JSONData *jsondata) {
85  ptrdiff_t left;
86 
87  left = jsondata->end-jsondata->ptr;
88 
89  if (left >= 4 && strncmp(jsondata->ptr, "null", 4) == 0) {
90  jsondata->ptr += 4;
91  Py_INCREF(Py_None);
92  return Py_None;
93  } else {
94  int row, col;
95 
96  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
97  PyErr_Format(JSON_DecodeError, "cannot parse JSON description: %.20s" "(row "SSIZE_T_F", col "SSIZE_T_F")", jsondata->ptr, (Py_ssize_t)row, (Py_ssize_t)col);
98  return NULL;
99  }
100 }
101 
102 static PyObject *decode_bool(JSONData *jsondata) {
103  ptrdiff_t left;
104 
105  left = jsondata->end-jsondata->ptr;
106 
107  if (left >= 4 && strncmp(jsondata->ptr, "true", 4) == 0) {
108  jsondata->ptr += 4;
109  Py_INCREF(Py_True);
110  return Py_True;
111  } else if (left >= 5 && strncmp(jsondata->ptr, "false", 5) == 0) {
112  jsondata->ptr += 5;
113  Py_INCREF(Py_False);
114  return Py_False;
115  } else {
116  int row, col;
117 
118  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
119  PyErr_Format(JSON_DecodeError, "cannot parse JSON description: %.20s" "(row "SSIZE_T_F", col "SSIZE_T_F")", jsondata->ptr, (Py_ssize_t)row, (Py_ssize_t)col);
120  return NULL;
121  }
122 }
123 
124 static PyObject *decode_string(JSONData *jsondata) {
125  PyObject *object;
126  int c, escaping, has_unicode, string_escape;
127  Py_ssize_t len;
128  char *ptr;
129 
130  /* look for the closing quote */
131  escaping = has_unicode = string_escape = False;
132  ptr = jsondata->ptr+1;
133  while (True) {
134  c = *ptr;
135  if (c == 0) {
136  int row, col;
137 
138  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
139  PyErr_Format(JSON_DecodeError, "unterminated string starting at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
140  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
141  return NULL;
142  }
143  if (!escaping) {
144  if (c == '\\') {
145  escaping = True;
146  } else if (c == '"') {
147  break;
148  } else if (!isascii(c)) {
149  has_unicode = True;
150  }
151  } else {
152  switch (c) {
153  case 'u':
154  has_unicode = True;
155  break;
156  case '"':
157  case 'r':
158  case 'n':
159  case 't':
160  case 'b':
161  case 'f':
162  case '\\':
163  string_escape = True;
164  break;
165  }
166  escaping = False;
167  }
168  ptr++;
169  }
170 
171  len = ptr-jsondata->ptr-1;
172 
173  if (has_unicode || jsondata->all_unicode)
174  object = PyUnicode_DecodeUnicodeEscape(jsondata->ptr+1, len, NULL);
175  else if (string_escape)
176  object = PyString_DecodeEscape(jsondata->ptr+1, len, NULL, 0, NULL);
177  else
178  object = PyString_FromStringAndSize(jsondata->ptr+1, len);
179 
180  if (object == NULL) {
181  PyObject *type, *value, *tb, *reason;
182 
183  PyErr_Fetch(&type, &value, &tb);
184  if (type == NULL) {
185  int row, col;
186 
187  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
188  PyErr_Format(JSON_DecodeError, "invalid string starting at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
189  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
190  } else {
191  if (PyErr_GivenExceptionMatches(type, PyExc_UnicodeDecodeError)) {
192  int row, col;
193 
194  reason = PyObject_GetAttrString(value, "reason");
195  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
196  PyErr_Format(JSON_DecodeError, "cannot decode string starting" " at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F"): %s",
197  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col,
198  reason ? PyString_AsString(reason) : "bad format");
199  Py_XDECREF(reason);
200  } else {
201  int row, col;
202 
203  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
204  PyErr_Format(JSON_DecodeError, "invalid string starting at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
205  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
206  }
207  }
208  Py_XDECREF(type);
209  Py_XDECREF(value);
210  Py_XDECREF(tb);
211  } else {
212  jsondata->ptr = ptr+1;
213  }
214 
215  return object;
216 }
217 
218 static PyObject *decode_inf(JSONData *jsondata) {
219  PyObject *object;
220  ptrdiff_t left;
221 
222  left = jsondata->end-jsondata->ptr;
223 
224  if (left >= 8 && strncmp(jsondata->ptr, "Infinity", 8) == 0) {
225  jsondata->ptr += 8;
226  object = PyFloat_FromDouble(INFINITY);
227  return object;
228  } else if (left >= 9 && strncmp(jsondata->ptr, "+Infinity", 9) == 0) {
229  jsondata->ptr += 9;
230  object = PyFloat_FromDouble(INFINITY);
231  return object;
232  } else if (left >= 9 && strncmp(jsondata->ptr, "-Infinity", 9) == 0) {
233  jsondata->ptr += 9;
234  object = PyFloat_FromDouble(-INFINITY);
235  return object;
236  } else {
237  int row, col;
238 
239  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
240  PyErr_Format(JSON_DecodeError, "cannot parse JSON description: %.20s (row "SSIZE_T_F", col "SSIZE_T_F")", jsondata->ptr, (Py_ssize_t)row, (Py_ssize_t)col);
241  return NULL;
242  }
243 }
244 
245 static PyObject *decode_nan(JSONData *jsondata) {
246  PyObject *object;
247  ptrdiff_t left;
248 
249  left = jsondata->end-jsondata->ptr;
250 
251  if (left >= 3 && strncmp(jsondata->ptr, "NaN", 3) == 0) {
252  jsondata->ptr += 3;
253  object = PyFloat_FromDouble(NAN);
254  return object;
255  } else {
256  int row, col;
257  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
258  PyErr_Format(JSON_DecodeError, "cannot parse JSON description: %.20s(row "SSIZE_T_F", col "SSIZE_T_F")", jsondata->ptr, (Py_ssize_t)row, (Py_ssize_t)col);
259  return NULL;
260  }
261 }
262 
263 static PyObject *decode_number(JSONData *jsondata) {
264  PyObject *object, *str;
265  int c, is_float, should_stop;
266  char *ptr;
267 
268  /* check if we got a floating point number */
269  ptr = jsondata->ptr;
270  is_float = should_stop = False;
271  while (True) {
272  c = *ptr;
273  if (c == 0)
274  break;
275  switch (c) {
276  case '0':
277  case '1':
278  case '2':
279  case '3':
280  case '4':
281  case '5':
282  case '6':
283  case '7':
284  case '8':
285  case '9':
286  case '-':
287  case '+':
288  break;
289 
290  case '.':
291  case 'e':
292  case 'E':
293  is_float = True;
294  break;
295 
296  default:
297  should_stop = True;
298  }
299  if (should_stop) {
300  break;
301  }
302  ptr++;
303  }
304 
305  str = PyString_FromStringAndSize(jsondata->ptr, ptr-jsondata->ptr);
306  if (str == NULL)
307  return NULL;
308 
309  if (is_float) {
310  object = PyFloat_FromString(str, NULL);
311  } else {
312  object = PyInt_FromString(PyString_AS_STRING(str), NULL, 10);
313  }
314 
315  Py_DECREF(str);
316 
317  if (object == NULL) {
318  int row, col;
319 
320  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
321  PyErr_Format(JSON_DecodeError, "invalid number starting at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")", (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
322  } else {
323  jsondata->ptr = ptr;
324  }
325 
326  return object;
327 }
328 
329 static PyObject *decode_array(JSONData *jsondata) {
330  PyObject *object, *item;
331  int c, expect_item, items, result;
332  char *start;
333 
334  object = PyList_New(0);
335 
336  start = jsondata->ptr;
337  jsondata->ptr++;
338  expect_item = True;
339  items = 0;
340  while (True) {
341  skipSpaces(jsondata);
342  c = *jsondata->ptr;
343  if (c == 0) {
344  int row, col;
345 
346  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
347  PyErr_Format(JSON_DecodeError, "unterminated array starting at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
348  (Py_ssize_t)(start-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
349  goto failure;
350  } else if (c == ']') {
351  if (expect_item && items > 0) {
352  int row, col;
353 
354  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
355  PyErr_Format(JSON_DecodeError, "expecting array item at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
356  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
357  goto failure;
358  }
359  jsondata->ptr++;
360  break;
361  } else if (c == ',') {
362  if (expect_item) {
363  int row, col;
364 
365  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
366  PyErr_Format(JSON_DecodeError, "expecting array item at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
367  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
368  goto failure;
369  }
370  expect_item = True;
371  jsondata->ptr++;
372  continue;
373  } else {
374  item = decode_json(jsondata);
375  if (item == NULL)
376  goto failure;
377  result = PyList_Append(object, item);
378  Py_DECREF(item);
379  if (result == -1)
380  goto failure;
381  expect_item = False;
382  items++;
383  }
384  }
385 
386  return object;
387 
388 failure:
389  Py_DECREF(object);
390  return NULL;
391 }
392 
393 static PyObject *decode_object(JSONData *jsondata) {
394  PyObject *object, *key, *value;
395  int c, expect_key, items, result;
396  char *start;
397 
398  object = PyDict_New();
399 
400  expect_key = True;
401  items = 0;
402  start = jsondata->ptr;
403  jsondata->ptr++;
404 
405  while (True) {
406  skipSpaces(jsondata);
407  c = *jsondata->ptr;
408  if (c == 0) {
409  int row, col;
410 
411  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
412  PyErr_Format(JSON_DecodeError, "unterminated object starting at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
413  (Py_ssize_t)(start-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
414  goto failure;
415  } else if (c == '}') {
416  if (expect_key && items > 0) {
417  int row, col;
418 
419  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
420  PyErr_Format(JSON_DecodeError, "expecting object property name at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
421  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
422  goto failure;
423  }
424  jsondata->ptr++;
425  break;
426  } else if (c == ',') {
427  if (expect_key) {
428  int row, col;
429 
430  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
431  PyErr_Format(JSON_DecodeError, "expecting object property name at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
432  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
433  goto failure;
434  }
435  expect_key = True;
436  jsondata->ptr++;
437  continue;
438  } else {
439  if (c != '"') {
440  int row, col;
441 
442  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
443  PyErr_Format(JSON_DecodeError, "expecting property name in object at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
444  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
445  goto failure;
446  }
447 
448  key = decode_json(jsondata);
449  if (key == NULL)
450  goto failure;
451 
452  skipSpaces(jsondata);
453  if (*jsondata->ptr != ':') {
454  int row, col;
455 
456  getRowAndCol(jsondata->str, jsondata->ptr, &row, &col);
457  PyErr_Format(JSON_DecodeError, "missing colon after object property name at position "SSIZE_T_F"(row "SSIZE_T_F", col "SSIZE_T_F")",
458  (Py_ssize_t)(jsondata->ptr-jsondata->str), (Py_ssize_t)row, (Py_ssize_t)col);
459  Py_DECREF(key);
460  goto failure;
461  } else {
462  jsondata->ptr++;
463  }
464 
465  value = decode_json(jsondata);
466  if (value == NULL) {
467  Py_DECREF(key);
468  goto failure;
469  }
470 
471  result = PyDict_SetItem(object, key, value);
472  Py_DECREF(key);
473  Py_DECREF(value);
474  if (result == -1)
475  goto failure;
476  expect_key = False;
477  items++;
478  }
479  }
480 
481  return object;
482 
483 failure:
484  Py_DECREF(object);
485  return NULL;
486 }
487 
488 static PyObject *decode_json(JSONData *jsondata) {
489  PyObject *object;
490 
491  skipSpaces(jsondata);
492  switch (*jsondata->ptr) {
493  case 0:
494  PyErr_SetString(JSON_DecodeError, "empty JSON description");
495  return NULL;
496 
497  case '{':
498  object = decode_object(jsondata);
499  break;
500 
501  case '[':
502  object = decode_array(jsondata);
503  break;
504 
505  case '"':
506  object = decode_string(jsondata);
507  break;
508 
509  case 't':
510  case 'f':
511  object = decode_bool(jsondata);
512  break;
513 
514  case 'n':
515  object = decode_null(jsondata);
516  break;
517 
518  case 'N':
519  object = decode_nan(jsondata);
520  break;
521 
522  case 'I':
523  object = decode_inf(jsondata);
524  break;
525 
526  case '+':
527  case '-':
528  if (*(jsondata->ptr+1) == 'I') {
529  object = decode_inf(jsondata);
530  } else {
531  object = decode_number(jsondata);
532  }
533  break;
534 
535  case '0':
536  case '1':
537  case '2':
538  case '3':
539  case '4':
540  case '5':
541  case '6':
542  case '7':
543  case '8':
544  case '9':
545  object = decode_number(jsondata);
546  break;
547 
548  default:
549  PyErr_SetString(JSON_DecodeError, "cannot parse JSON description");
550  return NULL;
551  }
552 
553  return object;
554 }
555 
556 /* ------------------------------ Encoding ----------------------------- */
557 
558 /*
559  * This function is an almost verbatim copy of PyString_Repr() from
560  * Python's stringobject.c with the following differences:
561  *
562  * - it always quotes the output using double quotes.
563  * - it also quotes \b and \f
564  * - it replaces any non ASCII character hh with \u00hh instead of \xhh
565  */
566 static PyObject *encode_string(PyObject *string) {
567  register PyStringObject *op = (PyStringObject *)string;
568  size_t newsize = 2+6*op->ob_size;
569  PyObject *v;
570 
571  if (op->ob_size > (PY_SSIZE_T_MAX-2)/6) {
572  PyErr_SetString(PyExc_OverflowError, "string is too large to make repr");
573  return NULL;
574  }
575  v = PyString_FromStringAndSize((char *)NULL, newsize);
576  if (v == NULL) {
577  return NULL;
578  } else {
579  register Py_ssize_t i;
580  register char c;
581  register char *p;
582  int quote;
583 
584  quote = '"';
585 
586  p = PyString_AS_STRING(v);
587  *p++ = quote;
588  for (i = 0; i < op->ob_size; i++) {
589  /* There's at least enough room for a hex escape
590  and a closing quote. */
591  assert(newsize-(p-PyString_AS_STRING(v)) >= 7);
592  c = op->ob_sval[i];
593  if (c == quote || c == '\\')
594  *p++ = '\\', *p++ = c;
595  else if (c == '\t')
596  *p++ = '\\', *p++ = 't';
597  else if (c == '\n')
598  *p++ = '\\', *p++ = 'n';
599  else if (c == '\r')
600  *p++ = '\\', *p++ = 'r';
601  else if (c == '\f')
602  *p++ = '\\', *p++ = 'f';
603  else if (c == '\b')
604  *p++ = '\\', *p++ = 'b';
605  else if (c < ' ' || c >= 0x7f) {
606  /* For performance, we don't want to call
607  * PyOS_snprintf here (extra layers of
608  * function call). */
609  sprintf(p, "\\u%04x", c&0xff);
610  p += 6;
611  }
612  else
613  *p++ = c;
614  }
615  assert(newsize-(p-PyString_AS_STRING(v)) >= 1);
616  *p++ = quote;
617  *p = '\0';
618  _PyString_Resize(&v, (int) (p-PyString_AS_STRING(v)));
619  return v;
620  }
621 }
622 
623 /*
624  * This function is an almost verbatim copy of unicodeescape_string() from
625  * Python's unicodeobject.c with the following differences:
626  *
627  * - it always quotes the output using double quotes.
628  * - it uses \u00hh instead of \xhh in output.
629  * - it also quotes \b and \f
630  */
631 static PyObject *encode_unicode(PyObject *unicode) {
632  PyObject *repr;
633  Py_UNICODE *s;
634  Py_ssize_t size;
635  char *p;
636  static const char *hexdigit = "0123456789abcdef";
637 
638  s = PyUnicode_AS_UNICODE(unicode);
639  size = PyUnicode_GET_SIZE(unicode);
640 
641  if (size > (PY_SSIZE_T_MAX-2-1)/6) {
642  PyErr_SetString(PyExc_OverflowError, "unicode object is too large to make repr");
643  return NULL;
644  }
645 
646  repr = PyString_FromStringAndSize(NULL, 2+6*size+1);
647  if (repr == NULL)
648  return NULL;
649 
650  p = PyString_AS_STRING(repr);
651 
652  *p++ = '"';
653 
654  while (size-- > 0) {
655  Py_UNICODE ch = *s++;
656 
657  /* Escape quotes */
658  if ((ch == (Py_UNICODE)PyString_AS_STRING(repr)[0] || ch == '\\')) {
659  *p++ = '\\';
660  *p++ = (char)ch;
661  continue;
662 #ifdef Py_UNICODE_WIDE
663  /* Map 21-bit characters to '\U00xxxxxx' */
664  } else if (ch >= 0x10000) {
665  int offset = p-PyString_AS_STRING(repr);
666 
667  /* Resize the string if necessary */
668  if (offset+12 > PyString_GET_SIZE(repr)) {
669  if (_PyString_Resize(&repr, PyString_GET_SIZE(repr)+100))
670  return NULL;
671  p = PyString_AS_STRING(repr)+offset;
672  }
673 
674  *p++ = '\\';
675  *p++ = 'U';
676  *p++ = hexdigit[(ch>>28)&0x0000000F];
677  *p++ = hexdigit[(ch>>24)&0x0000000F];
678  *p++ = hexdigit[(ch>>20)&0x0000000F];
679  *p++ = hexdigit[(ch>>16)&0x0000000F];
680  *p++ = hexdigit[(ch>>12)&0x0000000F];
681  *p++ = hexdigit[(ch>>8)&0x0000000F];
682  *p++ = hexdigit[(ch>>4)&0x0000000F];
683  *p++ = hexdigit[ch&0x0000000F];
684  continue;
685 #endif
686  /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */
687  } else if (ch >= 0xD800 && ch < 0xDC00) {
688  Py_UNICODE ch2;
689  Py_UCS4 ucs;
690 
691  ch2 = *s++;
692  size--;
693  if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
694  ucs = (((ch&0x03FF)<<10)|(ch2&0x03FF))+0x00010000;
695  *p++ = '\\';
696  *p++ = 'U';
697  *p++ = hexdigit[(ucs>>28)&0x0000000F];
698  *p++ = hexdigit[(ucs>>24)&0x0000000F];
699  *p++ = hexdigit[(ucs>>20)&0x0000000F];
700  *p++ = hexdigit[(ucs>>16)&0x0000000F];
701  *p++ = hexdigit[(ucs>>12)&0x0000000F];
702  *p++ = hexdigit[(ucs>>8)&0x0000000F];
703  *p++ = hexdigit[(ucs>>4)&0x0000000F];
704  *p++ = hexdigit[ucs&0x0000000F];
705  continue;
706  }
707  /* Fall through: isolated surrogates are copied as-is */
708  s--;
709  size++;
710  /* Map 16-bit characters to '\uxxxx' */
711  } if (ch >= 256) {
712  *p++ = '\\';
713  *p++ = 'u';
714  *p++ = hexdigit[(ch>>12)&0x000F];
715  *p++ = hexdigit[(ch>>8)&0x000F];
716  *p++ = hexdigit[(ch>>4)&0x000F];
717  *p++ = hexdigit[ch&0x000F];
718  /* Map special whitespace to '\t', \n', '\r', '\f', '\b' */
719  } else if (ch == '\t') {
720  *p++ = '\\';
721  *p++ = 't';
722  } else if (ch == '\n') {
723  *p++ = '\\';
724  *p++ = 'n';
725  } else if (ch == '\r') {
726  *p++ = '\\';
727  *p++ = 'r';
728  } else if (ch == '\f') {
729  *p++ = '\\';
730  *p++ = 'f';
731  } else if (ch == '\b') {
732  *p++ = '\\';
733  *p++ = 'b';
734  }
735 
736  /* Map non-printable US ASCII to '\u00hh' */
737  else if (ch < ' ' || ch >= 0x7F) {
738  *p++ = '\\';
739  *p++ = 'u';
740  *p++ = '0';
741  *p++ = '0';
742  *p++ = hexdigit[(ch>>4)&0x000F];
743  *p++ = hexdigit[ch&0x000F];
744  }
745 
746  /* Copy everything else as-is */
747  else
748  *p++ = (char)ch;
749  }
750 
751  *p++ = PyString_AS_STRING(repr)[0];
752 
753  *p = '\0';
754  _PyString_Resize(&repr, p-PyString_AS_STRING(repr));
755  return repr;
756 }
757 
758 /*
759  * This function is an almost verbatim copy of tuplerepr() from
760  * Python's tupleobject.c with the following differences:
761  *
762  * - it uses encode_object() to get the object's JSON reprezentation.
763  * - it uses [] as decorations isntead of () (to masquerade as a JSON array).
764  */
765 
766 static PyObject *encode_tuple(PyObject *tuple) {
767  Py_ssize_t i, n;
768  PyObject *s, *temp;
769  PyObject *pieces, *result = NULL;
770  PyTupleObject *v = (PyTupleObject *)tuple;
771 
772  n = v->ob_size;
773  if (n == 0)
774  return PyString_FromString("[]");
775 
776  pieces = PyTuple_New(n);
777  if (pieces == NULL)
778  return NULL;
779 
780  /* Do repr() on each element. */
781  for (i = 0; i < n; ++i) {
782  s = encode_object(v->ob_item[i]);
783  if (s == NULL)
784  goto Done;
785  PyTuple_SET_ITEM(pieces, i, s);
786  }
787 
788  /* Add "[]" decorations to the first and last items. */
789  assert(n > 0);
790  s = PyString_FromString("[");
791  if (s == NULL)
792  goto Done;
793  temp = PyTuple_GET_ITEM(pieces, 0);
794  PyString_ConcatAndDel(&s, temp);
795  PyTuple_SET_ITEM(pieces, 0, s);
796  if (s == NULL)
797  goto Done;
798 
799  s = PyString_FromString("]");
800  if (s == NULL)
801  goto Done;
802  temp = PyTuple_GET_ITEM(pieces, n-1);
803  PyString_ConcatAndDel(&temp, s);
804  PyTuple_SET_ITEM(pieces, n-1, temp);
805  if (temp == NULL)
806  goto Done;
807 
808  /* Paste them all together with ", " between. */
809  s = PyString_FromString(", ");
810  if (s == NULL)
811  goto Done;
812  result = _PyString_Join(s, pieces);
813  Py_DECREF(s);
814 
815 Done:
816  Py_DECREF(pieces);
817  return result;
818 }
819 
820 /*
821  * This function is an almost verbatim copy of list_repr() from
822  * Python's listobject.c with the following differences:
823  *
824  * - it uses encode_object() to get the object's JSON reprezentation.
825  * - it doesn't use the ellipsis to represent a list with references
826  * to itself, instead it raises an exception as such lists cannot be
827  * represented in JSON.
828  */
829 static PyObject *encode_list(PyObject *list) {
830  Py_ssize_t i;
831  PyObject *s, *temp;
832  PyObject *pieces = NULL, *result = NULL;
833  PyListObject *v = (PyListObject *)list;
834 
835  i = Py_ReprEnter((PyObject *)v);
836  if (i != 0) {
837  if (i > 0) {
838  PyErr_SetString(JSON_EncodeError, "a list with references to itself is not JSON encodable");
839  }
840  return NULL;
841  }
842 
843  if (v->ob_size == 0) {
844  result = PyString_FromString("[]");
845  goto Done;
846  }
847 
848  pieces = PyList_New(0);
849  if (pieces == NULL)
850  goto Done;
851 
852  /* Do repr() on each element. Note that this may mutate the list,
853  * so must refetch the list size on each iteration. */
854  for (i = 0; i < v->ob_size; ++i) {
855  int status;
856  s = encode_object(v->ob_item[i]);
857  if (s == NULL)
858  goto Done;
859  status = PyList_Append(pieces, s);
860  Py_DECREF(s); /* append created a new ref */
861  if (status < 0)
862  goto Done;
863  }
864 
865  /* Add "[]" decorations to the first and last items. */
866  assert(PyList_GET_SIZE(pieces) > 0);
867  s = PyString_FromString("[");
868  if (s == NULL)
869  goto Done;
870  temp = PyList_GET_ITEM(pieces, 0);
871  PyString_ConcatAndDel(&s, temp);
872  PyList_SET_ITEM(pieces, 0, s);
873  if (s == NULL)
874  goto Done;
875 
876  s = PyString_FromString("]");
877  if (s == NULL)
878  goto Done;
879  temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces)-1);
880  PyString_ConcatAndDel(&temp, s);
881  PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces)-1, temp);
882  if (temp == NULL)
883  goto Done;
884 
885  /* Paste them all together with ", " between. */
886  s = PyString_FromString(", ");
887  if (s == NULL)
888  goto Done;
889  result = _PyString_Join(s, pieces);
890  Py_DECREF(s);
891 
892 Done:
893  Py_XDECREF(pieces);
894  Py_ReprLeave((PyObject *)v);
895  return result;
896 }
897 
898 /*
899  * This function is an almost verbatim copy of dict_repr() from
900  * Python's dictobject.c with the following differences:
901  *
902  * - it uses encode_object() to get the object's JSON reprezentation.
903  * - only accept strings for keys.
904  * - it doesn't use the ellipsis to represent a dictionary with references
905  * to itself, instead it raises an exception as such dictionaries cannot
906  * be represented in JSON.
907  */
908 static PyObject *encode_dict(PyObject *dict) {
909  Py_ssize_t i;
910  PyObject *s, *temp, *colon = NULL;
911  PyObject *pieces = NULL, *result = NULL;
912  PyObject *key, *value;
913  PyDictObject *mp = (PyDictObject *)dict;
914 
915  i = Py_ReprEnter((PyObject *)mp);
916  if (i != 0) {
917  if (i > 0) {
918  PyErr_SetString(JSON_EncodeError, "a dict with references to "
919  "itself is not JSON encodable");
920  }
921  return NULL;
922  }
923 
924  if (mp->ma_used == 0) {
925  result = PyString_FromString("{}");
926  goto Done;
927  }
928 
929  pieces = PyList_New(0);
930  if (pieces == NULL)
931  goto Done;
932 
933  colon = PyString_FromString(": ");
934  if (colon == NULL)
935  goto Done;
936 
937  /* Do repr() on each key+value pair, and insert ": " between them.
938  * Note that repr may mutate the dict. */
939  i = 0;
940  while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
941  int status;
942 
943  if (!PyString_Check(key) && !PyUnicode_Check(key)) {
944  PyErr_SetString(JSON_EncodeError, "JSON encodable dictionaries must have string/unicode keys");
945  goto Done;
946  }
947 
948  /* Prevent repr from deleting value during key format. */
949  Py_INCREF(value);
950  s = encode_object(key);
951  PyString_Concat(&s, colon);
952  PyString_ConcatAndDel(&s, encode_object(value));
953  Py_DECREF(value);
954  if (s == NULL)
955  goto Done;
956  status = PyList_Append(pieces, s);
957  Py_DECREF(s); /* append created a new ref */
958  if (status < 0)
959  goto Done;
960  }
961 
962  /* Add "{}" decorations to the first and last items. */
963  assert(PyList_GET_SIZE(pieces) > 0);
964  s = PyString_FromString("{");
965  if (s == NULL)
966  goto Done;
967  temp = PyList_GET_ITEM(pieces, 0);
968  PyString_ConcatAndDel(&s, temp);
969  PyList_SET_ITEM(pieces, 0, s);
970  if (s == NULL)
971  goto Done;
972 
973  s = PyString_FromString("}");
974  if (s == NULL)
975  goto Done;
976  temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces)-1);
977  PyString_ConcatAndDel(&temp, s);
978  PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces)-1, temp);
979  if (temp == NULL)
980  goto Done;
981 
982  /* Paste them all together with ", " between. */
983  s = PyString_FromString(", ");
984  if (s == NULL)
985  goto Done;
986  result = _PyString_Join(s, pieces);
987  Py_DECREF(s);
988 
989 Done:
990  Py_XDECREF(pieces);
991  Py_XDECREF(colon);
992  Py_ReprLeave((PyObject *)mp);
993  return result;
994 }
995 
996 static PyObject *encode_object(PyObject *object) {
997  if (object == Py_True) {
998  return PyString_FromString("true");
999  } else if (object == Py_False) {
1000  return PyString_FromString("false");
1001  } else if (object == Py_None) {
1002  return PyString_FromString("null");
1003  } else if (PyString_Check(object)) {
1004  return encode_string(object);
1005  } else if (PyUnicode_Check(object)) {
1006  return encode_unicode(object);
1007  } else if (PyFloat_Check(object)) {
1008  double val = PyFloat_AS_DOUBLE(object);
1009  if (Py_IS_NAN(val)) {
1010  return PyString_FromString("NaN");
1011  } else if (Py_IS_INFINITY(val)) {
1012  if (val > 0) {
1013  return PyString_FromString("Infinity");
1014  } else {
1015  return PyString_FromString("-Infinity");
1016  }
1017  } else {
1018  return PyObject_Str(object);
1019  }
1020  } else if (PyInt_Check(object) || PyLong_Check(object)) {
1021  return PyObject_Str(object);
1022  } else if (PyList_Check(object)) {
1023  return encode_list(object);
1024  } else if (PyTuple_Check(object)) {
1025  return encode_tuple(object);
1026  } else if (PyDict_Check(object)) { /* use PyMapping_Check(object) instead? -Dan */
1027  return encode_dict(object);
1028  } else {
1029  PyErr_SetString(JSON_EncodeError, "object is not JSON encodable");
1030  return NULL;
1031  }
1032 }
1033 
1034 /* Encode object into its JSON representation */
1035 
1036 static PyObject *JSON_encode(PyObject *self, PyObject *object) {
1037  return encode_object(object);
1038 }
1039 
1040 /* Decode JSON representation into pyhton objects */
1041 
1042 static PyObject *JSON_decode(PyObject *self, PyObject *args, PyObject *kwargs) {
1043  static char *kwlist[] = { "json", "all_unicode", NULL };
1044  int all_unicode = False; /* by default return unicode only when needed */
1045  PyObject *object, *string, *str;
1046  JSONData jsondata;
1047 
1048  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:decode", kwlist, &string, &all_unicode))
1049  return NULL;
1050 
1051  if (PyUnicode_Check(string)) {
1052  str = PyUnicode_AsRawUnicodeEscapeString(string);
1053  if (str == NULL) {
1054  return NULL;
1055  }
1056  } else {
1057  Py_INCREF(string);
1058  str = string;
1059  }
1060 
1061  if (PyString_AsStringAndSize(str, &(jsondata.str), NULL) == -1) {
1062  Py_DECREF(str);
1063  return NULL; /* not a string object or it contains null bytes */
1064  }
1065 
1066  jsondata.ptr = jsondata.str;
1067  jsondata.end = jsondata.str+strlen(jsondata.str);
1068  jsondata.all_unicode = all_unicode;
1069 
1070  object = decode_json(&jsondata);
1071 
1072  if (object != NULL) {
1073  skipSpaces(&jsondata);
1074  if (jsondata.ptr < jsondata.end) {
1075  PyErr_Format(JSON_DecodeError, "extra data after JSON description at position "SSIZE_T_F, (Py_ssize_t)(jsondata.ptr-jsondata.str));
1076  Py_DECREF(str);
1077  Py_DECREF(object);
1078  return NULL;
1079  }
1080  }
1081 
1082  Py_DECREF(str);
1083 
1084  return object;
1085 }
1086 
1087 /* List of functions defined in the module */
1088 
1089 static PyMethodDef cjson_methods[] = {
1090  { "encode", (PyCFunction)JSON_encode, METH_O,
1091  PyDoc_STR("encode(object) -> generate the JSON representation for object.") },
1092 
1093  { "decode", (PyCFunction)JSON_decode, METH_VARARGS|METH_KEYWORDS,
1094  PyDoc_STR("decode(string, all_unicode=False) -> parse the JSON representation into\n"
1095  "python objects. The optional argument `all_unicode', specifies how to\n"
1096  "convert the strings in the JSON representation into python objects.\n"
1097  "If it is False (default), it will return strings everywhere possible\n"
1098  "and unicode objects only where necessary, else it will return unicode\n"
1099  "objects everywhere (this is slower).") },
1100 
1101  { NULL, NULL, 0, NULL } /* sentinel */
1102 };
1103 
1104 PyDoc_STRVAR(module_doc, "Fast JSON encoder/decoder module.");
1105 
1106 /* Initialization function for the module (*must *be called initcjson) */
1107 #define MODULE_VERSION "1.0.5"
1108 PyMODINIT_FUNC initcjson(void) {
1109  PyObject *m;
1110 
1111  m = Py_InitModule3("cjson", cjson_methods, module_doc);
1112 
1113  if (m == NULL)
1114  return;
1115 
1116  JSON_Error = PyErr_NewException("cjson.Error", NULL, NULL);
1117  if (JSON_Error == NULL)
1118  return;
1119  Py_INCREF(JSON_Error);
1120  PyModule_AddObject(m, "Error", JSON_Error);
1121 
1122  JSON_EncodeError = PyErr_NewException("cjson.EncodeError", JSON_Error, NULL);
1123  if (JSON_EncodeError == NULL)
1124  return;
1125  Py_INCREF(JSON_EncodeError);
1126  PyModule_AddObject(m, "EncodeError", JSON_EncodeError);
1127 
1128  JSON_DecodeError = PyErr_NewException("cjson.DecodeError", JSON_Error, NULL);
1129  if (JSON_DecodeError == NULL)
1130  return;
1131  Py_INCREF(JSON_DecodeError);
1132  PyModule_AddObject(m, "DecodeError", JSON_DecodeError);
1133 
1134  /* Module version (the MODULE_VERSION macro is defined by setup.py) */
1135  PyModule_AddStringConstant(m, "__version__", MODULE_VERSION);
1136 }
static PyObject * decode_number(JSONData *jsondata)
Definition: cjson.c:263
PyDoc_STRVAR(module_doc,"Fast JSON encoder/decoder module.")
#define True
Definition: cjson.c:54
Definition: cjson.c:15
static PyObject * decode_nan(JSONData *jsondata)
Definition: cjson.c:245
static PyObject * decode_object(JSONData *jsondata)
Definition: cjson.c:393
static PyObject * decode_array(JSONData *jsondata)
Definition: cjson.c:329
static PyObject * JSON_Error
Definition: cjson.c:39
static PyObject * encode_unicode(PyObject *object)
Definition: cjson.c:631
char * ptr
Definition: cjson.c:18
PyMODINIT_FUNC initcjson(void)
Definition: cjson.c:1108
#define NAN
Definition: cjson.c:62
static PyObject * encode_dict(PyObject *object)
Definition: cjson.c:908
struct obj object
static PyObject * encode_list(PyObject *object)
Definition: cjson.c:829
static void getRowAndCol(char *begin, char *current, int *row, int *col)
Definition: cjson.c:73
#define skipSpaces(d)
Definition: cjson.c:69
static PyMethodDef cjson_methods[]
Definition: cjson.c:1089
static PyObject * decode_inf(JSONData *jsondata)
Definition: cjson.c:218
struct JSONData JSONData
#define PY_SSIZE_T_MAX
Definition: cjson.c:46
static PyObject * JSON_encode(PyObject *self, PyObject *object)
Definition: cjson.c:1036
int all_unicode
Definition: cjson.c:19
char * str
Definition: cjson.c:16
#define INFINITY
Definition: cjson.c:58
#define Py_IS_NAN(X)
Definition: cjson.c:66
#define MODULE_VERSION
Definition: cjson.c:1107
#define False
Definition: cjson.c:55
static PyObject * decode_bool(JSONData *jsondata)
Definition: cjson.c:102
#define SSIZE_T_F
Definition: cjson.c:49
static PyObject * decode_null(JSONData *jsondata)
Definition: cjson.c:84
static PyObject * JSON_EncodeError
Definition: cjson.c:40
int Py_ssize_t
Definition: cjson.c:44
static PyObject * decode_json(JSONData *jsondata)
Definition: cjson.c:488
static PyObject * encode_tuple(PyObject *object)
Definition: cjson.c:766
static PyObject * encode_object(PyObject *object)
Definition: cjson.c:996
static PyObject * JSON_DecodeError
Definition: cjson.c:41
static PyObject * JSON_decode(PyObject *self, PyObject *args, PyObject *kwargs)
Definition: cjson.c:1042
char * end
Definition: cjson.c:17
static PyObject * decode_string(JSONData *jsondata)
Definition: cjson.c:124
static PyObject * encode_string(PyObject *object)
Definition: cjson.c:566