summaryrefslogtreecommitdiff
path: root/lang
diff options
context:
space:
mode:
authorDon Anderson <dda@ddanderson.com>2015-06-30 22:07:51 -0400
committerDon Anderson <dda@ddanderson.com>2015-06-30 22:07:51 -0400
commit3582893d8b28d1ce01b79ebdbc7e960ffca841ee (patch)
tree448be5fc3375194fe9006d327e1cc7afedff3321 /lang
parent8046020042484ecf9d383a4cf0a3c6002deba9a1 (diff)
downloadmongo-3582893d8b28d1ce01b79ebdbc7e960ffca841ee.tar.gz
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.
Diffstat (limited to 'lang')
-rw-r--r--lang/python/wiredtiger/intpacking.py5
-rw-r--r--lang/python/wiredtiger/packing.py23
2 files changed, 28 insertions, 0 deletions
diff --git a/lang/python/wiredtiger/intpacking.py b/lang/python/wiredtiger/intpacking.py
index 239bc84069d..fe2e93f3dca 100644
--- a/lang/python/wiredtiger/intpacking.py
+++ b/lang/python/wiredtiger/intpacking.py
@@ -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':
diff --git a/lang/python/wiredtiger/packing.py b/lang/python/wiredtiger/packing.py
index 103c0471724..b6f474face8 100644
--- a/lang/python/wiredtiger/packing.py
+++ b/lang/python/wiredtiger/packing.py
@@ -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)