1
0
Fork 0
mirror of https://github.com/ultrajson/ultrajson.git synced 2024-05-29 14:56:08 +02:00

add encoding support for unsigned long long

This commit is contained in:
kevin birch 2014-11-11 18:25:27 -05:00
parent 692f59d2aa
commit cbd68782c8
4 changed files with 81 additions and 12 deletions

View File

@ -146,16 +146,17 @@ typedef int64_t JSLONG;
enum JSTYPES
{
JT_NULL, // NULL
JT_TRUE, //boolean true
JT_FALSE, //boolean false
JT_INT, //(JSINT32 (signed 32-bit))
JT_LONG, //(JSINT64 (signed 64-bit))
JT_DOUBLE, //(double)
JT_UTF8, //(char 8-bit)
JT_ARRAY, // Array structure
JT_NULL, // NULL
JT_TRUE, // boolean true
JT_FALSE, // boolean false
JT_INT, // (JSINT32 (signed 32-bit))
JT_LONG, // (JSINT64 (signed 64-bit))
JT_ULONG, // (JSUINT64 (unsigned 64-bit))
JT_DOUBLE, // (double)
JT_UTF8, // (char 8-bit)
JT_ARRAY, // Array structure
JT_OBJECT, // Key/Value structure
JT_INVALID, // Internal, do not return nor expect
JT_INVALID, // Internal, do not return nor expect
};
typedef void * JSOBJ;
@ -184,6 +185,7 @@ typedef struct __JSONObjectEncoder
void (*endTypeContext)(JSOBJ obj, JSONTypeContext *tc);
const char *(*getStringValue)(JSOBJ obj, JSONTypeContext *tc, size_t *_outLen);
JSINT64 (*getLongValue)(JSOBJ obj, JSONTypeContext *tc);
JSUINT64 (*getUnsignedLongValue)(JSOBJ obj, JSONTypeContext *tc);
JSINT32 (*getIntValue)(JSOBJ obj, JSONTypeContext *tc);
double (*getDoubleValue)(JSOBJ obj, JSONTypeContext *tc);

View File

@ -510,6 +510,21 @@ void Buffer_AppendLongUnchecked(JSONObjectEncoder *enc, JSINT64 value)
enc->offset += (wstr - (enc->offset));
}
void Buffer_AppendUnsignedLongUnchecked(JSONObjectEncoder *enc, JSUINT64 value)
{
char* wstr;
JSUINT64 uvalue = value;
wstr = enc->offset;
// Conversion. Number is reversed.
do *wstr++ = (char)(48 + (uvalue % 10ULL)); while(uvalue /= 10ULL);
// Reverse string
strreverse(enc->offset,wstr - 1);
enc->offset += (wstr - (enc->offset));
}
int Buffer_AppendDoubleUnchecked(JSOBJ obj, JSONObjectEncoder *enc, double value)
{
/* if input is larger than thres_max, revert to exponential */
@ -786,6 +801,12 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
break;
}
case JT_ULONG:
{
Buffer_AppendUnsignedLongUnchecked (enc, enc->getUnsignedLongValue(obj, &tc));
break;
}
case JT_INT:
{
Buffer_AppendIntUnchecked (enc, enc->getIntValue(obj, &tc));

View File

@ -66,7 +66,11 @@ typedef struct __TypeContext
PyObject *attrList;
PyObject *iterator;
JSINT64 longValue;
union
{
JSINT64 longValue;
JSUINT64 unsignedLongValue;
};
} TypeContext;
#define GET_TC(__ptrtc) ((TypeContext *)((__ptrtc)->prv))
@ -118,6 +122,12 @@ static void *PyLongToINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size
return NULL;
}
static void *PyLongToUINT64(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
{
*((JSUINT64 *) outValue) = GET_TC(tc)->unsignedLongValue;
return NULL;
}
static void *PyFloatToDOUBLE(JSOBJ _obj, JSONTypeContext *tc, void *outValue, size_t *_outLen)
{
PyObject *obj = (PyObject *) _obj;
@ -531,11 +541,24 @@ void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc)
GET_TC(tc)->longValue = PyLong_AsLongLong(obj);
exc = PyErr_Occurred();
if (!exc)
{
return;
}
if (exc && PyErr_ExceptionMatches(PyExc_OverflowError))
{
PRINTMARK();
goto INVALID;
PyErr_Clear();
pc->PyTypeToJSON = PyLongToUINT64;
tc->type = JT_ULONG;
GET_TC(tc)->unsignedLongValue = PyLong_AsUnsignedLongLong(obj);
exc = PyErr_Occurred();
if (exc && PyErr_ExceptionMatches(PyExc_OverflowError))
{
PRINTMARK();
goto INVALID;
}
}
return;
@ -743,6 +766,13 @@ JSINT64 Object_getLongValue(JSOBJ obj, JSONTypeContext *tc)
return ret;
}
JSUINT64 Object_getUnsignedLongValue(JSOBJ obj, JSONTypeContext *tc)
{
JSUINT64 ret;
GET_TC(tc)->PyTypeToJSON (obj, tc, &ret, NULL);
return ret;
}
JSINT32 Object_getIntValue(JSOBJ obj, JSONTypeContext *tc)
{
JSINT32 ret;
@ -799,6 +829,7 @@ PyObject* objToJSON(PyObject* self, PyObject *args, PyObject *kwargs)
Object_endTypeContext,
Object_getStringValue,
Object_getLongValue,
Object_getUnsignedLongValue,
Object_getIntValue,
Object_getDoubleValue,
Object_iterNext,

View File

@ -641,6 +641,13 @@ class UltraJSONTests(TestCase):
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
def test_encodeListLongUnsignedConversion(self):
input = [18446744073709551615, 18446744073709551615, 18446744073709551615]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
def test_encodeLongConversion(self):
input = 9223372036854775807
output = ujson.encode(input)
@ -648,6 +655,14 @@ class UltraJSONTests(TestCase):
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
def test_encodeLongUnsignedConversion(self):
input = 18446744073709551615
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
def test_numericIntExp(self):
input = "1337E40"
output = ujson.decode(input)