summaryrefslogtreecommitdiff
path: root/simplejson/_speedups.c
diff options
context:
space:
mode:
authorKevin LaFlamme <kevin@lolatravel.com>2016-09-01 12:26:43 -0400
committerKevin LaFlamme <kevin@lolatravel.com>2016-09-01 12:26:43 -0400
commitda17e3529c4e41173519ea18ff3ee908761ef5d4 (patch)
treee987a357593f5184b45cd8482ba544b5a8d66978 /simplejson/_speedups.c
parent4b1dab370f8a32aaa3f9140c38645093d3287b82 (diff)
downloadsimplejson-da17e3529c4e41173519ea18ff3ee908761ef5d4.tar.gz
Add support for preprocessed JSON strings (with optimizations) in encoder
In some situations, you may have a large python dictionary you need to JSONify but one of the values inside the dict is already a JSON string. This is common when pulling an object from a database, for example, where one of the fields is a JSON blob/string. Previously you would have to deserialize and then reserialize that string just to serialize the high level object, but obviously this is unnecessarily slow. This changes adds a method/type that can be used to wrap a str and tell the serializer to just pass it through instead.
Diffstat (limited to 'simplejson/_speedups.c')
-rw-r--r--simplejson/_speedups.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
index 9976464..2d81063 100644
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -245,6 +245,8 @@ static void
encoder_dealloc(PyObject *self);
static int
encoder_clear(PyObject *self);
+static int
+is_raw_json(PyObject *obj);
static PyObject *
encoder_stringify_key(PyEncoderObject *s, PyObject *key);
static int
@@ -277,6 +279,20 @@ moduleinit(void);
#define MIN_EXPANSION 6
+static PyObject* RawJSONType;
+static int
+is_raw_json(PyObject *obj)
+{
+ if (RawJSONType == NULL) {
+ PyObject *encoder_module = PyImport_ImportModule("simplejson.encoder");
+ RawJSONType = PyObject_GetAttrString(encoder_module, "RawJSON");
+ Py_DECREF(encoder_module);
+ if (RawJSONType == NULL)
+ return 0;
+ }
+ return PyObject_IsInstance(obj, RawJSONType) ? 1 : 0;
+}
+
static int
JSON_Accu_Init(JSON_Accu *acc)
{
@@ -2868,6 +2884,12 @@ encoder_listencode_obj(PyEncoderObject *s, JSON_Accu *rval, PyObject *obj, Py_ss
if (encoded != NULL)
rv = _steal_accumulate(rval, encoded);
}
+ else if (is_raw_json(obj))
+ {
+ PyObject *encoded = PyObject_GetAttrString(obj, "encoded_json");
+ if (encoded != NULL)
+ rv = _steal_accumulate(rval, encoded);
+ }
else if (PyInt_Check(obj) || PyLong_Check(obj)) {
PyObject *encoded;
if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)) {