# HG changeset patch # User Fredrik Lundh # Date 1257416334 -3600 # Node ID 95a726e486ba7ba202a0f14cf12070640fe0e5a8 # Parent 8e8a3070287c28e880d0aa9d4ccad9a94cd9152c Added encoding context. diff -r 8e8a3070287c28e880d0aa9d4ccad9a94cd9152c -r 95a726e486ba7ba202a0f14cf12070640fe0e5a8 cjson.c --- a/cjson.c Thu Nov 05 00:29:13 2009 +0100 +++ b/cjson.c Thu Nov 05 11:18:54 2009 +0100 @@ -2,6 +2,8 @@ * Copyright (C) 2006-2007 Dan Pascu. See LICENSE for details. * Author: Dan Pascu * + * getdefaultencoding support etc added in 2009 by Fredrik Lundh. + * * Fast JSON encoder/decoder implementation for Python * */ @@ -19,12 +21,16 @@ int all_unicode; // make all output strings unicode if true } JSONData; -static PyObject* encode_object(PyObject *object); +typedef struct JSONEncode { + int utf8; // true if byte strings are utf-8 +} JSONEncode; + +static PyObject* encode_object(JSONEncode *encode, PyObject *object); static PyObject* encode_string(PyObject *object); static PyObject* encode_unicode(PyObject *object); -static PyObject* encode_tuple(PyObject *object); -static PyObject* encode_list(PyObject *object); -static PyObject* encode_dict(PyObject *object); +static PyObject* encode_tuple(JSONEncode *encode, PyObject *object); +static PyObject* encode_list(JSONEncode *encode, PyObject *object); +static PyObject* encode_dict(JSONEncode *encode, PyObject *object); static PyObject* decode_json(JSONData *jsondata); static PyObject* decode_null(JSONData *jsondata); @@ -756,7 +762,7 @@ */ static PyObject* -encode_tuple(PyObject *tuple) +encode_tuple(JSONEncode *encode, PyObject *tuple) { Py_ssize_t i, n; PyObject *s, *temp; @@ -773,7 +779,7 @@ /* Do repr() on each element. */ for (i = 0; i < n; ++i) { - s = encode_object(v->ob_item[i]); + s = encode_object(encode, v->ob_item[i]); if (s == NULL) goto Done; PyTuple_SET_ITEM(pieces, i, s); @@ -821,7 +827,7 @@ * represented in JSON. */ static PyObject* -encode_list(PyObject *list) +encode_list(JSONEncode *encode, PyObject *list) { Py_ssize_t i; PyObject *s, *temp; @@ -850,7 +856,7 @@ * so must refetch the list size on each iteration. */ for (i = 0; i < v->ob_size; ++i) { int status; - s = encode_object(v->ob_item[i]); + s = encode_object(encode, v->ob_item[i]); if (s == NULL) goto Done; status = PyList_Append(pieces, s); @@ -904,7 +910,7 @@ * be represented in JSON. */ static PyObject* -encode_dict(PyObject *dict) +encode_dict(JSONEncode *encode, PyObject *dict) { Py_ssize_t i; PyObject *s, *temp, *colon = NULL; @@ -948,9 +954,9 @@ /* Prevent repr from deleting value during key format. */ Py_INCREF(value); - s = encode_object(key); + s = encode_object(encode, key); PyString_Concat(&s, colon); - PyString_ConcatAndDel(&s, encode_object(value)); + PyString_ConcatAndDel(&s, encode_object(encode, value)); Py_DECREF(value); if (s == NULL) goto Done; @@ -996,7 +1002,7 @@ static PyObject* -encode_object(PyObject *object) +encode_object(JSONEncode *encode, PyObject *object) { if (object == Py_True) { return PyString_FromString("true"); @@ -1005,7 +1011,10 @@ } else if (object == Py_None) { return PyString_FromString("null"); } else if (PyString_Check(object)) { - return encode_string(object); + if (encode->utf8) + return encode_string(object); + else + return encode_string(object); } else if (PyUnicode_Check(object)) { return encode_unicode(object); } else if (PyFloat_Check(object)) { @@ -1024,11 +1033,11 @@ } else if (PyInt_Check(object) || PyLong_Check(object)) { return PyObject_Str(object); } else if (PyList_Check(object)) { - return encode_list(object); + return encode_list(encode, object); } else if (PyTuple_Check(object)) { - return encode_tuple(object); + return encode_tuple(encode, object); } else if (PyDict_Check(object)) { // use PyMapping_Check(object) instead? -Dan - return encode_dict(object); + return encode_dict(encode, object); } else { PyErr_SetString(JSON_EncodeError, "object is not JSON encodable"); return NULL; @@ -1041,7 +1050,11 @@ static PyObject* JSON_encode(PyObject *self, PyObject *object) { - return encode_object(object); + JSONEncode encode; + const char *encoding = PyUnicode_GetDefaultEncoding(); + + encode.utf8 = encoding[0] == 'u' && (strcmp(encoding, "utf-8") == 0); + return encode_object(&encode, object); }