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:
Don Anderson
2015-06-30 22:07:51 -04:00
parent 8046020042
commit 3582893d8b
2 changed files with 28 additions and 0 deletions

View File

@@ -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':

View File

@@ -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)