mercurial/util.py
changeset 35755 2384523cee4d
parent 35754 fb0be099063f
child 35900 72de5c504833
child 36234 48783333f45c
equal deleted inserted replaced
35754:fb0be099063f 35755:2384523cee4d
  3872     if len(s) < n:
  3872     if len(s) < n:
  3873         raise error.Abort(_("stream ended unexpectedly"
  3873         raise error.Abort(_("stream ended unexpectedly"
  3874                            " (got %d bytes, expected %d)")
  3874                            " (got %d bytes, expected %d)")
  3875                           % (len(s), n))
  3875                           % (len(s), n))
  3876     return s
  3876     return s
       
  3877 
       
  3878 def uvarintencode(value):
       
  3879     """Encode an unsigned integer value to a varint.
       
  3880 
       
  3881     A varint is a variable length integer of 1 or more bytes. Each byte
       
  3882     except the last has the most significant bit set. The lower 7 bits of
       
  3883     each byte store the 2's complement representation, least significant group
       
  3884     first.
       
  3885 
       
  3886     >>> uvarintencode(0)
       
  3887     '\\x00'
       
  3888     >>> uvarintencode(1)
       
  3889     '\\x01'
       
  3890     >>> uvarintencode(127)
       
  3891     '\\x7f'
       
  3892     >>> uvarintencode(1337)
       
  3893     '\\xb9\\n'
       
  3894     >>> uvarintencode(65536)
       
  3895     '\\x80\\x80\\x04'
       
  3896     >>> uvarintencode(-1)
       
  3897     Traceback (most recent call last):
       
  3898         ...
       
  3899     ProgrammingError: negative value for uvarint: -1
       
  3900     """
       
  3901     if value < 0:
       
  3902         raise error.ProgrammingError('negative value for uvarint: %d'
       
  3903                                      % value)
       
  3904     bits = value & 0x7f
       
  3905     value >>= 7
       
  3906     bytes = []
       
  3907     while value:
       
  3908         bytes.append(pycompat.bytechr(0x80 | bits))
       
  3909         bits = value & 0x7f
       
  3910         value >>= 7
       
  3911     bytes.append(pycompat.bytechr(bits))
       
  3912 
       
  3913     return ''.join(bytes)
       
  3914 
       
  3915 def uvarintdecodestream(fh):
       
  3916     """Decode an unsigned variable length integer from a stream.
       
  3917 
       
  3918     The passed argument is anything that has a ``.read(N)`` method.
       
  3919 
       
  3920     >>> try:
       
  3921     ...     from StringIO import StringIO as BytesIO
       
  3922     ... except ImportError:
       
  3923     ...     from io import BytesIO
       
  3924     >>> uvarintdecodestream(BytesIO(b'\\x00'))
       
  3925     0
       
  3926     >>> uvarintdecodestream(BytesIO(b'\\x01'))
       
  3927     1
       
  3928     >>> uvarintdecodestream(BytesIO(b'\\x7f'))
       
  3929     127
       
  3930     >>> uvarintdecodestream(BytesIO(b'\\xb9\\n'))
       
  3931     1337
       
  3932     >>> uvarintdecodestream(BytesIO(b'\\x80\\x80\\x04'))
       
  3933     65536
       
  3934     >>> uvarintdecodestream(BytesIO(b'\\x80'))
       
  3935     Traceback (most recent call last):
       
  3936         ...
       
  3937     Abort: stream ended unexpectedly (got 0 bytes, expected 1)
       
  3938     """
       
  3939     result = 0
       
  3940     shift = 0
       
  3941     while True:
       
  3942         byte = ord(readexactly(fh, 1))
       
  3943         result |= ((byte & 0x7f) << shift)
       
  3944         if not (byte & 0x80):
       
  3945             return result
       
  3946         shift += 7