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