Mercurial > cpython-lru_cache-weakref
comparison Lib/ArrayIO.py @ 3645:49ee89e017ab legacy-trunk
Total rewrite
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Tue, 28 May 1996 23:17:13 +0000 |
| parents | 02c9da20b41e |
| children |
comparison
equal
deleted
inserted
replaced
| 3644:017d3356a5ed | 3645:49ee89e017ab |
|---|---|
| 1 # port of StringIO.py using arrays | 1 """File-like objects that read/write an array buffer. |
| 2 # ArrayIO.py | 2 |
| 3 # jjk 02/28/96 001 direct mod of StringIO, test suite checks out | 3 This implements (nearly) all stdio methods. |
| 4 # jjk 02/28/96 002 inherit from StringIO, test suite checks out | 4 |
| 5 # jjk 02/28/96 003 add __xx__() functions | 5 f = ArrayIO() # ready for writing |
| 6 # | 6 f = ArrayIO(buf) # ready for reading |
| 7 # class ArrayIO implements file-like objects that read/write a | 7 f.close() # explicitly release resources held |
| 8 # string buffer (a.k.a. "memory files"). | 8 flag = f.isatty() # always false |
| 9 # | 9 pos = f.tell() # get current position |
| 10 # all methods that interface with ArrayIO pass strings. Internally, however, | 10 f.seek(pos) # set current position |
| 11 # ArrayIO uses an array object. | 11 f.seek(pos, mode) # mode 0: absolute; 1: relative; 2: relative to EOF |
| 12 # | 12 buf = f.read() # read until EOF |
| 13 # the interface is the same as StringIO.py | 13 buf = f.read(n) # read up to n bytes |
| 14 # also handles len(a), a[i], a[i]='x', a[i:j], a[i:j] = aString | 14 buf = f.readline() # read until end of line ('\n') or EOF |
| 15 # | 15 list = f.readlines()# list of f.readline() results until EOF |
| 16 f.write(buf) # write at current position | |
| 17 f.writelines(list) # for line in list: f.write(line) | |
| 18 f.getvalue() # return whole file's contents as a string | |
| 19 | |
| 20 Notes: | |
| 21 - This is very similar to StringIO. StringIO is faster for reading, | |
| 22 but ArrayIO is faster for writing. | |
| 23 - ArrayIO uses an array object internally, but all its interfaces | |
| 24 accept and return strings. | |
| 25 - Using a real file is often faster (but less convenient). | |
| 26 - fileno() is left unimplemented so that code which uses it triggers | |
| 27 an exception early. | |
| 28 - Seeking far beyond EOF and then writing will insert real null | |
| 29 bytes that occupy space in the buffer. | |
| 30 - There's a simple test set (see end of this file). | |
| 31 """ | |
| 16 | 32 |
| 17 import string | 33 import string |
| 18 import array | 34 from array import array |
| 19 import StringIO | |
| 20 | 35 |
| 21 class ArrayIO(StringIO.StringIO): | 36 class ArrayIO: |
| 22 # jjk 02/28/96 | |
| 23 def __init__(self, buf = ''): | 37 def __init__(self, buf = ''): |
| 24 #jjk 02/28/96 | 38 self.buf = array('c', buf) |
| 25 self.buf = array.array('c', buf) | |
| 26 self.pos = 0 | 39 self.pos = 0 |
| 27 self.closed = 0 | 40 self.closed = 0 |
| 28 def __len__(self): | 41 self.softspace = 0 |
| 29 #jjk 02/28/96 | 42 def close(self): |
| 30 return len(self.buf) | 43 if not self.closed: |
| 31 def __getitem__(self, key): | 44 self.closed = 1 |
| 32 #jjk 02/28/96 | 45 del self.buf, self.pos |
| 33 return self.buf[key] | 46 def isatty(self): |
| 34 def __setitem__(self, key, item): | 47 return 0 |
| 35 #jjk 02/28/96 | 48 def seek(self, pos, mode = 0): |
| 36 self.buf[key] = item | 49 if mode == 1: |
| 37 def __getslice__(self, i, j): | 50 pos = pos + self.pos |
| 38 #jjk 02/28/96 | 51 elif mode == 2: |
| 39 return self.buf[i:j].tostring() | 52 pos = pos + len(self.buf) |
| 40 def __setslice__(self, i, j, aString): | 53 self.pos = max(0, pos) |
| 41 #jjk 02/28/96 | 54 def tell(self): |
| 42 self.buf[i:j] = array.array('c', aString) | 55 return self.pos |
| 43 def read(self, n = 0): | 56 def read(self, n = -1): |
| 44 #jjk 02/28/96 | 57 if n < 0: |
| 45 r = StringIO.StringIO.read(self, n) | 58 newpos = len(self.buf) |
| 46 return (r.tostring()) | 59 else: |
| 47 def _findCharacter(self, char, start): | 60 newpos = min(self.pos+n, len(self.buf)) |
| 48 #probably very slow | 61 r = self.buf[self.pos:newpos].tostring() |
| 49 #jjk 02/28/96 | 62 self.pos = newpos |
| 50 for i in range(max(start, 0), len(self.buf)): | 63 return r |
| 51 if (self.buf[i] == char): | |
| 52 return(i) | |
| 53 return(-1) | |
| 54 def readline(self): | 64 def readline(self): |
| 55 #jjk 02/28/96 | 65 i = string.find(self.buf[self.pos:].tostring(), '\n') |
| 56 i = self._findCharacter('\n', self.pos) | |
| 57 if i < 0: | 66 if i < 0: |
| 58 newpos = len(self.buf) | 67 newpos = len(self.buf) |
| 59 else: | 68 else: |
| 60 newpos = i+1 | 69 newpos = self.pos+i+1 |
| 61 r = self.buf[self.pos:newpos].tostring() | 70 r = self.buf[self.pos:newpos].tostring() |
| 62 self.pos = newpos | 71 self.pos = newpos |
| 63 return r | 72 return r |
| 73 def readlines(self): | |
| 74 lines = string.splitfields(self.read(), '\n') | |
| 75 if not lines: | |
| 76 return lines | |
| 77 for i in range(len(lines)-1): | |
| 78 lines[i] = lines[i] + '\n' | |
| 79 if not lines[-1]: | |
| 80 del lines[-1] | |
| 81 return lines | |
| 64 def write(self, s): | 82 def write(self, s): |
| 65 #jjk 02/28/96 | |
| 66 if not s: return | 83 if not s: return |
| 67 if self.pos > len(self.buf): | 84 a = array('c', s) |
| 68 self.buf.fromstring('\0'*(self.pos - len(self.buf))) | 85 n = self.pos - len(self.buf) |
| 69 newpos = self.pos + len(s) | 86 if n > 0: |
| 70 self.buf[self.pos:newpos] = array.array('c', s) | 87 self.buf[len(self.buf):] = array('c', '\0')*n |
| 88 newpos = self.pos + len(a) | |
| 89 self.buf[self.pos:newpos] = a | |
| 71 self.pos = newpos | 90 self.pos = newpos |
| 91 def writelines(self, list): | |
| 92 self.write(string.joinfields(list, '')) | |
| 93 def flush(self): | |
| 94 pass | |
| 72 def getvalue(self): | 95 def getvalue(self): |
| 73 #jjk 02/28/96 | |
| 74 return self.buf.tostring() | 96 return self.buf.tostring() |
| 75 | 97 |
| 76 | 98 |
| 77 # A little test suite | 99 # A little test suite |
| 78 # identical to test suite in StringIO.py , except for "f = ArrayIO()" | |
| 79 # too bad I couldn't inherit this :-) | |
| 80 | 100 |
| 81 def test(): | 101 def test(): |
| 82 import sys | 102 import sys |
| 83 if sys.argv[1:]: | 103 if sys.argv[1:]: |
| 84 file = sys.argv[1] | 104 file = sys.argv[1] |
