6 def _make_literal_serializer(expected_value, literal):
8 assert to.instance is expected_value
13 def _make_integer_serializer(lower_bound, upper_bound, suffix):
15 assert lower_bound <= to.instance and to.instance < upper_bound
16 return '{}{}'.format(to.instance, suffix)
20 def _make_unsigned_integer_serializer(bit_length):
21 return _make_integer_serializer(0, 2 << (bit_length - 1), 'u{}'.format(bit_length))
23 def _make_signed_integer_serializer(bit_length):
24 upper_bound = 2 << (bit_length - 2)
25 lower_bound = -upper_bound
26 return _make_integer_serializer(lower_bound, upper_bound, 'i{}'.format(bit_length))
28 def _serialize_binary(to):
29 return 'bin"{}"'.format(binascii.hexlify(to.instance).decode('ascii'))
36 def _escape_character(ch):
37 return _ESCAPES.get(ch, ch)
40 return ''.join(_escape_character(ch) for ch in s)
42 def _make_string_serializer(prefix):
44 assert isinstance(to.instance, str)
45 return '{}"{}"'.format(prefix, _escape(to.instance))
50 tags.NULL: _make_literal_serializer(None, 'null'),
51 tags.TRUE: _make_literal_serializer(True, 'true'),
52 tags.FALSE: _make_literal_serializer(False, 'false'),
53 tags.UINT8: _make_unsigned_integer_serializer(8),
54 tags.UINT16: _make_unsigned_integer_serializer(16),
55 tags.UINT32: _make_unsigned_integer_serializer(32),
56 tags.UINT64: _make_unsigned_integer_serializer(64),
57 tags.INT8: _make_signed_integer_serializer(8),
58 tags.INT16: _make_signed_integer_serializer(16),
59 tags.INT32: _make_signed_integer_serializer(32),
60 tags.INT64: _make_signed_integer_serializer(64),
61 tags.BINARY: _serialize_binary,
62 tags.UTF8: _make_string_serializer('utf8'),
63 tags.UTF16: _make_string_serializer('utf16'),
64 tags.UTF32: _make_string_serializer('utf32'),
68 return _SERIALIZERS[to.tag](to)
70 def _make_literal_deserializer(tag, instance, literal):
72 if s.startswith(literal):
73 return True, tags.TaggedObject(tag = tag, instance = instance), s[len(literal):]
75 return False, None, None
79 def _make_regex_deserializer(tag, decoder, regex):
80 matcher = re.compile(regex).match
86 return False, None, None
88 return True, tags.TaggedObject(tag = tag, instance = decoder(match)), s[match.end():]
92 def _make_unsigned_int_deserializer(tag, bit_length):
93 bound = 2 << (bit_length - 1)
96 result = int(match.group(1))
100 return _make_regex_deserializer(tag, _decoder, r'(\d+)' + 'u{}'.format(bit_length))
102 def _make_signed_int_deserializer(tag, bit_length):
103 upper_bound = 2 << (bit_length - 2)
104 lower_bound = -upper_bound
107 result = int(match.group(1))
108 assert lower_bound <= result and result < upper_bound
111 return _make_regex_deserializer(tag, _decoder, r'(-?\d+)' + 'i{}'.format(bit_length))
113 _BINARY_MATCHER = re.compile(r'bin"([\da-f]*)"').match
115 def _deserialize_binary(s):
116 match = _BINARY_MATCHER(s)
119 return False, None, None
121 result = tags.TaggedObject(
123 instance = binascii.unhexlify(match.group(1)),
126 return True, result, s[match.end():]
128 def _make_string_matcher(prefix):
129 return re.compile(prefix + r'"(([^"]|\\.)*)"').match
131 _UNESCAPE_CHARACTERS = {
136 def _unescape_character(ch):
137 return _UNESCAPE_CHARACTERS[ch]
145 characters.append(_unescape_character(ch))
152 characters.append(ch)
154 return ''.join(characters)
156 def _make_string_deserializer(tag, prefix):
157 matcher = _make_string_matcher(prefix)
163 return False, None, None
165 result = tags.TaggedObject(
167 instance = _unescape(match.group(1)),
170 return True, result, s[match.end():]
175 _make_literal_deserializer(tags.NULL, None, 'null'),
176 _make_literal_deserializer(tags.TRUE, True, 'true'),
177 _make_literal_deserializer(tags.FALSE, False, 'false'),
178 _make_unsigned_int_deserializer(tags.UINT8, 8),
179 _make_unsigned_int_deserializer(tags.UINT16, 16),
180 _make_unsigned_int_deserializer(tags.UINT32, 32),
181 _make_unsigned_int_deserializer(tags.UINT64, 64),
182 _make_signed_int_deserializer(tags.INT8, 8),
183 _make_signed_int_deserializer(tags.INT16, 16),
184 _make_signed_int_deserializer(tags.INT32, 32),
185 _make_signed_int_deserializer(tags.INT64, 64),
187 _make_string_deserializer(tags.UTF8, 'utf8'),
188 _make_string_deserializer(tags.UTF16, 'utf16'),
189 _make_string_deserializer(tags.UTF32, 'utf32'),
193 for deserializer in _DESERIALIZERS:
194 succeeded, result, remaining = deserializer(s)
197 assert remaining == ''