Another refactoring of read() and readline(), this time based on the

observation that _rbuf could never have more than one string in it.
So make _rbuf a string.  The code branches for size<0 and size>=0
are completely separate now, both in read() and in readline().

I checked for tabs this time. :-)
This commit is contained in:
Guido van Rossum 2002-08-08 17:16:09 +00:00
parent de7cadec54
commit fb3deec2fc
1 changed files with 88 additions and 66 deletions

View File

@ -210,9 +210,8 @@ class _fileobject(object):
else: else:
self._rbufsize = bufsize self._rbufsize = bufsize
self._wbufsize = bufsize self._wbufsize = bufsize
# The buffers are lists of non-empty strings self._rbuf = "" # A string
self._rbuf = [] self._wbuf = [] # A list of strings
self._wbuf = []
def _getclosed(self): def _getclosed(self):
return self._sock is not None return self._sock is not None
@ -261,90 +260,113 @@ class _fileobject(object):
buf_len += len(x) buf_len += len(x)
return buf_len return buf_len
def _get_rbuf_len(self):
buf_len = 0
for x in self._rbuf:
buf_len += len(x)
return buf_len
def read(self, size=-1): def read(self, size=-1):
data = self._rbuf
if size < 0: if size < 0:
# Read until EOF # Read until EOF
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
if self._rbufsize <= 1: if self._rbufsize <= 1:
recv_size = self.default_bufsize recv_size = self.default_bufsize
else: else:
recv_size = self._rbufsize recv_size = self._rbufsize
while 1: while True:
data = self._sock.recv(recv_size) data = self._sock.recv(recv_size)
if not data: if not data:
break break
self._rbuf.append(data) buffers.append(data)
return "".join(buffers)
else: else:
buf_len = self._get_rbuf_len() # Read until size bytes or EOF seen, whichever comes first
while buf_len < size: buf_len = len(data)
recv_size = max(self._rbufsize, size - buf_len) if buf_len >= size:
self._rbuf = data[size:]
return data[:size]
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
while True:
left = size - buf_len
recv_size = max(self._rbufsize, left)
data = self._sock.recv(recv_size) data = self._sock.recv(recv_size)
if not data: if not data:
break break
buf_len += len(data) buffers.append(data)
self._rbuf.append(data) n = len(data)
data = "".join(self._rbuf) if n >= left:
self._rbuf = [] self._rbuf = data[left:]
if 0 <= size < buf_len: buffers[-1] = data[:left]
self._rbuf.append(data[size:]) break
data = data[:size] buf_len += n
return data return "".join(buffers)
def readline(self, size=-1): def readline(self, size=-1):
data_len = 0 data = self._rbuf
for index, x in enumerate(self._rbuf): if size < 0:
data_len += len(x) # Read until \n or EOF, whichever comes first
if '\n' in x or 0 <= size <= data_len: nl = data.find('\n')
index += 1 if nl >= 0:
data = "".join(self._rbuf[:index]) nl += 1
end = data.find('\n') self._rbuf = data[nl:]
if end < 0: return data[:nl]
end = len(data) buffers = []
else: if data:
end += 1 buffers.append(data)
if 0 <= size < end: self._rbuf = ""
end = size while True:
data, rest = data[:end], data[end:] data = self._sock.recv(self._rbufsize)
if rest: if not data:
self._rbuf[:index] = [rest]
else:
del self._rbuf[:index]
return data
recv_size = self._rbufsize
while 1:
if size >= 0:
recv_size = min(self._rbufsize, size - data_len)
x = self._sock.recv(recv_size)
if not x:
break break
data_len += len(x) buffers.append(data)
self._rbuf.append(x) nl = data.find('\n')
if '\n' in x or 0 <= size <= data_len: if nl >= 0:
nl += 1
self._rbuf = data[nl:]
buffers[-1] = data[:nl]
break break
data = "".join(self._rbuf) return "".join(buffers)
end = data.find('\n')
if end < 0:
end = len(data)
else: else:
end += 1 # Read until size bytes or \n or EOF seen, whichever comes first
if 0 <= size < end: nl = data.find('\n', 0, size)
end = size if nl >= 0:
data, rest = data[:end], data[end:] nl += 1
if rest: self._rbuf = data[nl:]
self._rbuf = [rest] return data[:nl]
else: buf_len = len(data)
self._rbuf = [] if buf_len >= size:
return data self._rbuf = data[size:]
return data[:size]
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
while True:
data = self._sock.recv(self._rbufsize)
if not data:
break
buffers.append(data)
left = size - buf_len
nl = data.find('\n', 0, left)
if nl >= 0:
nl += 1
self._rbuf = data[nl:]
buffers[-1] = data[:nl]
break
n = len(data)
if n >= left:
self._rbuf = data[left:]
buffers[-1] = data[:left]
break
buf_len += n
return "".join(buffers)
def readlines(self, sizehint=0): def readlines(self, sizehint=0):
total = 0 total = 0
list = [] list = []
while 1: while True:
line = self.readline() line = self.readline()
if not line: if not line:
break break