"""A readline()-style interface to the parts of a multipart message.
The MultiFile class makes each part of a multipart message "feel" like
an ordinary file, as long as you use fp.readline(). Allows recursive
use, for nested multipart messages. Probably best used together
"read some lines from fp"
"read lines from fp until it returns an empty string" (A)
"read remaining lines from fp until it returns an empty string"
The latter sequence may be used recursively at (A).
It is also allowed to use multiple push()...pop() sequences.
If seekable is given as 0, the class code will not do the bookkeeping
it normally attempts in order to make seeks relative to the beginning of the
current file part. This may be useful when using MultiFile with a non-
from warnings import warn
warn("the multifile module has been deprecated since Python 2.5",
DeprecationWarning, stacklevel=2)
__all__ = ["MultiFile","Error"]
def __init__(self, fp, seekable=1):
self.start = self.fp.tell()
return self.fp.tell() - self.start
def seek(self, pos, whence=0):
raise Error, "can't use whence=2 yet"
if not 0 <= pos <= here or \
self.level > 0 and pos > self.lastpos:
raise Error, 'bad MultiFile.seek() call'
self.fp.seek(pos + self.start)
line = self.fp.readline()
self.level = len(self.stack)
self.last = (self.level > 0)
raise Error, 'sudden EOF in MultiFile.readline()'
# Fast check to see if this is just data
# Ignore trailing whitespace on marker lines
# No? OK, try to match a boundary.
# Return the line (unstripped) if we don't.
for i, sep in enumerate(reversed(self.stack)):
if marker == self.section_divider(sep):
elif marker == self.end_marker(sep):
# We only get here if we see a section divider or EOM line
self.lastpos = self.tell() - len(line)
raise Error,'Missing endmarker in MultiFile.readline()'
def read(self): # Note: no size argument -- read until EOF only!
return ''.join(self.readlines())
while self.readline(): pass
if self.level > 1 or self.last:
self.start = self.fp.tell()
raise Error, 'bad MultiFile.push() call'
self.posstack.append(self.start)
self.start = self.fp.tell()
raise Error, 'bad MultiFile.pop() call'
abslastpos = self.lastpos + self.start
self.level = max(0, self.level - 1)
self.start = self.posstack.pop()
self.lastpos = abslastpos - self.start
def section_divider(self, str):
def end_marker(self, str):