Created
December 7, 2012 06:41
-
-
Save slingamn/4231260 to your computer and use it in GitHub Desktop.
_fileobject.readline() from Python's standard-library socket.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def readline(self, size=-1): | |
buf = self._rbuf | |
buf.seek(0, 2) # seek end | |
if buf.tell() > 0: | |
# check if we already have it in our buffer | |
buf.seek(0) | |
bline = buf.readline(size) | |
if bline.endswith('\n') or len(bline) == size: | |
self._rbuf = StringIO() | |
self._rbuf.write(buf.read()) | |
return bline | |
del bline | |
if size < 0: | |
# Read until \n or EOF, whichever comes first | |
if self._rbufsize <= 1: | |
# Speed up unbuffered case | |
buf.seek(0) | |
buffers = [buf.read()] | |
self._rbuf = StringIO() # reset _rbuf. we consume it via buf. | |
data = None | |
recv = self._sock.recv | |
while True: | |
try: | |
while data != "\n": | |
data = recv(1) | |
if not data: | |
break | |
buffers.append(data) | |
except error, e: | |
# The try..except to catch EINTR was moved outside the | |
# recv loop to avoid the per byte overhead. | |
if e.args[0] == EINTR: | |
continue | |
raise | |
break | |
return "".join(buffers) | |
buf.seek(0, 2) # seek end | |
self._rbuf = StringIO() # reset _rbuf. we consume it via buf. | |
while True: | |
try: | |
data = self._sock.recv(self._rbufsize) | |
except error, e: | |
if e.args[0] == EINTR: | |
continue | |
raise | |
if not data: | |
break | |
nl = data.find('\n') | |
if nl >= 0: | |
nl += 1 | |
buf.write(data[:nl]) | |
self._rbuf.write(data[nl:]) | |
del data | |
break | |
buf.write(data) | |
return buf.getvalue() | |
else: | |
# Read until size bytes or \n or EOF seen, whichever comes first | |
buf.seek(0, 2) # seek end | |
buf_len = buf.tell() | |
if buf_len >= size: | |
buf.seek(0) | |
rv = buf.read(size) | |
self._rbuf = StringIO() | |
self._rbuf.write(buf.read()) | |
return rv | |
self._rbuf = StringIO() # reset _rbuf. we consume it via buf. | |
while True: | |
try: | |
data = self._sock.recv(self._rbufsize) | |
except error, e: | |
if e.args[0] == EINTR: | |
continue | |
raise | |
if not data: | |
break | |
left = size - buf_len | |
# did we just receive a newline? | |
nl = data.find('\n', 0, left) | |
if nl >= 0: | |
nl += 1 | |
# save the excess data to _rbuf | |
self._rbuf.write(data[nl:]) | |
if buf_len: | |
buf.write(data[:nl]) | |
break | |
else: | |
# Shortcut. Avoid data copy through buf when returning | |
# a substring of our first recv(). | |
return data[:nl] | |
n = len(data) | |
if n == size and not buf_len: | |
# Shortcut. Avoid data copy through buf when | |
# returning exactly all of our first recv(). | |
return data | |
if n >= left: | |
buf.write(data[:left]) | |
self._rbuf.write(data[left:]) | |
break | |
buf.write(data) | |
buf_len += n | |
#assert buf_len == buf.tell() | |
return buf.getvalue() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment