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)