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