PageRenderTime 51ms CodeModel.GetById 7ms app.highlight 39ms RepoModel.GetById 2ms app.codeStats 0ms

/install/xbt/linux/misc/xif_key.cpp

http://torrentpier2.googlecode.com/
C++ | 196 lines | 185 code | 11 blank | 0 comment | 34 complexity | 9b8c8f1d3c9cf03293367f6ba8e36473 MD5 | raw file
  1#include "stdafx.h"
  2#include "xif_key.h"
  3
  4#include <zlib.h>
  5#include "stream_int.h"
  6
  7static int read_int(const byte*& r)
  8{
  9	r += 4;
 10	return read_int_le(4, r - 4);
 11}
 12
 13void Cxif_key::load_old(const byte*& data)
 14{
 15	for (int count = read_int(data); count--; )
 16	{
 17		Cxif_key& i = set_key(read_int(data));
 18		i.load_old(data);
 19	}
 20	for (int count = read_int(data); count--; )
 21	{
 22		Cxif_value& i = set_value(read_int(data));
 23		i.load_old(data);
 24	}
 25}
 26
 27void Cxif_key::load_new(const byte*& data)
 28{
 29	for (int count = read_int(data), id = 0; count--; )
 30	{
 31		id += read_int(data);
 32		open_key_write(id).load_new(data);
 33	}
 34	for (int count = read_int(data), id = 0; count--; )
 35	{
 36		id += read_int(data);
 37		open_value_write(id).load_new(data);
 38	}
 39}
 40
 41void Cxif_key::load_external(const byte*& data)
 42{
 43	BOOST_FOREACH(t_xif_key_map::reference i, m_keys)
 44		i.second.load_external(data);
 45	BOOST_FOREACH(t_xif_value_map::reference i, m_values)
 46		i.second.load_external(data);
 47}
 48
 49int Cxif_key::get_size() const
 50{
 51	int size = 8;
 52	BOOST_FOREACH(t_xif_key_map::const_reference i, m_keys)
 53		size += 4 + i.second.get_size();
 54	BOOST_FOREACH(t_xif_value_map::const_reference i, m_values)
 55	{
 56		size += 9;
 57		switch (i.second.get_type())
 58		{
 59		case vt_bin32:
 60		case vt_int32:
 61			break;
 62		default:
 63			if (!i.second.external_data())
 64				size += i.second.get_size();
 65		}
 66	}
 67	return size;
 68}
 69
 70int Cxif_key::get_external_size() const
 71{
 72	int size = 0;
 73	BOOST_FOREACH(t_xif_key_map::const_reference i, m_keys)
 74		size += i.second.get_external_size();			
 75	BOOST_FOREACH(t_xif_value_map::const_reference i, m_values)
 76		if (i.second.external_data())
 77			size += i.second.get_size();
 78	return size;
 79}
 80
 81void Cxif_key::save(byte*& data) const
 82{
 83	{
 84		data = write_int_le(4, data, m_keys.size());
 85		int id = 0;
 86		BOOST_FOREACH(t_xif_key_map::const_reference i, m_keys)
 87		{
 88			data = write_int_le(4, data, i.first - id);
 89			id = i.first;
 90			i.second.save(data);
 91		}
 92	}
 93	{
 94		data = write_int_le(4, data, m_values.size());
 95		int id = 0;
 96		BOOST_FOREACH(t_xif_value_map::const_reference i, m_values)
 97		{
 98			data = write_int_le(4, data, i.first - id);
 99			id = i.first;
100			i.second.save(data);
101		}
102	}
103}
104
105void Cxif_key::external_save(byte*& data) const
106{
107	BOOST_FOREACH(t_xif_key_map::const_reference i, m_keys)
108		i.second.external_save(data);
109	BOOST_FOREACH(t_xif_value_map::const_reference i, m_values)
110		i.second.external_save(data);
111}
112
113int Cxif_key::load_key(const byte* data, size_t size)
114{
115	const byte* read_p = data;
116	const t_xif_header_fast& header = *reinterpret_cast<const t_xif_header_fast*>(read_p);
117	if (size < sizeof(t_xif_header_old)
118		|| header.id != file_id
119		|| header.version != file_version_old && header.version != file_version_new && header.version != file_version_fast)
120		return 1;
121	int error = 0;
122	if (header.version == file_version_old)
123	{
124		read_p += sizeof(t_xif_header_old) - 4;
125		load_old(read_p);
126		error = size != read_p - data;
127	}
128	else
129	{
130		unsigned long cb_d = header.size_uncompressed;
131		if (cb_d)
132		{
133			Cvirtual_binary d;
134			if (header.version == file_version_new)
135				error = Z_OK != uncompress(d.write_start(cb_d), &cb_d, data + sizeof(t_xif_header_old), size - sizeof(t_xif_header_old));
136			else
137				error = Z_OK != uncompress(d.write_start(cb_d), &cb_d, data + sizeof(t_xif_header_fast), header.size_compressed);
138			if (!error)
139			{
140				read_p = d.data();
141				load_new(read_p);
142				error = read_p != d.end();
143				if (header.version == file_version_fast && !error)
144				{
145					read_p = data + sizeof(t_xif_header_fast) + header.size_compressed;
146					load_external(read_p);
147					error = size != read_p - data;
148				}
149			}
150		}
151		else
152		{
153			read_p = data + (header.version == file_version_fast ? sizeof(t_xif_header_fast) : sizeof(t_xif_header_old));
154			load_new(read_p);
155			load_external(read_p);
156			error = size != read_p - data;
157		}
158	}
159	return error;
160}
161
162Cvirtual_binary Cxif_key::vdata(bool fast) const
163{
164	Cvirtual_binary d;
165	int size = get_size();
166	int external_size = get_external_size();
167	if (fast)
168	{
169		t_xif_header_fast& header = *reinterpret_cast<t_xif_header_fast*>(d.write_start(sizeof(t_xif_header_fast) + size + external_size));
170		header.id = file_id;
171		header.version = file_version_fast;
172		header.size_uncompressed = 0;
173		header.size_compressed = size;
174		header.size_external = external_size;
175		byte* w = d.data_edit() + sizeof(t_xif_header_fast);
176		save(w);
177		external_save(w);
178		assert(d.end() == w);
179		return d;
180	}
181	Cvirtual_binary s;
182	byte* w = s.write_start(size);
183	save(w);
184	unsigned long cb_d = s.size() + (s.size() + 999) / 1000 + 12;
185	t_xif_header_fast& header = *reinterpret_cast<t_xif_header_fast*>(d.write_start(sizeof(t_xif_header_fast) + cb_d + external_size));
186	compress(d.data_edit() + sizeof(t_xif_header_fast), &cb_d, s.data(), s.size());
187	w = d.data_edit() + sizeof(t_xif_header_fast) + cb_d;
188	external_save(w);
189	header.id = file_id;
190	header.version = file_version_fast;
191	header.size_uncompressed = size;
192	header.size_compressed = cb_d;
193	header.size_external = external_size;
194	d.resize(sizeof(t_xif_header_fast) + cb_d + external_size);
195	return d;
196}