summaryrefslogtreecommitdiff
path: root/paramiko/file.py
diff options
context:
space:
mode:
authorScott Maxwell <scott@codecobblers.com>2013-11-02 14:56:43 -0700
committerScott Maxwell <scott@codecobblers.com>2013-11-02 14:56:43 -0700
commit45e65b6e1eb47944a26e4349d41998844c155df5 (patch)
tree3bc7cb1f1fcfd1d7230f71c9e083c30485f1f951 /paramiko/file.py
parent7decda3297089b2b2e73bb9cd7e577f9b2cb2789 (diff)
downloadparamiko-45e65b6e1eb47944a26e4349d41998844c155df5.tar.gz
Make sftp.open handle binary and text, more type conversion
Diffstat (limited to 'paramiko/file.py')
-rw-r--r--paramiko/file.py49
1 files changed, 25 insertions, 24 deletions
diff --git a/paramiko/file.py b/paramiko/file.py
index 625737fe..a0d94ef2 100644
--- a/paramiko/file.py
+++ b/paramiko/file.py
@@ -47,8 +47,8 @@ class BufferedFile (object):
self.newlines = None
self._flags = 0
self._bufsize = self._DEFAULT_BUFSIZE
- self._wbuffer = StringIO()
- self._rbuffer = ''
+ self._wbuffer = BytesIO()
+ self._rbuffer = bytes()
self._at_trailing_cr = False
self._closed = False
# pos - position within the file, according to the user
@@ -89,7 +89,7 @@ class BufferedFile (object):
buffering is not turned on.
"""
self._write_all(self._wbuffer.getvalue())
- self._wbuffer = StringIO()
+ self._wbuffer = BytesIO()
return
if PY3:
@@ -144,7 +144,7 @@ class BufferedFile (object):
if (size is None) or (size < 0):
# go for broke
result = self._rbuffer
- self._rbuffer = ''
+ self._rbuffer = bytes()
self._pos += len(result)
while True:
try:
@@ -156,12 +156,12 @@ class BufferedFile (object):
result += new_data
self._realpos += len(new_data)
self._pos += len(new_data)
- return result
+ return result if self._flags & self.FLAG_BINARY else u(result)
if size <= len(self._rbuffer):
result = self._rbuffer[:size]
self._rbuffer = self._rbuffer[size:]
self._pos += len(result)
- return result
+ return result if self._flags & self.FLAG_BINARY else u(result)
while len(self._rbuffer) < size:
read_size = size - len(self._rbuffer)
if self._flags & self.FLAG_BUFFERED:
@@ -177,7 +177,7 @@ class BufferedFile (object):
result = self._rbuffer[:size]
self._rbuffer = self._rbuffer[size:]
self._pos += len(result)
- return result
+ return result if self._flags & self.FLAG_BINARY else u(result)
def readline(self, size=None):
"""
@@ -207,11 +207,11 @@ class BufferedFile (object):
if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > 0):
# edge case: the newline may be '\r\n' and we may have read
# only the first '\r' last time.
- if line[0] == '\n':
+ if line[0] == linefeed_byte_value:
line = line[1:]
- self._record_newline('\r\n')
+ self._record_newline(crlf)
else:
- self._record_newline('\r')
+ self._record_newline(cr_byte)
self._at_trailing_cr = False
# check size before looking for a linefeed, in case we already have
# enough.
@@ -221,42 +221,42 @@ class BufferedFile (object):
self._rbuffer = line[size:]
line = line[:size]
self._pos += len(line)
- return line
+ return line if self._flags & self.FLAG_BINARY else u(line)
n = size - len(line)
else:
n = self._bufsize
- if ('\n' in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and ('\r' in line)):
+ if (linefeed_byte in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (cr_byte in line)):
break
try:
new_data = self._read(n)
except EOFError:
new_data = None
if (new_data is None) or (len(new_data) == 0):
- self._rbuffer = ''
+ self._rbuffer = bytes()
self._pos += len(line)
- return line
- line += b2s(new_data)
+ return line if self._flags & self.FLAG_BINARY else u(line)
+ line += new_data
self._realpos += len(new_data)
# find the newline
- pos = line.find('\n')
+ pos = line.find(linefeed_byte)
if self._flags & self.FLAG_UNIVERSAL_NEWLINE:
- rpos = line.find('\r')
+ rpos = line.find(cr_byte)
if (rpos >= 0) and ((rpos < pos) or (pos < 0)):
pos = rpos
xpos = pos + 1
- if (line[pos] == '\r') and (xpos < len(line)) and (line[xpos] == '\n'):
+ if (line[pos] == cr_byte_value) and (xpos < len(line)) and (line[xpos] == linefeed_byte_value):
xpos += 1
self._rbuffer = line[xpos:]
lf = line[pos:xpos]
- line = line[:pos] + '\n'
- if (len(self._rbuffer) == 0) and (lf == '\r'):
+ line = line[:pos] + linefeed_byte
+ if (len(self._rbuffer) == 0) and (lf == cr_byte):
# we could read the line up to a '\r' and there could still be a
# '\n' following that we read next time. note that and eat it.
self._at_trailing_cr = True
else:
self._record_newline(lf)
self._pos += len(line)
- return line
+ return line if self._flags & self.FLAG_BINARY else u(line)
def readlines(self, sizehint=None):
"""
@@ -323,6 +323,7 @@ class BufferedFile (object):
@param data: data to write.
@type data: str
"""
+ data = b(data)
if self._closed:
raise IOError('File is closed')
if not (self._flags & self.FLAG_WRITE):
@@ -333,12 +334,12 @@ class BufferedFile (object):
self._wbuffer.write(data)
if self._flags & self.FLAG_LINE_BUFFERED:
# only scan the new data for linefeed, to avoid wasting time.
- last_newline_pos = data.rfind('\n')
+ last_newline_pos = data.rfind(linefeed_byte)
if last_newline_pos >= 0:
wbuf = self._wbuffer.getvalue()
last_newline_pos += len(wbuf) - len(data)
self._write_all(wbuf[:last_newline_pos + 1])
- self._wbuffer = StringIO()
+ self._wbuffer = BytesIO()
self._wbuffer.write(wbuf[last_newline_pos + 1:])
return
# even if we're line buffering, if the buffer has grown past the
@@ -471,7 +472,7 @@ class BufferedFile (object):
return
if self.newlines is None:
self.newlines = newline
- elif (type(self.newlines) is str) and (self.newlines != newline):
+ elif self.newlines != newline and isinstance(self.newlines, bytes_types):
self.newlines = (self.newlines, newline)
elif newline not in self.newlines:
self.newlines += (newline,)