From 4714e340486e676ed50e8d6e08c5f2129daa4c59 Mon Sep 17 00:00:00 2001 From: David Kerkeslager Date: Thu, 13 Apr 2017 13:30:49 -0400 Subject: [PATCH] Parse floating point and binaries --- don/string.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ test_don.py | 18 ++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/don/string.py b/don/string.py index c7d810b..ee925f6 100644 --- a/don/string.py +++ b/don/string.py @@ -80,6 +80,7 @@ def _make_integer_parser(width): match = matcher.match(s) if match: + # TODO Validate that the integer is in range return _shared.ParseResult( success = True, value = int(match.group(1)), @@ -90,6 +91,52 @@ def _make_integer_parser(width): 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), @@ -98,6 +145,9 @@ _PARSERS = [ _make_integer_parser(16), _make_integer_parser(32), _make_integer_parser(64), + _binary32_parser, + _binary64_parser, + _binary_parser, ] def _object_parser(source): diff --git a/test_don.py b/test_don.py index 46034ec..1b68059 100644 --- a/test_don.py +++ b/test_don.py @@ -208,4 +208,22 @@ class TestStringDeserialize(unittest.TestCase): 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() -- 2.20.1