'Read one line from the input stream and return the
decoded data.
size, if given, is passed as size argument to the
read() method.'

def readline(self, size=None, keepends=True):

    if self.linebuffer:
        line = self.linebuffer[0]
        del self.linebuffer[0]
        if (len(self.linebuffer) == 1):
            self.charbuffer = self.linebuffer[0]
            self.linebuffer = None
        if (not keepends):
            line = line.splitlines(False)[0]
        return line
    readsize = (size or 72)
    line = ''
    while True:
        data = self.read(readsize, firstline=True)
        if data:
            if data.endswith('\r'):
                data += self.read(size=1, chars=1)
        line += data
        lines = line.splitlines(True)
        if lines:
            if (len(lines) > 1):
                line = lines[0]
                del lines[0]
                if (len(lines) > 1):
                    lines[(-1)] += self.charbuffer
                    self.linebuffer = lines
                    self.charbuffer = None
                else:
                    self.charbuffer = (lines[0] + self.charbuffer)
                if (not keepends):
                    line = line.splitlines(False)[0]
                break
            line0withend = lines[0]
            line0withoutend = lines[0].splitlines(False)[0]
            if (line0withend != line0withoutend):
                self.charbuffer = (''.join(lines[1:]) + self.charbuffer)
                if keepends:
                    line = line0withend
                else:
                    line = line0withoutend
                break
        if ((not data) or (size is not None)):
            if (line and (not keepends)):
                line = line.splitlines(False)[0]
            break
        if (readsize < 8000):
            readsize *= 2
    return line
