docs: def read(self, size=-1):
          """
          Read and return up to size bytes,
          with at most one call to the underlying raw stream’s.
  
          Use at most one call to the underlying raw stream’s read method.
  
          Args:
              size (int): Number of bytes to read. -1 to read the
                  stream until end.
  
          Returns:
              bytes: Object content
          """
          if not self._readable:
              raise UnsupportedOperation('read')
  
          # Checks if EOF
          if self._seek == self._size:
              return b''
  
          # Returns existing buffer with no copy
          if size == self._buffer_size:
              queue_index = self._seek
  
              # Starts initial preloading on first call
              if queue_index == 0:
                  self._preload_range()
  
              # Get buffer from future
              with handle_os_exceptions():
                  buffer = self._read_queue.pop(queue_index).result()
  
              # Append another buffer preload at end of queue
              buffer_size = self._buffer_size
              index = queue_index + buffer_size * self._max_buffers
              if index < self._size:
                  self._read_queue[index] = self._workers.submit(
                      self._read_range, index, index + buffer_size)
  
              # Update seek
                  self._seek += buffer_size
              else:
                  self._seek = self._size
  
              return buffer
  
          # Uses a prealocated buffer
          if size != -1:
              buffer = bytearray(size)
  
          # Uses a mutable buffer
          else:
              buffer = bytearray()
  
          read_size = self.readinto(buffer)
          return memoryview(buffer)[:read_size].tobytes()