[pypy-commit] pypy fastjson: start to implement the json decoder: decode only strings so far
antocuni
noreply at buildbot.pypy.org
Tue Jun 4 17:41:28 CEST 2013
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: fastjson
Changeset: r64768:6ec983152d16
Date: 2013-06-04 15:28 +0200
http://bitbucket.org/pypy/pypy/changeset/6ec983152d16/
Log: start to implement the json decoder: decode only strings so far
diff --git a/pypy/module/_fastjson/__init__.py b/pypy/module/_fastjson/__init__.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_fastjson/__init__.py
@@ -0,0 +1,10 @@
+from pypy.interpreter.mixedmodule import MixedModule
+
+class Module(MixedModule):
+ """fast json implementation"""
+
+ appleveldefs = {}
+
+ interpleveldefs = {
+ 'loads' : 'interp_decoder.loads',
+ }
diff --git a/pypy/module/_fastjson/interp_decoder.py b/pypy/module/_fastjson/interp_decoder.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_fastjson/interp_decoder.py
@@ -0,0 +1,65 @@
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter import unicodehelper
+
+def is_whitespace(ch):
+ return ch == ' ' or ch == '\t' or ch == '\r' or ch == '\n'
+
+TYPE_INVALID = 0
+TYPE_STRING = 0
+
+class JSONDecoder(object):
+ def __init__(self, space, s):
+ self.space = space
+ self.s = s
+ self.i = 0
+ self.last_type = TYPE_INVALID
+
+ def eof(self):
+ return self.i == len(self.s)
+
+ def peek(self):
+ return self.s[self.i]
+
+ def next(self):
+ ch = self.peek()
+ self.i += 1
+ return ch
+
+ def skip_whitespace(self):
+ while not self.eof():
+ ch = self.peek()
+ if is_whitespace(ch):
+ self.next()
+ else:
+ break
+
+ def decode_any(self):
+ self.skip_whitespace()
+ ch = self.peek()
+ if ch == '"':
+ return self.decode_string()
+ else:
+ assert False, 'Unkown char: %s' % ch
+
+ def decode_string(self):
+ self.next()
+ start = self.i
+ while True:
+ ch = self.next()
+ if ch == '"':
+ end = self.i-1
+ assert end > 0
+ content = self.s[start:end]
+ self.last_type = TYPE_STRING
+ return self.space.wrap(unicodehelper.decode_utf8(self.space, content))
+ elif ch == '\\':
+ raise Exception("escaped strings not supported yet")
+
+
+ at unwrap_spec(s=str)
+def loads(space, s):
+ decoder = JSONDecoder(space, s)
+ return decoder.decode_any()
+
+
diff --git a/pypy/module/_fastjson/test/test__fastjson.py b/pypy/module/_fastjson/test/test__fastjson.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_fastjson/test/test__fastjson.py
@@ -0,0 +1,32 @@
+# -*- encoding: utf-8 -*-
+import py
+from pypy.module._fastjson.interp_decoder import JSONDecoder
+
+def test_skip_whitespace():
+ dec = JSONDecoder('fake space', ' hello ')
+ assert dec.i == 0
+ dec.skip_whitespace()
+ assert dec.next() == 'h'
+ assert dec.next() == 'e'
+ assert dec.next() == 'l'
+ assert dec.next() == 'l'
+ assert dec.next() == 'o'
+ dec.skip_whitespace()
+ assert dec.eof()
+
+
+
+class AppTest(object):
+ spaceconfig = {"objspace.usemodules._fastjson": True}
+
+ def test_load_string(self):
+ import _fastjson
+ res = _fastjson.loads('"hello"')
+ assert res == u'hello'
+ assert type(res) is unicode
+
+ def test_load_string_utf8(self):
+ import _fastjson
+ s = u'àèìòù'
+ res = _fastjson.loads('"%s"' % s.encode('utf-8'))
+ assert res == s
More information about the pypy-commit
mailing list