docs: def _read_bytes(self, b):
          """Reads the requested number of bytes from a streaming message body.
  
          :param int b: Number of bytes to read
          :raises NotSupportedError: if content type is not supported
          """
          _LOGGER.debug("%d bytes requested from stream with content type: %s", b, self.content_type)
          if 0 <= b <= len(self.output_buffer) or self.__message_complete:
              _LOGGER.debug("No need to read from source stream or source stream closed")
              return
  
          if self.content_type == ContentType.FRAMED_DATA:
              _LOGGER.debug("Reading to framed body")
              self.output_buffer += self._read_bytes_to_framed_body(b)
          elif self.content_type == ContentType.NO_FRAMING:
              _LOGGER.debug("Reading to non-framed body")
              self.output_buffer += self._read_bytes_to_non_framed_body(b)
          else:
              raise NotSupportedError("Unsupported content type")
  
          # To maintain backwards compatibility, only enforce this if a CMM is provided by the caller.
          if self.config.key_provider is None and self.config.source_length is not None:
              # Enforce that if the caller provided a source length value, the total bytes encrypted
              # must not exceed that value.
              if self._bytes_encrypted > self.config.source_length:
                  raise CustomMaximumValueExceeded(
                      "Bytes encrypted has exceeded stated source length estimate:\n{actual:d} > {estimated:d}".format(
                          actual=self._bytes_encrypted, estimated=self.config.source_length
                      )
                  )