home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / EVE_1424_100181.exe / _Util.py < prev    next >
Encoding:
Python Source  |  2004-04-20  |  4.8 KB  |  137 lines

  1. from StringIO import StringIO
  2.  
  3. def startswith(string, initial):
  4.     if len(initial) > len(string): return 0
  5.     return string[:len(initial)] == initial
  6.  
  7. def endswith(string, final):
  8.     if len(final) > len(string): return 0
  9.     return string[-len(final):] == final
  10.  
  11.  
  12. try:
  13.     from calendar import timegm
  14. except:
  15.     EPOCH = 1970
  16.     def timegm(tuple):
  17.         """Unrelated but handy function to calculate Unix timestamp from GMT."""
  18.         year, month, day, hour, minute, second = tuple[:6]
  19.         assert year >= EPOCH
  20.         assert 1 <= month <= 12
  21.         days = 365*(year-EPOCH) + leapdays(EPOCH, year)
  22.         for i in range(1, month):
  23.             days = days + mdays[i]
  24.         if month > 2 and isleap(year):
  25.             days = days + 1
  26.         days = days + day - 1
  27.         hours = days*24 + hour
  28.         minutes = hours*60 + minute
  29.         seconds = minutes*60 + second
  30.         return seconds
  31.  
  32. # XXX Andrew Dalke kindly sent me a similar class in response to my request on
  33. # comp.lang.python, which I then proceeded to lose.  I wrote this class
  34. # instead, but I think he's released his code publicly since, could pinch the
  35. # tests from it, at least...
  36. class seek_wrapper:
  37.     """Adds a seek method to a file object.
  38.  
  39.     This is only designed for seeking on readonly file-like objects.
  40.  
  41.     Wrapped file-like object must have a read method.  The readline method is
  42.     only supported if that method is present on the wrapped object.  The
  43.     readlines method is always supported.
  44.  
  45.     Public attribute: wrapped (the wrapped file object).
  46.  
  47.     WARNING: All other attributes of the wrapped object (ie. those that are not
  48.     one of wrapped, read, readline or readlines) are passed through unaltered,
  49.     which may or may not make sense for your particular file object.
  50.  
  51.     """
  52.     # General strategy is to check that cache is full enough, then delegate
  53.     # everything to the cache (self._cache, which is a StringIO.StringIO
  54.     # instance -- cStringIO.StringIO won't work, because it has no write
  55.     # method!).
  56.  
  57.     # Invariant: the end of the cache is always at the same place as the
  58.     # end of the wrapped file:
  59.     # self.wrapped.tell() == len(self._cache.getvalue())
  60.  
  61.     def __init__(self, wrapped):
  62.         self.wrapped = wrapped
  63.         self.__have_readline = hasattr(self.wrapped, "readline")
  64.         self.__cache = StringIO("")
  65.  
  66.     def __getattr__(self, name): return getattr(self.wrapped, name)
  67.  
  68.     def seek(self, offset, whence=0):
  69.         # make sure we have read all data up to the point we are seeking to
  70.         pos = self.__cache.tell()
  71.         if whence == 0:  # absolute
  72.             to_read = offset - pos
  73.         elif whence == 1:  # relative to current position
  74.             to_read = offset
  75.         elif whence == 2:  # relative to end of *wrapped* file
  76.             # since we don't know yet where the end of that file is, we must
  77.             # read everything
  78.             to_read = None
  79.         if to_read >= 0 or to_read is None:
  80.             if to_read is None:
  81.                 self.__cache.write(self.wrapped.read())
  82.             else:
  83.                 self.__cache.write(self.wrapped.read(to_read))
  84.             self.__cache.seek(pos)
  85.  
  86.         return self.__cache.seek(offset, whence)
  87.  
  88.     def read(self, size=-1):
  89.         pos = self.__cache.tell()
  90.  
  91.         self.__cache.seek(pos)
  92.  
  93.         end = len(self.__cache.getvalue())
  94.         available = end - pos
  95.  
  96.         # enough data already cached?
  97.         if size <= available and size != -1:
  98.             return self.__cache.read(size)
  99.  
  100.         # no, so read sufficient data from wrapped file and cache it
  101.         to_read = size - available
  102.         assert to_read > 0 or size == -1
  103.         self.__cache.seek(0, 2)
  104.         if size == -1:
  105.             self.__cache.write(self.wrapped.read())
  106.         else:
  107.             self.__cache.write(self.wrapped.read(to_read))
  108.         self.__cache.seek(pos)
  109.  
  110.         return self.__cache.read(size)
  111.  
  112.     def readline(self, size=-1):
  113.         if not self.__have_readline:
  114.             raise NotImplementedError, "no readline method on wrapped object"
  115.  
  116.         # line we're about to read might not be complete in the cache, so
  117.         # read another line first
  118.         pos = self.__cache.tell()
  119.         self.__cache.seek(0, 2)
  120.         self.__cache.write(self.wrapped.readline())
  121.         self.__cache.seek(pos)
  122.  
  123.         data = self.__cache.readline()
  124.         if size != -1:
  125.             r = data[:size]
  126.             self.__cache.seek(pos+size)
  127.         else:
  128.             r = data
  129.         return r
  130.  
  131.     def readlines(self, sizehint=-1):
  132.         pos = self.__cache.tell()
  133.         self.__cache.seek(0, 2)
  134.         self.__cache.write(self.wrapped.read())
  135.         self.__cache.seek(pos)
  136.         return self.__cache.readlines(sizehint)
  137.