symbian-qemu-0.9.1-12/python-2.6.1/Lib/multifile.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """A readline()-style interface to the parts of a multipart message.
       
     2 
       
     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
       
     6 with module mimetools.
       
     7 
       
     8 Suggested use:
       
     9 
       
    10 real_fp = open(...)
       
    11 fp = MultiFile(real_fp)
       
    12 
       
    13 "read some lines from fp"
       
    14 fp.push(separator)
       
    15 while 1:
       
    16         "read lines from fp until it returns an empty string" (A)
       
    17         if not fp.next(): break
       
    18 fp.pop()
       
    19 "read remaining lines from fp until it returns an empty string"
       
    20 
       
    21 The latter sequence may be used recursively at (A).
       
    22 It is also allowed to use multiple push()...pop() sequences.
       
    23 
       
    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.
       
    28 """
       
    29 from warnings import warn
       
    30 warn("the multifile module has been deprecated since Python 2.5",
       
    31         DeprecationWarning, stacklevel=2)
       
    32 del warn
       
    33 
       
    34 __all__ = ["MultiFile","Error"]
       
    35 
       
    36 class Error(Exception):
       
    37     pass
       
    38 
       
    39 class MultiFile:
       
    40 
       
    41     seekable = 0
       
    42 
       
    43     def __init__(self, fp, seekable=1):
       
    44         self.fp = fp
       
    45         self.stack = []
       
    46         self.level = 0
       
    47         self.last = 0
       
    48         if seekable:
       
    49             self.seekable = 1
       
    50             self.start = self.fp.tell()
       
    51             self.posstack = []
       
    52 
       
    53     def tell(self):
       
    54         if self.level > 0:
       
    55             return self.lastpos
       
    56         return self.fp.tell() - self.start
       
    57 
       
    58     def seek(self, pos, whence=0):
       
    59         here = self.tell()
       
    60         if whence:
       
    61             if whence == 1:
       
    62                 pos = pos + here
       
    63             elif whence == 2:
       
    64                 if self.level > 0:
       
    65                     pos = pos + self.lastpos
       
    66                 else:
       
    67                     raise Error, "can't use whence=2 yet"
       
    68         if not 0 <= pos <= here or \
       
    69                         self.level > 0 and pos > self.lastpos:
       
    70             raise Error, 'bad MultiFile.seek() call'
       
    71         self.fp.seek(pos + self.start)
       
    72         self.level = 0
       
    73         self.last = 0
       
    74 
       
    75     def readline(self):
       
    76         if self.level > 0:
       
    77             return ''
       
    78         line = self.fp.readline()
       
    79         # Real EOF?
       
    80         if not line:
       
    81             self.level = len(self.stack)
       
    82             self.last = (self.level > 0)
       
    83             if self.last:
       
    84                 raise Error, 'sudden EOF in MultiFile.readline()'
       
    85             return ''
       
    86         assert self.level == 0
       
    87         # Fast check to see if this is just data
       
    88         if self.is_data(line):
       
    89             return line
       
    90         else:
       
    91             # Ignore trailing whitespace on marker lines
       
    92             marker = line.rstrip()
       
    93         # No?  OK, try to match a boundary.
       
    94         # Return the line (unstripped) if we don't.
       
    95         for i, sep in enumerate(reversed(self.stack)):
       
    96             if marker == self.section_divider(sep):
       
    97                 self.last = 0
       
    98                 break
       
    99             elif marker == self.end_marker(sep):
       
   100                 self.last = 1
       
   101                 break
       
   102         else:
       
   103             return line
       
   104         # We only get here if we see a section divider or EOM line
       
   105         if self.seekable:
       
   106             self.lastpos = self.tell() - len(line)
       
   107         self.level = i+1
       
   108         if self.level > 1:
       
   109             raise Error,'Missing endmarker in MultiFile.readline()'
       
   110         return ''
       
   111 
       
   112     def readlines(self):
       
   113         list = []
       
   114         while 1:
       
   115             line = self.readline()
       
   116             if not line: break
       
   117             list.append(line)
       
   118         return list
       
   119 
       
   120     def read(self): # Note: no size argument -- read until EOF only!
       
   121         return ''.join(self.readlines())
       
   122 
       
   123     def next(self):
       
   124         while self.readline(): pass
       
   125         if self.level > 1 or self.last:
       
   126             return 0
       
   127         self.level = 0
       
   128         self.last = 0
       
   129         if self.seekable:
       
   130             self.start = self.fp.tell()
       
   131         return 1
       
   132 
       
   133     def push(self, sep):
       
   134         if self.level > 0:
       
   135             raise Error, 'bad MultiFile.push() call'
       
   136         self.stack.append(sep)
       
   137         if self.seekable:
       
   138             self.posstack.append(self.start)
       
   139             self.start = self.fp.tell()
       
   140 
       
   141     def pop(self):
       
   142         if self.stack == []:
       
   143             raise Error, 'bad MultiFile.pop() call'
       
   144         if self.level <= 1:
       
   145             self.last = 0
       
   146         else:
       
   147             abslastpos = self.lastpos + self.start
       
   148         self.level = max(0, self.level - 1)
       
   149         self.stack.pop()
       
   150         if self.seekable:
       
   151             self.start = self.posstack.pop()
       
   152             if self.level > 0:
       
   153                 self.lastpos = abslastpos - self.start
       
   154 
       
   155     def is_data(self, line):
       
   156         return line[:2] != '--'
       
   157 
       
   158     def section_divider(self, str):
       
   159         return "--" + str
       
   160 
       
   161     def end_marker(self, str):
       
   162         return "--" + str + "--"