8#include "sio/definitions.h"
11#include <sio/compression/zlib.h>
23CollectionBase* SIOReader::readCollection(
const std::string& name) {
24 if (m_lastEventRead != m_eventNumber) {
30 std::find_if(begin(m_inputs), end(m_inputs), [&name](
const SIOReader::Input& t) {
return t.second == name; });
32 if (p != end(m_inputs)) {
33 p->first->setID(m_table->collectionID(name));
34 p->first->prepareAfterRead();
41std::map<int, GenericParameters>* SIOReader::readCollectionMetaData() {
43 m_collectionMetaData->data =
new ColMDMap();
44 readMetaDataRecord(m_collectionMetaData);
45 return m_collectionMetaData->data;
48std::map<int, GenericParameters>* SIOReader::readRunMetaData() {
50 m_runMetaData->data =
new RunMDMap();
51 readMetaDataRecord(m_runMetaData);
52 return m_runMetaData->data;
56 if (m_lastEventRead != m_eventNumber) {
59 return m_eventMetaData->metadata;
63 m_stream.open(filename, std::ios::binary);
65 throw std::runtime_error(
"File " + filename +
" couldn't be found");
67 readCollectionIDTable();
69 if (!readFileTOCRecord()) {
70 reconstructFileTOCRecord();
84 sio::api::go_to_record(m_stream,
"event_record");
86 sio::record_info rec_info;
87 sio::api::read_record_info(m_stream, rec_info, m_info_buffer);
88 sio::api::read_record_data(m_stream, rec_info, m_rec_buffer);
90 m_unc_buffer.resize(rec_info._uncompressed_length);
91 sio::zlib_compression compressor;
92 compressor.uncompress(m_rec_buffer.span(), m_unc_buffer);
93 sio::api::read_blocks(m_unc_buffer.span(), m_blocks);
95 for (
size_t i = 1; i < m_blocks.size(); ++i) {
97 m_inputs.emplace_back(blk->getCollection(), m_table->names()[i - 1]);
100 m_lastEventRead = m_eventNumber;
104 return m_stream.good();
115 if (eventNumber < (
unsigned)m_eventNumber) {
121 sio::api::go_to_record(m_stream,
"event_record");
122 if ((eventNumber - m_eventNumber) > 0) {
123 sio::api::skip_n_records(m_stream, eventNumber - m_eventNumber);
125 m_eventNumber = eventNumber;
131void SIOReader::createBlocks() {
135 m_blocks.push_back(m_eventMetaData);
137 for (
size_t i = 0; i < m_typeNames.size(); ++i) {
138 const bool subsetColl = !m_subsetCollectionBits.empty() && m_subsetCollectionBits[i];
140 m_blocks.push_back(blk);
144void SIOReader::readCollectionIDTable() {
145 sio::record_info rec_info;
146 sio::api::read_record_info(m_stream, rec_info, m_info_buffer);
147 sio::api::read_record_data(m_stream, rec_info, m_rec_buffer);
149 m_unc_buffer.resize(rec_info._uncompressed_length);
150 sio::zlib_compression compressor;
151 compressor.uncompress(m_rec_buffer.span(), m_unc_buffer);
153 sio::block_list blocks;
154 blocks.emplace_back(std::make_shared<SIOCollectionIDTableBlock>());
155 blocks.emplace_back(std::make_shared<SIOVersionBlock>());
156 sio::api::read_blocks(m_unc_buffer.span(), blocks);
158 auto* idTableBlock =
static_cast<SIOCollectionIDTableBlock*
>(blocks[0].get());
159 m_table = std::make_shared<podio::CollectionIDTable>();
160 m_table.reset(idTableBlock->getTable());
161 m_typeNames = idTableBlock->getTypeNames();
162 m_subsetCollectionBits = idTableBlock->getSubsetCollectionBits();
163 m_fileVersion =
static_cast<SIOVersionBlock*
>(blocks[1].get())->version;
166void SIOReader::readMetaDataRecord(
const std::shared_ptr<SIONumberedMetaDataBlock>& mdBlock) {
167 const auto currPos = m_stream.tellg();
168 sio::api::go_to_record(m_stream, mdBlock->name());
170 sio::record_info rec_info;
171 sio::api::read_record_info(m_stream, rec_info, m_info_buffer);
172 sio::api::read_record_data(m_stream, rec_info, m_rec_buffer);
174 m_unc_buffer.resize(rec_info._uncompressed_length);
175 sio::zlib_compression compressor;
176 compressor.uncompress(m_rec_buffer.span(), m_unc_buffer);
178 sio::block_list blocks{};
179 blocks.push_back(mdBlock);
180 sio::api::read_blocks(m_unc_buffer.span(), blocks);
182 m_stream.seekg(currPos);
185void SIOReader::reconstructFileTOCRecord() {
189 sio::api::skip_records(m_stream, [&](
const sio::record_info& rec_info) {
190 m_tocRecord.
addRecord(rec_info._name, rec_info._file_start);
193 }
catch (sio::exception& e) {
194 if (e.code() != sio::error_code::eof) {
195 SIO_RETHROW(e, e.code(), e.what());
204bool SIOReader::readFileTOCRecord() {
207 m_stream.seekg(-sio_helpers::SIOTocInfoSize, std::ios_base::end);
208 uint64_t firstWords{0};
209 m_stream.read(
reinterpret_cast<char*
>(&firstWords),
sizeof(firstWords));
211 const uint32_t marker = (firstWords >> 32) & 0xffffffff;
212 if (marker == sio_helpers::SIOTocMarker) {
213 const uint32_t position = firstWords & 0xffffffff;
214 m_stream.seekg(position);
216 sio::record_info rec_info;
217 sio::api::read_record_info(m_stream, rec_info, m_info_buffer);
218 sio::api::read_record_data(m_stream, rec_info, m_rec_buffer);
220 m_unc_buffer.resize(rec_info._uncompressed_length);
221 sio::zlib_compression compressor;
222 compressor.uncompress(m_rec_buffer.span(), m_unc_buffer);
224 sio::block_list blocks;
225 auto tocBlock = std::make_shared<SIOFileTOCRecordBlock>();
226 tocBlock->record = &m_tocRecord;
227 blocks.push_back(tocBlock);
229 sio::api::read_blocks(m_unc_buffer.span(), blocks);
231 m_unc_buffer.clear();
232 m_rec_buffer.clear();
static SIOBlockFactory & instance()
std::shared_ptr< SIOBlock > createBlock(const podio::CollectionBase *col, const std::string &name) const
static SIOBlockLibraryLoader & instance()
Base class for sio::block handlers used with PODIO.
void addRecord(const std::string &name, PositionType startPos)
void closeFile() override
void readEvent() override
Read all collections requested.
void openFile(const std::string &filename) override
void endOfEvent() override
Prepare the reader to read the next event.
bool isValid() const override
Check if file is valid.
void goToEvent(unsigned iEvent) override
std::map< int, GenericParameters > ColMDMap
std::map< int, GenericParameters > RunMDMap