From 233683d1670e89076c82401e2693315046c7244e Mon Sep 17 00:00:00 2001 From: vng Date: Thu, 30 Jun 2011 09:52:22 +0300 Subject: [PATCH] [Refactoring] Use Reader interface everywhere, when possible. Platform class now is a Reader factory. --- coding/coding.pro | 1 + coding/coding_tests/file_container_test.cpp | 16 ++-- coding/coding_tests/reader_test.cpp | 6 +- coding/file_container.cpp | 15 +++- coding/file_container.hpp | 10 ++- coding/file_reader.cpp | 36 ++------- coding/file_reader.hpp | 10 +-- coding/reader.cpp | 21 +++++ coding/reader.hpp | 77 ++++++++++++++++++- generator/dumper.cpp | 2 +- .../generator_tests/feature_bucketer_test.cpp | 6 +- generator/generator_tool/generator_tool.cpp | 10 ++- generator/statistics.cpp | 2 +- indexer/classificator.cpp | 38 +-------- indexer/classificator.hpp | 5 +- indexer/classificator_loader.cpp | 30 ++++++-- indexer/classificator_loader.hpp | 7 +- indexer/data_header.cpp | 4 +- indexer/data_header.hpp | 4 +- indexer/drawing_rules.cpp | 25 +++--- indexer/drawing_rules.hpp | 11 ++- indexer/feature.cpp | 4 +- indexer/feature_processor.hpp | 4 +- indexer/features_vector.hpp | 12 +-- indexer/file_reader_stream.hpp | 16 +++- indexer/index.hpp | 34 ++++---- indexer/index_builder.cpp | 2 +- indexer/indexer_tests/feature_test.cpp | 6 +- indexer/indexer_tests/index_builder_test.cpp | 12 +-- indexer/indexer_tests/index_test.cpp | 4 +- indexer/tree_structure.hpp | 2 +- map/feature_vec_model.cpp | 18 +++-- map/feature_vec_model.hpp | 14 ++-- map/framework.cpp | 59 +++++++++----- map/framework.hpp | 11 ++- map/languages.cpp | 9 ++- map/map_tests/map_foreach_test.cpp | 16 ++-- platform/platform.cpp | 6 ++ platform/platform.hpp | 10 ++- qt/classificator_tree.cpp | 5 +- qt/main.cpp | 5 +- search/categories_holder.cpp | 7 +- search/categories_holder.hpp | 4 +- search/engine.hpp | 5 +- search/search_tests/categories_test.cpp | 11 +-- storage/country.cpp | 15 ++-- storage/country.hpp | 9 ++- storage/storage.cpp | 39 +++++----- storage/storage.hpp | 6 +- storage/storage_tests/country_test.cpp | 2 +- 50 files changed, 412 insertions(+), 271 deletions(-) create mode 100644 coding/reader.cpp diff --git a/coding/coding.pro b/coding/coding.pro index 4f93b1b8c7..efd20bc090 100644 --- a/coding/coding.pro +++ b/coding/coding.pro @@ -23,6 +23,7 @@ SOURCES += \ base64.cpp \ sha2.cpp \ multilang_utf8_string.cpp \ + reader.cpp HEADERS += \ internal/xmlparser.h \ diff --git a/coding/coding_tests/file_container_test.cpp b/coding/coding_tests/file_container_test.cpp index 927d848e77..4df000ba59 100644 --- a/coding/coding_tests/file_container_test.cpp +++ b/coding/coding_tests/file_container_test.cpp @@ -33,8 +33,8 @@ UNIT_TEST(FilesContainer_Smoke) for (size_t i = 0; i < count; ++i) { - FileReader r = reader.GetReader(strings::to_string(i)); - ReaderSource src(r); + FilesContainerR::ReaderT r = reader.GetReader(strings::to_string(i)); + ReaderSource src(r); for (uint32_t j = 0; j < i; ++j) { @@ -61,8 +61,8 @@ UNIT_TEST(FilesContainer_Smoke) { FilesContainerR reader(fName); - FileReader r = reader.GetReader(strings::to_string(arrAppend[i])); - ReaderSource src(r); + FilesContainerR::ReaderT r = reader.GetReader(strings::to_string(arrAppend[i])); + ReaderSource src(r); uint32_t const test = ReadVarUint(src); TEST_EQUAL(arrAppend[i], test, ()); @@ -75,7 +75,7 @@ namespace { void CheckInvariant(FilesContainerR & reader, string const & tag, int64_t test) { - FileReader r = reader.GetReader(tag); + FilesContainerR::ReaderT r = reader.GetReader(tag); TEST_EQUAL(test, ReadPrimitiveFromPos(r, 0), ()); } } @@ -111,7 +111,7 @@ UNIT_TEST(FilesContainer_Shared) // shared container read and fill FilesContainerR reader(fName); - FileReader r1 = reader.GetReader("1"); + FilesContainerR::ReaderT r1 = reader.GetReader("1"); uint64_t const offset = sizeof(uint32_t); r1 = r1.SubReader(offset, r1.Size() - offset); @@ -120,7 +120,7 @@ UNIT_TEST(FilesContainer_Shared) FilesContainerW writer(fName, FileWriter::OP_APPEND); FileWriter w = writer.GetWriter("3"); - ReaderSource src(r1); + ReaderSource src(r1); for (uint32_t i = 0; i < count; ++i) { uint32_t test = ReadVarUint(src); @@ -175,7 +175,7 @@ UNIT_TEST(FilesContainer_RewriteExisting) for (size_t i = 0; i < ARRAY_SIZE(key); ++i) { - FileReader r = reader.GetReader(key[i]); + FilesContainerR::ReaderT r = reader.GetReader(key[i]); char s[10] = { 0 }; r.Read(0, s, strlen(value[i])); diff --git a/coding/coding_tests/reader_test.cpp b/coding/coding_tests/reader_test.cpp index f4f073838c..a0892e6788 100644 --- a/coding/coding_tests/reader_test.cpp +++ b/coding/coding_tests/reader_test.cpp @@ -74,10 +74,12 @@ UNIT_TEST(FileReaderReadAsText) FileWriter f(fName); f.Write(fName, ARRAY_SIZE(fName) - 1); } + { - FileReader f(fName); - string const text = f.ReadAsText(); + string text; + FileReader(fName).ReadAsString(text); TEST_EQUAL(text, fName, ()); } + FileWriter::DeleteFileX(fName); } diff --git a/coding/file_container.cpp b/coding/file_container.cpp index c17c7cb811..808f056e93 100644 --- a/coding/file_container.cpp +++ b/coding/file_container.cpp @@ -9,11 +9,12 @@ // FilesContainerBase ///////////////////////////////////////////////////////////////////////////// -void FilesContainerBase::ReadInfo(FileReader & reader) +template +void FilesContainerBase::ReadInfo(ReaderT & reader) { uint64_t offset = ReadPrimitiveFromPos(reader, 0); - ReaderSource src(reader); + ReaderSource src(reader); src.Skip(offset); uint32_t const count = ReadVarUint(src); @@ -37,12 +38,18 @@ void FilesContainerBase::ReadInfo(FileReader & reader) FilesContainerR::FilesContainerR(string const & fName, uint32_t logPageSize, uint32_t logPageCount) -: m_source(fName, logPageSize, logPageCount) + : m_source(new FileReader(fName, logPageSize, logPageCount)) { ReadInfo(m_source); } -FileReader FilesContainerR::GetReader(Tag const & tag) const +FilesContainerR::FilesContainerR(ReaderT const & file) + : m_source(file) +{ + ReadInfo(m_source); +} + +FilesContainerR::ReaderT FilesContainerR::GetReader(Tag const & tag) const { InfoContainer::const_iterator i = lower_bound(m_info.begin(), m_info.end(), tag, LessInfo()); diff --git a/coding/file_container.hpp b/coding/file_container.hpp index 63408b9972..db80621bdd 100644 --- a/coding/file_container.hpp +++ b/coding/file_container.hpp @@ -40,17 +40,21 @@ protected: typedef vector InfoContainer; InfoContainer m_info; - void ReadInfo(FileReader & reader); + template + void ReadInfo(ReaderT & reader); }; class FilesContainerR : public FilesContainerBase { public: + typedef ModelReaderPtr ReaderT; + explicit FilesContainerR(string const & fName, uint32_t logPageSize = 10, uint32_t logPageCount = 10); + FilesContainerR(ReaderT const & file); - FileReader GetReader(Tag const & tag) const; + ReaderT GetReader(Tag const & tag) const; template void ForEachTag(F f) const { @@ -59,7 +63,7 @@ public: } private: - FileReader m_source; + ReaderT m_source; }; class FilesContainerW : public FilesContainerBase diff --git a/coding/file_reader.cpp b/coding/file_reader.cpp index 270d24f675..eb092dc065 100644 --- a/coding/file_reader.cpp +++ b/coding/file_reader.cpp @@ -1,7 +1,6 @@ #include "file_reader.hpp" #include "reader_cache.hpp" #include "internal/file_data.hpp" -#include "../../base/string_utils.hpp" #ifndef LOG_FILE_READER_STATS #define LOG_FILE_READER_STATS 0 @@ -60,8 +59,6 @@ public: return m_ReaderCache.Read(m_FileData, pos, p, size); } - string GetName() const { return m_FileData.GetName(); } - private: FileDataWithCachedSize m_FileData; ReaderCache m_ReaderCache; @@ -72,13 +69,13 @@ private: }; FileReader::FileReader(string const & fileName, uint32_t logPageSize, uint32_t logPageCount) - : m_pFileData(new FileReaderData(fileName, logPageSize, logPageCount)), + : base_type(fileName), m_pFileData(new FileReaderData(fileName, logPageSize, logPageCount)), m_Offset(0), m_Size(m_pFileData->Size()) { } -FileReader::FileReader(shared_ptr const & pFileData, uint64_t offset, uint64_t size) - : m_pFileData(pFileData), m_Offset(offset), m_Size(size) +FileReader::FileReader(FileReader const & reader, uint64_t offset, uint64_t size) + : base_type(reader.GetName()), m_pFileData(reader.m_pFileData), m_Offset(offset), m_Size(size) { } @@ -96,34 +93,11 @@ void FileReader::Read(uint64_t pos, void * p, size_t size) const FileReader FileReader::SubReader(uint64_t pos, uint64_t size) const { ASSERT_LESS_OR_EQUAL(pos + size, Size(), (pos, size)); - return FileReader(m_pFileData, m_Offset + pos, size); + return FileReader(*this, m_Offset + pos, size); } FileReader * FileReader::CreateSubReader(uint64_t pos, uint64_t size) const { ASSERT_LESS_OR_EQUAL(pos + size, Size(), (pos, size)); - return new FileReader(m_pFileData, m_Offset + pos, size); -} - -bool FileReader::IsEqual(string const & fName) const -{ -#if defined(OMIM_OS_WINDOWS) - return strings::EqualNoCase(fName, m_pFileData->GetName()); -#else - return (fName == m_pFileData->GetName()); -#endif -} - -string FileReader::GetName() const -{ - return m_pFileData->GetName(); -} - -string FileReader::ReadAsText() const -{ - size_t size = static_cast(Size()); - vector buffer(size); - buffer.resize(size); - Read(0, &buffer[0], size); - return string(reinterpret_cast(&buffer[0]), size); + return new FileReader(*this, m_Offset + pos, size); } diff --git a/coding/file_reader.hpp b/coding/file_reader.hpp index 421a89c778..1ed7118b0c 100644 --- a/coding/file_reader.hpp +++ b/coding/file_reader.hpp @@ -6,8 +6,10 @@ // FileReader, cheap to copy, not thread safe. // It is assumed that file is not modified during FireReader lifetime, // because of caching and assumption that Size() is constant. -class FileReader : public Reader +class FileReader : public ModelReader { + typedef ModelReader base_type; + public: explicit FileReader(string const & fileName, uint32_t logPageSize = 10, @@ -20,12 +22,8 @@ public: FileReader SubReader(uint64_t pos, uint64_t size) const; FileReader * CreateSubReader(uint64_t pos, uint64_t size) const; - bool IsEqual(string const & fName) const; - string GetName() const; - string ReadAsText() const; - private: - FileReader(shared_ptr const & pFileData, uint64_t offset, uint64_t size); + FileReader(FileReader const & reader, uint64_t offset, uint64_t size); shared_ptr m_pFileData; uint64_t m_Offset; diff --git a/coding/reader.cpp b/coding/reader.cpp new file mode 100644 index 0000000000..2eb6bb7ed9 --- /dev/null +++ b/coding/reader.cpp @@ -0,0 +1,21 @@ +#include "reader.hpp" + +#include "../../base/string_utils.hpp" + + +void Reader::ReadAsString(string & s) const +{ + s.clear(); + size_t const sz = Size(); + s.resize(sz); + Read(0, &s[0], sz); +} + +bool ModelReader::IsEqual(string const & fName) const +{ +#if defined(OMIM_OS_WINDOWS) + return strings::EqualNoCase(fName, m_name); +#else + return (fName == m_name); +#endif +} diff --git a/coding/reader.hpp b/coding/reader.hpp index 04e2b4c5a5..6f95401a63 100644 --- a/coding/reader.hpp +++ b/coding/reader.hpp @@ -1,13 +1,17 @@ #pragma once #include "endianness.hpp" #include "source.hpp" + #include "../base/assert.hpp" #include "../base/base.hpp" #include "../base/exception.hpp" #include "../base/macros.hpp" + +#include "../std/shared_ptr.hpp" #include "../std/string.hpp" #include "../std/memcpy.hpp" + // Base class for random-access Reader. Not thread-safe. class Reader { @@ -20,6 +24,8 @@ public: virtual uint64_t Size() const = 0; virtual void Read(uint64_t pos, void * p, size_t size) const = 0; virtual Reader * CreateSubReader(uint64_t pos, uint64_t size) const = 0; + + void ReadAsString(string & s) const; }; // Reader from memory. @@ -62,9 +68,74 @@ private: size_t m_Size; }; -// Source that readers from a reader. -template -class ReaderSource +// Reader wrapper to hold the pointer to a polymorfic reader. +// Common use: ReaderSource >. +// Note! It takes the ownership of Reader. +template class ReaderPtr +{ +protected: + shared_ptr m_p; + +public: + ReaderPtr(ReaderT * p) : m_p(p) {} + + uint64_t Size() const + { + return m_p->Size(); + } + + void Read(uint64_t pos, void * p, size_t size) const + { + m_p->Read(pos, p, size); + } + + void ReadAsString(string & s) const + { + m_p->ReadAsString(s); + } +}; + +// Model reader store file id as string. +class ModelReader : public Reader +{ + string m_name; + +public: + ModelReader(string const & name) : m_name(name) {} + + virtual ModelReader * CreateSubReader(uint64_t pos, uint64_t size) const = 0; + + bool IsEqual(string const & name) const; + + string GetName() const { return m_name; } +}; + +// Reader pointer class for data files. +class ModelReaderPtr : public ReaderPtr +{ + typedef ReaderPtr base_type; + +public: + ModelReaderPtr(ModelReader * p) : base_type(p) {} + + inline ModelReaderPtr SubReader(uint64_t pos, uint64_t size) const + { + return m_p->CreateSubReader(pos, size); + } + + inline bool IsEqual(string const & name) const + { + return m_p->IsEqual(name); + } + + inline bool IsEqual(ModelReaderPtr const & file) const + { + return m_p->IsEqual(file.m_p->GetName()); + } +}; + +// Source that reads from a reader. +template class ReaderSource { public: typedef ReaderT ReaderType; diff --git a/generator/dumper.cpp b/generator/dumper.cpp index dd8ee08350..6693bde894 100644 --- a/generator/dumper.cpp +++ b/generator/dumper.cpp @@ -51,7 +51,7 @@ namespace feature void DumpTypes(string const & datFile) { TypesCollector doClass; - feature::ForEachFromDat(datFile, doClass); + feature::ForEachFromDat(new FileReader(datFile), doClass); typedef vector vec_to_sort; vec_to_sort vecToSort(doClass.m_stats.begin(), doClass.m_stats.end()); diff --git a/generator/generator_tests/feature_bucketer_test.cpp b/generator/generator_tests/feature_bucketer_test.cpp index 4341828010..39f22e8b01 100644 --- a/generator/generator_tests/feature_bucketer_test.cpp +++ b/generator/generator_tests/feature_bucketer_test.cpp @@ -49,9 +49,9 @@ UNIT_TEST(FeatureBucketerSmokeTest) { // classificator is needed because inside bucketer we're use it in WorldMapGenerator // @TODO clean up or remove cell bucketer and replace with world countries bucketer - classificator::Read(GetPlatform().ReadPathForFile("drawing_rules.bin"), - GetPlatform().ReadPathForFile("classificator.txt"), - GetPlatform().ReadPathForFile("visibility.txt")); + classificator::Read(GetPlatform().GetReader("drawing_rules.bin"), + GetPlatform().GetReader("classificator.txt"), + GetPlatform().GetReader("visibility.txt")); map > out, expectedOut; FeatureBucketer bucketer(1, &out); diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index 3224a5b7a0..3008ed9037 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -80,8 +80,10 @@ int main(int argc, char ** argv) google::ParseCommandLineFlags(&argc, &argv, true); + Platform & pl = GetPlatform(); + string const path = - FLAGS_data_path.empty() ? GetPlatform().WritableDir() : AddSlashIfNeeded(FLAGS_data_path); + FLAGS_data_path.empty() ? pl.WritableDir() : AddSlashIfNeeded(FLAGS_data_path); if (FLAGS_version) { @@ -115,9 +117,9 @@ int main(int argc, char ** argv) if (FLAGS_generate_features || FLAGS_generate_geometry || FLAGS_generate_index || FLAGS_calc_statistics || FLAGS_dump_types) { - classificator::Read(path + "drawing_rules.bin", - path + "classificator.txt", - path + "visibility.txt"); + classificator::Read(pl.GetReader("drawing_rules.bin"), + pl.GetReader("classificator.txt"), + pl.GetReader("visibility.txt")); classificator::PrepareForFeatureGeneration(); } diff --git a/generator/statistics.cpp b/generator/statistics.cpp index aba55716fc..be4a07f761 100644 --- a/generator/statistics.cpp +++ b/generator/statistics.cpp @@ -82,7 +82,7 @@ namespace stats void CalcStatistic(string const & fName, MapInfo & info) { AccumulateStatistic doProcess(info); - feature::ForEachFromDat(fName, doProcess); + feature::ForEachFromDat(new FileReader(fName), doProcess); } void PrintInfo(char const * prefix, GeneralInfo const & info) diff --git a/indexer/classificator.cpp b/indexer/classificator.cpp index 2c0a4c6e29..736d46e3b0 100644 --- a/indexer/classificator.cpp +++ b/indexer/classificator.cpp @@ -424,35 +424,8 @@ bool ClassifObject::IsDrawableLike(FeatureGeoType ft) const return false; } -namespace +void Classificator::ReadClassificator(string const & buffer) { - bool LoadFileToString(char const * fPath, string & buffer) - { - try - { - FileReader reader(fPath); - size_t const sz = static_cast(reader.Size()); - if (sz > 0) - { - buffer.resize(sz); - reader.Read(0, &buffer[0], sz); - return true; - } - } - catch (FileReader::OpenException const &) - { - // It's OK. Just return false. - } - return false; - } -} - -bool Classificator::ReadClassificator(char const * fPath) -{ - string buffer; - if (!LoadFileToString(fPath, buffer)) - return false; - istringstream iss(buffer); m_root.Clear(); @@ -461,7 +434,6 @@ bool Classificator::ReadClassificator(char const * fPath) tree::LoadTreeAsText(iss, policy); m_root.Sort(); - return true; } void Classificator::PrintClassificator(char const * fPath) @@ -477,18 +449,12 @@ void Classificator::PrintClassificator(char const * fPath) #endif } -bool Classificator::ReadVisibility(char const * fPath) +void Classificator::ReadVisibility(string const & buffer) { - string buffer; - if (!LoadFileToString(fPath, buffer)) - return false; - istringstream iss(buffer); ClassifObject::VisLoadPolicy policy(&m_root); tree::LoadTreeAsText(iss, policy); - - return true; } void Classificator::PrintVisibility(char const * fPath) diff --git a/indexer/classificator.hpp b/indexer/classificator.hpp index 7204363d4d..cabec15a86 100644 --- a/indexer/classificator.hpp +++ b/indexer/classificator.hpp @@ -5,7 +5,6 @@ #include "../std/vector.hpp" #include "../std/string.hpp" -#include "../std/sstream.hpp" #include "../std/fstream.hpp" #include "../std/bitset.hpp" @@ -205,10 +204,10 @@ public: /// @name Serialization-like functions. //@{ - bool ReadClassificator(char const * fPath); + void ReadClassificator(string const & buffer); void PrintClassificator(char const * fPath); - bool ReadVisibility(char const * fPath); + void ReadVisibility(string const & buffer); void PrintVisibility(char const * fPath); void SortClassificator(); diff --git a/indexer/classificator_loader.cpp b/indexer/classificator_loader.cpp index 3dbbbe9c53..23a1b74a7c 100644 --- a/indexer/classificator_loader.cpp +++ b/indexer/classificator_loader.cpp @@ -1,22 +1,38 @@ #include "classificator_loader.hpp" +#include "file_reader_stream.hpp" #include "classificator.hpp" #include "drawing_rules.hpp" -#include "../coding/reader.hpp" +#include "../coding/file_reader.hpp" + #include "../base/logging.hpp" + namespace classificator { - void Read(string const & rules, string const & classificator, string const & visibility) + void Read(file_t const & rules, file_t const & classificator, file_t const & visibility) { LOG(LINFO, ("Reading drawing rules")); - drule::ReadRules(rules.c_str()); + ReaderPtrStream rulesS(rules); + drule::ReadRules(rulesS); + + string buffer; + LOG(LINFO, ("Reading classificator")); - if (!classif().ReadClassificator(classificator.c_str())) - MYTHROW(Reader::OpenException, ("drawing rules or classificator file")); + classificator.ReadAsString(buffer); + classif().ReadClassificator(buffer); LOG(LINFO, ("Reading visibility")); - (void)classif().ReadVisibility(visibility.c_str()); - LOG(LINFO, ("Reading visibility done")); + visibility.ReadAsString(buffer); + classif().ReadVisibility(buffer); + + LOG(LINFO, ("Reading of classificator done")); + } + + void ReadVisibility(string const & fPath) + { + string buffer; + file_t(new FileReader(fPath)).ReadAsString(buffer); + classif().ReadVisibility(buffer); } } diff --git a/indexer/classificator_loader.hpp b/indexer/classificator_loader.hpp index 412e8a1d29..933904fa77 100644 --- a/indexer/classificator_loader.hpp +++ b/indexer/classificator_loader.hpp @@ -1,8 +1,13 @@ #pragma once +#include "../coding/reader.hpp" + #include "../std/string.hpp" + namespace classificator { - void Read(string const & rules, string const & classificator, string const & visibility); + typedef ReaderPtr file_t; + void Read(file_t const & rules, file_t const & classificator, file_t const & visibility); + void ReadVisibility(string const & fPath); } diff --git a/indexer/data_header.cpp b/indexer/data_header.cpp index da7efa5768..22486c90a1 100644 --- a/indexer/data_header.cpp +++ b/indexer/data_header.cpp @@ -64,9 +64,9 @@ namespace feature w.Write(m_scales.data(), m_scales.size()); } - void DataHeader::Load(FileReader const & r) + void DataHeader::Load(ModelReaderPtr const & r) { - ReaderSource src(r); + ReaderSource src(r); m_codingParams.Load(src); //int64_t const base = m_codingParams.GetBasePointInt64(); diff --git a/indexer/data_header.hpp b/indexer/data_header.hpp index b0badc5cb1..88d5c72f5d 100644 --- a/indexer/data_header.hpp +++ b/indexer/data_header.hpp @@ -9,7 +9,7 @@ #include "../base/start_mem_debug.hpp" -class FileReader; +class ModelReaderPtr; class FileWriter; namespace feature @@ -43,7 +43,7 @@ namespace feature /// @name Serialization //@{ void Save(FileWriter & w) const; - void Load(FileReader const & r); + void Load(ModelReaderPtr const & r); //@} }; } diff --git a/indexer/drawing_rules.cpp b/indexer/drawing_rules.cpp index a5cc8a9652..ab7c85d909 100644 --- a/indexer/drawing_rules.cpp +++ b/indexer/drawing_rules.cpp @@ -449,7 +449,7 @@ namespace drule { {} virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } virtual int GetColor() const { return m_params.get<4>().m_v; } @@ -514,7 +514,7 @@ namespace drule { AreaRule() : m_params(make_tuple(pattern_url_t(), 1.0, pattern_url_t(), 1.0, 1.0)) {} virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } virtual int GetFillColor() const { return m_params.get<0>().m_v; } @@ -537,7 +537,7 @@ namespace drule { tuple m_params; virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } virtual void GetSymbol(string & s) const @@ -569,7 +569,7 @@ namespace drule { {} virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } virtual double GetTextHeight() const { return m_params.get<5>().m_v; } @@ -606,7 +606,7 @@ namespace drule { CircleRule() : m_params(make_tuple(1, color_t(), 1.0, color_t::none, 0.0, 1.0)) {} virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } virtual double GetRadius() const { return m_params.get<0>().m_v; } @@ -643,7 +643,7 @@ namespace drule { {} virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } virtual double GetTextHeight() const { return m_params.get<6>().m_v; } @@ -686,7 +686,7 @@ namespace drule { WayMarkerRule() : m_params(make_tuple("", color_t(), 1.0, line_cap_t(), 1.0)) {} virtual bool IsEqual(BaseRule const * p) const { return is_equal_rules(this, p); } - virtual void Read(FileReaderStream & ar) { read_rules(ar, this); } + virtual void Read(ReaderPtrStream & ar) { read_rules(ar, this); } virtual void Write(FileWriterStream & ar) const { write_rules(ar, this); } static string arrKeys[5]; @@ -704,7 +704,7 @@ namespace drule { //////////////////////////////////////////////////////////////////////////////////////////// // BaseRule implementation //////////////////////////////////////////////////////////////////////////////////////////// -void BaseRule::ReadBase(FileReaderStream & ar) +void BaseRule::ReadBase(ReaderPtrStream & ar) { ar >> m_class >> m_type; } @@ -1014,7 +1014,7 @@ FileWriterStream & operator << (FileWriterStream & ar, BaseRule * p) return ar; } -void do_load(FileReaderStream & ar, size_t ind, BaseRule * & p) +void do_load(ReaderPtrStream & ar, size_t ind, BaseRule * & p) { switch (ind) { @@ -1033,7 +1033,7 @@ void do_load(FileReaderStream & ar, size_t ind, BaseRule * & p) p->Read(ar); } -void RulesHolder::Read(FileReaderStream & s) +void RulesHolder::Read(ReaderPtrStream & s) { Clean(); @@ -1052,10 +1052,9 @@ void WriteRules(char const * fPath) rules().Write(file); } -void ReadRules(char const * fPath) +void ReadRules(ReaderPtrStream & s) { - FileReaderStream file(fPath); - rules().Read(file); + rules().Read(s); } RulesHolder & rules() diff --git a/indexer/drawing_rules.hpp b/indexer/drawing_rules.hpp index ed784c7463..888e4178ae 100644 --- a/indexer/drawing_rules.hpp +++ b/indexer/drawing_rules.hpp @@ -3,13 +3,12 @@ #include "../base/base.hpp" -#include "../std/fstream.hpp" #include "../std/map.hpp" #include "../std/vector.hpp" #include "../std/array.hpp" #include "../std/string.hpp" -class FileReaderStream; +class ReaderPtrStream; class FileWriterStream; namespace drule @@ -46,11 +45,11 @@ namespace drule char GetType() const { return m_type; } bool IsEqualBase(BaseRule const * p) const { return (m_type == p->m_type); } - void ReadBase(FileReaderStream & ar); + void ReadBase(ReaderPtrStream & ar); void WriteBase(FileWriterStream & ar) const; virtual bool IsEqual(BaseRule const * p) const = 0; - virtual void Read(FileReaderStream & ar) = 0; + virtual void Read(ReaderPtrStream & ar) = 0; virtual void Write(FileWriterStream & ar) const = 0; /// @name This functions can tell us about the type of rule. @@ -105,7 +104,7 @@ namespace drule int GetScale() const { return m_currScale; } - void Read(FileReaderStream & s); + void Read(ReaderPtrStream & s); void Write(FileWriterStream & s); template void ForEachRule(ToDo toDo) @@ -126,7 +125,7 @@ namespace drule }; void WriteRules(char const * fPath); - void ReadRules(char const * fPath); + void ReadRules(ReaderPtrStream & s); RulesHolder & rules(); } diff --git a/indexer/feature.cpp b/indexer/feature.cpp index f2c7121fcc..ea35b90d38 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -829,7 +829,7 @@ uint32_t FeatureType::ParseGeometry(int scale) const int const ind = GetScaleIndex(scale, m_ptsOffsets); if (ind != -1) { - ReaderSource src( + ReaderSource src( m_cont->GetReader(feature::GetTagForIndex(GEOMETRY_FILE_TAG, ind))); src.Skip(m_ptsOffsets[ind]); serial::LoadOuterPath(src, m_CodingParams, m_Points); @@ -881,7 +881,7 @@ uint32_t FeatureType::ParseTriangles(int scale) const uint32_t const ind = GetScaleIndex(scale, m_trgOffsets); if (ind != -1) { - ReaderSource src( + ReaderSource src( m_cont->GetReader(feature::GetTagForIndex(TRIANGLE_FILE_TAG, ind))); src.Skip(m_trgOffsets[ind]); serial::LoadOuterTriangles(src, m_CodingParams, m_Triangles); diff --git a/indexer/feature_processor.hpp b/indexer/feature_processor.hpp index 7c36b1ba30..575223f3f4 100644 --- a/indexer/feature_processor.hpp +++ b/indexer/feature_processor.hpp @@ -10,9 +10,9 @@ namespace feature { template - void ForEachFromDat(string const & fName, ToDo & toDo) + void ForEachFromDat(ModelReaderPtr const & file, ToDo & toDo) { - FilesContainerR container(fName); + FilesContainerR container(file); FeaturesVector featureSource(container); featureSource.ForEachOffset(bind(ref(toDo), _1, _2)); } diff --git a/indexer/features_vector.hpp b/indexer/features_vector.hpp index 0f4b40592d..9fcd5cedc5 100644 --- a/indexer/features_vector.hpp +++ b/indexer/features_vector.hpp @@ -11,7 +11,7 @@ struct FeatureReaders { FilesContainerR m_cont; - FileReader m_datR; + FilesContainerR::ReaderT m_datR; FeatureReaders(FilesContainerR const & cont) : m_cont(cont), m_datR(cont.GetReader(DATA_FILE_TAG)) @@ -46,10 +46,10 @@ public: // bind(toDo, bind(&FeaturesVector::DeserializeFeature, this, _2, _3, &f))); //} - bool IsMyData(string const & fName) const - { - return m_RecordReader.IsEqual(fName); - } + //bool IsMyData(string const & fName) const + //{ + // return m_RecordReader.IsEqual(fName); + //} private: template class feature_getter @@ -71,6 +71,6 @@ private: } }; - VarRecordReader m_RecordReader; + VarRecordReader m_RecordReader; mutable FeatureType::read_source_t m_source; }; diff --git a/indexer/file_reader_stream.hpp b/indexer/file_reader_stream.hpp index a49ac81d23..3c2341b5fa 100644 --- a/indexer/file_reader_stream.hpp +++ b/indexer/file_reader_stream.hpp @@ -3,7 +3,20 @@ #include "../coding/streams.hpp" #include "../coding/file_reader.hpp" -/// @todo Remove and use ReadPrimitive() and other free functions. + +class ReaderPtrStream : public stream::ReaderStream > > +{ + typedef ReaderPtr ptr_t; + typedef ReaderSource source_t; + typedef stream::ReaderStream base_type; + + source_t m_src; +public: + ReaderPtrStream(Reader * p) : base_type(m_src), m_src(p) {} + ReaderPtrStream(ptr_t const & p) : base_type(m_src), m_src(p) {} +}; + + class FileReaderStream : public stream::ReaderStream > { typedef stream::ReaderStream > base_type; @@ -19,6 +32,7 @@ public: using base_type::operator >>; + // It is neccesary for DataFileReader. void Seek(uint64_t pos) { m_reader = m_file.SubReader(pos, m_file.Size() - pos); diff --git a/indexer/index.hpp b/indexer/index.hpp index b715aa0b34..8f5264abfc 100644 --- a/indexer/index.hpp +++ b/indexer/index.hpp @@ -134,16 +134,16 @@ public: } } - void Add(string const & path) + void Add(ModelReaderPtr const & file) { threads::MutexGuard mutexGuard(m_mutex); UNUSED_VALUE(mutexGuard); for (size_t i = 0; i < m_indexes.size(); ++i) - if (m_indexes[i]->IsMyData(path)) + if (m_indexes[i]->IsMyData(file)) return; - m_indexes.push_back(new IndexProxy(path)); + m_indexes.push_back(new IndexProxy(file)); UpdateIndexes(); } @@ -218,13 +218,15 @@ private: class IndexProxy { public: - explicit IndexProxy(string const & path) - : m_action(INDEX_DO_NOTHING), m_path(path), m_pIndex(NULL), m_lockCount(0), + typedef ModelReaderPtr ReaderT; + + explicit IndexProxy(ReaderT const & file) + : m_action(INDEX_DO_NOTHING), m_file(file), m_pIndex(NULL), m_lockCount(0), m_queriesSkipped(0) { // TODO: If path is cellid-style-square, make rect from cellid and don't open the file. feature::DataHeader header; - header.Load(FilesContainerR(path).GetReader(HEADER_FILE_TAG)); + header.Load(FilesContainerR(m_file).GetReader(HEADER_FILE_TAG)); m_rect = header.GetBounds(); m_scaleRange = header.GetScaleRange(); @@ -266,7 +268,11 @@ private: bool IsMyData(string const & path) const { - return m_path == path; + return m_file.IsEqual(path); + } + bool IsMyData(ReaderT const & file) const + { + return m_file.IsEqual(file); } void CloseIfUnlocked() @@ -307,9 +313,7 @@ private: if (!m_pIndex) { // LOG(LINFO, (m_Path)); - uint32_t const logPageSize = 10; - uint32_t const logPageCount = 12; - FilesContainerR container(m_path, logPageSize, logPageCount); + FilesContainerR container(m_file); m_pIndex = new IndexT(container); } } @@ -325,7 +329,7 @@ private: } } - string m_path; // TODO: Store prefix and suffix of path in MultiIndexAdapter. + ReaderT m_file; m2::RectD m_rect; pair m_scaleRange; @@ -381,10 +385,10 @@ public: BaseT::ForEachInIntervalAndScale(offsetToFeatureReplacer, beg, end, scale, query); } - bool IsMyData(string const & fName) const - { - return m_FeatureVector.IsMyData(fName); - } + //bool IsMyData(string const & fName) const + //{ + // return m_FeatureVector.IsMyData(fName); + //} private: FeatureVectorT m_FeatureVector; diff --git a/indexer/index_builder.cpp b/indexer/index_builder.cpp index f36177147c..a73439aac7 100644 --- a/indexer/index_builder.cpp +++ b/indexer/index_builder.cpp @@ -44,7 +44,7 @@ namespace indexer #ifdef DEBUG FilesContainerR readCont(datFile); - FileReader r = readCont.GetReader(HEADER_FILE_TAG); + FilesContainerR::ReaderT r = readCont.GetReader(HEADER_FILE_TAG); int64_t const base = ReadPrimitiveFromPos(r, 0); LOG(LINFO, ("OFFSET = ", base)); #endif diff --git a/indexer/indexer_tests/feature_test.cpp b/indexer/indexer_tests/feature_test.cpp index d20e6b612b..53627f6baa 100644 --- a/indexer/indexer_tests/feature_test.cpp +++ b/indexer/indexer_tests/feature_test.cpp @@ -42,9 +42,9 @@ namespace UNIT_TEST(Feature_Deserialize) { Platform & platform = GetPlatform(); - classificator::Read(platform.ReadPathForFile("drawing_rules.bin"), - platform.ReadPathForFile("classificator.txt"), - platform.ReadPathForFile("visibility.txt")); + classificator::Read(platform.GetReader("drawing_rules.bin"), + platform.GetReader("classificator.txt"), + platform.GetReader("visibility.txt")); FeatureBuilder2 fb; diff --git a/indexer/indexer_tests/index_builder_test.cpp b/indexer/indexer_tests/index_builder_test.cpp index ea81177eb3..25d43af4f1 100644 --- a/indexer/indexer_tests/index_builder_test.cpp +++ b/indexer/indexer_tests/index_builder_test.cpp @@ -13,9 +13,9 @@ UNIT_TEST(BuildIndexTest) { Platform & p = GetPlatform(); - classificator::Read(p.ReadPathForFile("drawing_rules.bin"), - p.ReadPathForFile("classificator.txt"), - p.ReadPathForFile("visibility.txt")); + classificator::Read(p.GetReader("drawing_rules.bin"), + p.GetReader("classificator.txt"), + p.GetReader("visibility.txt")); FilesContainerR originalContainer(p.WritablePathForFile("minsk-pass" DATA_FILE_EXTENSION)); @@ -41,7 +41,7 @@ UNIT_TEST(BuildIndexTest) { if (tags[i] != INDEX_FILE_TAG) { - FileReader reader = originalContainer.GetReader(tags[i]); + FilesContainerR::ReaderT reader = originalContainer.GetReader(tags[i]); size_t const sz = static_cast(reader.Size()); if (sz > 0) { @@ -56,8 +56,8 @@ UNIT_TEST(BuildIndexTest) { // Check that index actually works. - Index::Type index; - index.Add(fileName); + Index::Type index; + index.Add(new FileReader(fileName)); // Make sure that index is actually parsed. index.ForEachInScale(NoopFunctor(), 15); diff --git a/indexer/indexer_tests/index_test.cpp b/indexer/indexer_tests/index_test.cpp index 688a598e68..ee14da7fc2 100644 --- a/indexer/indexer_tests/index_test.cpp +++ b/indexer/indexer_tests/index_test.cpp @@ -10,8 +10,8 @@ UNIT_TEST(IndexParseTest) { - Index::Type index; - index.Add(GetPlatform().WritablePathForFile("minsk-pass" DATA_FILE_EXTENSION)); + Index::Type index; + index.Add(GetPlatform().GetReader("minsk-pass" DATA_FILE_EXTENSION)); // Make sure that index is actually parsed. index.ForEachInScale(NoopFunctor(), 15); diff --git a/indexer/tree_structure.hpp b/indexer/tree_structure.hpp index 540d6bd428..fb4a0f9800 100644 --- a/indexer/tree_structure.hpp +++ b/indexer/tree_structure.hpp @@ -3,7 +3,7 @@ #include "../base/assert.hpp" #include "../std/fstream.hpp" -#include "../std/sstream.hpp" + namespace tree { diff --git a/map/feature_vec_model.cpp b/map/feature_vec_model.cpp index 8d2b93ac13..616ce07958 100644 --- a/map/feature_vec_model.cpp +++ b/map/feature_vec_model.cpp @@ -20,16 +20,24 @@ namespace model void FeaturesFetcher::InitClassificator() { Platform & p = GetPlatform(); - classificator::Read(p.ReadPathForFile("drawing_rules.bin"), - p.ReadPathForFile("classificator.txt"), - p.ReadPathForFile("visibility.txt")); + + try + { + classificator::Read(p.GetReader("drawing_rules.bin"), + p.GetReader("classificator.txt"), + p.GetReader("visibility.txt")); + } + catch (FileAbsentException const & e) + { + LOG(LERROR, ("Classificator not found ", e.what())); + } } -void FeaturesFetcher::AddMap(string const & fName) +void FeaturesFetcher::AddMap(ReaderT const & file) { try { - m_multiIndex.Add(fName); + m_multiIndex.Add(file); } catch (Reader::OpenException const & e) { diff --git a/map/feature_vec_model.hpp b/map/feature_vec_model.hpp index dc6731a732..03d553984e 100644 --- a/map/feature_vec_model.hpp +++ b/map/feature_vec_model.hpp @@ -19,15 +19,17 @@ namespace model class FeaturesFetcher { - m2::RectD m_rect; - + public: #ifdef USE_BUFFER_READER - typedef BufferReader reader_t; + typedef BufferReader ReaderT; #else - typedef FileReader reader_t; + typedef ModelReaderPtr ReaderT; #endif - typedef Index::Type index_t; + private: + m2::RectD m_rect; + + typedef Index::Type index_t; index_t m_multiIndex; @@ -38,7 +40,7 @@ namespace model void InitClassificator(); - void AddMap(string const & fName); + void AddMap(ReaderT const & file); void RemoveMap(string const & fName); void Clean(); void ClearCaches(); diff --git a/map/framework.cpp b/map/framework.cpp index 2d73835e42..680e27a664 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -284,18 +284,18 @@ void FrameWork::AddRedrawCommandSure() } template - void FrameWork::AddMap(string const & datFile) + void FrameWork::AddMap(ReaderT const & file) { // update rect for Show All button feature::DataHeader header; - header.Load(FilesContainerR(datFile).GetReader(HEADER_FILE_TAG)); + header.Load(FilesContainerR(file).GetReader(HEADER_FILE_TAG)); m2::RectD bounds = header.GetBounds(); m_model.AddWorldRect(bounds); { threads::MutexGuard lock(m_modelSyn); - m_model.AddMap(datFile); + m_model.AddMap(file); } } @@ -496,19 +496,37 @@ void FrameWork::AddRedrawCommandSure() } }; - template - void FrameWork::EnumLocalMaps(Platform::FilesList & filesList) + class ReadersAdder { + typedef vector maps_list_t; + + Platform & m_pl; + maps_list_t & m_lst; + + public: + ReadersAdder(Platform & pl, maps_list_t & lst) : m_pl(pl), m_lst(lst) {} + + void operator() (string const & f) + { + m_lst.push_back(m_pl.GetReader(f)); + } + }; + + template + void FrameWork::EnumLocalMaps(maps_list_t & filesList) + { + Platform & pl = GetPlatform(); - Platform & p = GetPlatform(); // scan for pre-installed maps in resources - string const resPath = p.ResourcesDir(); + string const resPath = pl.ResourcesDir(); Platform::FilesList resFiles; - p.GetFilesInDir(resPath, "*" DATA_FILE_EXTENSION, resFiles); + pl.GetFilesInDir(resPath, "*" DATA_FILE_EXTENSION, resFiles); + // scan for probably updated maps in data dir - string const dataPath = p.WritableDir(); + string const dataPath = pl.WritableDir(); Platform::FilesList dataFiles; - p.GetFilesInDir(dataPath, "*" DATA_FILE_EXTENSION, dataFiles); + pl.GetFilesInDir(dataPath, "*" DATA_FILE_EXTENSION, dataFiles); + // wipe out same maps from resources, which have updated // downloaded versions in data path for (Platform::FilesList::iterator it = resFiles.begin(); it != resFiles.end();) @@ -519,21 +537,19 @@ void FrameWork::AddRedrawCommandSure() else ++it; } - // make full resources paths - for_each(resFiles.begin(), resFiles.end(), PathAppender(resPath)); - // make full data paths - for_each(dataFiles.begin(), dataFiles.end(), PathAppender(dataPath)); filesList.clear(); - filesList.assign(resFiles.begin(), resFiles.end()); - filesList.insert(filesList.end(), dataFiles.begin(), dataFiles.end()); + for_each(resFiles.begin(), resFiles.end(), ReadersAdder(pl, filesList)); + for_each(dataFiles.begin(), dataFiles.end(), ReadersAdder(pl, filesList)); } template - void FrameWork::EnumBenchmarkMaps(Platform::FilesList & filesList) + void FrameWork::EnumBenchmarkMaps(maps_list_t & filesList) { + Platform & pl = GetPlatform(); + set files; - ifstream fin(GetPlatform().WritablePathForFile("benchmarks/config.info").c_str()); + ifstream fin(pl.WritablePathForFile("benchmarks/config.info").c_str()); filesList.clear(); char buf[256]; @@ -554,7 +570,7 @@ void FrameWork::AddRedrawCommandSure() ++it; } - filesList.push_back(GetPlatform().ReadPathForFile(parts[0])); + filesList.push_back(pl.GetReader(parts[0])); } } @@ -1220,8 +1236,9 @@ void FrameWork::AddRedrawCommandSure() if (!m_pSearchEngine.get()) { search::CategoriesHolder holder; - ifstream file(GetPlatform().ReadPathForFile(SEARCH_CATEGORIES_FILE_NAME).c_str()); - holder.LoadFromStream(file); + string buffer; + ReaderT(GetPlatform().GetReader(SEARCH_CATEGORIES_FILE_NAME)).ReadAsString(buffer); + holder.LoadFromStream(buffer); m_pSearchEngine.reset(new search::Engine(&m_model.GetIndex(), holder)); } diff --git a/map/framework.hpp b/map/framework.hpp index cb35746f79..98364bec7f 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -43,7 +43,7 @@ #include "../std/vector.hpp" #include "../std/shared_ptr.hpp" #include "../std/target_os.hpp" -#include "../std/fstream.hpp" + //#define DRAW_TOUCH_POINTS @@ -181,7 +181,9 @@ class FrameWork void MarkBenchmarkResultsStart(); void MarkBenchmarkResultsEnd(); - void AddMap(string const & datFile); + typedef typename TModel::ReaderT ReaderT; + + void AddMap(ReaderT const & file); void RemoveMap(string const & datFile); void OnGpsUpdate(location::GpsInfo const & info); @@ -200,8 +202,9 @@ public: model_t & get_model(); - void EnumLocalMaps(Platform::FilesList & filesList); - void EnumBenchmarkMaps(Platform::FilesList & filesList); + typedef vector maps_list_t; + void EnumLocalMaps(maps_list_t & filesList); + void EnumBenchmarkMaps(maps_list_t & filesList); /// Initialization. template diff --git a/map/languages.cpp b/map/languages.cpp index fdd903cf0d..0024e0db63 100644 --- a/map/languages.cpp +++ b/map/languages.cpp @@ -124,9 +124,11 @@ namespace languages bool GetSupportedLanguages(CodesAndNamesT & outLanguages) { outLanguages.clear(); - FileReader file(GetPlatform().ReadPathForFile(LANGUAGES_FILE)); - string const langs = file.ReadAsText(); - istringstream stream(langs); + + string buffer; + ReaderPtr(GetPlatform().GetReader(LANGUAGES_FILE)).ReadAsString(buffer); + istringstream stream(buffer); + for (size_t i = 0; i < MAX_SUPPORTED_LANGUAGES; ++i) { string line; @@ -137,5 +139,4 @@ namespace languages } return !outLanguages.empty(); } - } diff --git a/map/map_tests/map_foreach_test.cpp b/map/map_tests/map_foreach_test.cpp index d4b13949fb..0bb4f33efe 100644 --- a/map/map_tests/map_foreach_test.cpp +++ b/map/map_tests/map_foreach_test.cpp @@ -154,14 +154,14 @@ void for_each_in_rect(TSource & src, feature_cont_t & cont, m2::RectD const & re class file_source_t { - string m_fDat; + ModelReaderPtr m_file; public: - file_source_t(string const & fDat) : m_fDat(fDat) {} + file_source_t(ModelReaderPtr const & file) : m_file(file) {} template void ForEachFeature(m2::RectD const & /*rect*/, ToDo toDo) { - feature::ForEachFromDat(m_fDat, toDo); + feature::ForEachFromDat(m_file, toDo); } }; @@ -227,14 +227,14 @@ namespace } }; - void RunTest(string const & path) + void RunTest(ModelReaderPtr const & file) { model::FeaturesFetcher src1; src1.InitClassificator(); - src1.AddMap(path); + src1.AddMap(file); feature::DataHeader mapInfo; - mapInfo.Load(FilesContainerR(path).GetReader(HEADER_FILE_TAG)); + mapInfo.Load(FilesContainerR(file).GetReader(HEADER_FILE_TAG)); vector rects; rects.push_back(mapInfo.GetBounds()); @@ -247,7 +247,7 @@ namespace feature_cont_t v1, v2; for_each_in_rect(src1, v1, r); - file_source_t src2(path); + file_source_t src2(file); for_each_in_rect(src2, v2, r); int const level = scales::GetScaleLevel(r); @@ -278,7 +278,7 @@ namespace char c; cin >> c; if (c == 'y') - RunTest(GetPlatform().WritablePathForFile(fName + DATA_FILE_EXTENSION)); + RunTest(GetPlatform().GetReader(fName + DATA_FILE_EXTENSION)); } } diff --git a/platform/platform.cpp b/platform/platform.cpp index 1cef3c44bd..d4410a7dba 100644 --- a/platform/platform.cpp +++ b/platform/platform.cpp @@ -2,6 +2,7 @@ #include "settings.hpp" #include "../coding/internal/file_data.hpp" +#include "../coding/file_reader.hpp" #include "../base/logging.hpp" @@ -26,6 +27,11 @@ string BasePlatformImpl::ReadPathForFile(string const & file) const return fullPath; } +ModelReader * BasePlatformImpl::GetReader(string const & file) const +{ + return new FileReader(ReadPathForFile(file), 10, 12); +} + bool BasePlatformImpl::GetFileSize(string const & file, uint64_t & size) const { return my::GetFileSize(file, size); diff --git a/platform/platform.hpp b/platform/platform.hpp index 593ec07ff3..0154335d99 100644 --- a/platform/platform.hpp +++ b/platform/platform.hpp @@ -1,5 +1,7 @@ #pragma once +#include "../coding/reader.hpp" + #include "../base/exception.hpp" #include "../std/string.hpp" @@ -27,11 +29,16 @@ public: /// @return resource dir (on some platforms it's differ from Writable dir) virtual string ResourcesDir() const = 0; + /// @name Get the reader path or reader itself for file decriptor. /// Throws FileAbsentException - /// @param[in] file just file name which we want to read + /// @param[in] file descriptor which we want to read + //@{ /// @return fully resolved path including file name virtual string ReadPathForFile(string const & file) const = 0; + virtual ModelReader * GetReader(string const & file) const = 0; + //@} + /// @name File operations //@{ typedef vector FilesList; @@ -84,6 +91,7 @@ public: virtual string WritableDir() const { return m_writableDir; } virtual string ResourcesDir() const { return m_resourcesDir; } virtual string ReadPathForFile(string const & file) const; + virtual ModelReader * GetReader(string const & file) const; virtual void GetFilesInDir(string const & directory, string const & mask, FilesList & res) const; virtual bool GetFileSize(string const & file, uint64_t & size) const; diff --git a/qt/classificator_tree.cpp b/qt/classificator_tree.cpp index 08373911f0..3936fa78fa 100644 --- a/qt/classificator_tree.cpp +++ b/qt/classificator_tree.cpp @@ -1,6 +1,7 @@ #include "../base/SRC_FIRST.hpp" #include "classificator_tree.hpp" +#include "../indexer/classificator_loader.hpp" #include "../indexer/classificator.hpp" #include "../platform/platform.hpp" @@ -16,9 +17,9 @@ #include #include - #include "../base/start_mem_debug.hpp" + namespace qt { @@ -229,7 +230,7 @@ void ClassifTreeHolder::OnLoad() QString::fromStdString(GetPlatform().WritableDir()), tr("Text Files (*.txt)")); - classif().ReadVisibility(fName.toAscii().constData()); + classificator::ReadVisibility(fName.toAscii().constData()); Rebuild(); } diff --git a/qt/main.cpp b/qt/main.cpp index 51ceb90e04..ea687e25c0 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -92,8 +92,9 @@ int main(int argc, char *argv[]) QStringList buttons; buttons << "Accept" << "Decline"; - FileReader f(GetPlatform().ReadPathForFile("eula.html")); - qt::InfoDialog eulaDialog("MapsWithMe End User Licensing Agreement", f.ReadAsText().c_str(), NULL, buttons); + string buffer; + FileReader(GetPlatform().ReadPathForFile("eula.html")).ReadAsString(buffer); + qt::InfoDialog eulaDialog("MapsWithMe End User Licensing Agreement", buffer.c_str(), NULL, buttons); eulaAccepted = (eulaDialog.exec() == 1); Settings::Set(SETTING_EULA_ACCEPTED, eulaAccepted); } diff --git a/search/categories_holder.cpp b/search/categories_holder.cpp index 5a1044a2b3..909495bb4e 100644 --- a/search/categories_holder.cpp +++ b/search/categories_holder.cpp @@ -3,6 +3,7 @@ #include "../indexer/classificator.hpp" #include "../coding/multilang_utf8_string.hpp" +#include "../coding/reader.hpp" #include "../base/string_utils.hpp" #include "../base/logging.hpp" @@ -26,7 +27,7 @@ enum State { EParseLanguages }; -size_t CategoriesHolder::LoadFromStream(istream & stream) +size_t CategoriesHolder::LoadFromStream(string const & buffer) { m_categories.clear(); @@ -34,10 +35,13 @@ size_t CategoriesHolder::LoadFromStream(istream & stream) string line; Category cat; + + istringstream stream(buffer); while (stream.good()) { getline(stream, line); strings::SimpleTokenizer iter(line, ":|"); + switch (state) { case EParseTypes: @@ -97,6 +101,7 @@ size_t CategoriesHolder::LoadFromStream(istream & stream) break; } } + // add last category if (!cat.m_synonyms.empty() && !cat.m_types.empty()) m_categories.push_back(cat); diff --git a/search/categories_holder.hpp b/search/categories_holder.hpp index d25d9b0f5e..b331ef9c45 100644 --- a/search/categories_holder.hpp +++ b/search/categories_holder.hpp @@ -3,9 +3,9 @@ #include "../std/vector.hpp" #include "../std/string.hpp" -#include "../std/fstream.hpp" #include "../std/algorithm.hpp" + namespace search { @@ -34,7 +34,7 @@ public: typedef ContainerT::const_iterator const_iterator; /// @return number of loaded categories or 0 if something goes wrong - size_t LoadFromStream(istream & stream); + size_t LoadFromStream(string const & buffer); template void ForEachCategory(ToDo toDo) const diff --git a/search/engine.hpp b/search/engine.hpp index 7fccb352dc..2f0b1543ec 100644 --- a/search/engine.hpp +++ b/search/engine.hpp @@ -12,7 +12,8 @@ #include "../std/string.hpp" -class FileReader; +class Reader; +class ModelReaderPtr; class FeatureType; namespace search @@ -25,7 +26,7 @@ class Result; class Engine { public: - typedef Index::Type IndexType; + typedef Index::Type IndexType; /// Doesn't take ownership of @pIndex. Modifies @categories. Engine(IndexType const * pIndex, CategoriesHolder & categories); diff --git a/search/search_tests/categories_test.cpp b/search/search_tests/categories_test.cpp index 753f9c6f4d..10e11a87fe 100644 --- a/search/search_tests/categories_test.cpp +++ b/search/search_tests/categories_test.cpp @@ -70,13 +70,14 @@ struct Checker UNIT_TEST(LoadCategories) { Platform & p = GetPlatform(); - classificator::Read(p.ReadPathForFile("drawing_rules.bin"), - p.ReadPathForFile("classificator.txt"), - p.ReadPathForFile("visibility.txt")); + classificator::Read(p.GetReader("drawing_rules.bin"), + p.GetReader("classificator.txt"), + p.GetReader("visibility.txt")); search::CategoriesHolder h; - istringstream file(TEST_STRING); - TEST_GREATER(h.LoadFromStream(file), 0, ()); + string buffer; + ReaderPtr(p.GetReader(TEST_STRING)).ReadAsString(buffer); + TEST_GREATER(h.LoadFromStream(buffer), 0, ()); size_t count = 0; Checker f(count); h.ForEachCategory(f); diff --git a/storage/country.cpp b/storage/country.cpp index 0a590a153b..bb42b4e87b 100644 --- a/storage/country.cpp +++ b/storage/country.cpp @@ -98,11 +98,15 @@ namespace storage return true; } - bool LoadCountries(string const & countriesFile, TTilesContainer const & sortedTiles, + bool LoadCountries(file_t const & file, TTilesContainer const & sortedTiles, TCountriesContainer & countries) { countries.Clear(); - ifstream stream(countriesFile.c_str()); + + string buffer; + file.ReadAsString(buffer); + istringstream stream(buffer); + std::string line; Country * currentCountry = &countries.Value(); while (stream.good()) @@ -174,15 +178,14 @@ namespace storage wStream << commonFiles; } - bool LoadTiles(TTilesContainer & tiles, string const & tilesFile, uint32_t & dataVersion) + bool LoadTiles(file_t const & file, TTilesContainer & tiles, uint32_t & dataVersion) { tiles.clear(); try { - FileReader fileReader(tilesFile); - ReaderSource source(fileReader); - stream::SinkReaderStream > stream(source); + ReaderSource source(file); + stream::SinkReaderStream > stream(source); TDataFiles dataFiles; TCommonFiles commonFiles; diff --git a/storage/country.hpp b/storage/country.hpp index 1850401ceb..b899fb79a1 100644 --- a/storage/country.hpp +++ b/storage/country.hpp @@ -9,6 +9,8 @@ #include "../std/string.hpp" #include "../std/vector.hpp" + +template class ReaderPtr; class Reader; class Writer; @@ -68,10 +70,11 @@ namespace storage /// @param tiles contains files and their sizes /// @return false if new application version should be downloaded - bool LoadCountries(string const & countriesFile, TTilesContainer const & sortedTiles, + typedef ReaderPtr file_t; + bool LoadCountries(file_t const & file, TTilesContainer const & sortedTiles, TCountriesContainer & countries); void SaveTiles(string const & file, int32_t level, TDataFiles const & cellFiles, TCommonFiles const & commonFiles); - bool LoadTiles(TTilesContainer & tiles, string const & tilesFile, uint32_t & dataVersion); -// void SaveCountries(TCountriesContainer const & countries, Writer & writer); + bool LoadTiles(file_t const & file, TTilesContainer & tiles, uint32_t & dataVersion); + //void SaveCountries(TCountriesContainer const & countries, Writer & writer); } diff --git a/storage/storage.cpp b/storage/storage.cpp index 103ce9dbbf..847772389e 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -53,19 +53,12 @@ namespace storage m_removeMap = removeFunc; m_updateRect = updateRectFunc; - Platform::FilesList filesList; + typedef vector map_list_t; + map_list_t filesList; enumMapsFunc(filesList); - for (Platform::FilesList::iterator it = filesList.begin(); it != filesList.end(); ++it) - { // simple way to avoid continuous crashes with invalid data files - try { - m_addMap(*it); - } catch (std::exception const & e) - { - FileWriter::DeleteFileX(*it); - LOG(LWARNING, (e.what(), "while adding file", *it, "so this file is deleted")); - } - } + for (map_list_t::iterator it = filesList.begin(); it != filesList.end(); ++it) + m_addMap(*it); } string Storage::UpdateBaseUrl() const @@ -303,10 +296,11 @@ namespace storage if (m_countries.SiblingsCount() == 0) { + Platform & pl = GetPlatform(); TTilesContainer tiles; - if (LoadTiles(tiles, GetPlatform().ReadPathForFile(DATA_UPDATE_FILE), m_currentVersion)) + if (LoadTiles(pl.GetReader(DATA_UPDATE_FILE), tiles, m_currentVersion)) { - if (!LoadCountries(GetPlatform().ReadPathForFile(COUNTRIES_FILE), tiles, m_countries)) + if (!LoadCountries(pl.GetReader(COUNTRIES_FILE), tiles, m_countries)) { LOG(LWARNING, ("Can't load countries file", COUNTRIES_FILE)); } @@ -358,8 +352,10 @@ namespace storage TLocalAndRemoteSize size = CountryByIndex(m_queue.front()).Size(); if (size.second != 0) m_countryProgress.m_current = size.first; + + /// @todo Get file reader from download framework. // activate downloaded map piece - m_addMap(result.m_file); + m_addMap(new FileReader(result.m_file)); feature::DataHeader header; header.Load(FilesContainerR(result.m_file).GetReader(HEADER_FILE_TAG)); @@ -433,19 +429,21 @@ namespace storage void Storage::OnBinaryUpdateCheckFinished(HttpFinishedParams const & params) { if (params.m_error == EHttpDownloadFileNotFound) - { // no binary update is available + { + // no binary update is available if (m_observerUpdateRequest) m_observerUpdateRequest(ENoAnyUpdateAvailable, "No update is available"); } else if (params.m_error == EHttpDownloadOk) - { // update is available! + { + // update is available! try { if (m_observerUpdateRequest) { - string const updateTextFilePath = GetPlatform().ReadPathForFile(params.m_file); - FileReader file(updateTextFilePath); - m_observerUpdateRequest(ENewBinaryAvailable, file.ReadAsText()); + string buffer; + FileReader(GetPlatform().ReadPathForFile(params.m_file)).ReadAsString(buffer); + m_observerUpdateRequest(ENewBinaryAvailable, buffer); } } catch (std::exception const & e) @@ -456,7 +454,8 @@ namespace storage } } else - { // connection error + { + // connection error if (m_observerUpdateRequest) m_observerUpdateRequest(EBinaryCheckFailed, ErrorString(params.m_error)); } diff --git a/storage/storage.hpp b/storage/storage.hpp index 4ba939a04e..9e8a482ebe 100644 --- a/storage/storage.hpp +++ b/storage/storage.hpp @@ -89,12 +89,12 @@ namespace storage /// @name Communicate with Framework //@{ public: - typedef function TAddMapFunction; + typedef function TAddMapFunction; typedef function TRemoveMapFunction; typedef function TUpdateRectFunction; - typedef function TEnumMapsFunction; - private: + typedef function &)> TEnumMapsFunction; + private: TAddMapFunction m_addMap; TRemoveMapFunction m_removeMap; TUpdateRectFunction m_updateRect; diff --git a/storage/storage_tests/country_test.cpp b/storage/storage_tests/country_test.cpp index 7945b2d5ec..b6794d0064 100644 --- a/storage/storage_tests/country_test.cpp +++ b/storage/storage_tests/country_test.cpp @@ -37,7 +37,7 @@ UNIT_TEST(TilesSerialization) uint32_t version; TTilesContainer tiles; - TEST( LoadTiles(tiles, FILE, version), ()); + TEST(LoadTiles(ReaderPtr(new FileReader(FILE)), tiles, version), ()); TEST_EQUAL( tiles.size(), 5, ()); TEST_EQUAL( tiles[0], TTilesContainer::value_type(