mercurial/utils/cborutil.py
changeset 39412 a40d3da89b7d
parent 39411 aeb551a3bb8a
child 39413 babad5ebaf0a
equal deleted inserted replaced
39411:aeb551a3bb8a 39412: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: