• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         _is_text_encoding=False,
130     )
131