forked from organicmaps/organicmaps-tmp
File container compile test.
This commit is contained in:
parent
2d8a35967c
commit
e04540f8b6
3 changed files with 163 additions and 0 deletions
|
@ -13,6 +13,7 @@ SOURCES += \
|
|||
file_reader.cpp \
|
||||
file_writer.cpp \
|
||||
lodepng.cpp \
|
||||
file_container.cpp \
|
||||
|
||||
|
||||
HEADERS += \
|
||||
|
@ -59,3 +60,4 @@ HEADERS += \
|
|||
streams.hpp \
|
||||
streams_sink.hpp \
|
||||
streams_common.hpp \
|
||||
file_container.hpp \
|
||||
|
|
91
coding/file_container.cpp
Normal file
91
coding/file_container.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include "../base/SRC_FIRST.hpp"
|
||||
|
||||
#include "file_container.hpp"
|
||||
#include "varint.hpp"
|
||||
|
||||
|
||||
FilesContainerR::FilesContainerR(string const & fName)
|
||||
: m_source(fName)
|
||||
{
|
||||
ReaderSource<FileReader> src(m_source);
|
||||
|
||||
uint64_t const offset = ReadVarUint<uint64_t>(src);
|
||||
src.Skip(offset);
|
||||
|
||||
uint32_t const count = ReadVarUint<uint32_t>(src);
|
||||
m_info.resize(count);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
uint32_t const tagSize = ReadVarUint<uint32_t>(src);
|
||||
m_info[i].m_tag.resize(tagSize);
|
||||
src.Read(&m_info[i].m_tag[0], tagSize);
|
||||
|
||||
m_info[i].m_offset = ReadVarUint<uint64_t>(src);
|
||||
m_info[i].m_size = ReadVarUint<uint64_t>(src);
|
||||
}
|
||||
}
|
||||
|
||||
FileReader FilesContainerR::GetReader(Tag const & tag)
|
||||
{
|
||||
info_cont_t::const_iterator i =
|
||||
lower_bound(m_info.begin(), m_info.end(), tag, less_info());
|
||||
|
||||
if (i != m_info.end() && i->m_tag == tag)
|
||||
return m_source.SubReader(i->m_offset, i->m_size);
|
||||
else
|
||||
MYTHROW(Reader::OpenException, (tag));
|
||||
}
|
||||
|
||||
FilesContainerW::FilesContainerW(string const & fName)
|
||||
: m_name(fName)
|
||||
{
|
||||
FileWriter writer(fName);
|
||||
uint64_t skip = 0;
|
||||
writer.Write(&skip, sizeof(skip));
|
||||
}
|
||||
|
||||
uint64_t FilesContainerW::SaveCurrentSize()
|
||||
{
|
||||
uint64_t const curr = FileReader(m_name).Size();
|
||||
if (!m_info.empty())
|
||||
m_info.back().m_size = curr - m_info.back().m_offset;
|
||||
return curr;
|
||||
}
|
||||
|
||||
FileWriter FilesContainerW::GetWriter(Tag const & tag)
|
||||
{
|
||||
uint64_t const curr = SaveCurrentSize();
|
||||
|
||||
m_info.push_back(Info(tag, curr));
|
||||
|
||||
return FileWriter(m_name, FileWriter::OP_APPEND);
|
||||
}
|
||||
|
||||
void FilesContainerW::Finish()
|
||||
{
|
||||
uint64_t const curr = SaveCurrentSize();
|
||||
|
||||
{
|
||||
FileWriter writer(m_name, FileWriter::OP_WRITE_EXISTING);
|
||||
writer.Write(&curr, sizeof(curr));
|
||||
}
|
||||
|
||||
FileWriter writer(m_name, FileWriter::OP_APPEND);
|
||||
writer.Write(&curr, sizeof(curr));
|
||||
|
||||
sort(m_info.begin(), m_info.end(), less_info());
|
||||
|
||||
uint32_t const count = m_info.size();
|
||||
WriteVarUint(writer, count);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
size_t const tagSize = m_info[i].m_tag.size();
|
||||
WriteVarUint(writer, tagSize);
|
||||
writer.Write(&m_info[i].m_tag[0], tagSize);
|
||||
|
||||
WriteVarUint(writer, m_info[i].m_offset);
|
||||
WriteVarUint(writer, m_info[i].m_size);
|
||||
}
|
||||
}
|
70
coding/file_container.hpp
Normal file
70
coding/file_container.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include "file_reader.hpp"
|
||||
#include "file_writer.hpp"
|
||||
|
||||
#include "../std/vector.hpp"
|
||||
#include "../std/string.hpp"
|
||||
|
||||
class FilesContainerBase
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef string Tag;
|
||||
|
||||
struct Info
|
||||
{
|
||||
Tag m_tag;
|
||||
uint64_t m_offset;
|
||||
uint64_t m_size;
|
||||
|
||||
Info() {}
|
||||
Info(Tag const & tag, uint64_t offset) : m_tag(tag), m_offset(offset) {}
|
||||
};
|
||||
|
||||
struct less_info
|
||||
{
|
||||
bool operator() (Info const & t1, Info const & t2) const
|
||||
{
|
||||
return (t1.m_tag < t2.m_tag);
|
||||
}
|
||||
bool operator() (Info const & t1, Tag const & t2) const
|
||||
{
|
||||
return (t1.m_tag < t2);
|
||||
}
|
||||
bool operator() (Tag const & t1, Info const & t2) const
|
||||
{
|
||||
return (t1 < t2.m_tag);
|
||||
}
|
||||
};
|
||||
|
||||
typedef vector<Info> info_cont_t;
|
||||
info_cont_t m_info;
|
||||
};
|
||||
|
||||
class FilesContainerR : public FilesContainerBase
|
||||
{
|
||||
typedef public FilesContainerBase base_type;
|
||||
|
||||
FileReader m_source;
|
||||
|
||||
public:
|
||||
FilesContainerR(string const & fName);
|
||||
|
||||
FileReader GetReader(Tag const & tag);
|
||||
};
|
||||
|
||||
class FilesContainerW : public FilesContainerBase
|
||||
{
|
||||
typedef public FilesContainerBase base_type;
|
||||
|
||||
string m_name;
|
||||
|
||||
uint64_t SaveCurrentSize();
|
||||
|
||||
public:
|
||||
FilesContainerW(string const & fName);
|
||||
|
||||
FileWriter GetWriter(Tag const & tag);
|
||||
|
||||
void Finish();
|
||||
};
|
Loading…
Add table
Reference in a new issue