def read()

in iopath/common/s3.py [0:0]


    def read(self, size: int = -1) -> bytes:
        """
        Read and return up to size bytes. If the argument is omitted, None, or negative,
        data is read and returned until EOF is reached. An empty bytes object is
        returned if the stream is already at EOF.
        """

        if size is None or size < 0:
            size = self.length - self.offset

        size = min(size, self.length - self.offset)

        ret = bytearray()

        if self.offset in self.buffered_window:
            buffer_offset = self.offset - self.buffered_window.start
            ret += self.buffer.getbuffer()[
                buffer_offset : min(buffer_offset + size, len(self.buffered_window))
            ]

        # if we already get enough data, return
        if len(ret) == size:
            self.offset += len(ret)
            return bytes(ret)

        # if partial data is available in the buffer, get the remaining data from S3
        if size - len(ret) > self.chunk_size:
            self.offset += len(ret)
            # For s3, range x-x means 1 byte at offset x
            output = self._read_from_s3(
                range(self.offset, min(self.offset + size - len(ret) - 1, self.length))
            )
            self.offset += len(output)
            return ret + output

        # otherwise download the next chunk from s3, update buffer and buffered window
        self._read_chunk_to_buffer(self.offset + len(ret))

        # append the remaining data from newly downloaded buffer and return
        ret += self.buffer.getbuffer()[0 : size - len(ret)]

        assert len(ret) == size
        self.offset += len(ret)
        return bytes(ret)