diff options
Diffstat (limited to 'Lib/dos-8x3/multifil.py')
-rwxr-xr-x | Lib/dos-8x3/multifil.py | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/Lib/dos-8x3/multifil.py b/Lib/dos-8x3/multifil.py index 8ba88e4..ce84087 100755 --- a/Lib/dos-8x3/multifil.py +++ b/Lib/dos-8x3/multifil.py @@ -18,26 +18,30 @@ # # The latter sequence may be used recursively at (A). # It is also allowed to use multiple push()...pop() sequences. -# Note that if a nested multipart message is terminated by a separator -# for an outer message, this is not reported, even though it is really -# illegal input. +# +# If seekable is given as 0, the class code will not do the bookeeping +# 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- +# seekable stream object. import sys import string -err = sys.stderr.write - Error = 'multifile.Error' class MultiFile: # - def __init__(self, fp): + seekable = 0 + # + def __init__(self, fp, seekable=1): self.fp = fp self.stack = [] # Grows down self.level = 0 self.last = 0 - self.start = self.fp.tell() - self.posstack = [] # Grows down + if seekable: + self.seekable = 1 + self.start = self.fp.tell() + self.posstack = [] # Grows down # def tell(self): if self.level > 0: @@ -62,36 +66,44 @@ class MultiFile: self.last = 0 # def readline(self): - if self.level > 0: return '' + if self.level > 0: + return '' line = self.fp.readline() + # Real EOF? if not line: self.level = len(self.stack) self.last = (self.level > 0) if self.last: - err('*** Sudden EOF in MultiFile.readline()\n') + raise Error, 'sudden EOF in MultiFile.readline()' return '' - if line[:2] <> '--': return line - n = len(line) - k = n - while k > 0 and line[k-1] in string.whitespace: k = k-1 - mark = line[2:k] - if mark[-2:] == '--': mark1 = mark[:-2] - else: mark1 = None + assert self.level == 0 + # Fast check to see if this is just data + if self.is_data(line): + return line + else: + # Ignore trailing whitespace on marker lines + k = len(line) - 1; + while line[k] in string.whitespace: + k = k - 1 + marker = line[:k+1] + # No? OK, try to match a boundary. + # Return the line (unstripped) if we don't. for i in range(len(self.stack)): sep = self.stack[i] - if sep == mark: + if marker == self.section_divider(sep): self.last = 0 break - elif mark1 <> None and sep == mark1: + elif marker == self.end_marker(sep): self.last = 1 break else: return line - # Get here after break out of loop - self.lastpos = self.tell() - len(line) + # We only get here if we see a section divider or EOM line + if self.seekable: + self.lastpos = self.tell() - len(line) self.level = i+1 if self.level > 1: - err('*** Missing endmarker in MultiFile.readline()\n') + raise Error,'Missing endmarker in MultiFile.readline()' return '' # def readlines(self): @@ -111,15 +123,17 @@ class MultiFile: return 0 self.level = 0 self.last = 0 - self.start = self.fp.tell() + if self.seekable: + self.start = self.fp.tell() return 1 # def push(self, sep): if self.level > 0: raise Error, 'bad MultiFile.push() call' self.stack.insert(0, sep) - self.posstack.insert(0, self.start) - self.start = self.fp.tell() + if self.seekable: + self.posstack.insert(0, self.start) + self.start = self.fp.tell() # def pop(self): if self.stack == []: @@ -130,8 +144,17 @@ class MultiFile: abslastpos = self.lastpos + self.start self.level = max(0, self.level - 1) del self.stack[0] - self.start = self.posstack[0] - del self.posstack[0] - if self.level > 0: - self.lastpos = abslastpos - self.start + if self.seekable: + self.start = self.posstack[0] + del self.posstack[0] + if self.level > 0: + self.lastpos = abslastpos - self.start + # + def is_data(self, line): + return line[:2] <> '--' + # + def section_divider(self, str): + return "--" + str # + def end_marker(self, str): + return "--" + str + "--" |