4 from don import tags, _shared
6 def _integer_size_to_string_serializer(integer_size):
7 minimum = -(2 ** (integer_size - 1))
8 maximum = 2 ** (integer_size - 1) - 1
10 def serializer(integer):
11 assert minimum <= integer and integer <= maximum
12 return '{}i{}'.format(integer, integer_size)
16 def _serialize_float(f):
17 return '{}f'.format(f)
19 def _serialize_double(d):
20 return '{}d'.format(d)
22 def _serialize_binary(b):
23 return '"{}"b'.format(binascii.hexlify(b).decode('ascii'))
25 def _utf_encoding_to_serializer(utf_encoding):
27 return '"{}"{}'.format(s, utf_encoding)
31 def _string_serialize_list(l):
32 return '[{}]'.format(', '.join(map(serialize, l)))
34 def _string_serialize_dictionary(d):
35 def serialize_kvp(kvp):
36 return serialize(kvp[0]) + ': ' + serialize(kvp[1])
37 return '{ ' + ', '.join(map(serialize_kvp, d.items())) + ' }'
39 _STRING_SERIALIZERS = {
40 tags.VOID: lambda o: 'null',
41 tags.TRUE: lambda o: 'true',
42 tags.FALSE: lambda o: 'false',
43 tags.INT8: _integer_size_to_string_serializer(8),
44 tags.INT16: _integer_size_to_string_serializer(16),
45 tags.INT32: _integer_size_to_string_serializer(32),
46 tags.INT64: _integer_size_to_string_serializer(64),
47 tags.FLOAT: _serialize_float,
48 tags.DOUBLE: _serialize_double,
49 tags.BINARY: _serialize_binary,
50 tags.UTF8: _utf_encoding_to_serializer('utf8'),
51 tags.UTF16: _utf_encoding_to_serializer('utf16'),
52 tags.UTF32: _utf_encoding_to_serializer('utf32'),
53 tags.LIST: _string_serialize_list,
54 tags.DICTIONARY: _string_serialize_dictionary,
60 return _STRING_SERIALIZERS[o.tag](o.value)
62 def _make_constant_parser(constant, value):
64 if s.startswith(constant):
65 result = _shared.ParseResult(
68 remaining = s[len(constant):],
72 return _shared._FAILED_PARSE_RESULT
76 def _make_integer_parser(width):
77 matcher = re.compile(r'(-?\d+)i' + str(width))
80 match = matcher.match(s)
83 return _shared.ParseResult(
85 value = int(match.group(1)),
86 remaining = s[match.end():],
89 return _shared._FAILED_PARSE_RESULT
94 _make_constant_parser('null', None),
95 _make_constant_parser('true', True),
96 _make_constant_parser('false', False),
97 _make_integer_parser(8),
98 _make_integer_parser(16),
99 _make_integer_parser(32),
100 _make_integer_parser(64),
103 def _object_parser(source):
104 for parser in _PARSERS:
105 result = parser(source)
110 return _shared._FAILED_PARSE_RESULT
112 def _parse(parser, source):
113 result = parser(source)
116 if result.remaining.strip() == '':
119 raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining))
121 raise Exception('Unable to parse: "{}"'.format(source))
124 return _parse(_object_parser, s)