12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- # -*- coding: utf-8 -
- #
- # This file is part of gunicorn released under the MIT license.
- # See the NOTICE for more information.
- import io
- import os
- # Classes that can undo reading data from
- # a given type of data source.
- class Unreader(object):
- def __init__(self):
- self.buf = io.BytesIO()
- def chunk(self):
- raise NotImplementedError()
- def read(self, size=None):
- if size is not None and not isinstance(size, int):
- raise TypeError("size parameter must be an int or long.")
- if size is not None:
- if size == 0:
- return b""
- if size < 0:
- size = None
- self.buf.seek(0, os.SEEK_END)
- if size is None and self.buf.tell():
- ret = self.buf.getvalue()
- self.buf = io.BytesIO()
- return ret
- if size is None:
- d = self.chunk()
- return d
- while self.buf.tell() < size:
- chunk = self.chunk()
- if not chunk:
- ret = self.buf.getvalue()
- self.buf = io.BytesIO()
- return ret
- self.buf.write(chunk)
- data = self.buf.getvalue()
- self.buf = io.BytesIO()
- self.buf.write(data[size:])
- return data[:size]
- def unread(self, data):
- self.buf.seek(0, os.SEEK_END)
- self.buf.write(data)
- class SocketUnreader(Unreader):
- def __init__(self, sock, max_chunk=8192):
- super().__init__()
- self.sock = sock
- self.mxchunk = max_chunk
- def chunk(self):
- return self.sock.recv(self.mxchunk)
- class IterUnreader(Unreader):
- def __init__(self, iterable):
- super().__init__()
- self.iter = iter(iterable)
- def chunk(self):
- if not self.iter:
- return b""
- try:
- return next(self.iter)
- except StopIteration:
- self.iter = None
- return b""
|