"""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 by Christian Heimes Thanks to Andreas Jung for his idea to use list.append(). """ from types import UnicodeType 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 = ''): self.buf = [] self.buf.append(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 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"]