in src/base64io/__init__.py [0:0]
def read(self, b=-1):
# type: (int) -> bytes
"""Read bytes from wrapped stream, base64-decoding before return.
.. note::
The number of bytes requested from the wrapped stream is adjusted to return the
requested number of bytes after decoding returned bytes.
:param int b: Number of bytes to read
:returns: Decoded bytes from wrapped stream
:rtype: bytes
"""
if self.closed:
raise ValueError("I/O operation on closed file.")
if not self.readable():
raise IOError("Stream is not readable")
if b is None or b < 0:
b = -1
_bytes_to_read = -1
elif b == 0:
_bytes_to_read = 0
elif b > 0:
# Calculate number of encoded bytes that must be read to get b raw bytes.
_bytes_to_read = int((b - len(self.__read_buffer)) * 4 / 3)
_bytes_to_read += 4 - _bytes_to_read % 4
# Read encoded bytes from wrapped stream.
data = _to_bytes(self.__wrapped.read(_bytes_to_read))
# Remove whitespace from read data and attempt to read more data to get the desired
# number of bytes.
if any(char in data for char in string.whitespace.encode("utf-8")):
data = self._read_additional_data_removing_whitespace(data, _bytes_to_read)
results = io.BytesIO()
# First, load any stashed bytes
results.write(self.__read_buffer)
# Decode encoded bytes.
results.write(base64.b64decode(data))
results.seek(0)
output_data = results.read(b)
# Stash any extra bytes for the next run.
self.__read_buffer = results.read()
return output_data