/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/_groupcompress_pyx.pyx

  • Committer: John Arbash Meinel
  • Date: 2009-03-27 21:29:32 UTC
  • mto: (3735.39.2 clean)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090327212932-psi820dh5qc5zthq
Implement (de|en)code_base128_int in pyrex.
Apply the tests to both implementations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
326
326
    # *dst_size = out - dst_buf;
327
327
    assert (out - dst_buf) == PyString_GET_SIZE(result)
328
328
    return result
 
329
 
 
330
 
 
331
def encode_base128_int(val):
 
332
    """Convert an integer into a 7-bit lsb encoding."""
 
333
    cdef unsigned int c_val
 
334
    cdef Py_ssize_t count
 
335
    cdef unsigned int num_bytes
 
336
    cdef unsigned char c_bytes[8] # max size for 32-bit int is 5 bytes
 
337
 
 
338
    c_val = val
 
339
    count = 0
 
340
    while c_val >= 0x80 and count < 8:
 
341
        c_bytes[count] = <unsigned char>((c_val | 0x80) & 0xFF)
 
342
        c_val = c_val >> 7
 
343
        count = count + 1
 
344
    if count >= 8 or c_val >= 0x80:
 
345
        raise ValueError('encode_base128_int overflowed the buffer')
 
346
    c_bytes[count] = <unsigned char>(c_val & 0xFF)
 
347
    count = count + 1
 
348
    return PyString_FromStringAndSize(<char *>c_bytes, count)
 
349
 
 
350
 
 
351
def decode_base128_int(bytes):
 
352
    """Decode an integer from a 7-bit lsb encoding."""
 
353
    cdef int offset
 
354
    cdef int val
 
355
    cdef unsigned int uval
 
356
    cdef int shift
 
357
    cdef Py_ssize_t num_low_bytes
 
358
    cdef unsigned char *c_bytes
 
359
 
 
360
    offset = 0
 
361
    val = 0
 
362
    shift = 0
 
363
    if not PyString_CheckExact(bytes):
 
364
        raise TypeError('bytes is not a string')
 
365
    c_bytes = <unsigned char*>PyString_AS_STRING(bytes)
 
366
    # We take off 1, because we have to be able to decode the non-expanded byte
 
367
    num_low_bytes = PyString_GET_SIZE(bytes) - 1
 
368
    while (c_bytes[offset] & 0x80) and offset < num_low_bytes:
 
369
        val |= (c_bytes[offset] & 0x7F) << shift
 
370
        shift = shift + 7
 
371
        offset = offset + 1
 
372
    if c_bytes[offset] & 0x80:
 
373
        raise ValueError('Data not properly formatted, we ran out of'
 
374
                         ' bytes before 0x80 stopped being set.')
 
375
    val |= c_bytes[offset] << shift
 
376
    offset = offset + 1
 
377
    if val < 0:
 
378
        uval = <unsigned int> val
 
379
        return uval, offset
 
380
    return val, offset
 
381
 
 
382