if esc not in escapes:
escapes[esc] = u"\\u%04x" % esc
-def __dump_string(stream, s):
- stream.write(u'"%s"' % ''.join(escapes.get(ord(c), c) for c in s))
+SPACES_PER_LEVEL = 2
+
+
+class _Serializer(object):
+ def __init__(self, stream, pretty, sort_keys):
+ self.stream = stream
+ self.pretty = pretty
+ self.sort_keys = sort_keys
+ self.depth = 0
+
+ def __serialize_string(self, s):
+ self.stream.write(u'"%s"' % ''.join(escapes.get(ord(c), c) for c in s))
+
+ def __indent_line(self):
+ if self.pretty:
+ self.stream.write('\n')
+ self.stream.write(' ' * (SPACES_PER_LEVEL * self.depth))
+
+ def serialize(self, obj):
+ if obj is None:
+ self.stream.write(u"null")
+ elif obj is False:
+ self.stream.write(u"false")
+ elif obj is True:
+ self.stream.write(u"true")
+ elif type(obj) in (int, long):
+ self.stream.write(u"%d" % obj)
+ elif type(obj) == float:
+ self.stream.write("%.15g" % obj)
+ elif type(obj) == unicode:
+ self.__serialize_string(obj)
+ elif type(obj) == str:
+ self.__serialize_string(unicode(obj))
+ elif type(obj) == dict:
+ self.stream.write(u"{")
+
+ self.depth += 1
+ self.__indent_line()
+
+ if self.sort_keys:
+ items = sorted(obj.items())
+ else:
+ items = obj.iteritems()
+ for i, (key, value) in enumerate(items):
+ if i > 0:
+ self.stream.write(u",")
+ self.__indent_line()
+ self.__serialize_string(unicode(key))
+ self.stream.write(u":")
+ if self.pretty:
+ self.stream.write(u' ')
+ self.serialize(value)
+
+ self.stream.write(u"}")
+ self.depth -= 1
+ elif type(obj) in (list, tuple):
+ self.stream.write(u"[")
+ self.depth += 1
+
+ if obj:
+ self.__indent_line()
+
+ for i, value in enumerate(obj):
+ if i > 0:
+ self.stream.write(u",")
+ self.__indent_line()
+ self.serialize(value)
+
+ self.depth -= 1
+ self.stream.write(u"]")
+ else:
+ raise Exception("can't serialize %s as JSON" % obj)
+
def to_stream(obj, stream, pretty=False, sort_keys=True):
- if obj is None:
- stream.write(u"null")
- elif obj is False:
- stream.write(u"false")
- elif obj is True:
- stream.write(u"true")
- elif type(obj) in (int, long):
- stream.write(u"%d" % obj)
- elif type(obj) == float:
- stream.write("%.15g" % obj)
- elif type(obj) == unicode:
- __dump_string(stream, obj)
- elif type(obj) == str:
- __dump_string(stream, unicode(obj))
- elif type(obj) == dict:
- stream.write(u"{")
- if sort_keys:
- items = sorted(obj.items())
- else:
- items = obj.iteritems()
- for i, (key, value) in enumerate(items):
- if i > 0:
- stream.write(u",")
- __dump_string(stream, unicode(key))
- stream.write(u":")
- to_stream(value, stream, pretty, sort_keys)
- stream.write(u"}")
- elif type(obj) in (list, tuple):
- stream.write(u"[")
- for i, value in enumerate(obj):
- if i > 0:
- stream.write(u",")
- to_stream(value, stream, pretty, sort_keys)
- stream.write(u"]")
- else:
- raise Exception("can't serialize %s as JSON" % obj)
+ _Serializer(stream, pretty, sort_keys).serialize(obj)
def to_file(obj, name, pretty=False, sort_keys=True):
stream = open(name, "w")