将C++代码全部写到头文件:)python脚本帮助自动生成相应的实现文件初始框架
嗯,现在基本没问题了,个人觉得类似python,java那样把类的实现完全写到类里面写起来更方便更快,(当然VC有写类函数的时候利用对话框自动生成实现函数的框架),我把程序放到了google code上:
http://code.google.com/p/h2cc/
利用Python脚本可以自动生成相应实现文件。
使用方法如下: h2cc.py -a a.h
//a.h
int abc(); //函数声明会转换到实现文件中
int nba() { //这种函数实现写法默认为在头文件中不变化
int x = 3;
}
int def() //这种函数实现写法{在单独一行,会自动转化到实现文件中
{
int x = 3;
}
转换之后
//a.h
int abc();
int nba() {
int x = 3;
}
int def() ;
//a.cc
#include "a.h"
int abc()
{
}
int def()
{
int x = 3;
}
上面是最简单的示例,对于类和模版类也适用。
-a 表示会自动将上面的def这样的函数转换,而python3.1 a.h 没有-a选项的话,需要用户标明哪些函数要转到实现文件中,方法是如下的写法加一个多余的;在()后面
int def() ;
{
int x = 3;
}
因为.h文件会变化,所以会备份执行操作前的a.h到a.h.bak.
另外有一个-t选项,开启-t的话表示处理模版类的情况即如下会加入些别的信息
在a.h 的namesapce 结束后
#ifndef A_CC_
#include "a.cc"
#endif
在a.cc文件的开头
#define A_CC_
#include "a.h"
这么做是为了避免循环引用是借鉴Openmesh的做法,对于模版函数的实现用户可以直接实现在.h文件中,现在我只支持分离的写法,这样更清晰些。
嗯看下实例,我原来将所有的模版类的函数都实现在.h类的定义内部,这样写起来很方便,但是看起来不舒服,希望把实现的部分,分离到.cc中。
于是调用python3.1 h2cc.py -a -t huff_tree.h 生成合适的huff_tree.cc并适当修改huff_tree.h,所以工作都由h2cc.py自动完成。已验证转换后通过编译链接。
当然目前不保证有些情况可能会出现未知的bug,那样用户可以参考头文件的拷贝文件.h.bak修正。
//原来写好的头文件
1 /*
3 * This is easier to implement but will cost more space.
4 *
5 * For the implementation of differnting internal and leaf
6 * refering to "A practical introduction to data structure
7 * and algorithm analisis p 115"
8 * */
9 #ifndef _HUFF_TREE_H_
10 #define _HUFF_TREE_H_ //TODO automate this for .h file
11
12 #include "type_traits.h"
13 #include "buffer.h"
14 #include "assert.h"
15 #include <queue>
16 #include <deque>
17 #include <vector>
18 #include <functional>
19 #include <iostream>
20 namespace glzip{
21 //----------------------------------------------------------------------------HuffNode------
22 template <typename _KeyType>
23 struct HuffNode {
24 typedef HuffNode<_KeyType> Node;
25 ///allow default construct
26 HuffNode() {}
27 ///construct a new leaf for character key or string key
28 HuffNode(_KeyType key, size_t weight = 0)
29 : key_(key), weight_(weight),
30 left_(NULL), right_(NULL){}
31
32 ///construct a internal leaf from two child
33 //TODO from const to non const fail
34 HuffNode(HuffNode* lchild, HuffNode* rchild)
35 : left_(lchild), right_(rchild) {
36 weight_ = lchild->weight() + rchild->weight();
37 }
38
39 _KeyType key() const{
40 return key_;
41 }
42
43 size_t weight() const {
44 return weight_;
45 }
46
47 Node* left() const {
48 return left_;
49 }
50
51 Node* right() const {
52 return right_;
53 }
54
55 bool is_leaf() {
56 return !left_; //left_ is NULL means right_ is also,for huf tree it is a full binary tree,every internal node is of degree 2
57 }
58
59 /////The comparison operator used to order the priority queue.
60 ////-----But I choose to use the func object for storing pointer in the queuq
61 ////-----not the Node it's self, TODO see the performance differnce
62 //bool operator > (const HuffNode& other) const {
63 // return weight > other.weight;
64 //}
65
66 //-------------------------------------------------------------------
67 _KeyType key_;
68 size_t weight_; //here weight is frequency of char or string
69 Node* left_;
70 Node* right_;
71 };
72
73 //-----------------------------------------------HuffTree-------------------HuffTreeBase----
74 /**
75 * For HuffTree
76 * It take the frequency_map_ and encode_map_ as input.
77 * Those two are not owned by HuffTree but HuffEncoder.
78 * HuffTree will use frequence_map_ info to make encode_map_ ok.
79 * 1. Wait until frequency_map_ is ready (which is handled by HuffEncoder)
80 * 2. build_tree()
81 * 3. gen_encode()
82 * 4. serialize_tree()
83 * The sequence is important can not break!
84 *
85 * TODO(Array based HuffTree) actually the hufftree can be implemented using simple array do
86 * not need building the tree.
87 *
88 * TODO For string type the tree might be so big, the rec is OK?
89 * */
90 template <typename _KeyType>
91 class HuffTreeBase {
92 public:
93 typedef HuffNode<_KeyType> Node;
94 public:
95 void set_root(Node* other) {
96 root_ = other;
97 }
98
99 void delete_tree(Node* root) { //TODO rec what if the tree is so big?
100 if (root) {
101 delete_tree(root->left());
102 delete_tree(root->right());
103 delete root;
104 }
105 }
106
107 //for test
108 void travel(Node* root) {
109 if (root) {
110 travel(root->left());
111 travel(root->right());
112 }
113 }
114
115 Node* root() const {
116 return root_;
117 }
118 protected:
119 Node* root_;
120 };
121
122 //---------------------------------------------------------------------------HuffTree for encode---
123 template <typename _KeyType, typename _TreeType = encode_hufftree>
124 class HuffTree: public HuffTreeBase<_KeyType> {
125 public:
126 using HuffTreeBase<_KeyType>::root;
127 using HuffTreeBase<_KeyType>::set_root;
128 using HuffTreeBase<_KeyType>::delete_tree;
129
130 typedef typename TypeTraits<_KeyType>::type_catergory type_catergory;
131 typedef typename TypeTraits<_KeyType>::FrequencyHashMap FrequencyHashMap;
132 typedef typename TypeTraits<_KeyType>::EncodeHashMap EncodeHashMap;
133 typedef HuffNode<_KeyType> Node;
134
135 struct HuffNodePtrGreater:
136 public std::binary_function<const Node *, const Node *, bool> {
137
138 bool operator() (const Node *p1, const Node *p2) {
139 return p1->weight() > p2->weight();
140 }
141 };
142 //typedef std::deque<Node> HuffDQU; //TODO use vector to see which is better and why
143 //typedef std::priority_queue<Node,HuffDQU, greater<Node> > HuffPRQUE; //desending order use less<HuffNode> if asending
144 typedef std::deque<Node*> HuffDQU; //TODO use vector to see which is better and why
145 typedef std::priority_queue<Node*, HuffDQU, HuffNodePtrGreater> HuffPRQUE; //desending order use less<HuffNode> if asending
146
147 public:
148 HuffTree(EncodeHashMap& encode_map, FrequencyHashMap& frequency_map) //long long int (&)[256] can not be inited by const long
149 : encode_map_(encode_map), frequency_map_(frequency_map)
150 {
151 build_tree(); //assmue frequency_map is ready when creating the tree
152 }
153 ~HuffTree() {
154 //std::cout << "dstruct hufftree\n";
155 delete_tree(root());
156 }
157 void gen_encode() {
158 std::string encode;
159 do_gen_encode(root(), encode);
160 //std::cout << "Finished encoding\n";
161 }
162 void build_tree()
163 {
164 init_queue(type_catergory());
165 int times = pqueue_.size() - 1;
166 for (int i = 0; i < times; i++) {
167 Node* lchild = pqueue_.top();
168 pqueue_.pop();
169 Node* rchild = pqueue_.top();
170 pqueue_.pop();
171 Node* p_internal = new Node(lchild, rchild);
172 pqueue_.push(p_internal);
173 }
174 set_root(pqueue_.top());
175 //std::cout << "Finished building tree\n";
176 }
177
178 ///write the header info to the outfile, for decompressor to rebuild the tree
179 //----write in pre order travelling
180 void serialize_tree(FILE* outfile) {
181 Buffer writer(outfile); //the input outfile cur should be at 0
182 do_serialize_tree(root(), writer);
183 writer.flush_buf(); //make sure writting to the file
184 }
185 private:
186 void init_queue(char_tag) {
187 for(int i = 0; i < 256; i++) {
188 if (frequency_map_[i]) {
189 Node* p_leaf = new Node(i, frequency_map_[i]); //key is i and weight is frequency_map_[i]
190 pqueue_.push(p_leaf); //push leaf
191 }
192 }
193 }
194
195 //TODO try to use char[256] to speed up!
196 void do_gen_encode(Node* root, std::string& encode)
197 {
198 if (root->is_leaf()) {
199 encode_map_[root->key()] = encode;
200 return;
201 }
202 encode.append("0"); //TODO how string operation is implemented what is the effecience??
203 do_gen_encode(root->left(), encode);
204 encode[encode.size() - 1] = '1';
205 do_gen_encode(root->right(), encode);
206 encode.erase(encode.size() - 1, 1);
207 }
208
209 //void do_gen_encode(Node* root, std::string encode) {
210 // //if (root->is_leaf()) {
211 // //if (root->left() == NULL || root->right() == NULL) {
212 // // //encode_map_[root->key()] = encode;
213 // // return;
214 // //}
215 // if (!root->right() && !root->left())
216 // return;
217 // do_gen_encode(root->left(), encode + "0");
218 // do_gen_encode(root->right(), encode + "1");
219 //}
220
221
222 //serialize like (1, 1), (1, 1), (0, 'a').
223 void do_serialize_tree(Node* root, Buffer& writer)
224 {
225 if (root->is_leaf()) {
226 writer.write_byte(0); //0 means the leaf
227 writer.write_byte(root->key()); //write the key
228 return;
229 }
230 writer.write_byte(255); //255 means the internal node
231 writer.write_byte(255); //any num is ok
232 do_serialize_tree(root->left(), writer);
233 do_serialize_tree(root->right(), writer);
234 }
235
236 //----------------------------------------------------for string_tag--------
237 void init_queue(string_tag) {
238
239 }
240 private:
241 HuffPRQUE pqueue_;
242 EncodeHashMap& encode_map_;
243 FrequencyHashMap& frequency_map_;
244 };
245
246 //---------------------------------------------------------------------------HuffTree for decode---
247 /** Specitialized HuffTree for decoding*/
248 template <typename _KeyType>
249 class HuffTree<_KeyType, decode_hufftree>
250 : public HuffTreeBase<_KeyType>{
251 public:
252 using HuffTreeBase<_KeyType>::root;
253 using HuffTreeBase<_KeyType>::root_;
254 using HuffTreeBase<_KeyType>::set_root;
255 using HuffTreeBase<_KeyType>::delete_tree;
256 typedef HuffNode<_KeyType> Node;
257
258 public:
259 HuffTree(FILE* infile, FILE* outfile)
260 :infile_(infile), outfile_(outfile),
261 reader_(infile) {}
262
263 ~HuffTree() {
264 delete_tree(root());
265 }
266
267 ///build_tree() is actually get_encode_info()
268 void build_tree() { //From the infile header info we can build the tree
269 do_build_tree(root_);
270 }
271
272 //help debug to see if the tree rebuild from file is the same as the intial one
273 void do_gen_encode(Node* root, std::string& encode)
274 {
275 if (root->is_leaf()) {
276 std::cout << root->key() << " " << encode << "\n";
277 return;
278 }
279 encode.append("0"); //TODO how string operation is implemented what is the effecience??
280 do_gen_encode(root->left(), encode);
281 encode[encode.size() - 1] = '1';
282 do_gen_encode(root->right(), encode);
283 encode.erase(encode.size() - 1, 1);
284 }
285
286 void decode_file();
287 private:
288 void do_build_tree(Node*& root)
289 {
290 unsigned char first, second;
291 reader_.read_byte(first);
292 reader_.read_byte(second);
293 if (first == 0) { //is leaf TODO actually we do not need weight this time so HuffNode can be smaller
294 root = new Node(second);
295 return;
296 }
297 root = new Node();
298 do_build_tree(root->left_);
299 do_build_tree(root->right_);
300 }
301
302 void decode_byte(unsigned char c, Buffer& writer, Node*& cur_node, int bit_num = 8);
303 FILE* infile_;
304 FILE* outfile_;
305 Buffer reader_; //need reader_ becuause for two function build_tree and decode_file we need the same reader
306 };
307
308 } //end of space glzip
309
//h2cc.py自动修改的头文件
2 * Here use one class for both internal node and leaf.
3 * This is easier to implement but will cost more space.
4 *
5 * For the implementation of differnting internal and leaf
6 * refering to "A practical introduction to data structure
7 * and algorithm analisis p 115"
8 * */
9 #ifndef _HUFF_TREE_H_
10 #define _HUFF_TREE_H_ //TODO automate this for .h file
11
12 #include "type_traits.h"
13 #include "buffer.h"
14 #include "assert.h"
15 #include <queue>
16 #include <deque>
17 #include <vector>
18 #include <functional>
19 #include <iostream>
20 namespace glzip{
21 //----------------------------------------------------------------------------HuffNode------
22 template <typename _KeyType>
23 struct HuffNode {
24 typedef HuffNode<_KeyType> Node;
25 ///allow default construct
26 HuffNode() {}
27 ///construct a new leaf for character key or string key
28 HuffNode(_KeyType key, size_t weight = 0)
29 : key_(key), weight_(weight),
30 left_(NULL), right_(NULL){}
31
32 ///construct a internal leaf from two child
33 //TODO from const to non const fail
34 HuffNode(HuffNode* lchild, HuffNode* rchild)
35 : left_(lchild), right_(rchild) {
36 weight_ = lchild->weight() + rchild->weight();
37 }
38
39 _KeyType key() const{
40 return key_;
41 }
42
43 size_t weight() const {
44 return weight_;
45 }
46
47 Node* left() const {
48 return left_;
49 }
50
51 Node* right() const {
52 return right_;
53 }
54
55 bool is_leaf() {
56 return !left_; //left_ is NULL means right_ is also,for huf tree it is a full binary tree,every internal node is of degree 2
57 }
58
59 /////The comparison operator used to order the priority queue.
60 ////-----But I choose to use the func object for storing pointer in the queuq
61 ////-----not the Node it's self, TODO see the performance differnce
62 //bool operator > (const HuffNode& other) const {
63 // return weight > other.weight;
64 //}
65
66 //-------------------------------------------------------------------
67 _KeyType key_;
68 size_t weight_; //here weight is frequency of char or string
69 Node* left_;
70 Node* right_;
71 };
72
73 //-----------------------------------------------HuffTree-------------------HuffTreeBase----
74 /**
75 * For HuffTree
76 * It take the frequency_map_ and encode_map_ as input.
77 * Those two are not owned by HuffTree but HuffEncoder.
78 * HuffTree will use frequence_map_ info to make encode_map_ ok.
79 * 1. Wait until frequency_map_ is ready (which is handled by HuffEncoder)
80 * 2. build_tree()
81 * 3. gen_encode()
82 * 4. serialize_tree()
83 * The sequence is important can not break!
84 *
85 * TODO(Array based HuffTree) actually the hufftree can be implemented using simple array do
86 * not need building the tree.
87 *
88 * TODO For string type the tree might be so big, the rec is OK?
89 * */
90 template <typename _KeyType>
91 class HuffTreeBase {
92 public:
93 typedef HuffNode<_KeyType> Node;
94 public:
95 void set_root(Node* other) {
96 root_ = other;
97 }
98
99 void delete_tree(Node* root) { //TODO rec what if the tree is so big?
100 if (root) {
101 delete_tree(root->left());
102 delete_tree(root->right());
103 delete root;
104 }
105 }
106
107 //for test
108 void travel(Node* root) {
109 if (root) {
110 travel(root->left());
111 travel(root->right());
112 }
113 }
114
115 Node* root() const {
116 return root_;
117 }
118 protected:
119 Node* root_;
120 };
121
122 //---------------------------------------------------------------------------HuffTree for encode---
123 template <typename _KeyType, typename _TreeType = encode_hufftree>
124 class HuffTree: public HuffTreeBase<_KeyType> {
125 public:
126 using HuffTreeBase<_KeyType>::root;
127 using HuffTreeBase<_KeyType>::set_root;
128 using HuffTreeBase<_KeyType>::delete_tree;
129
130 typedef typename TypeTraits<_KeyType>::type_catergory type_catergory;
131 typedef typename TypeTraits<_KeyType>::FrequencyHashMap FrequencyHashMap;
132 typedef typename TypeTraits<_KeyType>::EncodeHashMap EncodeHashMap;
133 typedef HuffNode<_KeyType> Node;
134
135 struct HuffNodePtrGreater:
136 public std::binary_function<const Node *, const Node *, bool> {
137
138 bool operator() (const Node *p1, const Node *p2) {
139 return p1->weight() > p2->weight();
140 }
141 };
142 //typedef std::deque<Node> HuffDQU; //TODO use vector to see which is better and why
143 //typedef std::priority_queue<Node,HuffDQU, greater<Node> > HuffPRQUE; //desending order use less<HuffNode> if asending
144 typedef std::deque<Node*> HuffDQU; //TODO use vector to see which is better and why
145 typedef std::priority_queue<Node*, HuffDQU, HuffNodePtrGreater> HuffPRQUE; //desending order use less<HuffNode> if asending
146
147 public:
148 HuffTree(EncodeHashMap& encode_map, FrequencyHashMap& frequency_map) //long long int (&)[256] can not be inited by const long
149 : encode_map_(encode_map), frequency_map_(frequency_map)
150 {
151 build_tree(); //assmue frequency_map is ready when creating the tree
152 }
153 ~HuffTree() {
154 //std::cout << "dstruct hufftree\n";
155 delete_tree(root());
156 }
157 void gen_encode() {
158 std::string encode;
159 do_gen_encode(root(), encode);
160 //std::cout << "Finished encoding\n";
161 }
162 void build_tree();
163 ///write the header info to the outfile, for decompressor to rebuild the tree
164 //----write in pre order travelling
165 void serialize_tree(FILE* outfile) {
166 Buffer writer(outfile); //the input outfile cur should be at 0
167 do_serialize_tree(root(), writer);
168 writer.flush_buf(); //make sure writting to the file
169 }
170 private:
171 void init_queue(char_tag) {
172 for(int i = 0; i < 256; i++) {
173 if (frequency_map_[i]) {
174 Node* p_leaf = new Node(i, frequency_map_[i]); //key is i and weight is frequency_map_[i]
175 pqueue_.push(p_leaf); //push leaf
176 }
177 }
178 }
179
180 //TODO try to use char[256] to speed up!
181 void do_gen_encode(Node* root, std::string& encode);
182 //void do_gen_encode(Node* root, std::string encode) {
183 // //if (root->is_leaf()) {
184 // //if (root->left() == NULL || root->right() == NULL) {
185 // // //encode_map_[root->key()] = encode;
186 // // return;
187 // //}
188 // if (!root->right() && !root->left())
189 // return;
190 // do_gen_encode(root->left(), encode + "0");
191 // do_gen_encode(root->right(), encode + "1");
192 //}
193
194
195 //serialize like (1, 1), (1, 1), (0, 'a').
196 void do_serialize_tree(Node* root, Buffer& writer);
197 //----------------------------------------------------for string_tag--------
198 void init_queue(string_tag) {
199
200 }
201 private:
202 HuffPRQUE pqueue_;
203 EncodeHashMap& encode_map_;
204 FrequencyHashMap& frequency_map_;
205 };
206
207 //---------------------------------------------------------------------------HuffTree for decode---
208 /** Specitialized HuffTree for decoding*/
209 template <typename _KeyType>
210 class HuffTree<_KeyType, decode_hufftree>
211 : public HuffTreeBase<_KeyType>{
212 public:
213 using HuffTreeBase<_KeyType>::root;
214 using HuffTreeBase<_KeyType>::root_;
215 using HuffTreeBase<_KeyType>::set_root;
216 using HuffTreeBase<_KeyType>::delete_tree;
217 typedef HuffNode<_KeyType> Node;
218
219 public:
220 HuffTree(FILE* infile, FILE* outfile)
221 :infile_(infile), outfile_(outfile),
222 reader_(infile) {}
223
224 ~HuffTree() {
225 delete_tree(root());
226 }
227
228 ///build_tree() is actually get_encode_info()
229 void build_tree() { //From the infile header info we can build the tree
230 do_build_tree(root_);
231 }
232
233 //help debug to see if the tree rebuild from file is the same as the intial one
234 void do_gen_encode(Node* root, std::string& encode);
235 void decode_file();
236 private:
237 void do_build_tree(Node*& root);
238 void decode_byte(unsigned char c, Buffer& writer, Node*& cur_node, int bit_num = 8);
239 FILE* infile_;
240 FILE* outfile_;
241 Buffer reader_; //need reader_ becuause for two function build_tree and decode_file we need the same reader
242 };
243
244 } //end of space glzip
245 #ifndef HUFF_TREE_CC_
246 #include "huff_tree.cc"
247 #endif
248 #endif //------------end of _HUFF_TREE_H_
249
//h2cc.py自动生成的实现文件
2 #include "huff_tree.h"
3
4 namespace glzip{
5
6 template <typename _KeyType>
7 void HuffTree<_KeyType, decode_hufftree>::decode_file()
8 {
9 Buffer writer(outfile_);
10 unsigned char left_bit, last_byte;
11 reader_.read_byte(left_bit);
12 reader_.read_byte(last_byte);
13 //--------------------------------------decode each byte
14 Node* cur_node = root();
15 unsigned char c;
16 while(reader_.read_byte(c))
17 decode_byte(c, writer, cur_node);
18 //--------------------------------------deal with the last byte
19 if (left_bit)
20 decode_byte(last_byte, writer, cur_node, (8 - left_bit));
21 writer.flush_buf();
22 fflush(outfile_);
23 }
24
25
26 template <typename _KeyType>
27 void HuffTree<_KeyType, decode_hufftree>::
28 decode_byte(unsigned char c, Buffer& writer, Node*& cur_node, int bit_num)
29 {
30 unsigned char mask = 128; //1 << 7
31 for (int i = 0; i < bit_num; i++) {
32 if ((c & mask) == 0) //--------------bit i of c is 0,turn left
33 cur_node = cur_node->left_;
34 else
35 cur_node = cur_node->right_;
36 mask >>= 1;
37 if (cur_node->is_leaf()) {
38 writer.write_byte(cur_node->key_);
39 cur_node = root();
40 }
41 }
42 }
43
44 template <typename _KeyType, typename _TreeType>
45 void HuffTree<_KeyType, _TreeType>::build_tree()
46 {
47 init_queue(type_catergory());
48 int times = pqueue_.size() - 1;
49 for (int i = 0; i < times; i++) {
50 Node* lchild = pqueue_.top();
51 pqueue_.pop();
52 Node* rchild = pqueue_.top();
53 pqueue_.pop();
54 Node* p_internal = new Node(lchild, rchild);
55 pqueue_.push(p_internal);
56 }
57 set_root(pqueue_.top());
58 //std::cout << "Finished building tree\n";
59 }
60
61
62 //TODO try to use char[256] to speed up!
63 template <typename _KeyType, typename _TreeType>
64 void HuffTree<_KeyType, _TreeType>::
65 do_gen_encode(Node* root, std::string& encode)
66 {
67 if (root->is_leaf()) {
68 encode_map_[root->key()] = encode;
69 return;
70 }
71 encode.append("0"); //TODO how string operation is implemented what is the effecience??
72 do_gen_encode(root->left(), encode);
73 encode[encode.size() - 1] = '1';
74 do_gen_encode(root->right(), encode);
75 encode.erase(encode.size() - 1, 1);
76 }
77
78
79 //serialize like (1, 1), (1, 1), (0, 'a').
80 template <typename _KeyType, typename _TreeType>
81 void HuffTree<_KeyType, _TreeType>::
82 do_serialize_tree(Node* root, Buffer& writer)
83 {
84 if (root->is_leaf()) {
85 writer.write_byte(0); //0 means the leaf
86 writer.write_byte(root->key()); //write the key
87 return;
88 }
89 writer.write_byte(255); //255 means the internal node
90 writer.write_byte(255); //any num is ok
91 do_serialize_tree(root->left(), writer);
92 do_serialize_tree(root->right(), writer);
93 }
94
95
96 //help debug to see if the tree rebuild from file is the same as the intial one
97 template <typename _KeyType>
98 void HuffTree<_KeyType, decode_hufftree>::
99 do_gen_encode(Node* root, std::string& encode)
100 {
101 if (root->is_leaf()) {
102 std::cout << root->key() << " " << encode << "\n";
103 return;
104 }
105 encode.append("0"); //TODO how string operation is implemented what is the effecience??
106 do_gen_encode(root->left(), encode);
107 encode[encode.size() - 1] = '1';
108 do_gen_encode(root->right(), encode);
109 encode.erase(encode.size() - 1, 1);
110 }
111
112
113 template <typename _KeyType>
114 void HuffTree<_KeyType, decode_hufftree>::
115 do_build_tree(Node*& root)
116 {
117 unsigned char first, second;
118 reader_.read_byte(first);
119 reader_.read_byte(second);
120 if (first == 0) { //is leaf TODO actually we do not need weight this time so HuffNode can be smaller
121 root = new Node(second);
122 return;
123 }
124 root = new Node();
125 do_build_tree(root->left_);
126 do_build_tree(root->right_);
127 }
128
129 } //end of space glzip
130
131
132