comparison mercurial/utils/cborutil.py @ 39439:a40d3da89b7d

cborutil: remove readindefinitebytestringtoiter() This was implemented as part of implementing streaming encoding. It was never used outside of tests. Now that we have a full CBOR decoder, it can be used for incremental decoding of indefinite-length byte strings. This also removes the last use of the vendored cbor2 package from this module. Differential Revision: https://phab.mercurial-scm.org/D4433
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 31 Aug 2018 15:54:17 -0700
parents aeb551a3bb8a
children babad5ebaf0a
comparison
equal deleted inserted replaced
39438:aeb551a3bb8a 39439:a40d3da89b7d
7 7
8 from __future__ import absolute_import 8 from __future__ import absolute_import
9 9
10 import struct 10 import struct
11 import sys 11 import sys
12
13 from ..thirdparty.cbor.cbor2 import (
14 decoder as decodermod,
15 )
16 12
17 # Very short very of RFC 7049... 13 # Very short very of RFC 7049...
18 # 14 #
19 # Each item begins with a byte. The 3 high bits of that byte denote the 15 # Each item begins with a byte. The 3 high bits of that byte denote the
20 # "major type." The lower 5 bits denote the "subtype." Each major type 16 # "major type." The lower 5 bits denote the "subtype." Each major type
216 212
217 if not fn: 213 if not fn:
218 raise ValueError('do not know how to encode %s' % type(v)) 214 raise ValueError('do not know how to encode %s' % type(v))
219 215
220 return fn(v) 216 return fn(v)
221
222 def readindefinitebytestringtoiter(fh, expectheader=True):
223 """Read an indefinite bytestring to a generator.
224
225 Receives an object with a ``read(X)`` method to read N bytes.
226
227 If ``expectheader`` is True, it is expected that the first byte read
228 will represent an indefinite length bytestring. Otherwise, we
229 expect the first byte to be part of the first bytestring chunk.
230 """
231 read = fh.read
232 decodeuint = decodermod.decode_uint
233 byteasinteger = decodermod.byte_as_integer
234
235 if expectheader:
236 initial = decodermod.byte_as_integer(read(1))
237
238 majortype = initial >> 5
239 subtype = initial & SUBTYPE_MASK
240
241 if majortype != MAJOR_TYPE_BYTESTRING:
242 raise decodermod.CBORDecodeError(
243 'expected major type %d; got %d' % (MAJOR_TYPE_BYTESTRING,
244 majortype))
245
246 if subtype != SUBTYPE_INDEFINITE:
247 raise decodermod.CBORDecodeError(
248 'expected indefinite subtype; got %d' % subtype)
249
250 # The indefinite bytestring is composed of chunks of normal bytestrings.
251 # Read chunks until we hit a BREAK byte.
252
253 while True:
254 # We need to sniff for the BREAK byte.
255 initial = byteasinteger(read(1))
256
257 if initial == BREAK_INT:
258 break
259
260 length = decodeuint(fh, initial & SUBTYPE_MASK)
261 chunk = read(length)
262
263 if len(chunk) != length:
264 raise decodermod.CBORDecodeError(
265 'failed to read bytestring chunk: got %d bytes; expected %d' % (
266 len(chunk), length))
267
268 yield chunk
269 217
270 class CBORDecodeError(Exception): 218 class CBORDecodeError(Exception):
271 """Represents an error decoding CBOR.""" 219 """Represents an error decoding CBOR."""
272 220
273 if sys.version_info.major >= 3: 221 if sys.version_info.major >= 3: