1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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
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
52
53
54 self._pos = self._realpos = 0
55
56 self._size = 0
57
60
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
74 """
75 Close the file. Future read and write operations will fail.
76 """
77 self.flush()
78 self._closed = True
79
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:
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:
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
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
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
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
211
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
219
220 if (size is not None) and (size >= 0):
221 if len(line) >= size:
222
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
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
256
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
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
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
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
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
344
345 if self._wbuffer.tell() >= self._bufsize:
346 self.flush()
347 return
348
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
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
372
373
374
376 """
377 (subclass override)
378 Read data from the stream. Return ``None`` or raise ``EOFError`` to
379 indicate EOF.
380 """
381 raise EOFError()
382
384 """
385 (subclass override)
386 Write data into the stream.
387 """
388 raise IOError('write not implemented')
389
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
402
404 """
405 Subclasses call this method to initialize the BufferedFile.
406 """
407
408 self._bufsize = self._DEFAULT_BUFSIZE
409 if bufsize < 0:
410
411
412 bufsize = 0
413 if bufsize == 1:
414
415
416
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
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
439
440
441 self.newlines = None
442
444
445
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
458
459
460
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