mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
It's Official: for LONG1/LONG4, a "byte count" of 0 is taken as a
shortcut meaning 0L. This allows LONG1 to encode 0L in two bytes total.
This commit is contained in:
parent
757246c189
commit
4b23f2b44b
2 changed files with 25 additions and 9 deletions
|
@ -1291,6 +1291,11 @@ import binascii as _binascii
|
|||
|
||||
def encode_long(x):
|
||||
r"""Encode a long to a two's complement little-endian binary string.
|
||||
Note that 0L is a special case, returning an empty string, to save a
|
||||
byte in the LONG1 pickling context.
|
||||
|
||||
>>> encode_long(0L)
|
||||
''
|
||||
>>> encode_long(255L)
|
||||
'\xff\x00'
|
||||
>>> encode_long(32767L)
|
||||
|
@ -1307,7 +1312,7 @@ def encode_long(x):
|
|||
"""
|
||||
|
||||
if x == 0:
|
||||
return '\x00'
|
||||
return ''
|
||||
if x > 0:
|
||||
ashex = hex(x)
|
||||
assert ashex.startswith("0x")
|
||||
|
@ -1316,7 +1321,7 @@ def encode_long(x):
|
|||
if nibbles & 1:
|
||||
# need an even # of nibbles for unhexlify
|
||||
ashex = "0x0" + ashex[2:]
|
||||
elif ashex[2] >= '8':
|
||||
elif int(ashex[2], 16) >= 8:
|
||||
# "looks negative", so need a byte of sign bits
|
||||
ashex = "0x00" + ashex[2:]
|
||||
else:
|
||||
|
@ -1330,11 +1335,11 @@ def encode_long(x):
|
|||
if nibbles & 1:
|
||||
# need an even # of nibbles for unhexlify
|
||||
nibbles += 1
|
||||
nbytes = nibbles >> 1
|
||||
x += 1L << (nbytes * 8)
|
||||
nbits = nibbles * 4
|
||||
x += 1L << nbits
|
||||
assert x > 0
|
||||
ashex = hex(x)
|
||||
if x >> (nbytes * 8 - 1) == 0:
|
||||
if x >> (nbits - 1) == 0:
|
||||
# "looks positive", so need a byte of sign bits
|
||||
ashex = "0xff" + x[2:]
|
||||
|
||||
|
@ -1348,6 +1353,9 @@ def encode_long(x):
|
|||
|
||||
def decode_long(data):
|
||||
r"""Decode a long from a two's complement little-endian binary string.
|
||||
|
||||
>>> decode_long('')
|
||||
0L
|
||||
>>> decode_long("\xff\x00")
|
||||
255L
|
||||
>>> decode_long("\xff\x7f")
|
||||
|
@ -1362,10 +1370,13 @@ def decode_long(data):
|
|||
127L
|
||||
"""
|
||||
|
||||
nbytes = len(data)
|
||||
if nbytes == 0:
|
||||
return 0L
|
||||
ashex = _binascii.hexlify(data[::-1])
|
||||
n = long(ashex, 16)
|
||||
if data[-1] >= '\x80':
|
||||
n -= 1L << (len(data) * 8)
|
||||
n -= 1L << (nbytes * 8)
|
||||
return n
|
||||
|
||||
# Shorthands
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue