'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
    else:
        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
