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 |