match = matcher.match(s)
if match:
+ # TODO Validate that the integer is in range
return _shared.ParseResult(
success = True,
value = int(match.group(1)),
return parser
+_BINARY32_MATCHER = re.compile(r'(-?\d+\.\d+)f')
+_BINARY64_MATCHER = re.compile(r'(-?\d+\.\d+)d')
+
+def _binary32_parser(s):
+ match = _BINARY32_MATCHER.match(s)
+
+ if match:
+ # TODO Validate that the double is in range
+ return _shared.ParseResult(
+ success = True,
+ value = float(match.group(1)),
+ remaining = s[match.end():],
+ )
+
+ return _shared._FAILED_PARSE_RESULT
+
+def _binary64_parser(s):
+ match = _BINARY64_MATCHER.match(s)
+
+ if match:
+ # TODO Validate that the double is in range
+ return _shared.ParseResult(
+ success = True,
+ value = float(match.group(1)),
+ remaining = s[match.end():],
+ )
+
+ return _shared._FAILED_PARSE_RESULT
+
+_BINARY_MATCHER = re.compile(r'"([\da-f]*)"b')
+
+def _binary_parser(s):
+ match = _BINARY_MATCHER.match(s)
+
+ if match:
+ # TODO Validate that the double is in range
+ return _shared.ParseResult(
+ success = True,
+ value = binascii.unhexlify(match.group(1)),
+ remaining = s[match.end():],
+ )
+
+ return _shared._FAILED_PARSE_RESULT
+
+
+
_PARSERS = [
_make_constant_parser('null', None),
_make_constant_parser('true', True),
_make_integer_parser(16),
_make_integer_parser(32),
_make_integer_parser(64),
+ _binary32_parser,
+ _binary64_parser,
+ _binary_parser,
]
def _object_parser(source):
self.assertEqual(10, string.deserialize('10i64'))
self.assertEqual(-1, string.deserialize('-1i64'))
+ def test_deserializes_float(self):
+ self.assertEqual(1.0, string.deserialize('1.0f'))
+
+ def test_deserializes_double(self):
+ self.assertEqual(1.0, string.deserialize('1.0d'))
+
+ def test_serializes_binary(self):
+ self.assertEqual(
+ b'\xde\xad\xbe\xef',
+ string.deserialize(b'\x30\x00\x00\x00\x04\xde\xad\xbe\xef'),
+ )
+
+ def test_serializes_binary(self):
+ self.assertEqual(
+ b'\xde\xad\xbe\xef',
+ string.deserialize('"deadbeef"b'),
+ )
+
unittest.main()