Add serialization/deserialization for binary
authorDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 2 Oct 2016 19:48:40 +0000 (15:48 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Sun, 2 Oct 2016 19:48:40 +0000 (15:48 -0400)
serial/serial/text.py
serial/test.py

index cf2bedc..7a09f96 100644 (file)
@@ -1,3 +1,4 @@
+import binascii
 import re
 
 from . import tags
@@ -24,6 +25,9 @@ def _make_signed_integer_serializer(bit_length):
     lower_bound = -upper_bound
     return _make_integer_serializer(lower_bound, upper_bound, 'i{}'.format(bit_length))
 
+def _serialize_binary(to):
+    return 'bin"{}"'.format(binascii.hexlify(to.instance).decode('ascii'))
+
 _SERIALIZERS = {
     tags.NULL: _make_literal_serializer(None, 'null'),
     tags.TRUE: _make_literal_serializer(True, 'true'),
@@ -36,6 +40,7 @@ _SERIALIZERS = {
     tags.INT16: _make_signed_integer_serializer(16),
     tags.INT32: _make_signed_integer_serializer(32),
     tags.INT64: _make_signed_integer_serializer(64),
+    tags.BINARY: _serialize_binary,
 }
 
 def serialize(to):
@@ -84,6 +89,21 @@ def _make_signed_int_deserializer(tag, bit_length):
 
     return _make_regex_deserializer(tag, _decoder, r'(-?\d+)' + 'i{}'.format(bit_length))
 
+_BINARY_MATCHER = re.compile(r'bin"([\da-f]*)"').match
+
+def _deserialize_binary(s):
+    match = _BINARY_MATCHER(s)
+
+    if match is None:
+        return False, None, None
+
+    result = tags.TaggedObject(
+        tag = tags.BINARY,
+        instance = binascii.unhexlify(match.group(1)),
+    )
+
+    return True, result, s[match.end():]
+
 _DESERIALIZERS = [
     _make_literal_deserializer(tags.NULL, None, 'null'),
     _make_literal_deserializer(tags.TRUE, True, 'true'),
@@ -96,6 +116,7 @@ _DESERIALIZERS = [
     _make_signed_int_deserializer(tags.INT16, 16),
     _make_signed_int_deserializer(tags.INT32, 32),
     _make_signed_int_deserializer(tags.INT64, 64),
+    _deserialize_binary,
 ]
 
 def deserialize(s):
index 35bb800..ffa9f91 100644 (file)
@@ -72,6 +72,7 @@ EXAMPLE_TEXT_REPRESENTATIONS = [
     (tags.TaggedObject(tags.INT16, -2), '-2i16'),
     (tags.TaggedObject(tags.INT32, -2), '-2i32'),
     (tags.TaggedObject(tags.INT64, -2), '-2i64'),
+    (tags.TaggedObject(tags.BINARY, b'\x42\xde\xad\xbe\xef'), 'bin"42deadbeef"'),
 ]
 
 class TextSerializeTests(unittest.TestCase):