in src/native/diffs/core/prepared_item.cpp [116:182]
std::unique_ptr<io::sequential::reader> prepared_item::make_sequential_reader() const
{
return std::visit(
overload{
[](reader_kind &kind)
{
auto reader = kind.m_factory->make_reader();
std::unique_ptr<io::sequential::reader> result =
std::make_unique<io::sequential::basic_reader_wrapper>(reader);
return result;
},
[](sequential_reader_kind &kind) { return kind.m_factory->make_sequential_reader(); },
[](slice_kind &kind)
{
auto reader = kind.m_item->make_reader();
auto slice = reader.slice(kind.m_offset, kind.m_length);
std::unique_ptr<io::sequential::reader> result =
std::make_unique<io::sequential::basic_reader_wrapper>(slice);
return result;
},
[](chain_kind &kind)
{
std::vector<std::unique_ptr<io::sequential::reader>> readers;
for (auto &item : kind.m_items)
{
readers.emplace_back(item->make_sequential_reader());
}
std::unique_ptr<io::sequential::reader> result =
std::make_unique<io::sequential::chain_reader>(std::move(readers));
return result;
},
[&](fetch_slice_kind &kind)
{
// printf("Fetching slice from kitchen...\n");
std::shared_ptr<prepared_item> fetched_slice;
// We're going to try to mutate into the reader version
// by fetching from the kitchen.
// We may wait here while more works is done as a result.
if (auto kitchen = kind.kitchen.lock())
{
fetched_slice = kitchen->fetch_slice(m_item_definition);
}
else
{
// kitchen is gone!
ADU_LOG("Kitchen missing when trying to prepare reader.");
throw errors::user_exception(errors::error_code::diffs_prepared_item_kitchen_gone);
}
if (!std::holds_alternative<reader_kind>(fetched_slice->m_kind))
{
throw errors::user_exception(
errors::error_code::diffs_prepared_item_wrong_kind, "Fetched item not reader kind");
}
m_kind = fetched_slice->m_kind;
auto &factory = std::get<reader_kind>(m_kind).m_factory;
auto reader = factory->make_reader();
std::unique_ptr<io::sequential::reader> result =
std::make_unique<io::sequential::basic_reader_wrapper>(reader);
return result;
},
},
m_kind);
}