def read()

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