Package paramiko :: Module file
[frames] | no frames]

Source Code for Module paramiko.file

  1  # Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com> 
  2  # 
  3  # This file is part of paramiko. 
  4  # 
  5  # Paramiko is free software; you can redistribute it and/or modify it under the 
  6  # terms of the GNU Lesser General Public License as published by the Free 
  7  # Software Foundation; either version 2.1 of the License, or (at your option) 
  8  # any later version. 
  9  # 
 10  # Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY 
 11  # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 
 12  # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 13  # details. 
 14  # 
 15  # You should have received a copy of the GNU Lesser General Public License 
 16  # along with Paramiko; if not, write to the Free Software Foundation, Inc., 
 17  # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. 
 18  from paramiko.common import linefeed_byte_value, crlf, cr_byte, linefeed_byte, \ 
 19      cr_byte_value 
 20  from paramiko.py3compat import BytesIO, PY2, u, b, bytes_types 
21 22 23 -class BufferedFile (object):
24 """ 25 Reusable base class to implement Python-style file buffering around a 26 simpler stream. 27 """ 28 29 _DEFAULT_BUFSIZE = 8192 30 31 SEEK_SET = 0 32 SEEK_CUR = 1 33 SEEK_END = 2 34 35 FLAG_READ = 0x1 36 FLAG_WRITE = 0x2 37 FLAG_APPEND = 0x4 38 FLAG_BINARY = 0x10 39 FLAG_BUFFERED = 0x20 40 FLAG_LINE_BUFFERED = 0x40 41 FLAG_UNIVERSAL_NEWLINE = 0x80 42
43 - def __init__(self):
44 self.newlines = None 45 self._flags = 0 46 self._bufsize = self._DEFAULT_BUFSIZE 47 self._wbuffer = BytesIO() 48 self._rbuffer = bytes() 49 self._at_trailing_cr = False 50 self._closed = False 51 # pos - position within the file, according to the user 52 # realpos - position according the OS 53 # (these may be different because we buffer for line reading) 54 self._pos = self._realpos = 0 55 # size only matters for seekable files 56 self._size = 0
57
58 - def __del__(self):
59 self.close()
60
61 - def __iter__(self):
62 """ 63 Returns an iterator that can be used to iterate over the lines in this 64 file. This iterator happens to return the file itself, since a file is 65 its own iterator. 66 67 :raises ValueError: if the file is closed. 68 """ 69 if self._closed: 70 raise ValueError('I/O operation on closed file') 71 return self
72
73 - def close(self):
74 """ 75 Close the file. Future read and write operations will fail. 76 """ 77 self.flush() 78 self._closed = True
79
80 - def flush(self):
81 """ 82 Write out any data in the write buffer. This may do nothing if write 83 buffering is not turned on. 84 """ 85 self._write_all(self._wbuffer.getvalue()) 86 self._wbuffer = BytesIO() 87 return
88 89 if PY2:
90 - def next(self):
91 """ 92 Returns the next line from the input, or raises 93 `~exceptions.StopIteration` when EOF is hit. Unlike Python file 94 objects, it's okay to mix calls to `next` and `readline`. 95 96 :raises StopIteration: when the end of the file is reached. 97 98 :return: a line (`str`) read from the file. 99 """ 100 line = self.readline() 101 if not line: 102 raise StopIteration 103 return line
104 else:
105 - def __next__(self):
106 """ 107 Returns the next line from the input, or raises L{StopIteration} when 108 EOF is hit. Unlike python file objects, it's okay to mix calls to 109 C{next} and L{readline}. 110 111 @raise StopIteration: when the end of the file is reached. 112 113 @return: a line read from the file. 114 @rtype: str 115 """ 116 line = self.readline() 117 if not line: 118 raise StopIteration 119 return line
120
121 - def read(self, size=None):
122 """ 123 Read at most ``size`` bytes from the file (less if we hit the end of the 124 file first). If the ``size`` argument is negative or omitted, read all 125 the remaining data in the file. 126 127 .. note:: 128 ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in 129 ``self._flags``), because SSH treats all files as binary, since we 130 have no idea what encoding the file is in, or even if the file is 131 text data. 132 133 :param int size: maximum number of bytes to read 134 :return: 135 data read from the file (as bytes), or an empty string if EOF was 136 encountered immediately 137 """ 138 if self._closed: 139 raise IOError('File is closed') 140 if not (self._flags & self.FLAG_READ): 141 raise IOError('File is not open for reading') 142 if (size is None) or (size < 0): 143 # go for broke 144 result = self._rbuffer 145 self._rbuffer = bytes() 146 self._pos += len(result) 147 while True: 148 try: 149 new_data = self._read(self._DEFAULT_BUFSIZE) 150 except EOFError: 151 new_data = None 152 if (new_data is None) or (len(new_data) == 0): 153 break 154 result += new_data 155 self._realpos += len(new_data) 156 self._pos += len(new_data) 157 return result 158 if size <= len(self._rbuffer): 159 result = self._rbuffer[:size] 160 self._rbuffer = self._rbuffer[size:] 161 self._pos += len(result) 162 return result 163 while len(self._rbuffer) < size: 164 read_size = size - len(self._rbuffer) 165 if self._flags & self.FLAG_BUFFERED: 166 read_size = max(self._bufsize, read_size) 167 try: 168 new_data = self._read(read_size) 169 except EOFError: 170 new_data = None 171 if (new_data is None) or (len(new_data) == 0): 172 break 173 self._rbuffer += new_data 174 self._realpos += len(new_data) 175 result = self._rbuffer[:size] 176 self._rbuffer = self._rbuffer[size:] 177 self._pos += len(result) 178 return result
179
180 - def readline(self, size=None):
181 """ 182 Read one entire line from the file. A trailing newline character is 183 kept in the string (but may be absent when a file ends with an 184 incomplete line). If the size argument is present and non-negative, it 185 is a maximum byte count (including the trailing newline) and an 186 incomplete line may be returned. An empty string is returned only when 187 EOF is encountered immediately. 188 189 .. note:: 190 Unlike stdio's ``fgets``, the returned string contains null 191 characters (``'\\0'``) if they occurred in the input. 192 193 :param int size: maximum length of returned string. 194 :return: 195 next line of the file, or an empty string if the end of the 196 file has been reached. 197 198 If the file was opened in binary (``'b'``) mode: bytes are returned 199 Else: the encoding of the file is assumed to be UTF-8 and character 200 strings (`str`) are returned 201 """ 202 # it's almost silly how complex this function is. 203 if self._closed: 204 raise IOError('File is closed') 205 if not (self._flags & self.FLAG_READ): 206 raise IOError('File not open for reading') 207 line = self._rbuffer 208 while True: 209 if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > 0): 210 # edge case: the newline may be '\r\n' and we may have read 211 # only the first '\r' last time. 212 if line[0] == linefeed_byte_value: 213 line = line[1:] 214 self._record_newline(crlf) 215 else: 216 self._record_newline(cr_byte) 217 self._at_trailing_cr = False 218 # check size before looking for a linefeed, in case we already have 219 # enough. 220 if (size is not None) and (size >= 0): 221 if len(line) >= size: 222 # truncate line and return 223 self._rbuffer = line[size:] 224 line = line[:size] 225 self._pos += len(line) 226 return line if self._flags & self.FLAG_BINARY else u(line) 227 n = size - len(line) 228 else: 229 n = self._bufsize 230 if (linefeed_byte in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (cr_byte in line)): 231 break 232 try: 233 new_data = self._read(n) 234 except EOFError: 235 new_data = None 236 if (new_data is None) or (len(new_data) == 0): 237 self._rbuffer = bytes() 238 self._pos += len(line) 239 return line if self._flags & self.FLAG_BINARY else u(line) 240 line += new_data 241 self._realpos += len(new_data) 242 # find the newline 243 pos = line.find(linefeed_byte) 244 if self._flags & self.FLAG_UNIVERSAL_NEWLINE: 245 rpos = line.find(cr_byte) 246 if (rpos >= 0) and (rpos < pos or pos < 0): 247 pos = rpos 248 xpos = pos + 1 249 if (line[pos] == cr_byte_value) and (xpos < len(line)) and (line[xpos] == linefeed_byte_value): 250 xpos += 1 251 self._rbuffer = line[xpos:] 252 lf = line[pos:xpos] 253 line = line[:pos] + linefeed_byte 254 if (len(self._rbuffer) == 0) and (lf == cr_byte): 255 # we could read the line up to a '\r' and there could still be a 256 # '\n' following that we read next time. note that and eat it. 257 self._at_trailing_cr = True 258 else: 259 self._record_newline(lf) 260 self._pos += len(line) 261 return line if self._flags & self.FLAG_BINARY else u(line)
262
263 - def readlines(self, sizehint=None):
264 """ 265 Read all remaining lines using `readline` and return them as a list. 266 If the optional ``sizehint`` argument is present, instead of reading up 267 to EOF, whole lines totalling approximately sizehint bytes (possibly 268 after rounding up to an internal buffer size) are read. 269 270 :param int sizehint: desired maximum number of bytes to read. 271 :return: `list` of lines read from the file. 272 """ 273 lines = [] 274 byte_count = 0 275 while True: 276 line = self.readline() 277 if len(line) == 0: 278 break 279 lines.append(line) 280 byte_count += len(line) 281 if (sizehint is not None) and (byte_count >= sizehint): 282 break 283 return lines
284
285 - def seek(self, offset, whence=0):
286 """ 287 Set the file's current position, like stdio's ``fseek``. Not all file 288 objects support seeking. 289 290 .. note:: 291 If a file is opened in append mode (``'a'`` or ``'a+'``), any seek 292 operations will be undone at the next write (as the file position 293 will move back to the end of the file). 294 295 :param int offset: 296 position to move to within the file, relative to ``whence``. 297 :param int whence: 298 type of movement: 0 = absolute; 1 = relative to the current 299 position; 2 = relative to the end of the file. 300 301 :raises IOError: if the file doesn't support random access. 302 """ 303 raise IOError('File does not support seeking.')
304
305 - def tell(self):
306 """ 307 Return the file's current position. This may not be accurate or 308 useful if the underlying file doesn't support random access, or was 309 opened in append mode. 310 311 :return: file position (`number <int>` of bytes). 312 """ 313 return self._pos
314
315 - def write(self, data):
316 """ 317 Write data to the file. If write buffering is on (``bufsize`` was 318 specified and non-zero), some or all of the data may not actually be 319 written yet. (Use `flush` or `close` to force buffered data to be 320 written out.) 321 322 :param str data: data to write 323 """ 324 data = b(data) 325 if self._closed: 326 raise IOError('File is closed') 327 if not (self._flags & self.FLAG_WRITE): 328 raise IOError('File not open for writing') 329 if not (self._flags & self.FLAG_BUFFERED): 330 self._write_all(data) 331 return 332 self._wbuffer.write(data) 333 if self._flags & self.FLAG_LINE_BUFFERED: 334 # only scan the new data for linefeed, to avoid wasting time. 335 last_newline_pos = data.rfind(linefeed_byte) 336 if last_newline_pos >= 0: 337 wbuf = self._wbuffer.getvalue() 338 last_newline_pos += len(wbuf) - len(data) 339 self._write_all(wbuf[:last_newline_pos + 1]) 340 self._wbuffer = BytesIO() 341 self._wbuffer.write(wbuf[last_newline_pos + 1:]) 342 return 343 # even if we're line buffering, if the buffer has grown past the 344 # buffer size, force a flush. 345 if self._wbuffer.tell() >= self._bufsize: 346 self.flush() 347 return
348
349 - def writelines(self, sequence):
350 """ 351 Write a sequence of strings to the file. The sequence can be any 352 iterable object producing strings, typically a list of strings. (The 353 name is intended to match `readlines`; `writelines` does not add line 354 separators.) 355 356 :param iterable sequence: an iterable sequence of strings. 357 """ 358 for line in sequence: 359 self.write(line) 360 return
361
362 - def xreadlines(self):
363 """ 364 Identical to ``iter(f)``. This is a deprecated file interface that 365 predates Python iterator support. 366 """ 367 return self
368 369 @property
370 - def closed(self):
371 return self._closed
372 373 ### overrides... 374
375 - def _read(self, size):
376 """ 377 (subclass override) 378 Read data from the stream. Return ``None`` or raise ``EOFError`` to 379 indicate EOF. 380 """ 381 raise EOFError()
382
383 - def _write(self, data):
384 """ 385 (subclass override) 386 Write data into the stream. 387 """ 388 raise IOError('write not implemented')
389
390 - def _get_size(self):
391 """ 392 (subclass override) 393 Return the size of the file. This is called from within `_set_mode` 394 if the file is opened in append mode, so the file position can be 395 tracked and `seek` and `tell` will work correctly. If the file is 396 a stream that can't be randomly accessed, you don't need to override 397 this method, 398 """ 399 return 0
400 401 ### internals... 402
403 - def _set_mode(self, mode='r', bufsize=-1):
404 """ 405 Subclasses call this method to initialize the BufferedFile. 406 """ 407 # set bufsize in any event, because it's used for readline(). 408 self._bufsize = self._DEFAULT_BUFSIZE 409 if bufsize < 0: 410 # do no buffering by default, because otherwise writes will get 411 # buffered in a way that will probably confuse people. 412 bufsize = 0 413 if bufsize == 1: 414 # apparently, line buffering only affects writes. reads are only 415 # buffered if you call readline (directly or indirectly: iterating 416 # over a file will indirectly call readline). 417 self._flags |= self.FLAG_BUFFERED | self.FLAG_LINE_BUFFERED 418 elif bufsize > 1: 419 self._bufsize = bufsize 420 self._flags |= self.FLAG_BUFFERED 421 self._flags &= ~self.FLAG_LINE_BUFFERED 422 elif bufsize == 0: 423 # unbuffered 424 self._flags &= ~(self.FLAG_BUFFERED | self.FLAG_LINE_BUFFERED) 425 426 if ('r' in mode) or ('+' in mode): 427 self._flags |= self.FLAG_READ 428 if ('w' in mode) or ('+' in mode): 429 self._flags |= self.FLAG_WRITE 430 if 'a' in mode: 431 self._flags |= self.FLAG_WRITE | self.FLAG_APPEND 432 self._size = self._get_size() 433 self._pos = self._realpos = self._size 434 if 'b' in mode: 435 self._flags |= self.FLAG_BINARY 436 if 'U' in mode: 437 self._flags |= self.FLAG_UNIVERSAL_NEWLINE 438 # built-in file objects have this attribute to store which kinds of 439 # line terminations they've seen: 440 # <http://www.python.org/doc/current/lib/built-in-funcs.html> 441 self.newlines = None
442
443 - def _write_all(self, data):
444 # the underlying stream may be something that does partial writes (like 445 # a socket). 446 while len(data) > 0: 447 count = self._write(data) 448 data = data[count:] 449 if self._flags & self.FLAG_APPEND: 450 self._size += count 451 self._pos = self._realpos = self._size 452 else: 453 self._pos += count 454 self._realpos += count 455 return None
456
457 - def _record_newline(self, newline):
458 # silliness about tracking what kinds of newlines we've seen. 459 # i don't understand why it can be None, a string, or a tuple, instead 460 # of just always being a tuple, but we'll emulate that behavior anyway. 461 if not (self._flags & self.FLAG_UNIVERSAL_NEWLINE): 462 return 463 if self.newlines is None: 464 self.newlines = newline 465 elif self.newlines != newline and isinstance(self.newlines, bytes_types): 466 self.newlines = (self.newlines, newline) 467 elif newline not in self.newlines: 468 self.newlines += (newline,)
469