Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Koronchik <denis@mapswithme.com>2014-09-16 12:05:39 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:28:17 +0300
commitd8f3008ecc7300e87262308e753c7bf3d850c9e9 (patch)
tree44b2d2bc6df3299d66681a200bf4d7f2962f4d59 /coding/file_container.cpp
parentb353a8adaef05206e4bf6769695e566d8e5989ce (diff)
[coding] Implement FileMappingContainer
Diffstat (limited to 'coding/file_container.cpp')
-rw-r--r--coding/file_container.cpp85
1 files changed, 79 insertions, 6 deletions
diff --git a/coding/file_container.cpp b/coding/file_container.cpp
index 28716334e1..40c64f7e64 100644
--- a/coding/file_container.cpp
+++ b/coding/file_container.cpp
@@ -5,6 +5,17 @@
#include "write_to_sink.hpp"
#include "internal/file_data.hpp"
+#ifndef OMIM_OS_WINDOWS
+ #include <unistd.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #ifdef OMIM_OS_ANDROID
+ #include <fcntl.h>
+ #else
+ #include <sys/fcntl.h>
+ #endif
+#endif
+
template <class TSource> void Read(TSource & src, FilesContainerBase::Info & i)
{
@@ -64,21 +75,83 @@ FilesContainerR::FilesContainerR(ReaderT const & file)
FilesContainerR::ReaderT FilesContainerR::GetReader(Tag const & tag) const
{
+ Info const * p = GetInfo(tag);
+ if (p)
+ return m_source.SubReader(p->m_offset, p->m_size);
+ else
+ MYTHROW(Reader::OpenException, (tag));
+}
+
+FilesContainerBase::Info const * FilesContainerBase::GetInfo(Tag const & tag) const
+{
InfoContainer::const_iterator i =
lower_bound(m_info.begin(), m_info.end(), tag, LessInfo());
if (i != m_info.end() && i->m_tag == tag)
- return m_source.SubReader(i->m_offset, i->m_size);
+ return &(*i);
else
- MYTHROW(Reader::OpenException, (tag));
+ return 0;
}
-bool FilesContainerR::IsReaderExist(Tag const & tag) const
+/////////////////////////////////////////////////////////////////////////////
+// FilesMappingContainer
+/////////////////////////////////////////////////////////////////////////////
+
+FilesMappingContainer::FilesMappingContainer(string const & fName)
{
- InfoContainer::const_iterator i =
- lower_bound(m_info.begin(), m_info.end(), tag, LessInfo());
+ {
+ FileReader reader(fName, 10, 1);
+ ReadInfo(reader);
+ }
+
+ m_fd = open(fName.c_str(), O_RDONLY | O_NONBLOCK);
+ if (m_fd == -1)
+ MYTHROW(Reader::OpenException, ("Can't open file:", fName));
+}
+
+FilesMappingContainer::~FilesMappingContainer()
+{
+ close(m_fd);
+}
+
+FilesMappingContainer::Handle FilesMappingContainer::Map(Tag const & tag) const
+{
+ Info const * p = GetInfo(tag);
+ if (p)
+ {
+ long const offsetAlign = sysconf(_SC_PAGE_SIZE);
+
+ uint64_t const offset = (p->m_offset / offsetAlign) * offsetAlign;
+ ASSERT_LESS_OR_EQUAL(offset, p->m_offset, ());
+ uint64_t const length = p->m_size + (p->m_offset - offset);
+ ASSERT_GREATER_OR_EQUAL(length, p->m_size, ());
+
+ char const * data = reinterpret_cast<char const *>(mmap(0, length, PROT_READ, MAP_SHARED, m_fd, offset));
+
+ if (data == reinterpret_cast<char const *>(-1))
+ MYTHROW(Reader::OpenException, ("Can't map section:", tag, "with [offset, size]:", *p));
+
+ char const * d = data + (p->m_offset - offset);
+ return Handle(d, data, p->m_size, length);
+ }
+ else
+ MYTHROW(Reader::OpenException, ("Can't find section:", tag));
+
+ return Handle();
+}
+
+FilesMappingContainer::Handle::~Handle()
+{
+// CHECK(!IsValid(), ());
+}
+
+void FilesMappingContainer::Handle::Unmap()
+{
+ ASSERT(IsValid(), ());
+ VERIFY(0 == munmap((void*)m_origBase, m_origSize), ());
- return (i != m_info.end() && i->m_tag == tag);
+ m_origBase = m_base = 0;
+ m_origSize = m_size = 0;
}
/////////////////////////////////////////////////////////////////////////////