diff --git a/coding/file_container.cpp b/coding/file_container.cpp index 11940738a5..4a1c29fb5b 100644 --- a/coding/file_container.cpp +++ b/coding/file_container.cpp @@ -355,20 +355,24 @@ FileWriter FilesContainerW::GetWriter(Tag const & tag) if (m_bNeedRewrite) { m_bNeedRewrite = false; - ASSERT ( !m_info.empty(), () ); + ASSERT(!m_info.empty(), ()); uint64_t const curr = m_info.back().m_offset + m_info.back().m_size; - m_info.push_back(Info(tag, curr)); - FileWriter writer(m_name, FileWriter::OP_WRITE_EXISTING, true); writer.Seek(curr); + writer.WritePaddingByPos(kSectionAlignment); + m_info.push_back(Info(tag, writer.Pos())); + ASSERT(m_info.back().m_offset % kSectionAlignment == 0, ()); return writer; } else { - uint64_t const curr = SaveCurrentSize(); - m_info.push_back(Info(tag, curr)); - return FileWriter(m_name, FileWriter::OP_APPEND); + SaveCurrentSize(); + FileWriter writer(m_name, FileWriter::OP_APPEND); + writer.WritePaddingByPos(kSectionAlignment); + m_info.push_back(Info(tag, writer.Pos())); + ASSERT(m_info.back().m_offset % kSectionAlignment == 0, ()); + return writer; } } diff --git a/coding/file_container.hpp b/coding/file_container.hpp index 31329ebf65..53ee935e2c 100644 --- a/coding/file_container.hpp +++ b/coding/file_container.hpp @@ -12,6 +12,13 @@ class FilesContainerBase public: typedef string Tag; + /// Alignment of each new section that will be added to a file + /// container, i.e. section's offset in bytes will be a multiple of + /// this value. + /// + /// WARNING! Existing sections may not be properly aligned. + static uint64_t const kSectionAlignment = 8; + bool IsExist(Tag const & tag) const { return GetInfo(tag) != 0; diff --git a/coding/file_writer.cpp b/coding/file_writer.cpp index 5dc2735abd..d64dd6509e 100644 --- a/coding/file_writer.cpp +++ b/coding/file_writer.cpp @@ -1,7 +1,6 @@ #include "file_writer.hpp" #include "internal/file_data.hpp" - FileWriter::FileWriter(FileWriter const & rhs) : Writer(*this), m_bTruncOnClose(rhs.m_bTruncOnClose) { @@ -40,18 +39,9 @@ void FileWriter::Write(void const * p, size_t size) m_pFileData->Write(p, size); } -void FileWriter::WritePadding(size_t factor) -{ - ASSERT(factor > 1, ()); +void FileWriter::WritePaddingByEnd(size_t factor) { WritePadding(Size(), factor); } - uint64_t sz = Size(); - sz = ((sz + factor - 1) / factor) * factor - sz; - if (sz > 0) - { - vector buffer(sz); - Write(buffer.data(), sz); - } -} +void FileWriter::WritePaddingByPos(size_t factor) { WritePadding(Pos(), factor); } string FileWriter::GetName() const { @@ -83,3 +73,12 @@ void FileWriter::DeleteFileX(string const & fName) (void)my::DeleteFileX(fName); } +void FileWriter::WritePadding(uint64_t offset, uint64_t factor) +{ + ASSERT(factor > 1, ()); + uint64_t const padding = ((offset + factor - 1) / factor) * factor - offset; + if (!padding) + return; + vector buffer(padding); + Write(buffer.data(), buffer.size()); +} diff --git a/coding/file_writer.hpp b/coding/file_writer.hpp index b36ba97711..5e127476cd 100644 --- a/coding/file_writer.hpp +++ b/coding/file_writer.hpp @@ -35,7 +35,9 @@ public: int64_t Pos() const; void Write(void const * p, size_t size); - void WritePadding(size_t factor); + void WritePaddingByEnd(size_t factor); + + void WritePaddingByPos(size_t factor); uint64_t Size() const; void Flush(); @@ -48,6 +50,9 @@ public: private: typedef my::FileData fdata_t; + + void WritePadding(uint64_t offset, uint64_t factor); + unique_ptr m_pFileData; bool m_bTruncOnClose; }; diff --git a/data/minsk-pass.mwm b/data/minsk-pass.mwm index 0188979938..be1583c489 100644 Binary files a/data/minsk-pass.mwm and b/data/minsk-pass.mwm differ diff --git a/generator/routing_generator.cpp b/generator/routing_generator.cpp index 3fc6fc75fa..2baaf6ebe1 100644 --- a/generator/routing_generator.cpp +++ b/generator/routing_generator.cpp @@ -269,7 +269,7 @@ void BuildRoutingIndex(string const & baseDir, string const & countryName, strin FileWriter w = routingCont.GetWriter(VERSION_FILE_TAG); ReaderSource src(mwmCont.GetReader(VERSION_FILE_TAG)); rw::ReadAndWrite(src, w); - w.WritePadding(4); + w.WritePaddingByEnd(4); } mapping.Save(routingCont); @@ -338,7 +338,7 @@ void BuildRoutingIndex(string const & baseDir, string const & countryName, strin FileWriter w = routingCont.GetWriter(ROUTING_CROSS_CONTEXT_TAG); size_t const start_size = w.Pos(); crossContext.Save(w); - w.WritePadding(4); + w.WritePaddingByEnd(4); LOG(LINFO, ("Have written routing info, bytes written:", w.Pos() - start_size, "bytes")); routingCont.Finish(); diff --git a/routing/osrm2feature_map.cpp b/routing/osrm2feature_map.cpp index ee06f65e80..deb1ad09ae 100644 --- a/routing/osrm2feature_map.cpp +++ b/routing/osrm2feature_map.cpp @@ -310,7 +310,7 @@ void OsrmFtSegMappingBuilder::Save(FilesContainerW & cont) const } // Write padding to make next elias_fano start address multiple of 4. - writer.WritePadding(4); + writer.WritePaddingByEnd(4); } string const fName = cont.GetFileName() + "." ROUTING_FTSEG_FILE_TAG;