comparison mercurial/utils/cborutil.py @ 39413:babad5ebaf0a

cborutil: add a buffering decoder The sansiodecoder leaves it up to the callers to feed in data that wasn't fully consumed last time. This commit implements a decoder that performs buffering of leftover chunks from the previous invocation. It otherwise behaves identically to sansiodecoder. Differential Revision: https://phab.mercurial-scm.org/D4434
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 29 Aug 2018 14:29:01 -0700
parents a40d3da89b7d
children 8d858fbf2759
comparison
equal deleted inserted replaced
39412:a40d3da89b7d 39413:babad5ebaf0a
896 896
897 l = list(self._decodedvalues) 897 l = list(self._decodedvalues)
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
904 In addition to regular decode errors, raises CBORDecodeError if the 946 In addition to regular decode errors, raises CBORDecodeError if the
905 entirety of the passed buffer does not fully decode to complete CBOR 947 entirety of the passed buffer does not fully decode to complete CBOR