Rev 3923: Implement (de|en)code_base128_int in pyrex. in http://bzr.arbash-meinel.com/branches/bzr/brisbane/vilajam
John Arbash Meinel
john at arbash-meinel.com
Fri Mar 27 21:29:55 GMT 2009
At http://bzr.arbash-meinel.com/branches/bzr/brisbane/vilajam
------------------------------------------------------------
revno: 3923
revision-id: john at arbash-meinel.com-20090327212932-psi820dh5qc5zthq
parent: john at arbash-meinel.com-20090327205036-a287nm5vyzstxlup
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: vilajam
timestamp: Fri 2009-03-27 16:29:32 -0500
message:
Implement (de|en)code_base128_int in pyrex.
Apply the tests to both implementations.
-------------- next part --------------
=== modified file 'bzrlib/_groupcompress_pyx.pyx'
--- a/bzrlib/_groupcompress_pyx.pyx 2009-03-27 19:30:46 +0000
+++ b/bzrlib/_groupcompress_pyx.pyx 2009-03-27 21:29:32 +0000
@@ -326,3 +326,57 @@
# *dst_size = out - dst_buf;
assert (out - dst_buf) == PyString_GET_SIZE(result)
return result
+
+
+def encode_base128_int(val):
+ """Convert an integer into a 7-bit lsb encoding."""
+ cdef unsigned int c_val
+ cdef Py_ssize_t count
+ cdef unsigned int num_bytes
+ cdef unsigned char c_bytes[8] # max size for 32-bit int is 5 bytes
+
+ c_val = val
+ count = 0
+ while c_val >= 0x80 and count < 8:
+ c_bytes[count] = <unsigned char>((c_val | 0x80) & 0xFF)
+ c_val = c_val >> 7
+ count = count + 1
+ if count >= 8 or c_val >= 0x80:
+ raise ValueError('encode_base128_int overflowed the buffer')
+ c_bytes[count] = <unsigned char>(c_val & 0xFF)
+ count = count + 1
+ return PyString_FromStringAndSize(<char *>c_bytes, count)
+
+
+def decode_base128_int(bytes):
+ """Decode an integer from a 7-bit lsb encoding."""
+ cdef int offset
+ cdef int val
+ cdef unsigned int uval
+ cdef int shift
+ cdef Py_ssize_t num_low_bytes
+ cdef unsigned char *c_bytes
+
+ offset = 0
+ val = 0
+ shift = 0
+ if not PyString_CheckExact(bytes):
+ raise TypeError('bytes is not a string')
+ c_bytes = <unsigned char*>PyString_AS_STRING(bytes)
+ # We take off 1, because we have to be able to decode the non-expanded byte
+ num_low_bytes = PyString_GET_SIZE(bytes) - 1
+ while (c_bytes[offset] & 0x80) and offset < num_low_bytes:
+ val |= (c_bytes[offset] & 0x7F) << shift
+ shift = shift + 7
+ offset = offset + 1
+ if c_bytes[offset] & 0x80:
+ raise ValueError('Data not properly formatted, we ran out of'
+ ' bytes before 0x80 stopped being set.')
+ val |= c_bytes[offset] << shift
+ offset = offset + 1
+ if val < 0:
+ uval = <unsigned int> val
+ return uval, offset
+ return val, offset
+
+
=== modified file 'bzrlib/groupcompress.py'
--- a/bzrlib/groupcompress.py 2009-03-27 20:27:05 +0000
+++ b/bzrlib/groupcompress.py 2009-03-27 21:29:32 +0000
@@ -1790,6 +1790,8 @@
from bzrlib._groupcompress_pyx import (
apply_delta,
DeltaIndex,
+ encode_base128_int,
+ decode_base128_int,
)
GroupCompressor = PyrexGroupCompressor
except ImportError:
=== modified file 'bzrlib/tests/test__groupcompress.py'
--- a/bzrlib/tests/test__groupcompress.py 2009-03-27 20:19:44 +0000
+++ b/bzrlib/tests/test__groupcompress.py 2009-03-27 21:29:32 +0000
@@ -45,7 +45,8 @@
'apply_delta': _groupcompress_py.apply_delta}),
])
to_adapt, result = tests.split_suite_by_condition(
- standard_tests, tests.condition_isinstance(TestMakeAndApplyDelta))
+ standard_tests, tests.condition_isinstance((TestMakeAndApplyDelta,
+ TestBase128Int)))
result = tests.multiply_tests(to_adapt, scenarios, result)
to_adapt, result = tests.split_suite_by_condition(result,
tests.condition_isinstance(TestMakeAndApplyCompatible))
@@ -203,8 +204,8 @@
class TestMakeAndApplyCompatible(tests.TestCase):
- make_delta = None # filled in by multiply_tests
- apply_delta = None # filled in by multiply_tests
+ make_delta = None # Set by load_tests
+ apply_delta = None # Set by load_tests
def assertMakeAndApply(self, source, target):
"""Assert that generating a delta and applying gives success."""
@@ -416,12 +417,14 @@
class TestBase128Int(tests.TestCase):
+ _gc_module = None # Set by load_tests
+
def assertEqualEncode(self, bytes, val):
- self.assertEqual(bytes, _groupcompress_py.encode_base128_int(val))
+ self.assertEqual(bytes, self._gc_module.encode_base128_int(val))
def assertEqualDecode(self, val, num_decode, bytes):
self.assertEqual((val, num_decode),
- _groupcompress_py.decode_base128_int(bytes))
+ self._gc_module.decode_base128_int(bytes))
def test_encode(self):
self.assertEqualEncode('\x01', 1)
More information about the bazaar-commits
mailing list