#pragma once #include "feature.hpp" #include "feature_loader_base.hpp" #include "coding/var_record_reader.hpp" namespace feature { class FeaturesOffsetsTable; } /// Note! This class is NOT Thread-Safe. /// You should have separate instance of Vector for every thread. class FeaturesVector { DISALLOW_COPY(FeaturesVector); public: FeaturesVector(FilesContainerR const & cont, feature::DataHeader const & header, feature::FeaturesOffsetsTable const * table) : m_LoadInfo(cont, header), m_RecordReader(m_LoadInfo.GetDataReader(), 256), m_table(table) { } void GetByIndex(uint32_t index, FeatureType & ft) const; size_t GetNumFeatures() const; template void ForEach(ToDo && toDo) const { uint32_t index = 0; m_RecordReader.ForEachRecord([&] (uint32_t pos, char const * data, uint32_t /*size*/) { FeatureType ft; ft.Deserialize(m_LoadInfo.GetLoader(), data); // We can't properly set MwmId here, because FeaturesVector // works with FileContainerR, not with MwmId/MwmHandle/MwmValue. // But it's OK to set at least feature's index, because it can // be used later for Metadata loading. ft.SetID(FeatureID(MwmSet::MwmId(), index)); toDo(ft, m_table ? index++ : pos); }); } template static void ForEachOffset(ModelReaderPtr reader, ToDo && toDo) { VarRecordReader recordReader(reader, 256); recordReader.ForEachRecord([&] (uint32_t pos, char const * /*data*/, uint32_t /*size*/) { toDo(pos); }); } private: friend class FeaturesVectorTest; feature::SharedLoadInfo m_LoadInfo; VarRecordReader m_RecordReader; mutable vector m_buffer; feature::FeaturesOffsetsTable const * m_table; }; /// Test features vector (reader) that combines all the needed data for stand-alone work. /// Used in generator_tool and unit tests. class FeaturesVectorTest { DISALLOW_COPY(FeaturesVectorTest); FilesContainerR m_cont; feature::DataHeader m_header; FeaturesVector m_vector; public: explicit FeaturesVectorTest(string const & filePath); explicit FeaturesVectorTest(FilesContainerR const & cont); ~FeaturesVectorTest(); feature::DataHeader const & GetHeader() const { return m_header; } FeaturesVector const & GetVector() const { return m_vector; } };