# HG changeset patch
# User shakefu <shakefu@gmail.com>
# Date 1366182970 25200
#      Wed Apr 17 00:16:10 2013 -0700
# Node ID 1eaef2b53c0754549b7768b77802f28f7a0654c4
# Parent  8cc5beb051eb5284a19f7f34fa7b50138f8f8512
Initial stab at for_json hook for C extension.

diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -260,6 +260,8 @@
 encoder_encode_float(PyEncoderObject *s, PyObject *obj);
 static int
 _is_namedtuple(PyObject *obj);
+static int
+_has_for_json_hook(PyObject *obj);
 static PyObject *
 moduleinit(void);
 
@@ -427,6 +429,20 @@
 }
 
 static int
+_has_for_json_hook(PyObject *obj)
+{
+    int rval = 0;
+    PyObject *for_json = PyObject_GetAttrString(obj, "for_json");
+    if (for_json == NULL) {
+        PyErr_Clear();
+        return 0;
+    }
+    rval = PyCallable_Check(for_json);
+    Py_DECREF(for_json);
+    return rval;
+}
+
+static int
 _convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr)
 {
     /* PyObject to Py_ssize_t converter */
@@ -2801,6 +2817,17 @@
             if (encoded != NULL)
                 rv = _steal_accumulate(rval, encoded);
         }
+        else if (_has_for_json_hook(obj)) {
+            PyObject *newobj;
+            if (Py_EnterRecursiveCall(" while encoding a JSON object"))
+                return rv;
+            newobj = PyObject_CallMethod(obj, "for_json", NULL);
+            if (newobj != NULL) {
+                rv = encoder_listencode_obj(s, rval, newobj, indent_level);
+                Py_DECREF(newobj);
+            }
+            Py_LeaveRecursiveCall();
+        }
         else if (s->namedtuple_as_object && _is_namedtuple(obj)) {
             PyObject *newobj;
             if (Py_EnterRecursiveCall(" while encoding a JSON object"))