Skip to content

Commit 7717fed

Browse files
author
Mingshen Sun
committed
pypy/module/binascii: bring back binascii since we have resolved all dependencies
1 parent 69b88e8 commit 7717fed

10 files changed

+1142
-1
lines changed

pypy/config/pypyoption.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"select", "_lsprof", "signal", "_rawffi", "termios",
3535
"zlib", "struct", "_md5", "_sha",
3636
"cStringIO", "thread", "itertools", "cpyext", "array",
37-
"_multiprocessing", '_warnings', "_collections",
37+
"binascii", "_multiprocessing", '_warnings', "_collections",
3838
"_multibytecodec", "micronumpy", "_continuation", "_cffi_backend",
3939
"_csv", "_cppyy", "_pypyjson", "_jitlog"
4040
])

pypy/module/binascii/__init__.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
"""
3+
Mixed-module definition for the binascii module.
4+
Note that there is also a pure Python implementation in lib_pypy/binascii.py;
5+
the pypy/module/binascii/ version takes precedence if it is enabled.
6+
"""
7+
8+
from pypy.interpreter.mixedmodule import MixedModule
9+
10+
11+
class Module(MixedModule):
12+
"""binascii - Conversion between binary data and ASCII"""
13+
14+
appleveldefs = {
15+
}
16+
17+
interpleveldefs = {
18+
'a2b_uu': 'interp_uu.a2b_uu',
19+
'b2a_uu': 'interp_uu.b2a_uu',
20+
'a2b_base64': 'interp_base64.a2b_base64',
21+
'b2a_base64': 'interp_base64.b2a_base64',
22+
'a2b_qp': 'interp_qp.a2b_qp',
23+
'b2a_qp': 'interp_qp.b2a_qp',
24+
'a2b_hqx': 'interp_hqx.a2b_hqx',
25+
'b2a_hqx': 'interp_hqx.b2a_hqx',
26+
'rledecode_hqx': 'interp_hqx.rledecode_hqx',
27+
'rlecode_hqx': 'interp_hqx.rlecode_hqx',
28+
'crc_hqx': 'interp_hqx.crc_hqx',
29+
'crc32': 'interp_crc32.crc32',
30+
'b2a_hex': 'interp_hexlify.hexlify',
31+
'hexlify': 'interp_hexlify.hexlify',
32+
'a2b_hex': 'interp_hexlify.unhexlify',
33+
'unhexlify': 'interp_hexlify.unhexlify',
34+
'Error' : 'space.fromcache(interp_binascii.Cache).w_error',
35+
'Incomplete': 'space.fromcache(interp_binascii.Cache).w_incomplete',
36+
}

pypy/module/binascii/interp_base64.py

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from pypy.interpreter.error import OperationError
2+
from pypy.interpreter.gateway import unwrap_spec
3+
from rpython.rlib.rstring import StringBuilder
4+
from pypy.module.binascii.interp_binascii import raise_Error
5+
from rpython.rlib.rarithmetic import ovfcheck
6+
7+
# ____________________________________________________________
8+
9+
PAD = '='
10+
11+
table_a2b_base64 = [
12+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
13+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
14+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
15+
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, # Note PAD->-1 here
16+
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
17+
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
18+
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
19+
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1,
20+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
21+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
22+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
23+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
24+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
25+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
26+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
27+
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
28+
]
29+
def _transform(n):
30+
if n == -1:
31+
return '\xff'
32+
else:
33+
return chr(n)
34+
table_a2b_base64 = ''.join(map(_transform, table_a2b_base64))
35+
assert len(table_a2b_base64) == 256
36+
37+
38+
@unwrap_spec(ascii='bufferstr')
39+
def a2b_base64(space, ascii):
40+
"Decode a line of base64 data."
41+
42+
res = StringBuilder((len(ascii) // 4) * 3) # maximum estimate
43+
quad_pos = 0
44+
leftchar = 0
45+
leftbits = 0
46+
last_char_was_a_pad = False
47+
48+
for c in ascii:
49+
if c == PAD:
50+
if quad_pos > 2 or (quad_pos == 2 and last_char_was_a_pad):
51+
break # stop on 'xxx=' or on 'xx=='
52+
last_char_was_a_pad = True
53+
else:
54+
n = ord(table_a2b_base64[ord(c)])
55+
if n == 0xff:
56+
continue # ignore strange characters
57+
#
58+
# Shift it in on the low end, and see if there's
59+
# a byte ready for output.
60+
quad_pos = (quad_pos + 1) & 3
61+
leftchar = (leftchar << 6) | n
62+
leftbits += 6
63+
#
64+
if leftbits >= 8:
65+
leftbits -= 8
66+
res.append(chr(leftchar >> leftbits))
67+
leftchar &= ((1 << leftbits) - 1)
68+
#
69+
last_char_was_a_pad = False
70+
else:
71+
if leftbits != 0:
72+
raise_Error(space, "Incorrect padding")
73+
74+
return space.newbytes(res.build())
75+
76+
# ____________________________________________________________
77+
78+
table_b2a_base64 = (
79+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
80+
81+
@unwrap_spec(bin='bufferstr')
82+
def b2a_base64(space, bin):
83+
"Base64-code line of data."
84+
85+
newlength = (len(bin) + 2) // 3
86+
try:
87+
newlength = ovfcheck(newlength * 4)
88+
except OverflowError:
89+
raise OperationError(space.w_MemoryError, space.w_None)
90+
newlength += 1
91+
res = StringBuilder(newlength)
92+
93+
leftchar = 0
94+
leftbits = 0
95+
for c in bin:
96+
# Shift into our buffer, and output any 6bits ready
97+
leftchar = (leftchar << 8) | ord(c)
98+
leftbits += 8
99+
res.append(table_b2a_base64[(leftchar >> (leftbits-6)) & 0x3f])
100+
leftbits -= 6
101+
if leftbits >= 6:
102+
res.append(table_b2a_base64[(leftchar >> (leftbits-6)) & 0x3f])
103+
leftbits -= 6
104+
#
105+
if leftbits == 2:
106+
res.append(table_b2a_base64[(leftchar & 3) << 4])
107+
res.append(PAD)
108+
res.append(PAD)
109+
elif leftbits == 4:
110+
res.append(table_b2a_base64[(leftchar & 0xf) << 2])
111+
res.append(PAD)
112+
res.append('\n')
113+
return space.newbytes(res.build())
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from pypy.interpreter.error import OperationError
2+
3+
class Cache:
4+
def __init__(self, space):
5+
self.w_error = space.new_exception_class("binascii.Error")
6+
self.w_incomplete = space.new_exception_class("binascii.Incomplete")
7+
8+
def raise_Error(space, msg):
9+
w_error = space.fromcache(Cache).w_error
10+
raise OperationError(w_error, space.newtext(msg))
11+
12+
def raise_Incomplete(space, msg):
13+
w_error = space.fromcache(Cache).w_incomplete
14+
raise OperationError(w_error, space.newtext(msg))

pypy/module/binascii/interp_crc32.py

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

0 commit comments

Comments
 (0)