Advertisement
NickG

nbt.cpp

Apr 12th, 2013
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.86 KB | None | 0 0
  1. #include <cstdint>
  2. #include <cstring>
  3. #include <string>
  4. #include <iostream>
  5. #include "nbt.hpp"
  6.  
  7. void alloc_tag(int id, TAG **ptr) {
  8.     switch (id) {
  9.         case TAG_Byte_id:
  10.             *ptr = new TAG_Byte; break;
  11.         case TAG_Short_id:
  12.             *ptr = new TAG_Short; break;
  13.         case TAG_Int_id:
  14.             *ptr = new TAG_Int; break;
  15.         case TAG_Long_id:
  16.             *ptr = new TAG_Long; break;
  17.         case TAG_Float_id:
  18.             *ptr = new TAG_Float; break;
  19.         case TAG_Double_id:
  20.             *ptr = new TAG_Double; break;
  21.         case TAG_Byte_Array_id:
  22.             *ptr = new TAG_Byte_Array; break;
  23.         case TAG_String_id:
  24.             *ptr = new TAG_String; break;
  25.         case TAG_List_id:
  26.             *ptr = new TAG_List; break;
  27.         case TAG_Compound_id:
  28.             *ptr = new TAG_Compound; break;
  29.         case TAG_Int_Array_id:
  30.             *ptr = new TAG_Int_Array; break;
  31.     }
  32. };
  33. void dealloc_tag(int id, TAG **ptr) {
  34.     switch (id) {
  35.         case TAG_Byte_id:
  36.             delete dynamic_cast<TAG_Byte*>(*ptr); break;
  37.         case TAG_Short_id:
  38.             delete dynamic_cast<TAG_Short*>(*ptr); break;
  39.         case TAG_Int_id:
  40.             delete dynamic_cast<TAG_Int*>(*ptr); break;
  41.         case TAG_Long_id:
  42.             delete dynamic_cast<TAG_Long*>(*ptr); break;
  43.         case TAG_Float_id:
  44.             delete dynamic_cast<TAG_Float*>(*ptr); break;
  45.         case TAG_Double_id:
  46.             delete dynamic_cast<TAG_Double*>(*ptr); break;
  47.         case TAG_Byte_Array_id:
  48.             delete dynamic_cast<TAG_Byte_Array*>(*ptr); break;
  49.         case TAG_String_id:
  50.             delete dynamic_cast<TAG_String*>(*ptr); break;
  51.         case TAG_List_id:
  52.             delete dynamic_cast<TAG_List*>(*ptr); break;
  53.         case TAG_Compound_id:
  54.             delete dynamic_cast<TAG_Compound*>(*ptr); break;
  55.         case TAG_Int_Array_id:
  56.             delete dynamic_cast<TAG_Int_Array*>(*ptr); break;
  57.     }
  58. };
  59.  
  60. std::string TAG::get_name() {
  61.     return name;
  62. };
  63. void TAG::set_name(std::string new_name) {
  64.     name = new_name;
  65. };
  66.  
  67. template<typename T, int id>
  68. _TAG_Numeric<T, id>::_TAG_Numeric(T new_val) {
  69.     val = new_val;
  70. };
  71. template<typename T, int id>
  72. unsigned int _TAG_Numeric<T, id>::tag_size() {
  73.     return sizeof(T);
  74. };
  75. template<typename T, int id>
  76. std::string _TAG_Numeric<T, id>::pretty_print(int tabs) {
  77.     return "";
  78. };
  79. template<typename T, int id>
  80. int _TAG_Numeric<T, id>::get_id() {
  81.     return id;
  82. };
  83. template<typename T, int id>
  84. T _TAG_Numeric<T, id>::get_val() {
  85.     return val;
  86. };
  87. template<typename T, int id>
  88. void _TAG_Numeric<T, id>::set_val(T new_val) {
  89.     val = new_val;
  90. };
  91.  
  92. template class _TAG_Numeric<int8_t, TAG_Byte_id>;
  93. template class _TAG_Numeric<int16_t, TAG_Short_id>;
  94. template class _TAG_Numeric<int32_t, TAG_Int_id>;
  95. template class _TAG_Numeric<int64_t, TAG_Long_id>;
  96. template class _TAG_Numeric<float, TAG_Float_id>;
  97. template class _TAG_Numeric<double, TAG_Double_id>;
  98.  
  99. template<typename T, typename Shift_T, int id>
  100. unsigned char* _TAG_Integral<T, Shift_T, id>::encode(unsigned char *buffer) {
  101.     unsigned char *ptr = buffer;
  102.     for (int i = sizeof(T)-1; i>=0; --i, ++ptr) {
  103.         *ptr = val>>(i*8);
  104.     }
  105.     return ptr++;
  106. };
  107. template<typename T, typename Shift_T, int id>
  108. unsigned char* _TAG_Integral<T, Shift_T, id>::decode(unsigned char *buffer) {
  109.     unsigned char *ptr = buffer;
  110.     Shift_T shift;
  111.     val = 0;
  112.     for (int i = sizeof(T)-1; i>=0; --i, ++ptr) {
  113.         shift = *ptr;
  114.         val = val | shift<<(i*8);
  115.     }
  116.     return ptr++;
  117. };
  118.  
  119. template class _TAG_Integral<int8_t, uint8_t, TAG_Byte_id>;
  120. template class _TAG_Integral<int16_t, uint16_t, TAG_Short_id>;
  121. template class _TAG_Integral<int32_t, uint32_t, TAG_Int_id>;
  122. template class _TAG_Integral<int64_t, uint64_t, TAG_Long_id>;
  123.  
  124. template<typename T, typename Shift_T, int id>
  125. unsigned char* _TAG_Precision<T, Shift_T, id>::encode(unsigned char *buffer) {
  126.     unsigned char *ptr = buffer;
  127.     union {
  128.         T p;
  129.         Shift_T s;
  130.     } u;
  131.     u.p = val;
  132.     for (int i = sizeof(T)-1; i>=0; --i, ++ptr) {
  133.         *ptr = u.s>>(i*8);
  134.     }
  135.     return ptr++;
  136. };
  137. template<typename T, typename Shift_T, int id>
  138. unsigned char* _TAG_Precision<T, Shift_T, id>::decode(unsigned char *buffer) {
  139.     unsigned char *ptr = buffer;
  140.     union {
  141.         T p;
  142.         Shift_T s;
  143.     } u;
  144.     Shift_T shift;
  145.     u.s = 0;
  146.     for (int i = sizeof(T)-1; i>=0; --i, ++ptr) {
  147.         shift = *ptr;
  148.         u.s = u.s | shift<<(i*8);
  149.     }
  150.     val = u.p;
  151.     return ptr++;
  152. };
  153.  
  154. template class _TAG_Precision<float, uint32_t, TAG_Float_id>;
  155. template class _TAG_Precision<double, uint64_t, TAG_Double_id>;
  156.  
  157. template<typename T, class TAG_T, int id>
  158. unsigned char* _TAG_Array<T, TAG_T, id>::encode(unsigned char *buffer) {
  159.     unsigned char *ptr = buffer;
  160.     ptr = TAG_Int(vtr.size()).encode(ptr);
  161.     for (unsigned int i = 0; i<vtr.size(); ++i) {
  162.         ptr = TAG_T(vtr[i]).encode(ptr);
  163.     }
  164.     return ptr;
  165. };
  166. template<typename T, class TAG_T, int id>
  167. unsigned char* _TAG_Array<T, TAG_T, id>::decode(unsigned char *buffer) {
  168.     unsigned char *ptr = buffer;
  169.     TAG_Int size_tag;
  170.     ptr = size_tag.decode(ptr);
  171.     vtr.resize(size_tag.get_val());
  172.     TAG_T decode_tag;
  173.     for (unsigned int i = 0; i<vtr.size(); ++i) {
  174.         ptr = decode_tag.decode(ptr);
  175.         vtr[i] = decode_tag.get_val();
  176.     }
  177.     return ptr;
  178. };
  179. template<typename T, class TAG_T, int id>
  180. unsigned int _TAG_Array<T, TAG_T, id>::tag_size() {
  181.     return 4+(vtr.size()*sizeof(T)); // 4 bytes for int prefix
  182. };
  183. template<typename T, class TAG_T, int id>
  184. std::string _TAG_Array<T, TAG_T, id>::pretty_print(int tabs) {
  185.     return "";
  186. };
  187. template<typename T, class TAG_T, int id>
  188. int _TAG_Array<T, TAG_T, id>::get_id() {
  189.     return id;
  190. };
  191. template<typename T, class TAG_T, int id>
  192. T& _TAG_Array<T, TAG_T, id>::operator[](unsigned int i) {
  193.     return vtr[i];
  194. };
  195. template<typename T, class TAG_T, int id>
  196. unsigned int _TAG_Array<T, TAG_T, id>::array_size() {
  197.     return vtr.size();
  198. };
  199. template<typename T, class TAG_T, int id>
  200. void _TAG_Array<T, TAG_T, id>::resize(unsigned int size) {
  201.     vtr.resize(size);
  202. };
  203.  
  204. template class _TAG_Array<int8_t, TAG_Byte, TAG_Byte_Array_id>;
  205. template class _TAG_Array<int32_t, TAG_Int, TAG_Int_Array_id>;
  206.  
  207. TAG_String::TAG_String(std::string new_str) {
  208.     str = new_str;
  209. };
  210. unsigned char* TAG_String::encode(unsigned char *buffer) {
  211.     unsigned char *ptr = buffer;
  212.     unsigned short len = str.length();
  213.     ptr = _TAG_Integral<uint16_t, uint16_t, -1>(len).encode(ptr);
  214.     std::memcpy(ptr, str.data(), len);
  215.     ptr+=len;
  216.     return ptr;
  217. };
  218. unsigned char* TAG_String::decode(unsigned char *buffer) {
  219.     unsigned char *ptr = buffer;
  220.     _TAG_Integral<uint16_t, uint16_t, -1> decode_tag;
  221.     ptr = decode_tag.decode(ptr);
  222.     unsigned short len = decode_tag.get_val();
  223.     str.assign(reinterpret_cast<char*>(ptr), len);
  224.     ptr+=len;
  225.     return ptr;
  226. };
  227. unsigned int TAG_String::tag_size() {
  228.     return 2+str.length(); // 2 bytes for short prefix
  229. };
  230. std::string TAG_String::pretty_print(int tabs) {
  231.     return "";
  232. };
  233. int TAG_String::get_id() {
  234.     return TAG_String_id;
  235. };
  236. std::string TAG_String::get_val() {
  237.     return str;
  238. };
  239. void TAG_String::set_val(std::string new_str) {
  240.     str = new_str;
  241. };
  242.  
  243. TAG_List::TAG_List(int id, int size) {
  244.     tag_type = id;
  245.     resize(size);
  246. };
  247. TAG_List::~TAG_List() {
  248.     resize(0);
  249. };
  250. unsigned char* TAG_List::encode(unsigned char *buffer) {
  251.     unsigned char *ptr = buffer;
  252.     *ptr = tag_type;
  253.     ++ptr;
  254.     ptr = TAG_Int(vtr.size()).encode(ptr);
  255.     for (unsigned int i = 0; i<vtr.size(); ++i) {
  256.         ptr = vtr[i]->encode(ptr);
  257.     }
  258.     return ptr;
  259. };
  260. unsigned char* TAG_List::decode(unsigned char *buffer) {
  261.     resize(0);
  262.     unsigned char *ptr = buffer;
  263.     tag_type = *ptr;
  264.     ++ptr;
  265.     TAG_Int decode_tag;
  266.     ptr = decode_tag.decode(ptr);
  267.     int len = decode_tag.get_val();
  268.     resize(len);
  269.     for (int i = 0; i < len; ++i) {
  270.         ptr = vtr[i]->decode(ptr);
  271.     }
  272.     return ptr;
  273. };
  274. unsigned int TAG_List::tag_size() {
  275.     unsigned int size = 5; //1 byte for type id, 4 bytes for int prefix
  276.     for (unsigned int i = 0; i<vtr.size(); ++i) {
  277.         size += vtr[i]->tag_size();
  278.     }
  279.     return size;
  280. };
  281. std::string TAG_List::pretty_print(int tabs) {
  282.     return "";
  283. };
  284. int TAG_List::get_id() {
  285.     return TAG_List_id;
  286. };
  287. TAG* TAG_List::operator[](unsigned int i) {
  288.     return vtr[i];
  289. };
  290. unsigned int TAG_List::array_size() {
  291.     return vtr.size();
  292. };
  293. void TAG_List::resize(unsigned int new_size) {
  294.     unsigned int old_size = vtr.size();
  295.     if (new_size>old_size) {
  296.         vtr.resize(new_size);
  297.         for (unsigned int i = old_size; i<new_size; ++i) {
  298.             alloc_tag(tag_type, &vtr[i]);
  299.         }
  300.     } else if (new_size<old_size) {
  301.         for (unsigned int i = new_size; i<old_size; ++i) {
  302.             //Using get_id instead of tag_type for dealloc, better safe than sorry
  303.             dealloc_tag(vtr[i]->get_id(), &vtr[i]);
  304.         }
  305.         vtr.resize(new_size);
  306.     }
  307. };
  308. int TAG_List::get_type() {
  309.     return tag_type;
  310. };
  311. void TAG_List::set_type(int id) {
  312.     resize(0);
  313.     tag_type = id;
  314. };
  315.  
  316. unsigned char* TAG_Compound::encode(unsigned char *buffer){return buffer;};
  317. unsigned char* TAG_Compound::decode(unsigned char *buffer){return buffer;};
  318. unsigned int TAG_Compound::tag_size(){return 0;};
  319. std::string TAG_Compound::pretty_print(int tabs) {
  320.     return "";
  321. };
  322. int TAG_Compound::get_id(){return 0;};
  323. TAG* TAG_Compound::operator[](unsigned int i){TAG *ptr=NULL; return ptr;};
  324. unsigned int TAG_Compound::array_size(){return 0;};
  325. void TAG_Compound::resize(unsigned int size){};
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement