##// END OF EJS Templates
cborutil: add a buffering decoder...
Gregory Szorc -
r39450:babad5eb default
parent child Browse files
Show More
@@ -898,6 +898,48 b' class sansiodecoder(object):'
898 self._decodedvalues = []
898 self._decodedvalues = []
899 return l
899 return l
900
900
901 class bufferingdecoder(object):
902 """A CBOR decoder that buffers undecoded input.
903
904 This is a glorified wrapper around ``sansiodecoder`` that adds a buffering
905 layer. All input that isn't consumed by ``sansiodecoder`` will be buffered
906 and concatenated with any new input that arrives later.
907
908 TODO consider adding limits as to the maximum amount of data that can
909 be buffered.
910 """
911 def __init__(self):
912 self._decoder = sansiodecoder()
913 self._leftover = None
914
915 def decode(self, b):
916 """Attempt to decode bytes to CBOR values.
917
918 Returns a tuple with the following fields:
919
920 * Bool indicating whether new values are available for retrieval.
921 * Integer number of bytes decoded from the new input.
922 * Integer number of bytes wanted to decode the next value.
923 """
924
925 if self._leftover:
926 oldlen = len(self._leftover)
927 b = self._leftover + b
928 self._leftover = None
929 else:
930 b = b
931 oldlen = 0
932
933 available, readcount, wanted = self._decoder.decode(b)
934
935 if readcount < len(b):
936 self._leftover = b[readcount:]
937
938 return available, readcount - oldlen, wanted
939
940 def getavailable(self):
941 return self._decoder.getavailable()
942
901 def decodeall(b):
943 def decodeall(b):
902 """Decode all CBOR items present in an iterable of bytes.
944 """Decode all CBOR items present in an iterable of bytes.
903
945
@@ -941,6 +941,30 b' class SansIODecoderTests(TestCase):'
941 decoder = cborutil.sansiodecoder()
941 decoder = cborutil.sansiodecoder()
942 self.assertEqual(decoder.decode(b''), (False, 0, 0))
942 self.assertEqual(decoder.decode(b''), (False, 0, 0))
943
943
944 class BufferingDecoderTests(TestCase):
945 def testsimple(self):
946 source = [
947 b'foobar',
948 b'x' * 128,
949 {b'foo': b'bar'},
950 True,
951 False,
952 None,
953 [None for i in range(128)],
954 ]
955
956 encoded = b''.join(cborutil.streamencode(source))
957
958 for step in range(1, 32):
959 decoder = cborutil.bufferingdecoder()
960 start = 0
961
962 while start < len(encoded):
963 decoder.decode(encoded[start:start + step])
964 start += step
965
966 self.assertEqual(decoder.getavailable(), [source])
967
944 class DecodeallTests(TestCase):
968 class DecodeallTests(TestCase):
945 def testemptyinput(self):
969 def testemptyinput(self):
946 self.assertEqual(cborutil.decodeall(b''), [])
970 self.assertEqual(cborutil.decodeall(b''), [])
General Comments 0
You need to be logged in to leave comments. Login now