2024-11-17 22:55:28 -05:00
|
|
|
import socket
|
|
|
|
|
2024-11-17 22:47:30 -05:00
|
|
|
class BufferOverflow(Exception):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__("Buffer overflow")
|
|
|
|
|
|
|
|
class LineBuffer():
|
2024-11-18 21:40:10 -05:00
|
|
|
__slots__ = 'buf', 'size', 'offset', 'count', 'eof', 'done',
|
2024-11-17 22:47:30 -05:00
|
|
|
|
|
|
|
BUFFER_SIZE = 4096
|
|
|
|
|
|
|
|
def __init__(self, size: int=BUFFER_SIZE):
|
|
|
|
self.buf: bytearray = bytearray(size)
|
2024-11-18 21:40:10 -05:00
|
|
|
self.size: int = size
|
2024-11-17 22:47:30 -05:00
|
|
|
self.offset: int = 0
|
2024-11-18 21:40:10 -05:00
|
|
|
self.count: int = 0
|
|
|
|
self.eof: bool = False
|
|
|
|
self.done: bool = False
|
2024-11-17 22:47:30 -05:00
|
|
|
|
2024-11-18 21:40:10 -05:00
|
|
|
def _shift(self):
|
|
|
|
count = self.size - self.offset
|
|
|
|
|
|
|
|
self.buf[0:count] = self.buf[self.offset:self.count]
|
|
|
|
|
|
|
|
self.offset = 0
|
|
|
|
self.count = count
|
|
|
|
|
|
|
|
def _is_full(self):
|
|
|
|
return self.count == self.size
|
|
|
|
|
|
|
|
def _fill(self, sock: socket.socket):
|
|
|
|
if self.eof:
|
|
|
|
return
|
|
|
|
|
|
|
|
readlen = self.size - self.count
|
|
|
|
data = sock.recv(readlen)
|
|
|
|
|
|
|
|
if data == b'':
|
|
|
|
self.eof = True
|
|
|
|
return
|
|
|
|
|
|
|
|
readlen = len(data)
|
|
|
|
|
|
|
|
self.buf[self.offset:self.offset+readlen] = data
|
|
|
|
|
|
|
|
self.count += readlen
|
|
|
|
|
|
|
|
def _flush(self, end: int):
|
|
|
|
ret = self.buf[self.offset:end+1]
|
|
|
|
|
|
|
|
self.offset = end + 1
|
|
|
|
|
|
|
|
return str(ret, 'ascii')
|
|
|
|
|
|
|
|
def readline(self, sock: socket.socket) -> str:
|
2024-11-17 22:47:30 -05:00
|
|
|
while True:
|
2024-11-18 21:40:10 -05:00
|
|
|
index = self.buf.find(b'\n', self.offset, self.count)
|
|
|
|
|
|
|
|
if index < 0:
|
|
|
|
if self._is_full():
|
|
|
|
if self.offset == 0:
|
|
|
|
raise BufferOverflow()
|
|
|
|
else:
|
|
|
|
self._shift()
|
|
|
|
else:
|
|
|
|
self._fill(sock)
|
2024-11-17 22:47:30 -05:00
|
|
|
else:
|
2024-11-18 21:40:10 -05:00
|
|
|
return self._flush(index)
|