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