1
0
Fork 0
mirror of https://github.com/ultrajson/ultrajson.git synced 2024-06-10 22:36:06 +02:00

- Optimized UTF-8 encoding and decoding

- Improved error reporting when encoding and decoding utf-8
- Change from tabs to spaces in most Python code
- General code cleanup of C code
- Added UTF-8 encoding/decoding to tests
This commit is contained in:
Jonas Trnstrm 2011-03-16 12:04:28 +01:00
parent d11844ad50
commit 9d6dd489ec
7 changed files with 879 additions and 924 deletions

View File

@ -17,7 +17,7 @@ extern "C"
//char indata[] = "R├ñksm├Ârg├Ñs ϺÏ│Ϻ┘àÏ® Ï¿┘å ┘àÏ¡┘àÏ» Ï¿┘å Ï╣┘êÏ Ͽ┘å ┘äϺϻ┘å";
//char indata[] = "اسامة بن محمد بن عوض بن لادن,";
char indata[] = "\xf3\xbf\xbf\xbfTRAILINGNORMAL";
char indata[] = "\xf0\x91\x80\xb0TRAILINGNORMAL";
/*
\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e*/
using namespace std;
@ -518,6 +518,7 @@ void Object_releaseObject(JSOBJ obj)
delete (BaseObject *) obj;
}
int main (int argc, char **argv)
{
BaseObject *obj;

View File

@ -1,4 +1,4 @@
# coding=UTF-8
# coding=UTF-8
import simplejson
import ujson
import json
@ -15,164 +15,190 @@ decodeData = ""
"""=========================================================================="""
def ujsonEnc():
x = ujson.encode(testObject)
x = ujson.encode(testObject)
#print "ujsonEnc", x
def simplejsonEnc():
x = simplejson.dumps(testObject)
x = simplejson.dumps(testObject)
#print "simplejsonEnc", x
def jsonEnc():
x = json.dumps(testObject)
x = json.dumps(testObject)
#print "jsonEnc", x
def cjsonEnc():
x = cjson.encode(testObject)
x = cjson.encode(testObject)
#print "cjsonEnc", x
"""=========================================================================="""
def ujsonDec():
x = ujson.decode(decodeData)
x = ujson.decode(decodeData)
#print "ujsonDec: ", x
def simplejsonDec():
x = simplejson.loads(decodeData)
x = simplejson.loads(decodeData)
#print "simplejsonDec: ", x
def jsonDec():
x = json.loads(decodeData)
x = json.loads(decodeData)
#print "jsonDec: ", x
def cjsonDec():
x = cjson.decode(decodeData)
x = cjson.decode(decodeData)
#print "cjsonDec: ", x
"""=========================================================================="""
if __name__ == "__main__":
import timeit
print "Ready? Configure affinity and priority, starting in 20..."
time.sleep(20)
import timeit
print "Ready? Configure affinity and priority, starting in 20..."
time.sleep(20)
print "Array with 256 utf-8 strings:"
testObject = []
for x in xrange(256):
testObject.append("نظام الحكم سلطاني وراثي في الذكور من ذرية السيد تركي بن سعيد بن سلطان ويشترط فيمن يختار لولاية الحكم من بينهم ان يكون مسلما رشيدا عاقلا ًوابنا شرعيا لابوين عمانيين ")
COUNT = 5000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Medium complex object:"
testObject = [ [user, friends], [user, friends], [user, friends], [user, friends], [user, friends], [user, friends]]
COUNT = 5000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Array with 256 strings:"
testObject = []
for x in xrange(256):
testObject.append("A pretty long string which is in a list")
COUNT = 10000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Array with 256 doubles:"
testObject = []
for x in xrange(256):
testObject.append(sys.maxint * random.random())
COUNT = 10000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Array with 256 True values:"
testObject = []
for x in xrange(256):
testObject.append(True)
COUNT = 50000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Medium complex object:"
testObject = [ [user, friends], [user, friends], [user, friends], [user, friends], [user, friends], [user, friends]]
COUNT = 5000
print "Array with 256 dict{string, int} pairs:"
testObject = []
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
for x in xrange(256):
testObject.append({str(random.random()*20): int(random.random()*1000000)})
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
COUNT = 5000
print "Array with 256 strings:"
testObject = []
for x in xrange(256):
testObject.append("A pretty long string which is in a list")
COUNT = 10000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Array with 256 doubles:"
testObject = []
for x in xrange(256):
testObject.append(sys.maxint * random.random())
COUNT = 10000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Array with 256 True values:"
testObject = []
for x in xrange(256):
testObject.append(True)
COUNT = 50000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Array with 256 dict{string, int} pairs:"
testObject = []
for x in xrange(256):
testObject.append({str(random.random()*20): int(random.random()*1000000)})
COUNT = 5000
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
print "Dict with 256 arrays with 256 dict{string, int} pairs:"
testObject = {}
print "Dict with 256 arrays with 256 dict{string, int} pairs:"
testObject = {}
for y in xrange(256):
arrays = []
for x in xrange(256):
arrays.append({str(random.random()*20): int(random.random()*1000000)})
testObject[str(random.random()*20)] = arrays
COUNT = 50
for y in xrange(256):
arrays = []
for x in xrange(256):
arrays.append({str(random.random()*20): int(random.random()*1000000)})
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
testObject[str(random.random()*20)] = arrays
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )
COUNT = 50
print "ujson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonEnc()", "from __main__ import ujsonEnc", time.clock,10, COUNT)), )
print "simplejson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonEnc()", "from __main__ import simplejsonEnc", time.clock,10, COUNT)), )
print "cjson encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonEnc()", "from __main__ import cjsonEnc", time.clock, 10, COUNT)), )
#print "json encode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonEnc()", "from __main__ import jsonEnc", time.clock, 3, COUNT)), )
decodeData = json.dumps(testObject)
print "ujson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("ujsonDec()", "from __main__ import ujsonDec", time.clock,10, COUNT)), )
print "cjson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("cjsonDec()", "from __main__ import cjsonDec", time.clock,10, COUNT)), )
print "simplejson decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("simplejsonDec()", "from __main__ import simplejsonDec", time.clock,10, COUNT)), )
#print "json decode : %.05f calls/sec" % (COUNT / min(timeit.repeat("jsonDec()", "from __main__ import jsonDec", time.clock, 3, COUNT)), )

Binary file not shown.

View File

@ -10,504 +10,497 @@ import datetime
import calendar
class UltraJSONTests(TestCase):
def test_encodeDoubleConversion(self):
input = math.pi
output = ujson.encode(input)
self.assertEquals(round(input, 5), round(json.loads(output), 5))
self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
pass
def test_encodeDoubleNegConversion(self):
input = -math.pi
output = ujson.encode(input)
self.assertEquals(round(input, 5), round(json.loads(output), 5))
self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
pass
def test_encodeArrayOfNestedArrays(self):
input = [[[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]] ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
#self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
def test_encodeArrayOfDoubles(self):
input = [ 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337 ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
#self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
def test_encodeStringConversion(self):
input = "A string \\ \/ \b \f \n \r \t"
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_decodeUnicodeConversion(self):
pass
def test_encodeUnicodeConversion1(self):
input = "Räksmörgås اسامة بن محمد بن عوض بن لادن"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicodeConversion2(self):
input = "\xe6\x97\xa5\xd1\x88"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicodeSurrogatePair(self):
input = "\xf0\x90\x8d\x86"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicode4BytesUTF8(self):
input = "\xf0\xbf\xbf\xbfTRAILINGNORMAL"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicode4BytesUTF8Highest(self):
input = "\xf3\xbf\xbf\xbfTRAILINGNORMAL"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeArrayInArray(self):
input = [[[[]]]]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeIntConversion(self):
input = 31337
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeIntNegConversion(self):
input = -31337
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeLongNegConversion(self):
input = -9223372036854775808
output = ujson.encode(input)
outputjson = json.loads(output)
outputujson = ujson.decode(output)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeListConversion(self):
input = [ 1, 2, 3, 4 ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeDictConversion(self):
input = { "k1": 1, "k2": 2, "k3": 3, "k4": 4 }
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeNoneConversion(self):
input = None
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeTrueConversion(self):
input = True
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeFalseConversion(self):
input = False
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeDatetimeConversion(self):
ts = time.time()
input = datetime.datetime.fromtimestamp(ts)
output = ujson.encode(input)
expected = calendar.timegm(input.utctimetuple())
self.assertEquals(int(expected), json.loads(output))
self.assertEquals(int(expected), ujson.decode(output))
pass
def test_encodeDateConversion(self):
ts = time.time()
input = datetime.date.fromtimestamp(ts)
output = ujson.encode(input)
tup = ( input.year, input.month, input.day, 0, 0, 0 )
expected = calendar.timegm(tup)
self.assertEquals(int(expected), json.loads(output))
self.assertEquals(int(expected), ujson.decode(output))
pass
def test_encodeRecursionMax(self):
# 8 is the max recursion depth
class O2:
member = 0
pass
class O1:
member = 0
pass
input = O1()
input.member = O2()
input.member.member = input
try:
output = ujson.encode(input)
assert False, "Expected overflow exception"
except(OverflowError):
pass
def test_decodeJibberish(self):
input = "fdsa sda v9sa fdsa"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenArrayStart(self):
input = "["
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenObjectStart(self):
input = "{"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenArrayEnd(self):
input = "]"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenObjectEnd(self):
input = "}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringUnterminated(self):
input = "\"TESTING"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringUntermEscapeSequence(self):
input = "\"TESTING\\\""
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringBadEscape(self):
input = "\"TESTING\\\""
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeTrueBroken(self):
input = "tru"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeFalseBroken(self):
input = "fa"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNullBroken(self):
input = "n"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenDictKeyTypeLeakTest(self):
input = '{{1337:""}}'
for x in xrange(1000):
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError),e:
continue
assert False, "Wrong exception"
def test_decodeBrokenDictLeakTest(self):
input = '{{"key":"}'
for x in xrange(1000):
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
continue
assert False, "Wrong exception"
def test_decodeBrokenListLeakTest(self):
input = '[[[true'
for x in xrange(1000):
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
continue
assert False, "Wrong exception"
def test_decodeDictWithNoKey(self):
input = "{{{{31337}}}}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeDictWithNoColonOrValue(self):
input = "{{{{\"key\"}}}}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeDictWithNoValue(self):
input = "{{{{\"key\":}}}}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNumericIntPos(self):
input = "31337"
self.assertEquals (31337, ujson.decode(input))
def test_decodeNumericIntNeg(self):
input = "-31337"
self.assertEquals (-31337, ujson.decode(input))
"""
# Should fail with exception
def test_encodeUnicode4BytesUTF8Fail(self):
input = "\xfd\xbf\xbf\xbf\xbf\xbf"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
# This test fails. I'm not sure it's an issue or not
def test_encodeListLongConversion(self):
input = [9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807 ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
pass
# This test fails, I'm not sure it's an issue or not
def test_encodeLongConversion(self):
input = 9223372036854775807
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeUTF8Conversion(self):
input = u"A \"string\"\"\\\/\b\f\n\r\t"
raise NotImplementedError("Implement this test!")
pass
def test_decodeNumericIntExp(self):
input = "<int>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntFrcExp(self):
input = "<int>.<frc>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntFrcOverflow(self):
input = "X.Y"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntPosOverflow(self):
input = "9223372036854775807322"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNumericIntNegOverflow(self):
input = "-9223372036854775807322"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
#Exponent specific tests
def test_decodeNumericIntExpEPLUS(self):
input = "<int>E+<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpePLUS(self):
input = "<int>e+<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpE(self):
input = "<int>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpe(self):
input = "<int>e<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpE(self):
input = "<int>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpe(self):
input = "<int>e<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpEMinus(self):
input = "<int>E-<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpeMinus(self):
input = "<int>e-<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeStringUnicodeEscape(self):
input = "\u3131"
raise NotImplementedError("Implement this test!")
def test_decodeStringUnicodeBrokenEscape(self):
input = "\u3131"
raise NotImplementedError("Implement this test!")
def test_decodeStringUnicodeInvalidEscape(self):
input = "\u3131"
raise NotImplementedError("Implement this test!")
def test_decodeStringUTF8(self):
input = "someutfcharacters"
raise NotImplementedError("Implement this test!")
def test_decodeNumericFloatInf(self):
pass
def test_decodeNumericFloatNan(self):
pass
"""
def test_encodeDoubleConversion(self):
input = math.pi
output = ujson.encode(input)
self.assertEquals(round(input, 5), round(json.loads(output), 5))
self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
pass
def test_encodeDoubleNegConversion(self):
input = -math.pi
output = ujson.encode(input)
self.assertEquals(round(input, 5), round(json.loads(output), 5))
self.assertEquals(round(input, 5), round(ujson.decode(output), 5))
pass
def test_encodeArrayOfNestedArrays(self):
input = [[[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]], [[[]]] ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
#self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
def test_encodeArrayOfDoubles(self):
input = [ 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337, 31337.31337 ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
#self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
def test_encodeStringConversion(self):
input = "A string \\ \/ \b \f \n \r \t"
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_decodeUnicodeConversion(self):
pass
def test_encodeUnicodeConversion1(self):
input = "Räksmörgås اسامة بن محمد بن عوض بن لادن"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicodeConversion2(self):
input = "\xe6\x97\xa5\xd1\x88"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicodeSurrogatePair(self):
input = "\xf0\x90\x8d\x86"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicode4BytesUTF8(self):
input = "\xf0\x91\x80\xb0TRAILINGNORMAL"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeUnicode4BytesUTF8Highest(self):
input = "\xf3\xbf\xbf\xbfTRAILINGNORMAL"
enc = ujson.encode(input)
dec = ujson.decode(enc)
self.assertEquals(input, dec)
self.assertEquals(enc, json.dumps(input, encoding="utf-8"))
def test_encodeArrayInArray(self):
input = [[[[]]]]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeIntConversion(self):
input = 31337
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeIntNegConversion(self):
input = -31337
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeLongNegConversion(self):
input = -9223372036854775808
output = ujson.encode(input)
outputjson = json.loads(output)
outputujson = ujson.decode(output)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeListConversion(self):
input = [ 1, 2, 3, 4 ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeDictConversion(self):
input = { "k1": 1, "k2": 2, "k3": 3, "k4": 4 }
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeNoneConversion(self):
input = None
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeTrueConversion(self):
input = True
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeFalseConversion(self):
input = False
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeDatetimeConversion(self):
ts = time.time()
input = datetime.datetime.fromtimestamp(ts)
output = ujson.encode(input)
expected = calendar.timegm(input.utctimetuple())
self.assertEquals(int(expected), json.loads(output))
self.assertEquals(int(expected), ujson.decode(output))
pass
def test_encodeDateConversion(self):
ts = time.time()
input = datetime.date.fromtimestamp(ts)
output = ujson.encode(input)
tup = ( input.year, input.month, input.day, 0, 0, 0 )
expected = calendar.timegm(tup)
self.assertEquals(int(expected), json.loads(output))
self.assertEquals(int(expected), ujson.decode(output))
pass
def test_encodeRecursionMax(self):
# 8 is the max recursion depth
class O2:
member = 0
pass
class O1:
member = 0
pass
input = O1()
input.member = O2()
input.member.member = input
try:
output = ujson.encode(input)
assert False, "Expected overflow exception"
except(OverflowError):
pass
def test_decodeJibberish(self):
input = "fdsa sda v9sa fdsa"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenArrayStart(self):
input = "["
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenObjectStart(self):
input = "{"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenArrayEnd(self):
input = "]"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenObjectEnd(self):
input = "}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringUnterminated(self):
input = "\"TESTING"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringUntermEscapeSequence(self):
input = "\"TESTING\\\""
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeStringBadEscape(self):
input = "\"TESTING\\\""
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeTrueBroken(self):
input = "tru"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeFalseBroken(self):
input = "fa"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNullBroken(self):
input = "n"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeBrokenDictKeyTypeLeakTest(self):
input = '{{1337:""}}'
for x in xrange(1000):
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError),e:
continue
assert False, "Wrong exception"
def test_decodeBrokenDictLeakTest(self):
input = '{{"key":"}'
for x in xrange(1000):
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
continue
assert False, "Wrong exception"
def test_decodeBrokenListLeakTest(self):
input = '[[[true'
for x in xrange(1000):
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
continue
assert False, "Wrong exception"
def test_decodeDictWithNoKey(self):
input = "{{{{31337}}}}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeDictWithNoColonOrValue(self):
input = "{{{{\"key\"}}}}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeDictWithNoValue(self):
input = "{{{{\"key\":}}}}"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNumericIntPos(self):
input = "31337"
self.assertEquals (31337, ujson.decode(input))
def test_decodeNumericIntNeg(self):
input = "-31337"
self.assertEquals (-31337, ujson.decode(input))
def test_encodeUnicode4BytesUTF8Fail(self):
input = "\xfd\xbf\xbf\xbf\xbf\xbf"
try:
enc = ujson.encode(input)
assert False, "Expected exception"
except OverflowError:
pass
"""
# This test fails. I'm not sure it's an issue or not
def test_encodeListLongConversion(self):
input = [9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807, 9223372036854775807 ]
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(input, ujson.decode(output))
pass
# This test fails, I'm not sure it's an issue or not
def test_encodeLongConversion(self):
input = 9223372036854775807
output = ujson.encode(input)
self.assertEquals(input, json.loads(output))
self.assertEquals(output, json.dumps(input))
self.assertEquals(input, ujson.decode(output))
pass
def test_encodeUTF8Conversion(self):
input = u"A \"string\"\"\\\/\b\f\n\r\t"
raise NotImplementedError("Implement this test!")
pass
def test_decodeNumericIntExp(self):
input = "<int>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntFrcExp(self):
input = "<int>.<frc>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntFrcOverflow(self):
input = "X.Y"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntPosOverflow(self):
input = "9223372036854775807322"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
def test_decodeNumericIntNegOverflow(self):
input = "-9223372036854775807322"
try:
ujson.decode(input)
assert False, "Expected exception!"
except(ValueError):
return
assert False, "Wrong exception"
#Exponent specific tests
def test_decodeNumericIntExpEPLUS(self):
input = "<int>E+<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpePLUS(self):
input = "<int>e+<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpE(self):
input = "<int>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpe(self):
input = "<int>e<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpE(self):
input = "<int>E<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpe(self):
input = "<int>e<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpEMinus(self):
input = "<int>E-<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeNumericIntExpeMinus(self):
input = "<int>e-<exp>"
raise NotImplementedError("Implement this test!")
def test_decodeStringUnicodeEscape(self):
input = "\u3131"
raise NotImplementedError("Implement this test!")
def test_decodeStringUnicodeBrokenEscape(self):
input = "\u3131"
raise NotImplementedError("Implement this test!")
def test_decodeStringUnicodeInvalidEscape(self):
input = "\u3131"
raise NotImplementedError("Implement this test!")
def test_decodeStringUTF8(self):
input = "someutfcharacters"
raise NotImplementedError("Implement this test!")
def test_decodeNumericFloatInf(self):
pass
def test_decodeNumericFloatNan(self):
pass
"""
if __name__ == "__main__":
unittest.main()
unittest.main()

View File

@ -142,7 +142,7 @@ typedef unsigned __int64 JSUINT64;
typedef unsigned __int32 uint32_t;
typedef __int32 JSINT32;
typedef uint32_t JSUINT32;
typedef unsigned __int8 JSUINT8;
typedef unsigned __int16 JSUTF16;
typedef unsigned __int32 JSUTF32;
@ -153,14 +153,12 @@ typedef unsigned __int32 JSUTF32;
#define FASTCALL_ATTR
#define INLINE_PREFIX __inline
/*
#define FASTCALL_MSVC
#define FASTCALL_ATTR
#define INLINE_PREFIX
*/
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif
#else
#include <sys/types.h>
typedef int64_t JSINT64;
typedef u_int64_t JSUINT64;
@ -174,12 +172,18 @@ typedef u_int32_t JSUINT32;
typedef u_int32_t uint32_t;
typedef u_int8_t JSUINT8;
typedef u_int16_t JSUTF16;
typedef u_int16_t JSUTF32;
#define EXPORTFUNCTION
#endif
#ifndef __LITTLE_ENDIAN__
#error "Endianess not supported"
#endif
enum JSTYPES
{
JT_NULL, // NULL

View File

@ -446,8 +446,6 @@ FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds)
JSUTF32 u32chr;
inputOffset ++;
//FIXME: Can't use this function in real life
for (index = 0; index < 4; index ++)
{
switch (*inputOffset)
@ -499,15 +497,6 @@ FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds)
iSur ++;
break;
}
/*
else
if ((sur[iSur] & 0xfc00) != 0xdc00)
{
// Unpaired surogate
return SetError (ds, -1, "Unpaired low surrogate when decoding 'string'");
}
*/
u32chr = sur[iSur];
iSur = 0;
}
@ -523,50 +512,54 @@ FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds)
iSur = 0;
}
// Convert UTF32 char to UTF-8 (gah!)
if(u32chr < 0x80)
if (u32chr < 0x80)
{
*(escOffset++) = u32chr;
}
else
if(u32chr < 0x800)
{
*(escOffset++) = (MASK2BYTES | u32chr >> 6);
*(escOffset++) = (MASKBYTE | u32chr & MASKBITS);
}
else
if(u32chr < 0x10000)
{
*(escOffset++) = (MASK3BYTES | u32chr >> 12);
*(escOffset++) = (MASKBYTE | u32chr >> 6 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr & MASKBITS);
*(escOffset++) = (char) u32chr;
}
else
if(u32chr < 0x200000)
if (u32chr < 0x0800)
{
*(escOffset++) = (MASK4BYTES | u32chr >> 18);
*(escOffset++) = (MASKBYTE | u32chr >> 12 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr >> 6 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr & MASKBITS);
(*escOffset++) = 0xC0 | ((u32chr >> 6) & 0x1F);
(*escOffset++) = 0x80 | ((u32chr >> 0) & 0x3F);
}
else
if (u32chr < 0x10000)
{
(*escOffset++) = 0xE0 | ((u32chr >> 12) & 0x0F);
(*escOffset++) = 0x80 | ((u32chr >> 6) & 0x3F);
(*escOffset++) = 0x80 | ((u32chr >> 0) & 0x3F);
}
else
if (u32chr < 0x200000)
{
(*escOffset++) = 0xF0 | ((u32chr >> 18) & 0x07);
(*escOffset++) = 0x80 | ((u32chr >> 12) & 0x3F);
(*escOffset++) = 0x80 | ((u32chr >> 6) & 0x3F);
(*escOffset++) = 0x80 | ((u32chr >> 0) & 0x3F);
}
else
//FIXME: Does it even make sense supporting 4+ bytes UTF-8 sequences?
if(u32chr < 0x4000000)
{
*(escOffset++) = (MASK5BYTES | u32chr >> 24);
*(escOffset++) = (MASKBYTE | u32chr >> 18 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr >> 12 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr >> 6 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr & MASKBITS);
*(escOffset++) = 0xF8 | ((u32chr >> 24) & 0x03);
*(escOffset++) = 0x80 | ((u32chr >> 18) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 12) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 6) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 0) & 0x3F);
}
else
if(u32chr < 0x8000000)
{
*(escOffset++) = (MASK6BYTES | u32chr >> 30);
*(escOffset++) = (MASKBYTE | u32chr >> 24 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr >> 18 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr >> 12 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr >> 6 & MASKBITS);
*(escOffset++) = (MASKBYTE | u32chr & MASKBITS);
*(escOffset++) = 0xFC | ((u32chr >> 30) & 0x01);
*(escOffset++) = 0x80 | ((u32chr >> 24) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 18) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 12) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 6) & 0x3F);
*(escOffset++) = 0x80 | ((u32chr >> 0)& 0x3F);
}
else
{
return SetError (ds, -1, "Unicode code point of out bounds when decoding 'string'");
}

View File

@ -47,35 +47,48 @@ Copyright (c) 2007 Nick Galbreath -- nickg [at] modp [dot] com. All rights rese
#ifndef FALSE
#define FALSE 0
#endif
static const double g_pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
static const unsigned char g_utf8LengthLookup[256] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
//#define __LINE_PROFILER__
#ifdef __LINE_PROFILER__
unsigned int g_profLines[1000] = { 0 };
#define PROFILE_MARK() g_profLines[__LINE__] ++;
#else
#define PROFILE_MARK()
#endif
static void SetError (JSOBJ obj, JSONObjectEncoder *enc, const char *message)
{
enc->errorMsg = message;
enc->errorObj = obj;
}
/*
FIXME: Keep track of how big these get across several encoder calls and try to make an estimate
Thay way we won't run our head into the wall each call */
They way we won't run our head into the wall each call */
void Buffer_Realloc (JSONObjectEncoder *enc, size_t cbNeeded)
{
size_t curSize = enc->end - enc->start;
size_t newSize = curSize * 2;
size_t offset = enc->offset - enc->start;
PROFILE_MARK();
while (newSize < curSize + cbNeeded)
{
newSize *= 2;
}
if (enc->heap)
{
enc->start = (char *) enc->realloc (enc->start, newSize);
@ -98,155 +111,175 @@ FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_AppendShortHexUnchecked (c
*(outputOffset++) = s_hexChars[(value & 0x0f00) >> 8];
*(outputOffset++) = s_hexChars[(value & 0x00f0) >> 4];
*(outputOffset++) = s_hexChars[(value & 0x000f) >> 0];
}
/*
TODO:
Performance hotspot. A lot of time is spent here */
void Buffer_EscapeString (JSONObjectEncoder *enc, char *io)
{
char *of = enc->offset;
PROFILE_MARK();
FIXME:
This function only works on Little Endian at the moment.
There's a preprocessor check for this so you really can't compile on non little endian
FIXME: The JSON spec says escape "/" but non of the others do and we don't
want to be left alone doing it so we don't :)
FIXME: I guess it would be possible to combine the UTF-8 length lookup with escaping lookup
to make one bug super lookup table!
*/
int Buffer_EscapeString (JSOBJ obj, JSONObjectEncoder *enc, char *io, char *end)
{
JSUTF32 ucs;
char *of = enc->offset;
while (1)
{
unsigned char chr = (unsigned char) *io;
int temp;
unsigned char utflen;
unsigned char chr;
if (chr >= 0x80)
NEXT_CHARACTER:
chr = (unsigned char) *io;
utflen = g_utf8LengthLookup[chr];
if (io + (utflen - 1) > end)
{
unsigned int len = 1;
JSUTF32 u32chr = 0;
enc->offset += (of - enc->offset);
SetError (obj, enc, "Unterminated UTF-8 sequence when encoding string");
return FALSE;
}
io ++;
while (chr & (1 << (7 - len)) && len < 4)
switch(utflen)
{
case 1:
{
if (*io == '\0')
switch (chr)
{
//FIXME: Suppose this is decoding error, let's not take that crap
return;
case '\0': enc->offset += (of - enc->offset); return TRUE;
case '\"': *(of++) = '\\'; *(of++) = '\"';break;
case '\\': *(of++) = '\\'; *(of++) = '\\';break;
//case '/': *(enc->offset++) = '\\'; *(enc->offset++) = '/';break;
case '\b': *(of++) = '\\'; *(of++) = 'b';break;
case '\f': *(of++) = '\\'; *(of++) = 'f';break;
case '\n': *(of++) = '\\'; *(of++) = 'n';break;
case '\r': *(of++) = '\\'; *(of++) = 'r';break;
case '\t': *(of++) = '\\'; *(of++) = 't';break;
case 0x01: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; break;
case 0x02: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '2'; break;
case 0x03: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '3'; break;
case 0x04: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '4'; break;
case 0x05: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '5'; break;
case 0x06: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '6'; break;
case 0x07: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '7'; break;
case 0x0b: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = 'b'; break;
case 0x0e: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = 'e'; break;
case 0x0f: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = 'f'; break;
case 0x10: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '0'; break;
case 0x11: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '1'; break;
case 0x12: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '2'; break;
case 0x13: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '3'; break;
case 0x14: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '4'; break;
case 0x15: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '5'; break;
case 0x16: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '6'; break;
case 0x17: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '7'; break;
case 0x18: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '8'; break;
case 0x19: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '9'; break;
case 0x1a: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'a'; break;
case 0x1b: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'b'; break;
case 0x1c: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'c'; break;
case 0x1d: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'd'; break;
case 0x1e: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'e'; break;
case 0x1f: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'f'; break;
default: *(of++)= chr; break;
}
io ++;
goto NEXT_CHARACTER;
}
case 2:
{
JSUTF32 in = *((JSUTF16 *) io);
ucs = ((in & 0x1f) << 6) | ((in >> 8) & 0x3f);
if (ucs < 0x80)
{
enc->offset += (of - enc->offset);
SetError (obj, enc, "Overlong 2 byte UTF-8 sequence detected when encoding string");
return FALSE;
}
temp = (*io & 0x3f);
u32chr <<= 6;
u32chr |= (*io & 0x3f);
io ++;
len ++;
io += 2;
break;
}
//u32chr >>= (len * 6);
/*
FIXME: Performance issue
I guess we can do this with a lookup of some sort */
switch (len)
case 3:
{
case 2: u32chr |= (chr & 0x1f) << ((len - 1) * 6); break;
case 3: u32chr |= (chr & 0x0f) << ((len - 1) * 6); break;
case 4: u32chr |= (chr & 0x07) << ((len - 1) * 6); break;
JSUTF32 in = *((JSUTF16 *) io);
in |= *((JSUINT8 *) io + 2) << 16;
default:
/*
FIXME: This happens when a UTF-8 sequence which we can't encode it UTF-16 anyhow is encountered */
return;
//case 5: u32chr |= (chr & 0x03) << ((len - 1) * 6); break;
//case 6: u32chr |= (chr & 0x01) << ((len - 1) * 6); break;
ucs = ((in & 0x0f) << 12) | ((in & 0x3f00) >> 2) | ((in & 0x3f0000) >> 16);
if (ucs < 0x800)
{
enc->offset += (of - enc->offset);
SetError (obj, enc, "Overlong 3 byte UTF-8 sequence detected when encoding string");
return FALSE;
}
io += 3;
break;
}
if (u32chr > 0x10000)
case 4:
{
JSUTF16 s1;
JSUTF16 s2;
u32chr -= 0x10000;
JSUTF32 in = *((JSUTF32 *) io);
ucs = ((in & 0x07) << 18) | ((in & 0x3f00) << 4) | ((in & 0x3f0000) >> 10) | ((in & 0x3f000000) >> 24);
s1 = (u32chr >> 10) + 0xd800;
s2 = (u32chr & 0x3ff) + 0xdc00;
if (ucs < 0x10000)
{
enc->offset += (of - enc->offset);
SetError (obj, enc, "Overlong 4 byte UTF-8 sequence detected when encoding string");
return FALSE;
}
*(of++) = '\\';
*(of++) = 'u';
Buffer_AppendShortHexUnchecked(of, s1);
of += 4;
*(of++) = '\\';
*(of++) = 'u';
Buffer_AppendShortHexUnchecked(of, s2);
of += 4;
io += 4;
break;
}
else
case 5:
case 6:
default:
{
*(of++) = '\\';
*(of++) = 'u';
Buffer_AppendShortHexUnchecked(of, u32chr);
of += 4;
enc->offset += (of - enc->offset);
SetError (obj, enc, "Unsupported UTF-8 sequence length when encoding string");
return FALSE;
}
}
/*
If the character is a UTF8 sequence of length > 1 we end up here */
if (ucs > 0x10000)
{
ucs -= 0x10000;
*(of++) = '\\';
*(of++) = 'u';
Buffer_AppendShortHexUnchecked(of, (ucs >> 10) + 0xd800);
of += 4;
*(of++) = '\\';
*(of++) = 'u';
Buffer_AppendShortHexUnchecked(of, (ucs & 0x3ff) + 0xdc00);
of += 4;
}
else
{
switch (chr)
{
case '\0':
enc->offset += (of - enc->offset);
return;
case '\"': *(of++) = '\\'; *(of++) = '\"';break;
case '\\': *(of++) = '\\'; *(of++) = '\\';break;
//NOTE: The RFC says escape solidus but none of the reference encoders does so.
//We don't do it either now ;)
//case '/': *(enc->offset++) = '\\'; *(enc->offset++) = '/';break;
case '\b': *(of++) = '\\'; *(of++) = 'b';break;
case '\f': *(of++) = '\\'; *(of++) = 'f';break;
case '\n': *(of++) = '\\'; *(of++) = 'n';break;
case '\r': *(of++) = '\\'; *(of++) = 'r';break;
case '\t': *(of++) = '\\'; *(of++) = 't';break;
case 0x01: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; break;
case 0x02: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '2'; break;
case 0x03: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '3'; break;
case 0x04: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '4'; break;
case 0x05: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '5'; break;
case 0x06: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '6'; break;
case 0x07: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = '7'; break;
case 0x0b: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = 'b'; break;
case 0x0e: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = 'e'; break;
case 0x0f: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '0'; *(of++) = 'f'; break;
case 0x10: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '0'; break;
case 0x11: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '1'; break;
case 0x12: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '2'; break;
case 0x13: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '3'; break;
case 0x14: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '4'; break;
case 0x15: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '5'; break;
case 0x16: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '6'; break;
case 0x17: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '7'; break;
case 0x18: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '8'; break;
case 0x19: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = '9'; break;
case 0x1a: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'a'; break;
case 0x1b: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'b'; break;
case 0x1c: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'c'; break;
case 0x1d: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'd'; break;
case 0x1e: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'e'; break;
case 0x1f: *(of++) = '\\'; *(of++) = 'u'; *(of++) = '0'; *(of++) = '0'; *(of++) = '1'; *(of++) = 'f'; break;
default: *(of++)= chr; break;
}
io ++;
*(of++) = '\\';
*(of++) = 'u';
Buffer_AppendShortHexUnchecked(of, ucs);
of += 4;
}
}
return FALSE;
}
#define Buffer_Reserve(__enc, __len) \
if ((__enc)->offset + (__len) > (__enc)->end) \
{ \
@ -254,73 +287,20 @@ void Buffer_EscapeString (JSONObjectEncoder *enc, char *io)
} \
#define Buffer_AppendCharUnchecked(__enc, __chr) \
*((__enc)->offset++) = __chr; \
/*
FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_AppendEscape(JSONObjectEncoder *enc, const char *_pstr, size_t _len)
{
while (enc->offset + ((_len * 2) + 2) > enc->end)
{
Buffer_Realloc(enc);
}
*(enc->offset++) = '\"';
Buffer_Escape(enc, (char *)_pstr);
*(enc->offset++) = '\"';
}
FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_AppendEscapeUnchecked(JSONObjectEncoder *enc, const char *_pstr)
{
*(enc->offset++) = '\"';
Buffer_Escape(enc, (char *)_pstr);
*(enc->offset++) = '\"';
}
FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_Append(JSONObjectEncoder *enc, const char *_pstr, size_t _len)
{
while (enc->offset + _len > enc->end)
{
Buffer_Realloc(enc);
}
memcpy (enc->offset, _pstr, _len);
enc->offset += _len;
}
FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC Buffer_Reserve(JSONObjectEncoder *enc, size_t _len)
{
while (enc->offset + _len > enc->end)
{
Buffer_Realloc(enc);
}
}
*/
/**
* Powers of 10
* 10^0 to 10^9
*/
static const double g_pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
#define Buffer_AppendCharUnchecked(__enc, __chr) \
*((__enc)->offset++) = __chr; \
FASTCALL_ATTR INLINE_PREFIX void FASTCALL_MSVC strreverse(char* begin, char* end)
{
char aux;
PROFILE_MARK();
while (end > begin)
aux = *end, *end-- = *begin, *begin++ = aux;
}
void Buffer_AppendIntUnchecked(JSONObjectEncoder *enc, JSINT32 value)
{
char* wstr;
JSUINT32 uvalue = (value < 0) ? -value : value;
PROFILE_MARK();
wstr = enc->offset;
// Conversion. Number is reversed.
@ -337,8 +317,6 @@ void Buffer_AppendLongUnchecked(JSONObjectEncoder *enc, JSINT64 value)
{
char* wstr;
JSUINT64 uvalue = (value < 0) ? -value : value;
PROFILE_MARK();
wstr = enc->offset;
// Conversion. Number is reversed.
@ -364,7 +342,6 @@ void Buffer_AppendDoubleUnchecked(JSONObjectEncoder *enc, double value)
uint32_t frac;
int neg;
PROFILE_MARK();
/* Hacky test for NaN
* under -fast-math this won't work, but then you also won't
@ -499,19 +476,12 @@ FIXME:
Perhaps implement recursion detection */
static void SetError (JSOBJ obj, JSONObjectEncoder *enc, const char *message)
{
enc->errorMsg = message;
enc->errorObj = obj;
}
void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
{
JSONTypeContext tc;
size_t szlen;
PROFILE_MARK();
if (enc->level > enc->recursionMax)
{
SetError (obj, enc, "Maximum recursion level reached");
@ -525,21 +495,19 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
maxLength of double to string OR maxLength of JSLONG to string
Since input is assumed to be UTF-8 the worst character length is:
UTF-8: 6 bytes (31 bit real data) =>
UCS-4: 4 bytes =>
UTF-16: 2 surrogate pairs (4 bytes) =>
Encoded: \uXXXX\uXXXX (12 bytes)
12 / 6 => 2
4 bytes (of UTF-8) => "\uXXXX\uXXXX" (12 bytes)
*/
Buffer_Reserve(enc, 256 + (cbName * 2));
Buffer_Reserve(enc, 256 + (((cbName / 4) + 1) * 12));
if (name)
{
Buffer_AppendCharUnchecked(enc, '\"');
Buffer_EscapeString(enc, name);
if (!Buffer_EscapeString(obj, enc, name, name + cbName))
{
return;
}
Buffer_AppendCharUnchecked(enc, '\"');
Buffer_AppendCharUnchecked (enc, ':');
@ -560,9 +528,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
{
int count = 0;
JSOBJ iterObj;
PROFILE_MARK();
enc->iterBegin(obj, &tc);
Buffer_AppendCharUnchecked (enc, '[');
@ -595,8 +560,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
JSOBJ iterObj;
char *objName;
PROFILE_MARK();
enc->iterBegin(obj, &tc);
Buffer_AppendCharUnchecked (enc, '{');
@ -626,24 +589,18 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
case JT_LONG:
{
PROFILE_MARK();
Buffer_AppendLongUnchecked (enc, enc->getLongValue(obj, &tc));
break;
}
case JT_INT:
{
PROFILE_MARK();
Buffer_AppendIntUnchecked (enc, enc->getIntValue(obj, &tc));
break;
}
case JT_TRUE:
{
PROFILE_MARK();
Buffer_AppendCharUnchecked (enc, 't');
Buffer_AppendCharUnchecked (enc, 'r');
Buffer_AppendCharUnchecked (enc, 'u');
@ -653,9 +610,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
case JT_FALSE:
{
//Buffer_AppendUnchecked (buffer, "false", 5);
PROFILE_MARK();
Buffer_AppendCharUnchecked (enc, 'f');
Buffer_AppendCharUnchecked (enc, 'a');
Buffer_AppendCharUnchecked (enc, 'l');
@ -667,9 +621,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
case JT_NULL:
{
//Buffer_AppendUnchecked(buffer, "null", 4);
PROFILE_MARK();
Buffer_AppendCharUnchecked (enc, 'n');
Buffer_AppendCharUnchecked (enc, 'u');
Buffer_AppendCharUnchecked (enc, 'l');
@ -679,8 +630,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
case JT_DOUBLE:
{
PROFILE_MARK();
Buffer_AppendDoubleUnchecked (enc, enc->getDoubleValue(obj, &tc));
break;
}
@ -688,11 +637,16 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
case JT_UTF8:
{
const char *value = enc->getStringValue(obj, &tc, &szlen);
PROFILE_MARK();
Buffer_Reserve(enc, (szlen * 2) + 2);
Buffer_Reserve(enc, ((szlen / 4) + 1) * 12);
Buffer_AppendCharUnchecked (enc, '\"');
Buffer_EscapeString(enc, value);
if (!Buffer_EscapeString(obj, enc, value, value + szlen))
{
enc->endTypeContext(obj, &tc);
enc->level --;
return;
}
Buffer_AppendCharUnchecked (enc, '\"');
break;
}
@ -703,9 +657,6 @@ void encode(JSOBJ obj, JSONObjectEncoder *enc, const char *name, size_t cbName)
}
//FIXME: Depending on performance make JSON_NO_EXTRA_WHITESPACE as configuration option
char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *_buffer, size_t _cbBuffer)
{
enc->malloc = enc->malloc ? enc->malloc : malloc;
@ -747,18 +698,5 @@ char *JSON_EncodeObject(JSOBJ obj, JSONObjectEncoder *enc, char *_buffer, size_t
Buffer_Reserve(enc, 1);
Buffer_AppendCharUnchecked(enc, '\0');
#ifdef __LINE_PROFILER__
{
int index;
for (index = 0; index < 1000; index ++)
{
if (g_profLines[index] > 0)
fprintf (stderr, "%d %u\n", index, g_profLines[index]);
}
getchar();
}
#endif
return enc->start;
}