A number of methods in UnitChecker were called very, very frequently
[translate_toolkit.git] / misc / wStringIO.py
blob2c8d4ae1dd0692fd2097f4437909c0c8d0557e60
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright 2004-2006 Zuza Software Foundation
5 #
6 # This file is part of translate.
8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 """A wrapper for cStringIO that provides more of the functions of StringIO at the speed of cStringIO"""
24 import cStringIO
26 class StringIO:
27 def __init__(self, buf = ''):
28 if not isinstance(buf, (str, unicode)):
29 buf = str(buf)
30 if isinstance(buf, unicode):
31 buf = buf.encode('utf-8')
32 self.len = len(buf)
33 self.buf = cStringIO.StringIO()
34 self.buf.write(buf)
35 self.buf.seek(0)
36 self.pos = 0
37 self.closed = 0
39 def __iter__(self):
40 return self
42 def next(self):
43 if self.closed:
44 raise StopIteration
45 r = self.readline()
46 if not r:
47 raise StopIteration
48 return r
50 def close(self):
51 """Free the memory buffer.
52 """
53 if not self.closed:
54 self.closed = 1
55 del self.buf, self.pos
57 def isatty(self):
58 if self.closed:
59 raise ValueError, "I/O operation on closed file"
60 return False
62 def seek(self, pos, mode = 0):
63 if self.closed:
64 raise ValueError, "I/O operation on closed file"
65 self.buf.seek(pos, mode)
66 self.pos = self.buf.tell()
68 def tell(self):
69 if self.closed:
70 raise ValueError, "I/O operation on closed file"
71 return self.pos
73 def read(self, n = None):
74 if self.closed:
75 raise ValueError, "I/O operation on closed file"
76 if n == None:
77 r = self.buf.read()
78 else:
79 r = self.buf.read(n)
80 self.pos = self.buf.tell()
81 return r
83 def readline(self, length=None):
84 if self.closed:
85 raise ValueError, "I/O operation on closed file"
86 if length is not None:
87 r = self.buf.readline(length)
88 else:
89 r = self.buf.readline(length)
90 self.pos = self.buf.tell()
91 return r
93 def readlines(self):
94 if self.closed:
95 raise ValueError, "I/O operation on closed file"
96 lines = self.buf.readlines()
97 self.pos = self.buf.tell()
98 return lines
100 def truncate(self, size=None):
101 if self.closed:
102 raise ValueError, "I/O operation on closed file"
103 self.buf.truncate(size)
104 self.pos = self.buf.tell()
105 self.buf.seek(0, 2)
106 self.len = self.buf.tell()
107 self.buf.seek(self.pos)
109 def write(self, s):
110 if self.closed:
111 raise ValueError, "I/O operation on closed file"
112 origpos = self.buf.tell()
113 self.buf.write(s)
114 self.pos = self.buf.tell()
115 if origpos + len(s) > self.len:
116 self.buf.seek(0, 2)
117 self.len = self.buf.tell()
118 self.buf.seek(self.pos)
120 def writelines(self, lines):
121 if self.closed:
122 raise ValueError, "I/O operation on closed file"
123 self.buf.writelines(lines)
124 self.pos = self.buf.tell()
125 self.buf.seek(0, 2)
126 self.len = self.buf.tell()
127 self.buf.seek(self.pos)
129 def flush(self):
130 if self.closed:
131 raise ValueError, "I/O operation on closed file"
132 self.buf.flush()
134 def getvalue(self):
135 if self.closed:
136 raise ValueError, "I/O operation on closed file"
137 return self.buf.getvalue()
139 class CatchStringOutput(StringIO, object):
140 """catches the output before it is closed and sends it to an onclose method"""
141 def __init__(self, onclose):
142 """Set up the output stream, and remember a method to call on closing"""
143 StringIO.__init__(self)
144 self.onclose = onclose
146 def close(self):
147 """wrap the underlying close method, to pass the value to onclose before it goes"""
148 value = self.getvalue()
149 self.onclose(value)
150 super(CatchStringOutput, self).close()
152 def slam(self):
153 """use this method to force the closing of the stream if it isn't closed yet"""
154 if not self.closed:
155 self.close()