File container compile test.

This commit is contained in:
vng 2010-12-29 23:40:34 +02:00 committed by Alex Zolotarev
parent 2d8a35967c
commit e04540f8b6
3 changed files with 163 additions and 0 deletions

View file

@ -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
View 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
View 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();
};