From 8070e0c84b38fdd2ec14d6364c581d5e948b72e5 Mon Sep 17 00:00:00 2001 From: Maksim Andrianov Date: Tue, 13 Aug 2019 18:10:09 +0300 Subject: [PATCH] [generator] Added new parser interface. --- coding/parse_xml.hpp | 42 ++++++++ generator/osm_o5m_source.hpp | 6 +- generator/osm_source.cpp | 190 ++++++++++++++++++++--------------- generator/osm_source.hpp | 51 +++++++++- 4 files changed, 206 insertions(+), 83 deletions(-) diff --git a/coding/parse_xml.hpp b/coding/parse_xml.hpp index db00519b03..5a129fbe02 100644 --- a/coding/parse_xml.hpp +++ b/coding/parse_xml.hpp @@ -40,6 +40,48 @@ uint64_t ParseXMLSequence(SequenceT & source, XMLDispatcherT & dispatcher, bool return res; } +template +class ParserXMLSequence +{ +public: + ParserXMLSequence(SequenceT & source, XMLDispatcherT & dispatcher) + : m_res(0) + , m_readed(0) + , m_source(source) + , m_parser(dispatcher, false /* useCharData */) + { + CHECK(m_parser.Create(), ()); + + } + + bool Read() + { + char * buffer = static_cast(m_parser.GetBuffer(kBufferSize)); + ASSERT(buffer, ()); + + m_readed = m_source.Read(buffer, kBufferSize); + if (m_readed == 0) + return false; + + if (!m_parser.ParseBuffer(static_cast(m_readed), false)) + { + m_parser.PrintError(); + return false; + } + + m_res += m_readed; + return m_readed == kBufferSize; + } + +private: + uint32_t static const kBufferSize = 16 * 1024; + + uint64_t m_res; + uint64_t m_readed; + SequenceT & m_source; + XmlParser m_parser; +}; + namespace { diff --git a/generator/osm_o5m_source.hpp b/generator/osm_o5m_source.hpp index 78c3b2b731..2e250232b0 100644 --- a/generator/osm_o5m_source.hpp +++ b/generator/osm_o5m_source.hpp @@ -215,7 +215,8 @@ public: NextValue(); } - bool operator!=(Iterator const & iter) { return m_reader != iter.m_reader; } + bool operator==(Iterator const & iter) { return m_reader == iter.m_reader; } + bool operator!=(Iterator const & iter) { return !(*this == iter); } Iterator & operator++() { NextValue(); return *this; } @@ -567,7 +568,8 @@ public: NextValue(); } - bool operator!=(Iterator const & iter) { return m_reader != iter.m_reader; } + bool operator==(Iterator const & iter) { return m_reader == iter.m_reader; } + bool operator!=(Iterator const & iter) { return !(*this == iter); } Iterator & operator++() { NextValue(); return *this; } void NextValue() { m_reader = m_reader->ReadEntity(&m_entity) ? m_reader : nullptr; } diff --git a/generator/osm_source.cpp b/generator/osm_source.cpp index 4f7488c8e7..07a3601970 100644 --- a/generator/osm_source.cpp +++ b/generator/osm_source.cpp @@ -1,18 +1,16 @@ #include "generator/osm_source.hpp" +#include "generator/intermediate_data.hpp" #include "generator/intermediate_elements.hpp" #include "generator/osm_element.hpp" -#include "generator/osm_o5m_source.hpp" -#include "generator/osm_xml_source.hpp" #include "generator/towns_dumper.hpp" +#include "generator/translator_factory.hpp" #include "platform/platform.hpp" #include "geometry/mercator.hpp" #include "geometry/tree4d.hpp" -#include "coding/parse_xml.hpp" - #include "base/assert.hpp" #include "base/stl_helpers.hpp" #include "base/file_name_utils.hpp" @@ -24,6 +22,7 @@ #include "defines.hpp" using namespace std; +using namespace base::thread_pool::computational; namespace generator { @@ -121,8 +120,13 @@ void BuildIntermediateDataFromXML(SourceReader & stream, cache::IntermediateData void ProcessOsmElementsFromXML(SourceReader & stream, function processor) { - XMLSource parser([&](OsmElement * element) { processor(element); }); - ParseXMLSequence(stream, parser); + ProcessorXmlElementsFromXml processorXmlElementsFromXml(stream); + OsmElement element; + while (processorXmlElementsFromXml.TryRead(element)) + { + processor(&element); + element = {}; + } } void BuildIntermediateDataFromO5M(SourceReader & stream, cache::IntermediateDataWriter & cache, @@ -140,14 +144,29 @@ void BuildIntermediateDataFromO5M(SourceReader & stream, cache::IntermediateData void ProcessOsmElementsFromO5M(SourceReader & stream, function processor) { - using Type = osm::O5MSource::EntityType; - - osm::O5MSource dataset([&stream](uint8_t * buffer, size_t size) + ProcessorOsmElementsFromO5M processorOsmElementsFromO5M(stream); + OsmElement element; + while (processorOsmElementsFromO5M.TryRead(element)) { - return stream.Read(reinterpret_cast(buffer), size); - }); + processor(&element); + element = {}; + } +} - auto translate = [](Type t) -> OsmElement::EntityType { +ProcessorOsmElementsFromO5M::ProcessorOsmElementsFromO5M(SourceReader & stream) + : m_stream(stream) + , m_dataset([&, this](uint8_t * buffer, size_t size) { return m_stream.Read(reinterpret_cast(buffer), size); }) + , m_pos(m_dataset.begin()) +{ +} + +bool ProcessorOsmElementsFromO5M::TryRead(OsmElement & element) +{ + if (m_pos == m_dataset.end()) + return false; + + using Type = osm::O5MSource::EntityType; + auto const translate = [](Type t) -> OsmElement::EntityType { switch (t) { case Type::Node: return OsmElement::EntityType::Node; @@ -157,48 +176,69 @@ void ProcessOsmElementsFromO5M(SourceReader & stream, function #include #include +#include #include #include #include @@ -62,7 +73,6 @@ private: DISALLOW_COPY(CacheLoader); }; - // This function is needed to generate intermediate data from OSM elements. // The translators collection contains translators that translate the OSM element into // some intermediate representation. @@ -116,4 +126,41 @@ bool GenerateIntermediateData(feature::GenerateInfo & info); void ProcessOsmElementsFromO5M(SourceReader & stream, std::function processor); void ProcessOsmElementsFromXML(SourceReader & stream, std::function processor); + +class ProcessorOsmElementsInterface +{ +public: + virtual ~ProcessorOsmElementsInterface() = default; + + virtual bool TryRead(OsmElement & element) = 0; +}; + +class ProcessorOsmElementsFromO5M : public ProcessorOsmElementsInterface +{ +public: + explicit ProcessorOsmElementsFromO5M(SourceReader & stream); + + // ProcessorOsmElementsInterface overrides: + bool TryRead(OsmElement & element) override; + +private: + SourceReader & m_stream; + osm::O5MSource m_dataset; + osm::O5MSource::Iterator m_pos; +}; + +class ProcessorXmlElementsFromXml : public ProcessorOsmElementsInterface +{ +public: + explicit ProcessorXmlElementsFromXml(SourceReader & stream); + // ProcessorOsmElementsInterface overrides: + bool TryRead(OsmElement & element) override; + +private: + bool TryReadFromQueue(OsmElement & element); + + XMLSource m_xmlSource; + ParserXMLSequence m_parser; + std::queue m_queue; +}; } // namespace generator