1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
namespace fs
{
template<typename StreamType>
class pack;
class header
{
public:
typedef std::shared_ptr<header> ptr;
// --
static const short_t version_size = 5;
static const short_t header_size = 5;
// --
header() : m_version(), m_header() {}
header(const std::string& v, const std::string& h) :
m_version(v), m_header(h) {}
virtual ~header() {}
std::ostream& operator<<(std::ostream& os)
{
char vx[header::version_size];
char hx[header::header_size];
::memcpy(vx, m_version.c_str(), header::version_size);
::memcpy(hx, m_header.c_str(), header::header_size);
os << vx << hx;
return os;
}
std::istream& operator>>(std::istream& is)
{
char* vx = new char[header::version_size];
char* hx = new char[header::header_size];
is.read(vx, header::version_size);
is.read(hx, header::header_size);
m_version = std::string(vx, header::version_size);
m_header = std::string(hx, header::header_size);
delete[] vx;
delete[] hx;
return is;
}
const std::string& version() const { return m_version; }
const std::string& unique_id() const { return m_header; }
private:
std::string m_version;
std::string m_header;
};
template<typename StreamType>
class pack
{
public:
typedef std::shared_ptr<pack> ptr;
pack() : m_stream(), m_header() {}
pack(const pack<StreamType>& p) = delete;
pack& operator=(const pack<StreamType>& p) = delete;
virtual ~pack() { m_stream.close(); }
node::ptr open(fs::path& p)
{
m_stream.open(p(false), std::istream::in | std::istream::binary);
m_stream >> m_header;
fs::directory::ptr rootd;
fs::any::ptr entry;
fs::node::ptr rootnode;
m_stream >> rootd;
auto type(rootd->packing_type());
if(type == rules::package::packing_types::FolderAny
|| type == rules::package::packing_types::FolderFramed)
{
read_table<fs::any::ptr>(m_stream, rootd);
}
else if(type == rules::package::packing_types::FolderRessource)
{
read_table<fs::file::ptr>(m_stream, rootd);
}
return rootnode;
}
private:
StreamType m_stream;
fs::header::ptr m_header;
template<typename ChildType>
void read_table(StreamType& stream, fs::directory::ptr d)
{
auto buffer(d->get_buffer<ChildType>());
for(fs::size_t ci = 0, cl = std::get<0>(buffer); ci < cl; ++ci)
{
ChildType child;
stream >> child;
std::get<1>(buffer).push_back(child);
}
d->set_childs(std::get<1>(buffer));
for(auto& child: *d)
{
auto type(child->packing_type());
if(type == rules::package::packing_types::FolderAny
|| type == rules::package::packing_types::FolderFramed)
{
read_table<fs::any::ptr>(stream, child);
}
else if(type == rules::package::packing_types::FolderRessource)
{
read_table<fs::file::ptr>(stream, child);
}
else { throw; }
}
}
};
} |