1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import unwrap_spec
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rarithmetic import ovfcheck
from pypy.module.binascii.interp_binascii import raise_Error
from pypy.module.binascii.interp_binascii import AsciiBufferUnwrapper
# ____________________________________________________________
def _value2char(value):
if value < 10:
return chr(ord('0') + value)
else:
return chr((ord('a')-10) + value)
_value2char._always_inline_ = True
@unwrap_spec(data='bufferstr')
def hexlify(space, data):
'''Hexadecimal representation of binary data.
This function is also available as "hexlify()".'''
try:
newlength = ovfcheck(len(data) * 2)
except OverflowError:
raise OperationError(space.w_MemoryError, space.w_None)
res = StringBuilder(newlength)
for c in data:
res.append(_value2char(ord(c) >> 4))
res.append(_value2char(ord(c) & 0xf))
return space.newbytes(res.build())
# ____________________________________________________________
def _char2value(space, c):
if c <= '9':
if c >= '0':
return ord(c) - ord('0')
elif c <= 'F':
if c >= 'A':
return ord(c) - (ord('A')-10)
elif c <= 'f':
if c >= 'a':
return ord(c) - (ord('a')-10)
raise_Error(space, 'Non-hexadecimal digit found')
_char2value._always_inline_ = True
@unwrap_spec(hexstr=AsciiBufferUnwrapper)
def unhexlify(space, hexstr):
'''Binary data of hexadecimal representation.
hexstr must contain an even number of hex digits (upper or lower case).
This function is also available as "unhexlify()".'''
if len(hexstr) & 1:
raise_Error(space, 'Odd-length string')
res = StringBuilder(len(hexstr) >> 1)
for i in range(0, len(hexstr), 2):
a = _char2value(space, hexstr[i])
b = _char2value(space, hexstr[i+1])
res.append(chr((a << 4) | b))
return space.newbytes(res.build())
|