将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 /* 

  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   {
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() - 11);
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() - 11);
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自动修改的头文件

  1 /* 
  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自动生成的实现文件

  1 #define HUFF_TREE_CC_
  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() - 11);
 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() - 11);
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  

原文地址:https://www.cnblogs.com/rocketfan/p/1589871.html