"""File-like objects that read from or write to a string buffer. This implements (nearly) all stdio methods. f = StringIO() # ready for writing f = StringIO(buf) # ready for reading f.close() # explicitly release resources held flag = f.isatty() # always false buf = f.read() # returns the whole file (like getvalue()) buf = f.readline() # returns one line from the list buffer list = f.readlines()# the whole list buffer f.write(buf) # write at current position f.writelines(list) # extends the list buffer with another list f.getvalue() # return whole file's contents as a string Notes: FasterStringIO is a very basic but fast implementation with lot's of limitations. I ripped of all functionality that isn't needed by TAL and replaced the rest with a very basic implementation. Limitations: * read() does return all data * no seek/truncate/tell methods are available * write is unicode aware * readlines does't guarantee lines * no len value available You need the global request patch from PlacelessTranslationService! Based on the StringIO module from python 2.3 Adapted for the PlacelessTranslationService / SpeedPack by Christian Heimes Thanks to Andreas Jung for his idea to use list.append(). """ try: True except NameError: True=1 False=0 from types import UnicodeType, StringType from TAL.TALInterpreter import _write_ValueError class FasterStringIO: """class FasterStringIO([buffer]) unicode aware and restricted version of StringIO for Zope's TAL """ def __init__(self, buf = ''): ## disabled ## Force self.buf to be a string or unicode ##if type(buf) in (UnicodeType, StringType): ## buf = str(buf) self.buf = [] self.buf.append(buf) #self.len = len(buf) self.linepos = 0 self.closed = 0 def __iter__(self): return self def next(self): if self.closed: raise StopIteration r = self.readline() if not r: raise StopIteration return r def close(self): if not self.closed: self.closed = 1 self.write = _write_ValueError del self.buf def isatty(self): if self.closed: raise ValueError("I/O operation on closed file") return False def seek(self, pos, mode = 0): raise RuntimeError("FasterStringIO doesn't support seeking") def tell(self): if self.closed: raise RuntimeError("FasterStringIO doesn't support tell") def read(self): if self.closed: raise ValueError("I/O operation on closed file") return ''.join(self.buf) def readline(self, length=None): if self.closed: raise ValueError("I/O operation on closed file") if self.linepos <= len(self.buf): self.linepos+=1 return self.buf[self.linepos] def readlines(self): return self.buf def truncate(self, size=None): raise RuntimeError("FasterStringIO doesn't support truncating") def write(self, s): if self.closed: raise ValueError("I/O operation on closed file") if not s: return if isinstance(s, UnicodeType): # XXX: import the get_request method # this will fail the first time we need it if the patch wasn't applied # before try: from Globals import get_request except ImportError: from PatchStringIO import applyRequestPatch applyRequestPatch() request = None else: request = get_request() try: response = request.RESPONSE s = response._encode_unicode(s) except AttributeError: # not an HTTPResponse pass #for l in s.split('\n'): # self.len += len(l) +1 # self.buf.append(l) #self.len += len(s) +1 self.buf.append(s) def writelines(self, list): self.buf.extend(list) def flush(self): if self.closed: raise RuntimeError("I/O operation on closed file") def getvalue(self): return self.read() __all__ = ["StringIO"]