Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / python2.4 / mimetools.py
CommitLineData
86530b38
AT
1"""Various tools used by MIME-reading or MIME-writing programs."""
2
3
4import os
5import rfc822
6import tempfile
7
8__all__ = ["Message","choose_boundary","encode","decode","copyliteral",
9 "copybinary"]
10
11class Message(rfc822.Message):
12 """A derived class of rfc822.Message that knows about MIME headers and
13 contains some hooks for decoding encoded and multipart messages."""
14
15 def __init__(self, fp, seekable = 1):
16 rfc822.Message.__init__(self, fp, seekable)
17 self.encodingheader = \
18 self.getheader('content-transfer-encoding')
19 self.typeheader = \
20 self.getheader('content-type')
21 self.parsetype()
22 self.parseplist()
23
24 def parsetype(self):
25 str = self.typeheader
26 if str is None:
27 str = 'text/plain'
28 if ';' in str:
29 i = str.index(';')
30 self.plisttext = str[i:]
31 str = str[:i]
32 else:
33 self.plisttext = ''
34 fields = str.split('/')
35 for i in range(len(fields)):
36 fields[i] = fields[i].strip().lower()
37 self.type = '/'.join(fields)
38 self.maintype = fields[0]
39 self.subtype = '/'.join(fields[1:])
40
41 def parseplist(self):
42 str = self.plisttext
43 self.plist = []
44 while str[:1] == ';':
45 str = str[1:]
46 if ';' in str:
47 # XXX Should parse quotes!
48 end = str.index(';')
49 else:
50 end = len(str)
51 f = str[:end]
52 if '=' in f:
53 i = f.index('=')
54 f = f[:i].strip().lower() + \
55 '=' + f[i+1:].strip()
56 self.plist.append(f.strip())
57 str = str[end:]
58
59 def getplist(self):
60 return self.plist
61
62 def getparam(self, name):
63 name = name.lower() + '='
64 n = len(name)
65 for p in self.plist:
66 if p[:n] == name:
67 return rfc822.unquote(p[n:])
68 return None
69
70 def getparamnames(self):
71 result = []
72 for p in self.plist:
73 i = p.find('=')
74 if i >= 0:
75 result.append(p[:i].lower())
76 return result
77
78 def getencoding(self):
79 if self.encodingheader is None:
80 return '7bit'
81 return self.encodingheader.lower()
82
83 def gettype(self):
84 return self.type
85
86 def getmaintype(self):
87 return self.maintype
88
89 def getsubtype(self):
90 return self.subtype
91
92
93
94
95# Utility functions
96# -----------------
97
98try:
99 import thread
100except ImportError:
101 import dummy_thread as thread
102_counter_lock = thread.allocate_lock()
103del thread
104
105_counter = 0
106def _get_next_counter():
107 global _counter
108 _counter_lock.acquire()
109 _counter += 1
110 result = _counter
111 _counter_lock.release()
112 return result
113
114_prefix = None
115
116def choose_boundary():
117 """Return a string usable as a multipart boundary.
118
119 The string chosen is unique within a single program run, and
120 incorporates the user id (if available), process id (if available),
121 and current time. So it's very unlikely the returned string appears
122 in message text, but there's no guarantee.
123
124 The boundary contains dots so you have to quote it in the header."""
125
126 global _prefix
127 import time
128 if _prefix is None:
129 import socket
130 hostid = socket.gethostbyname(socket.gethostname())
131 try:
132 uid = repr(os.getuid())
133 except AttributeError:
134 uid = '1'
135 try:
136 pid = repr(os.getpid())
137 except AttributeError:
138 pid = '1'
139 _prefix = hostid + '.' + uid + '.' + pid
140 return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter())
141
142
143# Subroutines for decoding some common content-transfer-types
144
145def decode(input, output, encoding):
146 """Decode common content-transfer-encodings (base64, quopri, uuencode)."""
147 if encoding == 'base64':
148 import base64
149 return base64.decode(input, output)
150 if encoding == 'quoted-printable':
151 import quopri
152 return quopri.decode(input, output)
153 if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
154 import uu
155 return uu.decode(input, output)
156 if encoding in ('7bit', '8bit'):
157 return output.write(input.read())
158 if encoding in decodetab:
159 pipethrough(input, decodetab[encoding], output)
160 else:
161 raise ValueError, \
162 'unknown Content-Transfer-Encoding: %s' % encoding
163
164def encode(input, output, encoding):
165 """Encode common content-transfer-encodings (base64, quopri, uuencode)."""
166 if encoding == 'base64':
167 import base64
168 return base64.encode(input, output)
169 if encoding == 'quoted-printable':
170 import quopri
171 return quopri.encode(input, output, 0)
172 if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
173 import uu
174 return uu.encode(input, output)
175 if encoding in ('7bit', '8bit'):
176 return output.write(input.read())
177 if encoding in encodetab:
178 pipethrough(input, encodetab[encoding], output)
179 else:
180 raise ValueError, \
181 'unknown Content-Transfer-Encoding: %s' % encoding
182
183# The following is no longer used for standard encodings
184
185# XXX This requires that uudecode and mmencode are in $PATH
186
187uudecode_pipe = '''(
188TEMP=/tmp/@uu.$$
189sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode
190cat $TEMP
191rm $TEMP
192)'''
193
194decodetab = {
195 'uuencode': uudecode_pipe,
196 'x-uuencode': uudecode_pipe,
197 'uue': uudecode_pipe,
198 'x-uue': uudecode_pipe,
199 'quoted-printable': 'mmencode -u -q',
200 'base64': 'mmencode -u -b',
201}
202
203encodetab = {
204 'x-uuencode': 'uuencode tempfile',
205 'uuencode': 'uuencode tempfile',
206 'x-uue': 'uuencode tempfile',
207 'uue': 'uuencode tempfile',
208 'quoted-printable': 'mmencode -q',
209 'base64': 'mmencode -b',
210}
211
212def pipeto(input, command):
213 pipe = os.popen(command, 'w')
214 copyliteral(input, pipe)
215 pipe.close()
216
217def pipethrough(input, command, output):
218 (fd, tempname) = tempfile.mkstemp()
219 temp = os.fdopen(fd, 'w')
220 copyliteral(input, temp)
221 temp.close()
222 pipe = os.popen(command + ' <' + tempname, 'r')
223 copybinary(pipe, output)
224 pipe.close()
225 os.unlink(tempname)
226
227def copyliteral(input, output):
228 while 1:
229 line = input.readline()
230 if not line: break
231 output.write(line)
232
233def copybinary(input, output):
234 BUFSIZE = 8192
235 while 1:
236 line = input.read(BUFSIZE)
237 if not line: break
238 output.write(line)