in src/native/io/reader.cpp [135:189]
size_t reader::chained_reader_impl::read_some(uint64_t offset, std::span<char> buffer) const
{
if ((buffer.size() == 0) || (m_length == 0))
{
return 0;
}
auto lower_bound = std::lower_bound(m_offsets.begin(), m_offsets.end(), offset);
if (lower_bound < m_offsets.begin())
{
std::string msg = "reader::chained_reader_impl::slice(): lower_bound too low. lower_bound: "
+ std::to_string(*lower_bound) + ", m_offset.begin(): " + std::to_string(*m_offsets.begin());
throw errors::user_exception(errors::error_code::io_reader_slice_bound_error, msg);
}
auto index = static_cast<size_t>(lower_bound - m_offsets.begin());
if (index != 0)
{
// This is past the last offset value, try last reader.
if (index >= m_offsets.size())
{
index = m_offsets.size() - 1;
}
else if (offset < m_offsets[index])
{
index--;
}
}
uint64_t offset_in_reader = offset - m_offsets[index];
auto remaining = buffer.size();
uint64_t total_read = 0;
while (remaining > 0 && index < m_readers.size())
{
auto &reader = m_readers[index];
std::span<char> remaining_buffer{buffer.data() + total_read, remaining};
auto actual_read = reader.read_some(offset_in_reader, remaining_buffer);
if (actual_read == 0)
{
break;
}
remaining -= actual_read;
total_read += actual_read;
index++;
offset_in_reader = 0;
}
return total_read;
}