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]