WT-1985. Fixed problems with integer packing in Python:
1) Applied special case from C code for POS_2BYTE_MAX + 1. 2) Handle B/b format chars directly. Up to now these would have been encoded using default int encoding (so values above 63 get errors when encoding.
This commit is contained in:
@@ -89,6 +89,11 @@ def pack_int(x):
|
||||
elif x <= POS_2BYTE_MAX:
|
||||
x -= (POS_1BYTE_MAX + 1)
|
||||
return chr(POS_2BYTE_MARKER | getbits(x, 13, 8)) + chr(getbits(x, 8))
|
||||
elif x == POS_2BYTE_MAX + 1:
|
||||
# This is a special case where we could store the value with
|
||||
# just a single byte, but we append a zero byte so that the
|
||||
# encoding doesn't get shorter for this one value.
|
||||
return chr(POS_MULTI_MARKER | 0x1) + chr(0)
|
||||
else:
|
||||
packed = struct.pack('>Q', x - (POS_2BYTE_MAX + 1))
|
||||
while packed and packed[0] == '\x00':
|
||||
|
||||
@@ -108,6 +108,16 @@ def unpack(fmt, s):
|
||||
size = 1
|
||||
result.append(ord(s[0:1]))
|
||||
s = s[1:]
|
||||
elif f in 'Bb':
|
||||
# byte type
|
||||
if not havesize:
|
||||
size = 1
|
||||
for i in xrange(size):
|
||||
v = ord(s[0:1])
|
||||
if f != 'B':
|
||||
v -= 0x80
|
||||
result.append(v)
|
||||
s = s[1:]
|
||||
else:
|
||||
# integral type
|
||||
if not havesize:
|
||||
@@ -177,6 +187,19 @@ def pack(fmt, *values):
|
||||
if (mask & val) != val:
|
||||
raise ValueError("value out of range for 't' encoding")
|
||||
result += chr(val)
|
||||
elif f in 'Bb':
|
||||
# byte type
|
||||
if not havesize:
|
||||
size = 1
|
||||
for i in xrange(size):
|
||||
if f == 'B':
|
||||
v = val
|
||||
else:
|
||||
# Translate to maintain ordering with the sign bit.
|
||||
v = val + 0x80
|
||||
if v > 255 or v < 0:
|
||||
raise ValueError("value out of range for 'B' encoding")
|
||||
result += chr(v)
|
||||
else:
|
||||
# integral type
|
||||
result += pack_int(val)
|
||||
|
||||
Reference in New Issue
Block a user