1 | """ Python 'uu_codec' Codec - UU content transfer encoding
|
---|
2 |
|
---|
3 | Unlike most of the other codecs which target Unicode, this codec
|
---|
4 | will return Python string objects for both encode and decode.
|
---|
5 |
|
---|
6 | Written by Marc-Andre Lemburg (mal@lemburg.com). Some details were
|
---|
7 | adapted from uu.py which was written by Lance Ellinghouse and
|
---|
8 | modified by Jack Jansen and Fredrik Lundh.
|
---|
9 |
|
---|
10 | """
|
---|
11 | import codecs, binascii
|
---|
12 |
|
---|
13 | ### Codec APIs
|
---|
14 |
|
---|
15 | def uu_encode(input,errors='strict',filename='<data>',mode=0666):
|
---|
16 |
|
---|
17 | """ Encodes the object input and returns a tuple (output
|
---|
18 | object, length consumed).
|
---|
19 |
|
---|
20 | errors defines the error handling to apply. It defaults to
|
---|
21 | 'strict' handling which is the only currently supported
|
---|
22 | error handling for this codec.
|
---|
23 |
|
---|
24 | """
|
---|
25 | assert errors == 'strict'
|
---|
26 | from cStringIO import StringIO
|
---|
27 | from binascii import b2a_uu
|
---|
28 | # using str() because of cStringIO's Unicode undesired Unicode behavior.
|
---|
29 | infile = StringIO(str(input))
|
---|
30 | outfile = StringIO()
|
---|
31 | read = infile.read
|
---|
32 | write = outfile.write
|
---|
33 |
|
---|
34 | # Encode
|
---|
35 | write('begin %o %s\n' % (mode & 0777, filename))
|
---|
36 | chunk = read(45)
|
---|
37 | while chunk:
|
---|
38 | write(b2a_uu(chunk))
|
---|
39 | chunk = read(45)
|
---|
40 | write(' \nend\n')
|
---|
41 |
|
---|
42 | return (outfile.getvalue(), len(input))
|
---|
43 |
|
---|
44 | def uu_decode(input,errors='strict'):
|
---|
45 |
|
---|
46 | """ Decodes the object input and returns a tuple (output
|
---|
47 | object, length consumed).
|
---|
48 |
|
---|
49 | input must be an object which provides the bf_getreadbuf
|
---|
50 | buffer slot. Python strings, buffer objects and memory
|
---|
51 | mapped files are examples of objects providing this slot.
|
---|
52 |
|
---|
53 | errors defines the error handling to apply. It defaults to
|
---|
54 | 'strict' handling which is the only currently supported
|
---|
55 | error handling for this codec.
|
---|
56 |
|
---|
57 | Note: filename and file mode information in the input data is
|
---|
58 | ignored.
|
---|
59 |
|
---|
60 | """
|
---|
61 | assert errors == 'strict'
|
---|
62 | from cStringIO import StringIO
|
---|
63 | from binascii import a2b_uu
|
---|
64 | infile = StringIO(str(input))
|
---|
65 | outfile = StringIO()
|
---|
66 | readline = infile.readline
|
---|
67 | write = outfile.write
|
---|
68 |
|
---|
69 | # Find start of encoded data
|
---|
70 | while 1:
|
---|
71 | s = readline()
|
---|
72 | if not s:
|
---|
73 | raise ValueError, 'Missing "begin" line in input data'
|
---|
74 | if s[:5] == 'begin':
|
---|
75 | break
|
---|
76 |
|
---|
77 | # Decode
|
---|
78 | while 1:
|
---|
79 | s = readline()
|
---|
80 | if not s or \
|
---|
81 | s == 'end\n':
|
---|
82 | break
|
---|
83 | try:
|
---|
84 | data = a2b_uu(s)
|
---|
85 | except binascii.Error, v:
|
---|
86 | # Workaround for broken uuencoders by /Fredrik Lundh
|
---|
87 | nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3
|
---|
88 | data = a2b_uu(s[:nbytes])
|
---|
89 | #sys.stderr.write("Warning: %s\n" % str(v))
|
---|
90 | write(data)
|
---|
91 | if not s:
|
---|
92 | raise ValueError, 'Truncated input data'
|
---|
93 |
|
---|
94 | return (outfile.getvalue(), len(input))
|
---|
95 |
|
---|
96 | class Codec(codecs.Codec):
|
---|
97 |
|
---|
98 | def encode(self,input,errors='strict'):
|
---|
99 | return uu_encode(input,errors)
|
---|
100 |
|
---|
101 | def decode(self,input,errors='strict'):
|
---|
102 | return uu_decode(input,errors)
|
---|
103 |
|
---|
104 | class IncrementalEncoder(codecs.IncrementalEncoder):
|
---|
105 | def encode(self, input, final=False):
|
---|
106 | return uu_encode(input, self.errors)[0]
|
---|
107 |
|
---|
108 | class IncrementalDecoder(codecs.IncrementalDecoder):
|
---|
109 | def decode(self, input, final=False):
|
---|
110 | return uu_decode(input, self.errors)[0]
|
---|
111 |
|
---|
112 | class StreamWriter(Codec,codecs.StreamWriter):
|
---|
113 | pass
|
---|
114 |
|
---|
115 | class StreamReader(Codec,codecs.StreamReader):
|
---|
116 | pass
|
---|
117 |
|
---|
118 | ### encodings module API
|
---|
119 |
|
---|
120 | def getregentry():
|
---|
121 | return codecs.CodecInfo(
|
---|
122 | name='uu',
|
---|
123 | encode=uu_encode,
|
---|
124 | decode=uu_decode,
|
---|
125 | incrementalencoder=IncrementalEncoder,
|
---|
126 | incrementaldecoder=IncrementalDecoder,
|
---|
127 | streamreader=StreamReader,
|
---|
128 | streamwriter=StreamWriter,
|
---|
129 | )
|
---|