# port of StringIO.py using arrays # ArrayIO.py # jjk 02/28/96 001 direct mod of StringIO, test suite checks out # jjk 02/28/96 002 inherit from StringIO, test suite checks out # jjk 02/28/96 003 add __xx__() functions # # class ArrayIO implements file-like objects that read/write a # string buffer (a.k.a. "memory files"). # # all methods that interface with ArrayIO pass strings. Internally, however, # ArrayIO uses an array object. # # the interface is the same as StringIO.py # also handles len(a), a[i], a[i]='x', a[i:j], a[i:j] = aString # import string import array import StringIO class ArrayIO(StringIO.StringIO): # jjk 02/28/96 def __init__(self, buf = ''): #jjk 02/28/96 self.buf = array.array('c', buf) self.pos = 0 self.closed = 0 def __len__(self): #jjk 02/28/96 return len(self.buf) def __getitem__(self, key): #jjk 02/28/96 return self.buf[key] def __setitem__(self, key, item): #jjk 02/28/96 self.buf[key] = item def __getslice__(self, i, j): #jjk 02/28/96 return self.buf[i:j].tostring() def __setslice__(self, i, j, aString): #jjk 02/28/96 self.buf[i:j] = array.array('c', aString) def read(self, n = 0): #jjk 02/28/96 r = StringIO.StringIO.read(self, n) return (r.tostring()) def _findCharacter(self, char, start): #probably very slow #jjk 02/28/96 for i in range(max(start, 0), len(self.buf)): if (self.buf[i] == char): return(i) return(-1) def readline(self): #jjk 02/28/96 i = self._findCharacter('\n', self.pos) if i < 0: newpos = len(self.buf) else: newpos = i+1 r = self.buf[self.pos:newpos].tostring() self.pos = newpos return r def write(self, s): #jjk 02/28/96 if not s: return if self.pos > len(self.buf): self.buf.fromstring('\0'*(self.pos - len(self.buf))) newpos = self.pos + len(s) self.buf[self.pos:newpos] = array.array('c', s) self.pos = newpos def getvalue(self): #jjk 02/28/96 return self.buf.tostring() # A little test suite # identical to test suite in StringIO.py , except for "f = ArrayIO()" # too bad I couldn't inherit this :-) def test(): import sys if sys.argv[1:]: file = sys.argv[1] else: file = '/etc/passwd' lines = open(file, 'r').readlines() text = open(file, 'r').read() f = ArrayIO() for line in lines[:-2]: f.write(line) f.writelines(lines[-2:]) if f.getvalue() != text: raise RuntimeError, 'write failed' length = f.tell() print 'File length =', length f.seek(len(lines[0])) f.write(lines[1]) f.seek(0) print 'First line =', `f.readline()` here = f.tell() line = f.readline() print 'Second line =', `line` f.seek(-len(line), 1) line2 = f.read(len(line)) if line != line2: raise RuntimeError, 'bad result after seek back' f.seek(len(line2), 1) list = f.readlines() line = list[-1] f.seek(f.tell() - len(line)) line2 = f.read() if line != line2: raise RuntimeError, 'bad result after seek back from EOF' print 'Read', len(list), 'more lines' print 'File length =', f.tell() if f.tell() != length: raise RuntimeError, 'bad length' f.close() if __name__ == '__main__': test()