from Interface import Interface class IStreamIterator(Interface): """ An iterator that can be published. IStreamIterators must not read from the object database. After the application finishes interpreting a request and returns an iterator to be processed asynchronously, it closes the ZODB connection. If the iterator then tries to load some ZODB object, ZODB would do one of two things. If the connection is still closed, ZODB would raise an error. If the connection happens to be re-opened by another thread, ZODB might allow it, but it has a chance of going insane if it happens to be loading or storing something in the other thread at the same time. """ def next(): """ Return a sequence of bytes out of the bytestream, or raise StopIeration if we've reached the end of the bytestream. """ def __len__(): """ Return an integer representing the length of the object in bytes. """ class filestream_iterator(file): """ a file subclass which implements an iterator that returns a fixed-sized sequence of bytes. """ __implements__ = (IStreamIterator,) def __init__(self, name, mode='r', bufsize=-1, streamsize=1<<16): file.__init__(self, name, mode, bufsize) self.streamsize = streamsize def next(self): data = self.read(self.streamsize) if not data: raise StopIteration return data def __len__(self): cur_pos = self.tell() self.seek(0, 2) size = self.tell() self.seek(cur_pos, 0) return size