1 """A readline()-style interface to the parts of a multipart message.
3 The MultiFile class makes each part of a multipart message "feel" like
4 an ordinary file, as long as you use fp.readline(). Allows recursive
5 use, for nested multipart messages. Probably best used together
11 fp = MultiFile(real_fp)
13 "read some lines from fp"
16 "read lines from fp until it returns an empty string" (A)
17 if not fp.next(): break
19 "read remaining lines from fp until it returns an empty string"
21 The latter sequence may be used recursively at (A).
22 It is also allowed to use multiple push()...pop() sequences.
24 If seekable is given as 0, the class code will not do the bookkeeping
25 it normally attempts in order to make seeks relative to the beginning of the
26 current file part. This may be useful when using MultiFile with a non-
27 seekable stream object.
30 __all__ = [
"MultiFile",
"Error"]
55 def seek(self, pos, whence=0):
64 raise Error,
"can't use whence=2 yet"
65 if not 0 <= pos <= here
or \
67 raise Error,
'bad MultiFile.seek() call'
68 self.fp.seek(pos + self.
start)
80 if line[-2:] ==
"\r\n":
82 elif line[-1:] ==
"\n":
89 line = self.fp.readline()
95 raise Error,
'sudden EOF in MultiFile.readline()'
97 assert self.
level == 0
103 marker = line.rstrip()
106 for i
in range(len(self.
stack)):
121 raise Error,
'Missing endmarker in MultiFile.readline()'
142 self.
start = self.fp.tell()
147 raise Error,
'bad MultiFile.push() call'
148 self.stack.insert(0, sep)
150 self.posstack.insert(0, self.
start)
151 self.
start = self.fp.tell()
155 raise Error,
'bad MultiFile.pop() call'
169 return line[:2] !=
'--'
175 return "--" + str +
"--"