objToJSON.c
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2011-2012, ESN Social Software AB and Jonas Tarnstrom
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the ESN Social Software AB nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL ESN SOCIAL SOFTWARE AB OR JONAS TARNSTROM BE LIABLE 
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Portions of code from:
00028 MODP_ASCII - Ascii transformations (upper/lower, etc)
00029 http://code.google.com/p/stringencoders/
00030 Copyright (c) 2007  Nick Galbreath -- nickg [at] modp [dot] com. All rights reserved.
00031 
00032 */
00033 
00034 #include "py_defines.h"
00035 #include <stdio.h>
00036 #include <datetime.h>
00037 #include <ultrajson.h>
00038 
00039 #define EPOCH_ORD 719163
00040 
00041 typedef void *(*PFN_PyTypeToJSON)(JSOBJ obj, JSONTypeContext *ti, void *outValue, size_t *_outLen);
00042 
00043 
00044 #if (PY_VERSION_HEX < 0x02050000)
00045 typedef ssize_t Py_ssize_t;
00046 #endif
00047 
00048 
00049 typedef struct __TypeContext
00050 {
00051     JSPFN_ITERBEGIN iterBegin;
00052     JSPFN_ITEREND iterEnd;
00053     JSPFN_ITERNEXT iterNext;
00054     JSPFN_ITERGETNAME iterGetName;
00055     JSPFN_ITERGETVALUE iterGetValue;
00056     PFN_PyTypeToJSON PyTypeToJSON;
00057     PyObject *newObj;
00058     PyObject *dictObj;
00059     Py_ssize_t index;
00060     Py_ssize_t size;
00061     PyObject *itemValue;
00062     PyObject *itemName;
00063     PyObject *attrList;
00064 
00065     JSINT64 longValue;
00066 
00067 } TypeContext;
00068 
00069 #define GET_TC(__ptrtc) ((TypeContext *)((__ptrtc)->prv))
00070 
00071 struct PyDictIterState
00072 {
00073     PyObject *keys;
00074     size_t i;
00075     size_t sz;
00076 };
00077 
00078 
00079 //#define PRINTMARK() fprintf(stderr, "%s: MARK(%d)\n", __FILE__, __LINE__)     
00080 #define PRINTMARK()         
00081 
00082 void initObjToJSON(void)
00083 {
00084     PyDateTime_IMPORT;
00085 }
00086 
00087 static void *PyIntToINT32(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00088 {
00089     PyObject *obj = (PyObject *) _obj;
00090     *((JSINT32 *) outValue) = PyInt_AS_LONG (obj);
00091     return NULL;
00092 }
00093 
00094 static void *PyIntToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00095 {
00096     PyObject *obj = (PyObject *) _obj;
00097     *((JSINT64 *) outValue) = PyInt_AS_LONG (obj);
00098     return NULL;
00099 }
00100 
00101 static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00102 {
00103     *((JSINT64 *) outValue) = GET_TC(tc)->longValue;
00104     return NULL;
00105 }
00106 
00107 static void *PyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00108 {
00109     PyObject *obj = (PyObject *) _obj;
00110     *((double *) outValue) = PyFloat_AS_DOUBLE (obj);
00111     return NULL;
00112 }
00113 
00114 static void *PyStringToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00115 {
00116     PyObject *obj = (PyObject *) _obj;
00117     *_outLen = PyString_GET_SIZE(obj);
00118     return PyString_AS_STRING(obj);
00119 }
00120 
00121 static void *PyUnicodeToUTF8(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00122 {
00123     PyObject *obj = (PyObject *) _obj;
00124     PyObject *newObj = PyUnicode_EncodeUTF8 (PyUnicode_AS_UNICODE(obj), PyUnicode_GET_SIZE(obj), NULL);
00125 
00126     GET_TC(tc)->newObj = newObj;
00127 
00128     *_outLen = PyString_GET_SIZE(newObj);
00129     return PyString_AS_STRING(newObj);
00130 }
00131 
00132 static void *PyDateTimeToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00133 {
00134     PyObject *obj = (PyObject *) _obj;
00135     PyObject *date, *ord;
00136     int y, m, d, h, mn, s, days;
00137 
00138     y = PyDateTime_GET_YEAR(obj);
00139     m = PyDateTime_GET_MONTH(obj);
00140     d = PyDateTime_GET_DAY(obj);
00141     h = PyDateTime_DATE_GET_HOUR(obj);
00142     mn = PyDateTime_DATE_GET_MINUTE(obj);
00143     s = PyDateTime_DATE_GET_SECOND(obj);
00144 
00145     date = PyDate_FromDate(y, m, 1);
00146     ord = PyObject_CallMethod(date, "toordinal", NULL);
00147     days = PyInt_AS_LONG(ord) - EPOCH_ORD + d - 1;
00148     Py_DECREF(date);
00149     Py_DECREF(ord);
00150     *( (JSINT64 *) outValue) = (((JSINT64) ((days * 24 + h) * 60 + mn)) * 60 + s);
00151     return NULL;
00152 }
00153 
00154 static void *PyDateToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
00155 {
00156     PyObject *obj = (PyObject *) _obj;
00157     PyObject *date, *ord;
00158     int y, m, d, days;
00159 
00160     y = PyDateTime_GET_YEAR(obj);
00161     m = PyDateTime_GET_MONTH(obj);
00162     d = PyDateTime_GET_DAY(obj);
00163 
00164     date = PyDate_FromDate(y, m, 1);
00165     ord = PyObject_CallMethod(date, "toordinal", NULL);
00166     days = PyInt_AS_LONG(ord) - EPOCH_ORD + d - 1;
00167     Py_DECREF(date);
00168     Py_DECREF(ord);
00169     *( (JSINT64 *) outValue) = ((JSINT64) days * 86400);
00170 
00171     return NULL;
00172 }
00173 
00174 //=============================================================================
00175 // Tuple iteration functions 
00176 // itemValue is borrowed reference, no ref counting
00177 //=============================================================================
00178 void Tuple_iterBegin(JSOBJ obj, JSONTypeContext *tc)
00179 {
00180     GET_TC(tc)->index = 0;
00181     GET_TC(tc)->size = PyTuple_GET_SIZE( (PyObject *) obj);
00182     GET_TC(tc)->itemValue = NULL;
00183 }
00184 
00185 int Tuple_iterNext(JSOBJ obj, JSONTypeContext *tc)
00186 {
00187     PyObject *item;
00188 
00189     if (GET_TC(tc)->index >= GET_TC(tc)->size)
00190     {
00191         return 0;
00192     }
00193 
00194     item = PyTuple_GET_ITEM (obj, GET_TC(tc)->index);
00195 
00196     GET_TC(tc)->itemValue = item;
00197     GET_TC(tc)->index ++;
00198     return 1;
00199 }
00200 
00201 void Tuple_iterEnd(JSOBJ obj, JSONTypeContext *tc)
00202 {
00203 }
00204 
00205 JSOBJ Tuple_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
00206 {
00207     return GET_TC(tc)->itemValue;
00208 }
00209 
00210 char *Tuple_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
00211 {
00212     return NULL;
00213 }
00214 
00215 //=============================================================================
00216 // Dir iteration functions 
00217 // itemName ref is borrowed from PyObject_Dir (attrList). No refcount
00218 // itemValue ref is from PyObject_GetAttr. Ref counted
00219 //=============================================================================
00220 void Dir_iterBegin(JSOBJ obj, JSONTypeContext *tc)
00221 {
00222     GET_TC(tc)->attrList = PyObject_Dir(obj); 
00223     GET_TC(tc)->index = 0;
00224     GET_TC(tc)->size = PyList_GET_SIZE(GET_TC(tc)->attrList);
00225     PRINTMARK();
00226 }
00227 
00228 void Dir_iterEnd(JSOBJ obj, JSONTypeContext *tc)
00229 {
00230     if (GET_TC(tc)->itemValue)
00231     {
00232         Py_DECREF(GET_TC(tc)->itemValue);
00233         GET_TC(tc)->itemValue = NULL;
00234     }
00235 
00236     if (GET_TC(tc)->itemName)
00237     {
00238         Py_DECREF(GET_TC(tc)->itemName);
00239         GET_TC(tc)->itemName = NULL;
00240     }
00241 
00242     Py_DECREF( (PyObject *) GET_TC(tc)->attrList);
00243     PRINTMARK();
00244 }
00245 
00246 int Dir_iterNext(JSOBJ _obj, JSONTypeContext *tc)
00247 {
00248     PyObject *obj = (PyObject *) _obj;
00249     PyObject *itemValue = GET_TC(tc)->itemValue;
00250     PyObject *itemName = GET_TC(tc)->itemName;
00251     PyObject* attr;
00252     PyObject* attrName;
00253     char* attrStr;
00254 
00255 
00256     if (itemValue)
00257     {
00258         Py_DECREF(GET_TC(tc)->itemValue);
00259         GET_TC(tc)->itemValue = itemValue = NULL;
00260     }
00261 
00262     if (itemName)
00263     {
00264         Py_DECREF(GET_TC(tc)->itemName);
00265         GET_TC(tc)->itemName = itemName = NULL;
00266     }
00267 
00268     for (; GET_TC(tc)->index  < GET_TC(tc)->size; GET_TC(tc)->index ++)
00269     {
00270         attrName = PyList_GET_ITEM(GET_TC(tc)->attrList, GET_TC(tc)->index);
00271 #if PY_MAJOR_VERSION >= 3
00272         attr = PyUnicode_AsUTF8String(attrName);
00273 #else 
00274         attr = attrName;
00275         Py_INCREF(attr);
00276 #endif
00277         attrStr = PyString_AS_STRING(attr);
00278 
00279         if (attrStr[0] == '_')
00280         {
00281             PRINTMARK();
00282             Py_DECREF(attr);
00283             continue;
00284         }
00285 
00286         itemValue = PyObject_GetAttr(obj, attrName);
00287         if (itemValue == NULL)
00288         {
00289             PyErr_Clear();
00290             Py_DECREF(attr);
00291             PRINTMARK();
00292             continue;
00293         }
00294 
00295         if (PyCallable_Check(itemValue))
00296         {
00297             Py_DECREF(itemValue);
00298             Py_DECREF(attr);
00299             PRINTMARK();
00300             continue;
00301         }
00302 
00303         PRINTMARK();
00304         itemName = attr;
00305         break;
00306     }
00307 
00308     if (itemName == NULL)
00309     {
00310         GET_TC(tc)->index = GET_TC(tc)->size;
00311         GET_TC(tc)->itemValue = NULL;
00312         return 0;
00313     }
00314 
00315     GET_TC(tc)->itemName = itemName;
00316     GET_TC(tc)->itemValue = itemValue;
00317     GET_TC(tc)->index ++;
00318     
00319     PRINTMARK();
00320     return 1;
00321 }
00322 
00323 
00324 
00325 JSOBJ Dir_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
00326 {
00327     PRINTMARK();
00328     return GET_TC(tc)->itemValue;
00329 }
00330 
00331 char *Dir_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
00332 {
00333     PRINTMARK();
00334     *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName);
00335     return PyString_AS_STRING(GET_TC(tc)->itemName);
00336 }
00337 
00338 
00339 
00340 
00341 //=============================================================================
00342 // List iteration functions 
00343 // itemValue is borrowed from object (which is list). No refcounting
00344 //=============================================================================
00345 void List_iterBegin(JSOBJ obj, JSONTypeContext *tc)
00346 {
00347     GET_TC(tc)->index =  0;
00348     GET_TC(tc)->size = PyList_GET_SIZE( (PyObject *) obj);
00349 }
00350 
00351 int List_iterNext(JSOBJ obj, JSONTypeContext *tc)
00352 {
00353     if (GET_TC(tc)->index >= GET_TC(tc)->size)
00354     {
00355         PRINTMARK();
00356         return 0;
00357     }
00358 
00359     GET_TC(tc)->itemValue = PyList_GET_ITEM (obj, GET_TC(tc)->index);
00360     GET_TC(tc)->index ++;
00361     return 1;
00362 }
00363 
00364 void List_iterEnd(JSOBJ obj, JSONTypeContext *tc)
00365 {
00366 }
00367 
00368 JSOBJ List_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
00369 {
00370     return GET_TC(tc)->itemValue;
00371 }
00372 
00373 char *List_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
00374 {
00375     return NULL;
00376 }
00377 
00378 //=============================================================================
00379 // Dict iteration functions 
00380 // itemName might converted to string (Python_Str). Do refCounting
00381 // itemValue is borrowed from object (which is dict). No refCounting
00382 //=============================================================================
00383 void Dict_iterBegin(JSOBJ obj, JSONTypeContext *tc)
00384 {
00385     GET_TC(tc)->index = 0;
00386     PRINTMARK();
00387 }
00388 
00389 int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc)
00390 {
00391 #if PY_MAJOR_VERSION >= 3
00392     PyObject* itemNameTmp;
00393 #endif
00394 
00395     if (GET_TC(tc)->itemName)
00396     {
00397         Py_DECREF(GET_TC(tc)->itemName);
00398         GET_TC(tc)->itemName = NULL;
00399     }
00400 
00401 
00402     if (!PyDict_Next ( (PyObject *)GET_TC(tc)->dictObj, &GET_TC(tc)->index, &GET_TC(tc)->itemName, &GET_TC(tc)->itemValue))
00403     {
00404         PRINTMARK();
00405         return 0;
00406     }
00407 
00408     if (PyUnicode_Check(GET_TC(tc)->itemName))
00409     {
00410         GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
00411     }
00412     else
00413     if (!PyString_Check(GET_TC(tc)->itemName))
00414     {
00415         GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName);
00416 #if PY_MAJOR_VERSION >= 3
00417         itemNameTmp = GET_TC(tc)->itemName; 
00418         GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
00419         Py_DECREF(itemNameTmp);
00420 #endif
00421     }
00422     else 
00423     {
00424         Py_INCREF(GET_TC(tc)->itemName);
00425     }
00426     PRINTMARK();
00427     return 1;
00428 }
00429 
00430 void Dict_iterEnd(JSOBJ obj, JSONTypeContext *tc)
00431 {
00432     if (GET_TC(tc)->itemName)
00433     {
00434         Py_DECREF(GET_TC(tc)->itemName);
00435         GET_TC(tc)->itemName = NULL;
00436     }
00437     Py_DECREF(GET_TC(tc)->dictObj);
00438     PRINTMARK();
00439 }
00440 
00441 JSOBJ Dict_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
00442 {
00443     return GET_TC(tc)->itemValue;
00444 }
00445 
00446 char *Dict_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
00447 {
00448     *outLen = PyString_GET_SIZE(GET_TC(tc)->itemName);
00449     return PyString_AS_STRING(GET_TC(tc)->itemName);
00450 }
00451 
00452 
00453 void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc)
00454 {
00455     PyObject *obj, *exc, *toDictFunc;
00456     TypeContext *pc;
00457     PRINTMARK();
00458     if (!_obj) {
00459         tc->type = JT_INVALID;
00460         return;
00461     }
00462 
00463     obj = (PyObject*) _obj;
00464 
00465     tc->prv = PyObject_Malloc(sizeof(TypeContext));
00466     pc = (TypeContext *) tc->prv;
00467     if (!pc)
00468     {
00469         tc->type = JT_INVALID;
00470         PyErr_NoMemory();
00471         return;
00472     }
00473     pc->newObj = NULL;
00474     pc->dictObj = NULL;
00475     pc->itemValue = NULL;
00476     pc->itemName = NULL;
00477     pc->attrList = NULL;
00478     pc->index = 0;
00479     pc->size = 0;
00480     pc->longValue = 0;
00481     
00482     if (PyIter_Check(obj))
00483     {
00484         goto ISITERABLE;
00485     }
00486 
00487     if (PyBool_Check(obj))
00488     {
00489         PRINTMARK();
00490         tc->type = (obj == Py_True) ? JT_TRUE : JT_FALSE;
00491         return;
00492     }
00493     else
00494     if (PyLong_Check(obj))
00495     {
00496         PRINTMARK();
00497         pc->PyTypeToJSON = PyLongToINT64;
00498         tc->type = JT_LONG;
00499         GET_TC(tc)->longValue = PyLong_AsLongLong(obj);
00500 
00501         exc = PyErr_Occurred();
00502 
00503         if (exc && PyErr_ExceptionMatches(PyExc_OverflowError))
00504         {
00505             PRINTMARK();
00506             goto INVALID;
00507         }
00508 
00509         return;
00510     }
00511     else
00512     if (PyInt_Check(obj))
00513     {
00514         PRINTMARK();
00515 #ifdef _LP64
00516         pc->PyTypeToJSON = PyIntToINT64; tc->type = JT_LONG;
00517 #else
00518         pc->PyTypeToJSON = PyIntToINT32; tc->type = JT_INT;
00519 #endif
00520         return;
00521     }
00522     else
00523     if (PyString_Check(obj))
00524     {
00525         PRINTMARK();
00526         pc->PyTypeToJSON = PyStringToUTF8; tc->type = JT_UTF8;
00527         return;
00528     }
00529     else
00530     if (PyUnicode_Check(obj))
00531     {
00532         PRINTMARK();
00533         pc->PyTypeToJSON = PyUnicodeToUTF8; tc->type = JT_UTF8;
00534         return;
00535     }
00536     else
00537     if (PyFloat_Check(obj))
00538     {
00539         PRINTMARK();
00540         pc->PyTypeToJSON = PyFloatToDOUBLE; tc->type = JT_DOUBLE;
00541         return;
00542     }
00543     else 
00544     if (PyDateTime_Check(obj))
00545     {
00546         PRINTMARK();
00547         pc->PyTypeToJSON = PyDateTimeToINT64; tc->type = JT_LONG;
00548         return;
00549     }
00550     else 
00551     if (PyDate_Check(obj))
00552     {
00553         PRINTMARK();
00554         pc->PyTypeToJSON = PyDateToINT64; tc->type = JT_LONG;
00555         return;
00556     }
00557     else
00558     if (obj == Py_None)
00559     {
00560         PRINTMARK();
00561         tc->type = JT_NULL;
00562         return;
00563     }
00564 
00565 
00566 ISITERABLE:
00567 
00568     if (PyDict_Check(obj))
00569     {
00570         PRINTMARK();
00571         tc->type = JT_OBJECT;
00572         pc->iterBegin = Dict_iterBegin;
00573         pc->iterEnd = Dict_iterEnd;
00574         pc->iterNext = Dict_iterNext;
00575         pc->iterGetValue = Dict_iterGetValue;
00576         pc->iterGetName = Dict_iterGetName;
00577         pc->dictObj = obj;
00578         Py_INCREF(obj);
00579 
00580         return;
00581     }
00582     else
00583     if (PyList_Check(obj))
00584     {
00585         PRINTMARK();
00586         tc->type = JT_ARRAY;
00587         pc->iterBegin = List_iterBegin;
00588         pc->iterEnd = List_iterEnd;
00589         pc->iterNext = List_iterNext;
00590         pc->iterGetValue = List_iterGetValue;
00591         pc->iterGetName = List_iterGetName;
00592         return;
00593     }
00594     else
00595     if (PyTuple_Check(obj))
00596     {
00597         PRINTMARK();
00598         tc->type = JT_ARRAY;
00599         pc->iterBegin = Tuple_iterBegin;
00600         pc->iterEnd = Tuple_iterEnd;
00601         pc->iterNext = Tuple_iterNext;
00602         pc->iterGetValue = Tuple_iterGetValue;
00603         pc->iterGetName = Tuple_iterGetName;
00604         return;
00605     }
00606 
00607 
00608     toDictFunc = PyObject_GetAttrString(obj, "toDict");
00609 
00610     if (toDictFunc)
00611     {
00612         PyObject* tuple = PyTuple_New(0);
00613         PyObject* toDictResult = PyObject_Call(toDictFunc, tuple, NULL);
00614         Py_DECREF(tuple);
00615         Py_DECREF(toDictFunc);
00616 
00617         if (toDictResult == NULL)
00618         {
00619             PyErr_Clear();
00620             tc->type = JT_NULL;
00621             return;
00622         }
00623 
00624         if (!PyDict_Check(toDictResult))
00625         {
00626             Py_DECREF(toDictResult);
00627             tc->type = JT_NULL;
00628             return;
00629         }
00630 
00631         PRINTMARK();
00632         tc->type = JT_OBJECT;
00633         pc->iterBegin = Dict_iterBegin;
00634         pc->iterEnd = Dict_iterEnd;
00635         pc->iterNext = Dict_iterNext;
00636         pc->iterGetValue = Dict_iterGetValue;
00637         pc->iterGetName = Dict_iterGetName;
00638         pc->dictObj = toDictResult;
00639         return;
00640     }
00641 
00642     PyErr_Clear();
00643 
00644     tc->type = JT_OBJECT;
00645     pc->iterBegin = Dir_iterBegin;
00646     pc->iterEnd = Dir_iterEnd;
00647     pc->iterNext = Dir_iterNext;
00648     pc->iterGetValue = Dir_iterGetValue;
00649     pc->iterGetName = Dir_iterGetName;
00650 
00651     return;
00652 
00653 INVALID:
00654     tc->type = JT_INVALID;
00655     PyObject_Free(tc->prv);
00656     tc->prv = NULL;
00657     return;
00658 }
00659 
00660 
00661 void Object_endTypeContext(JSOBJ obj, JSONTypeContext *tc)
00662 {
00663     Py_XDECREF(GET_TC(tc)->newObj);
00664 
00665     PyObject_Free(tc->prv);
00666     tc->prv = NULL;
00667 }
00668 
00669 const char *Object_getStringValue(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen)
00670 {
00671     return GET_TC(tc)->PyTypeToJSON (obj, tc, NULL, _outLen);
00672 }
00673 
00674 JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc)
00675 {
00676     JSINT64 ret;
00677     GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
00678 
00679     return ret;
00680 }
00681 
00682 JSINT32 Object_getIntValue(JSOBJ obj, JSONTypeContext *tc)
00683 {
00684     JSINT32 ret;
00685     GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
00686     return ret;
00687 }
00688 
00689 
00690 double Object_getDoubleValue(JSOBJ obj, JSONTypeContext *tc)
00691 {
00692     double ret;
00693     GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
00694     return ret;
00695 }
00696 
00697 static void Object_releaseObject(JSOBJ _obj)
00698 {
00699     Py_DECREF( (PyObject *) _obj);
00700 }
00701 
00702 
00703 
00704 void Object_iterBegin(JSOBJ obj, JSONTypeContext *tc)
00705 {
00706     GET_TC(tc)->iterBegin(obj, tc);
00707 }
00708 
00709 int Object_iterNext(JSOBJ obj, JSONTypeContext *tc)
00710 {
00711     return GET_TC(tc)->iterNext(obj, tc);
00712 }
00713 
00714 void Object_iterEnd(JSOBJ obj, JSONTypeContext *tc)
00715 {
00716     GET_TC(tc)->iterEnd(obj, tc);
00717 }
00718 
00719 JSOBJ Object_iterGetValue(JSOBJ obj, JSONTypeContext *tc)
00720 {
00721     return GET_TC(tc)->iterGetValue(obj, tc);
00722 }
00723 
00724 char *Object_iterGetName(JSOBJ obj, JSONTypeContext *tc, size_t *outLen)
00725 {
00726     return GET_TC(tc)->iterGetName(obj, tc, outLen);
00727 }
00728 
00729 
00730 PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
00731 {
00732     static char *kwlist[] = { "obj", "ensure_ascii", "double_precision", NULL};
00733 
00734     char buffer[65536];
00735     char *ret;
00736     PyObject *newobj;
00737     PyObject *oinput = NULL;
00738     PyObject *oensureAscii = NULL;
00739     int idoublePrecision = 5; // default double precision setting
00740 
00741     JSONObjectEncoder encoder = 
00742     {
00743         Object_beginTypeContext,    //void (*beginTypeContext)(JSOBJ obj, JSONTypeContext *tc);
00744         Object_endTypeContext, //void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc);
00745         Object_getStringValue, //const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen);
00746         Object_getLongValue, //JSLONG (*getLongValue)(JSOBJ obj, JSONTypeContext *tc);
00747         Object_getIntValue, //JSLONG (*getLongValue)(JSOBJ obj, JSONTypeContext *tc);
00748         Object_getDoubleValue, //double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc);
00749         Object_iterBegin, //JSPFN_ITERBEGIN iterBegin;
00750         Object_iterNext, //JSPFN_ITERNEXT iterNext;
00751         Object_iterEnd, //JSPFN_ITEREND iterEnd;
00752         Object_iterGetValue, //JSPFN_ITERGETVALUE iterGetValue;
00753         Object_iterGetName, //JSPFN_ITERGETNAME iterGetName;
00754         Object_releaseObject, //void (*releaseValue)(JSONTypeContext *ti);
00755         PyObject_Malloc, //JSPFN_MALLOC malloc;
00756         PyObject_Realloc, //JSPFN_REALLOC realloc;
00757         PyObject_Free, //JSPFN_FREE free;
00758         -1, //recursionMax
00759         idoublePrecision,
00760         1, //forceAscii
00761     };
00762 
00763 
00764     PRINTMARK();
00765 
00766     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi", kwlist, &oinput, &oensureAscii, &idoublePrecision))
00767     {
00768         return NULL;
00769     }
00770 
00771     
00772     if (oensureAscii != NULL && !PyObject_IsTrue(oensureAscii))
00773     {
00774         encoder.forceASCII = 0;
00775     }
00776 
00777     encoder.doublePrecision = idoublePrecision;
00778 
00779     PRINTMARK();
00780     ret = JSON_EncodeObject (oinput, &encoder, buffer, sizeof (buffer));
00781     PRINTMARK();
00782 
00783     if (PyErr_Occurred())
00784     {
00785         return NULL;
00786     }
00787 
00788     if (encoder.errorMsg)
00789     {
00790         if (ret != buffer)
00791         {
00792             encoder.free (ret);
00793         }
00794 
00795         PyErr_Format (PyExc_OverflowError, "%s", encoder.errorMsg);
00796         return NULL;
00797     }
00798 
00799     newobj = PyString_FromString (ret);
00800 
00801     if (ret != buffer)
00802     {
00803         encoder.free (ret);
00804     }
00805 
00806     PRINTMARK();
00807 
00808     return newobj;
00809 }
00810 
00811 PyObject* objToJSONFile(PyObject* self, PyObject *args, PyObject *kwargs)
00812 {
00813     PyObject *data;
00814     PyObject *file;
00815     PyObject *string;
00816     PyObject *write;
00817     PyObject *argtuple;
00818 
00819     PRINTMARK();
00820 
00821     if (!PyArg_ParseTuple (args, "OO", &data, &file)) {
00822         return NULL;
00823     }
00824 
00825     if (!PyObject_HasAttrString (file, "write"))
00826     {
00827         PyErr_Format (PyExc_TypeError, "expected file");
00828         return NULL;
00829     }
00830 
00831     write = PyObject_GetAttrString (file, "write");
00832 
00833     if (!PyCallable_Check (write)) {
00834         Py_XDECREF(write);
00835         PyErr_Format (PyExc_TypeError, "expected file");
00836         return NULL;
00837     }
00838 
00839     argtuple = PyTuple_Pack(1, data);
00840 
00841     string = objToJSON (self, argtuple, kwargs);
00842 
00843     if (string == NULL)
00844     {
00845         Py_XDECREF(write);
00846         Py_XDECREF(argtuple);
00847         return NULL;
00848     }
00849 
00850     Py_XDECREF(argtuple);
00851 
00852     argtuple = PyTuple_Pack (1, string);
00853     if (argtuple == NULL)
00854     {
00855         Py_XDECREF(write);
00856         return NULL;
00857     }
00858     if (PyObject_CallObject (write, argtuple) == NULL)
00859     {
00860         Py_XDECREF(write);
00861         Py_XDECREF(argtuple);
00862         return NULL;
00863     }
00864 
00865     Py_XDECREF(write);
00866     Py_DECREF(argtuple);
00867     Py_XDECREF(string);
00868 
00869     PRINTMARK();
00870 
00871     Py_RETURN_NONE;
00872     
00873 
00874 }
00875 


rosbridge_library
Author(s): Jonathan Mace
autogenerated on Thu Jan 2 2014 11:53:35