xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/encodings/uu_codec.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Python 'uu_codec' Codec - UU content transfer encoding.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerThis codec de/encodes from bytes to bytes.
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard WorkerWritten by Marc-Andre Lemburg ([email protected]). Some details were
6*cda5da8dSAndroid Build Coastguard Workeradapted from uu.py which was written by Lance Ellinghouse and
7*cda5da8dSAndroid Build Coastguard Workermodified by Jack Jansen and Fredrik Lundh.
8*cda5da8dSAndroid Build Coastguard Worker"""
9*cda5da8dSAndroid Build Coastguard Worker
10*cda5da8dSAndroid Build Coastguard Workerimport codecs
11*cda5da8dSAndroid Build Coastguard Workerimport binascii
12*cda5da8dSAndroid Build Coastguard Workerfrom io import BytesIO
13*cda5da8dSAndroid Build Coastguard Worker
14*cda5da8dSAndroid Build Coastguard Worker### Codec APIs
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard Workerdef uu_encode(input, errors='strict', filename='<data>', mode=0o666):
17*cda5da8dSAndroid Build Coastguard Worker    assert errors == 'strict'
18*cda5da8dSAndroid Build Coastguard Worker    infile = BytesIO(input)
19*cda5da8dSAndroid Build Coastguard Worker    outfile = BytesIO()
20*cda5da8dSAndroid Build Coastguard Worker    read = infile.read
21*cda5da8dSAndroid Build Coastguard Worker    write = outfile.write
22*cda5da8dSAndroid Build Coastguard Worker
23*cda5da8dSAndroid Build Coastguard Worker    # Remove newline chars from filename
24*cda5da8dSAndroid Build Coastguard Worker    filename = filename.replace('\n','\\n')
25*cda5da8dSAndroid Build Coastguard Worker    filename = filename.replace('\r','\\r')
26*cda5da8dSAndroid Build Coastguard Worker
27*cda5da8dSAndroid Build Coastguard Worker    # Encode
28*cda5da8dSAndroid Build Coastguard Worker    write(('begin %o %s\n' % (mode & 0o777, filename)).encode('ascii'))
29*cda5da8dSAndroid Build Coastguard Worker    chunk = read(45)
30*cda5da8dSAndroid Build Coastguard Worker    while chunk:
31*cda5da8dSAndroid Build Coastguard Worker        write(binascii.b2a_uu(chunk))
32*cda5da8dSAndroid Build Coastguard Worker        chunk = read(45)
33*cda5da8dSAndroid Build Coastguard Worker    write(b' \nend\n')
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard Worker    return (outfile.getvalue(), len(input))
36*cda5da8dSAndroid Build Coastguard Worker
37*cda5da8dSAndroid Build Coastguard Workerdef uu_decode(input, errors='strict'):
38*cda5da8dSAndroid Build Coastguard Worker    assert errors == 'strict'
39*cda5da8dSAndroid Build Coastguard Worker    infile = BytesIO(input)
40*cda5da8dSAndroid Build Coastguard Worker    outfile = BytesIO()
41*cda5da8dSAndroid Build Coastguard Worker    readline = infile.readline
42*cda5da8dSAndroid Build Coastguard Worker    write = outfile.write
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Worker    # Find start of encoded data
45*cda5da8dSAndroid Build Coastguard Worker    while 1:
46*cda5da8dSAndroid Build Coastguard Worker        s = readline()
47*cda5da8dSAndroid Build Coastguard Worker        if not s:
48*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('Missing "begin" line in input data')
49*cda5da8dSAndroid Build Coastguard Worker        if s[:5] == b'begin':
50*cda5da8dSAndroid Build Coastguard Worker            break
51*cda5da8dSAndroid Build Coastguard Worker
52*cda5da8dSAndroid Build Coastguard Worker    # Decode
53*cda5da8dSAndroid Build Coastguard Worker    while True:
54*cda5da8dSAndroid Build Coastguard Worker        s = readline()
55*cda5da8dSAndroid Build Coastguard Worker        if not s or s == b'end\n':
56*cda5da8dSAndroid Build Coastguard Worker            break
57*cda5da8dSAndroid Build Coastguard Worker        try:
58*cda5da8dSAndroid Build Coastguard Worker            data = binascii.a2b_uu(s)
59*cda5da8dSAndroid Build Coastguard Worker        except binascii.Error as v:
60*cda5da8dSAndroid Build Coastguard Worker            # Workaround for broken uuencoders by /Fredrik Lundh
61*cda5da8dSAndroid Build Coastguard Worker            nbytes = (((s[0]-32) & 63) * 4 + 5) // 3
62*cda5da8dSAndroid Build Coastguard Worker            data = binascii.a2b_uu(s[:nbytes])
63*cda5da8dSAndroid Build Coastguard Worker            #sys.stderr.write("Warning: %s\n" % str(v))
64*cda5da8dSAndroid Build Coastguard Worker        write(data)
65*cda5da8dSAndroid Build Coastguard Worker    if not s:
66*cda5da8dSAndroid Build Coastguard Worker        raise ValueError('Truncated input data')
67*cda5da8dSAndroid Build Coastguard Worker
68*cda5da8dSAndroid Build Coastguard Worker    return (outfile.getvalue(), len(input))
69*cda5da8dSAndroid Build Coastguard Worker
70*cda5da8dSAndroid Build Coastguard Workerclass Codec(codecs.Codec):
71*cda5da8dSAndroid Build Coastguard Worker    def encode(self, input, errors='strict'):
72*cda5da8dSAndroid Build Coastguard Worker        return uu_encode(input, errors)
73*cda5da8dSAndroid Build Coastguard Worker
74*cda5da8dSAndroid Build Coastguard Worker    def decode(self, input, errors='strict'):
75*cda5da8dSAndroid Build Coastguard Worker        return uu_decode(input, errors)
76*cda5da8dSAndroid Build Coastguard Worker
77*cda5da8dSAndroid Build Coastguard Workerclass IncrementalEncoder(codecs.IncrementalEncoder):
78*cda5da8dSAndroid Build Coastguard Worker    def encode(self, input, final=False):
79*cda5da8dSAndroid Build Coastguard Worker        return uu_encode(input, self.errors)[0]
80*cda5da8dSAndroid Build Coastguard Worker
81*cda5da8dSAndroid Build Coastguard Workerclass IncrementalDecoder(codecs.IncrementalDecoder):
82*cda5da8dSAndroid Build Coastguard Worker    def decode(self, input, final=False):
83*cda5da8dSAndroid Build Coastguard Worker        return uu_decode(input, self.errors)[0]
84*cda5da8dSAndroid Build Coastguard Worker
85*cda5da8dSAndroid Build Coastguard Workerclass StreamWriter(Codec, codecs.StreamWriter):
86*cda5da8dSAndroid Build Coastguard Worker    charbuffertype = bytes
87*cda5da8dSAndroid Build Coastguard Worker
88*cda5da8dSAndroid Build Coastguard Workerclass StreamReader(Codec, codecs.StreamReader):
89*cda5da8dSAndroid Build Coastguard Worker    charbuffertype = bytes
90*cda5da8dSAndroid Build Coastguard Worker
91*cda5da8dSAndroid Build Coastguard Worker### encodings module API
92*cda5da8dSAndroid Build Coastguard Worker
93*cda5da8dSAndroid Build Coastguard Workerdef getregentry():
94*cda5da8dSAndroid Build Coastguard Worker    return codecs.CodecInfo(
95*cda5da8dSAndroid Build Coastguard Worker        name='uu',
96*cda5da8dSAndroid Build Coastguard Worker        encode=uu_encode,
97*cda5da8dSAndroid Build Coastguard Worker        decode=uu_decode,
98*cda5da8dSAndroid Build Coastguard Worker        incrementalencoder=IncrementalEncoder,
99*cda5da8dSAndroid Build Coastguard Worker        incrementaldecoder=IncrementalDecoder,
100*cda5da8dSAndroid Build Coastguard Worker        streamreader=StreamReader,
101*cda5da8dSAndroid Build Coastguard Worker        streamwriter=StreamWriter,
102*cda5da8dSAndroid Build Coastguard Worker        _is_text_encoding=False,
103*cda5da8dSAndroid Build Coastguard Worker    )
104