summaryrefslogtreecommitdiffstats
path: root/Lib/socket.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-08 17:16:09 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-08 17:16:09 (GMT)
commitfb3deec2fc81a4bf7e16ddbaa8271005524ab1b0 (patch)
treeb6134f5996ac0be48abd9433f5db5ffee8e6dcd5 /Lib/socket.py
parentde7cadec54f6c67f65c35df8b5df5233ab9eb97c (diff)
downloadcpython-fb3deec2fc81a4bf7e16ddbaa8271005524ab1b0.zip
cpython-fb3deec2fc81a4bf7e16ddbaa8271005524ab1b0.tar.gz
cpython-fb3deec2fc81a4bf7e16ddbaa8271005524ab1b0.tar.bz2
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. :-)
Diffstat (limited to 'Lib/socket.py')
-rw-r--r--Lib/socket.py154
1 files changed, 88 insertions, 66 deletions
diff --git a/Lib/socket.py b/Lib/socket.py
index 6c39d76..833a456 100644
--- a/Lib/socket.py
+++ b/Lib/socket.py
@@ -210,9 +210,8 @@ class _fileobject(object):
else:
self._rbufsize = bufsize
self._wbufsize = bufsize
- # The buffers are lists of non-empty strings
- self._rbuf = []
- self._wbuf = []
+ self._rbuf = "" # A string
+ self._wbuf = [] # A list of strings
def _getclosed(self):
return self._sock is not None
@@ -261,90 +260,113 @@ class _fileobject(object):
buf_len += len(x)
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):
+ data = self._rbuf
if size < 0:
# Read until EOF
+ buffers = []
+ if data:
+ buffers.append(data)
+ self._rbuf = ""
if self._rbufsize <= 1:
recv_size = self.default_bufsize
else:
recv_size = self._rbufsize
- while 1:
+ while True:
data = self._sock.recv(recv_size)
if not data:
break
- self._rbuf.append(data)
+ buffers.append(data)
+ return "".join(buffers)
else:
- buf_len = self._get_rbuf_len()
- while buf_len < size:
- recv_size = max(self._rbufsize, size - buf_len)
+ # Read until size bytes or EOF seen, whichever comes first
+ buf_len = len(data)
+ 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)
if not data:
break
- buf_len += len(data)
- self._rbuf.append(data)
- data = "".join(self._rbuf)
- self._rbuf = []
- if 0 <= size < buf_len:
- self._rbuf.append(data[size:])
- data = data[:size]
- return data
+ buffers.append(data)
+ n = len(data)
+ if n >= left:
+ self._rbuf = data[left:]
+ buffers[-1] = data[:left]
+ break
+ buf_len += n
+ return "".join(buffers)
def readline(self, size=-1):
- data_len = 0
- for index, x in enumerate(self._rbuf):
- data_len += len(x)
- if '\n' in x or 0 <= size <= data_len:
- index += 1
- data = "".join(self._rbuf[:index])
- end = data.find('\n')
- if end < 0:
- end = len(data)
- else:
- end += 1
- if 0 <= size < end:
- end = size
- data, rest = data[:end], data[end:]
- if rest:
- 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
- data_len += len(x)
- self._rbuf.append(x)
- if '\n' in x or 0 <= size <= data_len:
- break
- data = "".join(self._rbuf)
- end = data.find('\n')
- if end < 0:
- end = len(data)
- else:
- end += 1
- if 0 <= size < end:
- end = size
- data, rest = data[:end], data[end:]
- if rest:
- self._rbuf = [rest]
+ data = self._rbuf
+ if size < 0:
+ # Read until \n or EOF, whichever comes first
+ nl = data.find('\n')
+ if nl >= 0:
+ nl += 1
+ self._rbuf = data[nl:]
+ return data[:nl]
+ buffers = []
+ if data:
+ buffers.append(data)
+ self._rbuf = ""
+ while True:
+ data = self._sock.recv(self._rbufsize)
+ if not data:
+ break
+ buffers.append(data)
+ nl = data.find('\n')
+ if nl >= 0:
+ nl += 1
+ self._rbuf = data[nl:]
+ buffers[-1] = data[:nl]
+ break
+ return "".join(buffers)
else:
- self._rbuf = []
- return data
+ # Read until size bytes or \n or EOF seen, whichever comes first
+ nl = data.find('\n', 0, size)
+ if nl >= 0:
+ nl += 1
+ self._rbuf = data[nl:]
+ return data[:nl]
+ buf_len = len(data)
+ if buf_len >= size:
+ 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):
total = 0
list = []
- while 1:
+ while True:
line = self.readline()
if not line:
break