Show More
@@ -913,7 +913,8 b' class bufferingdecoder(object):' | |||||
913 | """ |
|
913 | """ | |
914 | def __init__(self): |
|
914 | def __init__(self): | |
915 | self._decoder = sansiodecoder() |
|
915 | self._decoder = sansiodecoder() | |
916 |
self._ |
|
916 | self._chunks = [] | |
|
917 | self._wanted = 0 | |||
917 |
|
918 | |||
918 | def decode(self, b): |
|
919 | def decode(self, b): | |
919 | """Attempt to decode bytes to CBOR values. |
|
920 | """Attempt to decode bytes to CBOR values. | |
@@ -924,19 +925,40 b' class bufferingdecoder(object):' | |||||
924 | * Integer number of bytes decoded from the new input. |
|
925 | * Integer number of bytes decoded from the new input. | |
925 | * Integer number of bytes wanted to decode the next value. |
|
926 | * Integer number of bytes wanted to decode the next value. | |
926 | """ |
|
927 | """ | |
|
928 | # Our strategy for buffering is to aggregate the incoming chunks in a | |||
|
929 | # list until we've received enough data to decode the next item. | |||
|
930 | # This is slightly more complicated than using an ``io.BytesIO`` | |||
|
931 | # or continuously concatenating incoming data. However, because it | |||
|
932 | # isn't constantly reallocating backing memory for a growing buffer, | |||
|
933 | # it prevents excessive memory thrashing and is significantly faster, | |||
|
934 | # especially in cases where the percentage of input chunks that don't | |||
|
935 | # decode into a full item is high. | |||
927 |
|
936 | |||
928 |
if self._ |
|
937 | if self._chunks: | |
929 | oldlen = len(self._leftover) |
|
938 | # A previous call said we needed N bytes to decode the next item. | |
930 | b = self._leftover + b |
|
939 | # But this call doesn't provide enough data. We buffer the incoming | |
931 | self._leftover = None |
|
940 | # chunk without attempting to decode. | |
|
941 | if len(b) < self._wanted: | |||
|
942 | self._chunks.append(b) | |||
|
943 | self._wanted -= len(b) | |||
|
944 | return False, 0, self._wanted | |||
|
945 | ||||
|
946 | # Else we may have enough data to decode the next item. Aggregate | |||
|
947 | # old data with new and reset the buffer. | |||
|
948 | newlen = len(b) | |||
|
949 | self._chunks.append(b) | |||
|
950 | b = b''.join(self._chunks) | |||
|
951 | self._chunks = [] | |||
|
952 | oldlen = len(b) - newlen | |||
|
953 | ||||
932 | else: |
|
954 | else: | |
933 | b = b |
|
|||
934 | oldlen = 0 |
|
955 | oldlen = 0 | |
935 |
|
956 | |||
936 | available, readcount, wanted = self._decoder.decode(b) |
|
957 | available, readcount, wanted = self._decoder.decode(b) | |
|
958 | self._wanted = wanted | |||
937 |
|
959 | |||
938 | if readcount < len(b): |
|
960 | if readcount < len(b): | |
939 |
self._ |
|
961 | self._chunks.append(b[readcount:]) | |
940 |
|
962 | |||
941 | return available, readcount - oldlen, wanted |
|
963 | return available, readcount - oldlen, wanted | |
942 |
|
964 |
General Comments 0
You need to be logged in to leave comments.
Login now