iterio.py (6546B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\werkzeug\contrib\iterio.py 2 try: 3 from py.magic import greenlet 4 except: 5 greenlet = None 6 7 class IterIO(object): 8 9 def __new__(cls, obj): 10 try: 11 iterator = iter(obj) 12 except TypeError: 13 return IterI(obj) 14 15 return IterO(iterator) 16 17 def __iter__(self): 18 return self 19 20 def tell(self): 21 if self.closed: 22 raise ValueError('I/O operation on closed file') 23 return self.pos 24 25 def isatty(self): 26 if self.closed: 27 raise ValueError('I/O operation on closed file') 28 return False 29 30 def seek(self, pos, mode = 0): 31 if self.closed: 32 raise ValueError('I/O operation on closed file') 33 raise IOError(9, 'Bad file descriptor') 34 35 def truncate(self, size = None): 36 if self.closed: 37 raise ValueError('I/O operation on closed file') 38 raise IOError(9, 'Bad file descriptor') 39 40 def write(self, s): 41 if self.closed: 42 raise ValueError('I/O operation on closed file') 43 raise IOError(9, 'Bad file descriptor') 44 45 def writelines(self, list): 46 if self.closed: 47 raise ValueError('I/O operation on closed file') 48 raise IOError(9, 'Bad file descriptor') 49 50 def read(self, n = -1): 51 if self.closed: 52 raise ValueError('I/O operation on closed file') 53 raise IOError(9, 'Bad file descriptor') 54 55 def readlines(self, sizehint = 0): 56 if self.closed: 57 raise ValueError('I/O operation on closed file') 58 raise IOError(9, 'Bad file descriptor') 59 60 def readline(self, length = None): 61 if self.closed: 62 raise ValueError('I/O operation on closed file') 63 raise IOError(9, 'Bad file descriptor') 64 65 def flush(self): 66 if self.closed: 67 raise ValueError('I/O operation on closed file') 68 raise IOError(9, 'Bad file descriptor') 69 70 def next(self): 71 if self.closed: 72 raise StopIteration() 73 line = self.readline() 74 if not line: 75 raise StopIteration() 76 return line 77 78 79 class IterI(IterIO): 80 81 def __new__(cls, func): 82 if greenlet is None: 83 raise RuntimeError('IterI requires greenlet support') 84 stream = object.__new__(cls) 85 stream.__init__(greenlet.getcurrent()) 86 87 def run(): 88 func(stream) 89 stream.flush() 90 91 g = greenlet(run, stream._parent) 92 while 1: 93 rv = g.switch() 94 if not rv: 95 return 96 yield rv[0] 97 98 def __init__(self, parent): 99 self._parent = parent 100 self._buffer = [] 101 self.closed = False 102 self.pos = 0 103 104 def close(self): 105 if not self.closed: 106 self.closed = True 107 108 def write(self, s): 109 if self.closed: 110 raise ValueError('I/O operation on closed file') 111 self.pos += len(s) 112 self._buffer.append(s) 113 114 def writelines(self, list): 115 self.write(''.join(list)) 116 117 def flush(self): 118 if self.closed: 119 raise ValueError('I/O operation on closed file') 120 data = ''.join(self._buffer) 121 self._buffer = [] 122 self._parent.switch((data,)) 123 124 125 class IterO(IterIO): 126 127 def __new__(cls, gen): 128 return object.__new__(cls) 129 130 def __init__(self, gen): 131 self._gen = gen 132 self._buf = '' 133 self.closed = False 134 self.pos = 0 135 136 def __iter__(self): 137 return self 138 139 def close(self): 140 if not self.closed: 141 self.closed = True 142 if hasattr(self._gen, 'close'): 143 self._gen.close() 144 145 def seek(self, pos, mode = 0): 146 if self.closed: 147 raise ValueError('I/O operation on closed file') 148 if mode == 1: 149 pos += self.pos 150 else: 151 if mode == 2: 152 self.read() 153 self.pos = min(self.pos, self.pos + pos) 154 return 155 if mode != 0: 156 raise IOError('Invalid argument') 157 buf = [] 158 try: 159 tmp_end_pos = len(self._buf) 160 while pos > tmp_end_pos: 161 item = self._gen.next() 162 tmp_end_pos += len(item) 163 buf.append(item) 164 165 except StopIteration: 166 pass 167 168 if buf: 169 self._buf += ''.join(buf) 170 self.pos = max(0, pos) 171 172 def read(self, n = -1): 173 if self.closed: 174 raise ValueError('I/O operation on closed file') 175 if n < 0: 176 self._buf += ''.join(self._gen) 177 result = self._buf[self.pos:] 178 self.pos += len(result) 179 return result 180 new_pos = self.pos + n 181 buf = [] 182 try: 183 tmp_end_pos = len(self._buf) 184 while new_pos > tmp_end_pos: 185 item = self._gen.next() 186 tmp_end_pos += len(item) 187 buf.append(item) 188 189 except StopIteration: 190 pass 191 192 if buf: 193 self._buf += ''.join(buf) 194 new_pos = max(0, new_pos) 195 try: 196 return self._buf[self.pos:new_pos] 197 finally: 198 self.pos = min(new_pos, len(self._buf)) 199 200 def readline(self, length = None): 201 if self.closed: 202 raise ValueError('I/O operation on closed file') 203 nl_pos = self._buf.find('\n', self.pos) 204 buf = [] 205 try: 206 pos = self.pos 207 while nl_pos < 0: 208 item = self._gen.next() 209 local_pos = item.find('\n') 210 buf.append(item) 211 if local_pos >= 0: 212 nl_pos = pos + local_pos 213 break 214 pos += len(item) 215 216 except StopIteration: 217 pass 218 219 if buf: 220 self._buf += ''.join(buf) 221 if nl_pos < 0: 222 new_pos = len(self._buf) 223 else: 224 new_pos = nl_pos + 1 225 if length is not None and self.pos + length < new_pos: 226 new_pos = self.pos + length 227 try: 228 return self._buf[self.pos:new_pos] 229 finally: 230 self.pos = min(new_pos, len(self._buf)) 231 232 def readlines(self, sizehint = 0): 233 total = 0 234 lines = [] 235 line = self.readline() 236 while line: 237 lines.append(line) 238 total += len(line) 239 if 0 < sizehint <= total: 240 break 241 line = self.readline() 242 243 return lines