326
326
# *dst_size = out - dst_buf;
327
327
assert (out - dst_buf) == PyString_GET_SIZE(result)
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
340
while c_val >= 0x80 and count < 8:
341
c_bytes[count] = <unsigned char>((c_val | 0x80) & 0xFF)
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)
348
return PyString_FromStringAndSize(<char *>c_bytes, count)
351
def decode_base128_int(bytes):
352
"""Decode an integer from a 7-bit lsb encoding."""
355
cdef unsigned int uval
357
cdef Py_ssize_t num_low_bytes
358
cdef unsigned char *c_bytes
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
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
378
uval = <unsigned int> val