Chinaunix首页 | 论坛 | 博客
  • 博客访问: 584676
  • 博文数量: 104
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1559
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-21 00:58
个人简介

锻炼精神,首先要锻炼肉体

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-04-16 10:47:47

这篇文章中记录了编程实现解析以 B 编码方式构成的种子文件的不同模块的作用,
和不同方法之间的相互调用的关系。
在程序中使用了 google 的 glog 日志库,详情可以参考前一篇文章:
http://blog.chinaunix.net/uid-28595538-id-4956104.html

平台:linux
编程工具 : g++ 


// Makefile

点击(此处)折叠或打开

  1. CPPFLAGS = -O3
  2. LDFLAGS = -lglog
  3. all: Main
  4. clean:
  5.     rm -f *.o
  6. Main: Main.o parserUtil.o torrentParser.o
  7.     g++ -o $@ $^ $(LDFLAGS)
// torrentParser.h 

点击(此处)折叠或打开

  1. #ifndef TORRENT_PARSER_H
  2. #define TORRENT_PARSER_H

  3. #include <string>
  4. #include <stdint.h> // int64_t
  5. #include <map>
  6. #include <vector>
  7. #include <iostream>

  8. using namespace std ;

  9. typedef struct _file
  10. {
  11.     int64_t file_length ;
  12.     string file_path ;
  13. } file_t;


  14. typedef struct _info
  15. {
  16.     int64_t piece_length ; // length of each file block (B)
  17.     string pieces ; // hash value length of 20*n
  18.     
  19.     bool is_multi_file ;
  20.     vector<file_t> file_list ;
  21. } info_t ;

  22. typedef struct _torrent_file
  23. {
  24.     string announce ;
  25.     vector<string> announce_list ;
  26.     string comment ;
  27.     string created_by ;
  28.     int64_t creation_date ;
  29.     string encoding ;
  30.     info_t info ;
  31. } torrent_file_t ;


  32. class AnyNode
  33. {
  34.     public :
  35.         virtual ~AnyNode () {}
  36.         virtual void print () = 0 ;
  37.         virtual bool parser (string &content) = 0 ;
  38. } ;

  39. class IntegerNode : public AnyNode
  40. {
  41.       public :
  42.         virtual ~IntegerNode () {}
  43.         virtual bool parser( std::string &content ) ;
  44.         
  45.         virtual void print ()
  46.         {
  47.          cout<<"integer type , value ["<< _value <<"]" <<endl;
  48.         }
  49.         
  50.         int64_t _value ;
  51. } ;

  52. class StringNode : public AnyNode
  53. {
  54. public :
  55.     virtual ~StringNode () {}
  56.     virtual bool parser ( string &content ) ;

  57.     virtual void print ()
  58.     {
  59.         cout<<"string type ,value ["<< _value <<"]"<<endl;
  60.     }

  61.     string _value ;
  62. } ;

  63. class ListNode : public AnyNode
  64. {
  65. public :
  66.     virtual ~ListNode ()
  67.     {
  68.         for ( vector<AnyNode*>::iterator it = _value_list.begin () ;
  69.                 it != _value_list.end () ; it++ )
  70.         {
  71.             delete *it ; // equal delete AnyNode *
  72.         }
  73.         
  74.         _value_list.clear () ;
  75.     }
  76.     
  77.     virtual bool parser ( string &content ) ;
  78.     virtual void print ()
  79.     {
  80.         cout << "type list "<< endl ;
  81.         for ( vector<AnyNode*>::iterator it = _value_list.begin () ;
  82.             it != _value_list.end () ; it++ )
  83.         {
  84.             AnyNode* it1 = *it ;

  85.             cout << "value " ;
  86.             it1->print () ;
  87.             cout << endl ;
  88.         }
  89.     }
  90.     
  91.     vector<AnyNode*> _value_list ;
  92. } ;

  93. class DictNode : public AnyNode
  94. {
  95. public :
  96.     ~DictNode ()
  97.     {
  98.         for ( map<StringNode *, AnyNode*>::iterator it = _value_map.begin () ;
  99.          it != _value_map.end () ; it++ )
  100.         {
  101.             delete it->first ;
  102.             delete it->second ;
  103.         }

  104.         _value_map.clear () ;
  105.     }

  106.     virtual bool parser ( string &content ) ;

  107.     virtual void print ()
  108.     {
  109.         StringNode *it1 ;
  110.         AnyNode *it2 ;

  111.         cout << "type dictionary "<< endl ;

  112.         for ( map<StringNode *, AnyNode *>::iterator it = _value_map.begin () ;
  113.             it != _value_map.end () ; it++ )
  114.         {
  115.             it1 = it->first ;
  116.             it2 = it->second ;
  117.         
  118.             cout << "key " << endl ;
  119.             it1->print();
  120.             cout << "value " << endl ;
  121.             it2->print () ;
  122.         }
  123.     }

  124.     map<StringNode*, AnyNode*> _value_map ;
  125. } ;

  126. class TorrentFile
  127. {
  128.     public :    
  129.         torrent_file_t torrent_file ;

  130.         static bool encode ( const string & torrent_file_content ,
  131.                 torrent_file_t &torrent_structure ) ;

  132. // update date : 2015/4/15 by Aimer

  133.         static void get_node_value ( IntegerNode *pIntegerNode , int64_t &integer_value ) ;
  134.     
  135.         static void get_node_value ( StringNode *pStringNode , string &string_value ) ;

  136.         static AnyNode *find_target_node ( map<StringNode *, AnyNode*> &hash_map , const string &key ) ;     
  137. } ;

  138. #endif
//torrentParser.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>

  4. #include <vector>
  5. #include <map>

  6. #include <glog/logging.h>

  7. #include "parserUtil.h"
  8. #include "torrentParser.h"

  9. using namespace std ;

  10. bool IntegerNode::parser ( string &content )
  11. {
  12.     if ( content.empty () )
  13.     {
  14.         LOG(WARNING)<< "[warnning] in integer's parser content is empty";
  15.         return false ;
  16.     }
  17.     
  18.     if ( content[0] != 'i' )
  19.     {
  20.         LOG(WARNING)<< "[warnning] integer's parser content first element illegal";
  21.         return false ;
  22.     }
  23.     
  24.     uint64_t pos = content.find ( 'e' , 0 ) ;
  25.     // find the position of char e from beginning of content
  26.     
  27.     if ( pos == string::npos )
  28.     {
  29.         LOG(WARNING) << "[warnning] integer's parser content not find char e";
  30.         return false ;
  31.     }
  32.     
  33.     string s_value = content.substr(1 , pos-1) ;
  34.     // extract the sub-string integer from content with out begin 'i' and end 'e'
  35.     
  36.     parserUtils::string_to_integer (s_value , _value ) ;
  37.     // transfer string into integer(int64_t)
  38.     
  39.     content = content.erase ( 0 , pos+1 ) ;    
  40.     
  41.     LOG(INFO) << "[info] integer's parser extract message "<< _value << " remain message " << content ;
  42.     return true ;
  43. }

  44. bool StringNode::parser ( string & content )
  45. {
  46.     if ( content.empty () )
  47.     {
  48.      LOG(WARNING) <<"[warnning] string type's parser content is empty ";
  49.      return false ;
  50.     }
  51.     
  52.     if ( content.size () < 3 )
  53.     {
  54.      LOG(WARNING)<<"[warnning] string type's parser content length is illegal" ;
  55.      return false ;
  56.     }
  57.     
  58.     int64_t pos = content.find (':', 0) ;
  59.     // find ':' in string_length:string_content structure
  60.     
  61.     if ( pos == string::npos )
  62.     {
  63.      LOG(WARNING)<<"[warnning] string type's it is illegal string type with out ':' ";
  64.      return false ;
  65.     }
  66.     
  67.     int64_t count = 0 ;
  68.     
  69.     parserUtils::string_to_integer (content.substr(0 , pos) , count ) ;
  70.     // extract string 's length from content

  71.     _value = content.substr (pos+1, count ) ;
  72.     cout << " in method string node parser " << _value << endl ;
  73.     cout << " length " << count << endl ;
  74.     // pos+1 : beginning of the string content , count : length of the string content
  75.     
  76.     content = content.erase (0 , pos+count+1) ;
  77.     // pos : number of the length , count : numbers of the string's char
  78.     // eraser method erase range [begin , end) 1 should be plus to (pos+count)

  79.     LOG(INFO)<<"[info] string type parser extract message "<< _value
  80.             << " remain content " << content ;
  81.     return true ;
  82. }


  83. bool ListNode::parser ( string &content )
  84. {
  85.     if ( content.empty () )
  86.     {
  87.         LOG(WARNING)<<"[warnning] list type parser content is empty ";
  88.         return false ;
  89.     }
  90.     
  91.     if ( content[0] != 'l' )
  92.     {
  93.         LOG(WARNING)<<"[warnning] list type parser content with out list mark" ;
  94.         return false ;
  95.     }
  96.     
  97.     content = content.erase ( 0 , 1 ) ;
  98.     // delete 'l' from content
  99.     
  100.     while ( !content.empty () )
  101.     {
  102.         AnyNode *anyNode = NULL ;
  103.     
  104.         if ( content [0] == 'l' )
  105.         {
  106.          anyNode = new ListNode () ;
  107.         }
  108.     
  109.         else if ( content [0] == 'd')
  110.         {
  111.          anyNode = new DictNode () ;
  112.         }
  113.     
  114.         else if ( content [0] == 'i' )
  115.         {
  116.          anyNode = new IntegerNode () ;
  117.         }
  118.     
  119.         else if (content[0] >= '1' && content[0] <= '9')
  120.         {
  121.           anyNode = new StringNode () ;
  122.         }
  123.         
  124.         else
  125.         {
  126.             LOG(WARNING)<<"[warnning] list parser list contain illegal message" ;
  127.             return false;
  128.         }
  129.     
  130.         anyNode->parser ( content ) ;
  131.         // this method will parse the content into the right value type
  132.         // and store it into the memeber value variable (_value , _value_list ,value_map...)
  133.         
  134.         _value_list.push_back ( anyNode ) ;
  135.     
  136.         if ( content[0] == 'e' ) // is it the end of the list type ?
  137.         {
  138.             // here we arrived the end of the list ,
  139.             // we should erase the 'e' in content and break the cycle
  140.             
  141.             content = content.erase ( 0 , 1 ) ;
  142.             break ;
  143.         }

  144.     }// while
  145.     
  146.         LOG(INFO)<<"[info] list type parser remainning content " << content ;
  147.         return true ;
  148. }

  149. bool DictNode::parser ( string & content )
  150. {
  151.     if ( content[0] != 'd' )
  152.     {
  153.      LOG(WARNING)<<"dictionary type parser content not begin with 'd' " ;
  154.      return false ;
  155.     }
  156.     
  157.     if ( content.size () < 3 )
  158.     {
  159.      LOG(WARNING)<<"dictionary type parser content length illegal " ;
  160.      return false ;
  161.     }
  162.     
  163.     content = content.erase ( 0 , 1 ) ;
  164.     // erase 'd' from content
  165.     
  166.     // dict type : <key: string type><value: any type>

  167.     while ( !content.empty () )
  168.     {
  169.         StringNode *key = new StringNode () ;
  170.         key->parser ( content ) ;
  171.         // extract key message from content
  172.         
  173.         if ( content.empty () )
  174.         {
  175.             LOG(INFO) << "[info] content is empty ,break ";
  176.             break ;
  177.         }
  178.         
  179.         AnyNode *value = NULL ;
  180.     
  181.         if ( content [0] == 'i' )
  182.             value = new IntegerNode () ;
  183.         else if ( content [0] == 'l' )
  184.             value = new ListNode () ;
  185.         else if ( content [0] == 'd' )
  186.             value = new DictNode () ;
  187.         else if ( content[0] >= '1' && content[0] <= '9' )
  188.             value = new StringNode () ;
  189.     
  190.         else
  191.         {
  192.          LOG(WARNING)<<"[warnning] dict type parser dict contains illegal type" ;
  193.          return false ;
  194.         }
  195.         
  196.         value->parser ( content ) ;
  197.         _value_map[key] = value ;
  198.         
  199.         if ( content[0] == 'e' )
  200.         {
  201.             // arrived the end of the dict ; erase the 'e' in content
  202.             content = content.erase( 0 , 1 );
  203.             break ;
  204.         }
  205.     }
  206.     
  207.     return true ;
  208. }

  209. // update date : 2015/4/15 by Aimer
  210. void TorrentFile::get_node_value (StringNode *pStringNode, string &string_value)
  211. {
  212.     if ( pStringNode == NULL )
  213.     {
  214.      LOG(WARNING)<<"[warnning] can not get string type value , empty" ;
  215.      string_value = "" ;
  216.     }
  217.     else
  218.     {
  219.      string_value = pStringNode->_value ;
  220.     }
  221. }

  222. void TorrentFile::get_node_value ( IntegerNode *pIntegerNode , int64_t &integer_value )
  223. {
  224.     if ( pIntegerNode == NULL )
  225.     {
  226.      LOG(WARNING)<<"[warnning] can not get integer type value , empty";
  227.      integer_value = -1 ;
  228.     }
  229.     else
  230.     {
  231.      integer_value = pIntegerNode->_value ;
  232.     }
  233. }

  234. AnyNode * TorrentFile::find_target_node ( map<StringNode*, AnyNode*>&hash_map ,
  235.         const string &key )
  236. {
  237.     for ( map<StringNode*,AnyNode*>::iterator it_map = hash_map.begin() ;
  238.         it_map != hash_map.end() ; it_map++ )
  239.     {
  240.     StringNode *pStringNode = dynamic_cast<StringNode*>(it_map->first) ;
  241.     if ( pStringNode == NULL )
  242.     {
  243.      LOG(WARNING)<<"[warnning] hash map key is NULL ";
  244.      return NULL ;
  245.     }
  246.     
  247.     if ( pStringNode->_value == key )
  248.      return it_map->second ;
  249.     }

  250.    return NULL ; // not find
  251. }


  252. // following method is used the parser torrent file which is the combination
  253. // of all the B encoding parsers (type: integer , string , list, dict ...)

  254. bool TorrentFile::encode ( const string & torrent_file_content , torrent_file_t &torrent_structure )
  255. {
  256.   string file_string = torrent_file_content ;
  257.   DictNode *pFileDict = new DictNode () ;

  258.   pFileDict->parser ( file_string ) ;
  259.   
  260.   // key word : "announce" ; type: string
  261.   get_node_value ( dynamic_cast<StringNode*>
  262.     (find_target_node( pFileDict->_value_map , "announce" )) , torrent_structure.announce ) ;
  263.  
  264.  // key word : "created by" ; type : string
  265.   get_node_value ( dynamic_cast<StringNode*>
  266.     (find_target_node(pFileDict->_value_map, "created by")) , torrent_structure.created_by) ;

  267. // key word : "creatation date" ; type :integer
  268.   get_node_value ( dynamic_cast<IntegerNode*>
  269.     ( find_target_node( pFileDict->_value_map , "creation date")) , torrent_structure.creation_date ) ;
  270.  
  271. // key word : "comment" ; type : string
  272.   get_node_value ( dynamic_cast<StringNode*>
  273.     (find_target_node( pFileDict->_value_map , "comment" ) ), torrent_structure.comment ) ;

  274. // key word : "encoding" ; type : string
  275.   get_node_value ( dynamic_cast<StringNode*>
  276.     (find_target_node (pFileDict->_value_map , "encoding" )), torrent_structure.encoding ) ;


  277. // key word : "announce-list" ; type : list< contain element type : string >
  278.   AnyNode *pAnyNode_list = find_target_node ( pFileDict->_value_map , "announce-list" ) ;
  279.  
  280.  if ( pAnyNode_list != NULL) // "announce-list" exists in .torrent file
  281.  {
  282.     ListNode *pAnnounceList = dynamic_cast<ListNode*>(pAnyNode_list) ;
  283.     
  284.     // traverse the list , extract string into --> torrent_strucutre.announce_list :(vector<string> type)
  285.     for ( vector<AnyNode*>::iterator it = pAnnounceList->_value_list.begin () ;
  286.                 it != pAnnounceList->_value_list.end () ; it++ )
  287.     {
  288.         string string_announce ;
  289.     
  290.         get_node_value ( dynamic_cast<StringNode*>(*it) , string_announce ) ;
  291.         
  292.         torrent_structure.announce_list.push_back (string_announce) ;
  293.     }
  294.  }
  295.  
  296.  else
  297.  {
  298.     LOG(INFO)<<"[info] no key words : exists in torrent file" ;
  299.  }
  300.  
  301.  // key word : "info" ; type : dictionary
  302. // if single file mode , dictionary elements type : string
  303. // if multi-file mode , dictionary elements type : string , list < element type : dictinary >
  304. //                            dictionary element type : string<length>
  305. //                                 list <element type : string>
  306. //
  307.  
  308. {

  309.     // first get info|type : dict ; from pFileDict
  310.     AnyNode *pAnyNode_dict = find_target_node ( pFileDict->_value_map , "info") ;
  311.     
  312.     if ( pAnyNode_dict != NULL ) // get "info" key word
  313.     {
  314.         DictNode *pInfoDict = dynamic_cast<DictNode*>(pAnyNode_dict) ;
  315.         
  316.         // get key word "pieces" from info --------> info.pieces type : string
  317.          get_node_value ( dynamic_cast<StringNode*>
  318.             (find_target_node( pInfoDict->_value_map , "pieces" )) , torrent_structure.info.pieces ) ;
  319.         
  320.         // get key word "piece_length" from info ---> info.piece_length type : integer
  321.         get_node_value ( dynamic_cast<IntegerNode*>
  322.             (find_target_node(pInfoDict->_value_map , "piece length")), torrent_structure.info.piece_length ) ;
  323.         
  324.         // get info.files from info ------> info.files type: list
  325.         AnyNode *pAnyNode_info_list = find_target_node ( pInfoDict->_value_map , "files" ) ;
  326.         
  327.         if ( pAnyNode_info_list != NULL )
  328.         {
  329.             LOG(INFO)<<"[info] multi-file mode" ;
  330.             torrent_structure.info.is_multi_file = true ;

  331.             
  332.             // files : list type exists , transfer it into ListType *
  333.             ListNode *pInfoFileList = dynamic_cast<ListNode*>( pAnyNode_info_list ) ;
  334.             
  335.             // get main dir from info , type : string , k-words "name"
  336.             string main_dir ;
  337.             
  338.             get_node_value ( dynamic_cast<StringNode*>
  339.                 (find_target_node(pInfoDict->_value_map, "name")) , main_dir ) ;
  340.             
  341.             // traverse the list : info.files list with element in dict type
  342.             for ( vector<AnyNode*>::iterator it_dict = pInfoFileList->_value_list.begin() ;
  343.                         it_dict != pInfoFileList->_value_list.end() ; it_dict++ )
  344.             {
  345.                 DictNode *pDictNode = dynamic_cast<DictNode*>(*it_dict) ;
  346.                 
  347.                 if ( pDictNode != NULL)
  348.                 {
  349.                     // here on dict refers a sub file node
  350.                     // a sub file node contain
  351.                     // { integer type : file_length , list<string>: file sub-path }
  352.             
  353.                     file_t sub_file ;
  354.                     sub_file.file_path += main_dir ; // first append the main dictionary into sub file
  355.                     
  356.                     // extract sub file length from pDictNode
  357.                     get_node_value ( dynamic_cast<IntegerNode*>
  358.                         (find_target_node( pDictNode->_value_map , "length" ) ) ,
  359.                                          sub_file.file_length ) ;
  360.                     
  361.                     // extract sub file path from pDictNode
  362.                     // first find the path-list from pDictNode
  363.                     AnyNode* pAnyNode_path_list = find_target_node ( pDictNode->_value_map , "path" ) ;
  364.                     if ( pAnyNode_path_list != NULL )
  365.                     {
  366.                         // second if it is not null , transfer it into List type
  367.                         ListNode *pSubPathList = dynamic_cast<ListNode*>(pAnyNode_path_list) ;
  368.                             
  369.                         // third traverse the list's _value_list , extract each string
  370.                         // append them together into the absolute path of subfile
  371.                         
  372.                         // take care : the *it_sub_path is in type of StringNode *

  373.                     for ( vector<AnyNode*>::iterator it_sub_path = pSubPathList->_value_list.begin() ;
  374.                             it_sub_path != pSubPathList->_value_list.end () ; it_sub_path++ )
  375.                     {
  376.                         sub_file.file_path += "//" ; // first you should add seperator
  377.                         
  378.                         get_node_value ( dynamic_cast<StringNode*>(*it_sub_path ),
  379.                                                 sub_file.file_path ) ;
  380.                     }
  381.                     

  382.                     }
  383.                     else
  384.                     {
  385.                         LOG(WARNING)<<"[warning] oh ,no , sub file path is empty ";
  386.                         return false ;
  387.                     }

  388.                     torrent_structure.info.file_list.push_back (sub_file) ;
  389.                 }
  390.                 else
  391.                 {
  392.                     LOG(WARNING)<<"[warnning] failed transfer AnyNode* into DictNode* ";
  393.                     return false ;
  394.                 }
  395.             }
  396.             
  397.             
  398.             
  399.         }
  400.         else
  401.         {
  402.             LOG(INFO)<<"[info] single file mode";
  403.             
  404.             torrent_structure.info.is_multi_file = false ;
  405.             
  406.             file_t single_file ;

  407.             // get info.files.file_length from info , type : integer , k-words "length"
  408.             get_node_value ( dynamic_cast<IntegerNode*>
  409.                 (find_target_node(pInfoDict->_value_map , "length")) , single_file.file_length) ;
  410.             
  411.             // get info.files.file_name from into , type : string , k-words "name"
  412.             get_node_value ( dynamic_cast<StringNode*>
  413.                 (find_target_node(pInfoDict->_value_map , "name")) , single_file.file_path ) ;
  414.             
  415.             torrent_structure.info.file_list.push_back (single_file) ;
  416.             
  417.         }
  418.         

  419.     }
  420.     
  421.     else
  422.     {
  423.         LOG(WARNING)<<"[warnning] can not find key word : in torrent file " ;
  424.         return false ;
  425.     }
  426.  }

  427.   delete pFileDict ;
  428.   return true ;
  429. }
公共类
//parserUtil.h

点击(此处)折叠或打开

  1. #ifndef PARSER_UTIL_H
  2. #define PARSER_UTIL_H

  3. #include <string>
  4. #include <stdint.h>

  5. class parserUtils
  6. {
  7. public :
  8.     static void string_to_integer ( std::string value , int64_t &integer );


  9. } ;
  10. #endif

//parserUtil.cpp
在该方法中主要实现了将字符串数字"32167" 转换为数值类型的 32167 的方法实现 string_to_integer

点击(此处)折叠或打开

  1. #include <stdint.h>
  2. #include <string>

  3. #include "parserUtil.h"

  4. using namespace std ;

  5. void parserUtils::string_to_integer ( std::string value , int64_t &integer )
  6.         {
  7.                 int64_t result = 0 ;
  8.                 int temp = 0 ;

  9.                 for ( int i = 0 ; i < value.size() ; i++)
  10.                 {
  11.                         temp = value[i] -'0' ;
  12.                         result = result*10 ;
  13.                         result += temp ;
  14.                 }

  15.                 integer = result ;
  16.         }
// Main.cpp
主函数调用

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <string>
  3. #include <iostream>

  4. #include <glog/logging.h>


  5. #include "torrentParser.h"
  6. #include "parserUtil.h"

  7. using namespace std ;


  8. int main ( int argc , char * argv[] )
  9. {
  10.   string content ;
  11.   char type ;

  12.   AnyNode *pAnyNode = NULL ;

  13.   // first let init the google log
  14.  google::InitGoogleLogging(argv[0]) ;
  15.   
  16. // and then set the log file store path
  17.    FLAGS_log_dir = "./log/" ;
  18.   
  19.     

  20.   cout << "input parser's type [i->integer] [s->string] [l->list] [d->dictionary]" << endl ;
  21.   cin >> type ;

  22.   cout << "input content " << endl ;
  23.   cin >> content ;
  24.  
  25.   switch ( type )
  26.   {
  27.     case 'i':
  28.     {
  29.     pAnyNode = new IntegerNode () ;
  30.     cout << "type of integer:" <<endl ;
  31.         pAnyNode->parser ( content ) ;
  32.       pAnyNode->print () ;
  33.     
  34.     // update : 2015/4/15 by Aimer
  35.     // test get_node_value
  36.     int64_t integer_value ;
  37.     
  38.     TorrentFile::get_node_value ( dynamic_cast<IntegerNode*>( pAnyNode) , integer_value ) ;
  39.     cout << "integer value "<< integer_value << endl ;
  40.         
  41.     break ;
  42.     }
  43.    
  44.    case 's' :
  45.    {
  46.     pAnyNode = new StringNode () ;
  47.     cout << "type of string :" <<endl ;
  48.     pAnyNode->parser( content ) ;
  49.     pAnyNode->print () ;

  50.     // update : 2015/4/15 by Aimer
  51.     // test TorrentFile::get_node_value , string type
  52.     string string_value ;
  53.     
  54.     TorrentFile::get_node_value ( dynamic_cast<StringNode*>( pAnyNode) , string_value ) ;
  55.     cout<< "string value "<< string_value << endl ;

  56.     break ;
  57.    }
  58.    case 'l' :
  59.    {
  60.     pAnyNode = new ListNode () ;
  61.     cout <<"type of list :" <<endl ;
  62.     pAnyNode->parser ( content ) ;
  63.     pAnyNode->print () ;    

  64.     break ;
  65.    }
  66.   case 'd' :
  67.   {
  68.     pAnyNode = new DictNode () ;
  69.     cout <<"type of dictionary" <<endl ;
  70.     pAnyNode->parser ( content ) ;
  71.     pAnyNode->print () ;

  72.     // update : 2015/4/15 , test find_target_node method
  73.     string key ;

  74.     cout << "input searching key words"<< endl ;
  75.     cin>> key ;
  76.     
  77.     AnyNode *pAnyNode_value = TorrentFile::find_target_node ( (dynamic_cast<DictNode*>(pAnyNode))->_value_map, key ) ;
  78.     cout << "key->" << key << "value->";
  79.     pAnyNode_value->print () ;

  80.     break ;
  81.   }
  82.   default :
  83.     cout <<" error not such kind type " << endl ;
  84.     break ;
  85.   }

  86.  // here we begin testing the TorrentFile::encode method
  87.  // we need torrent-type file input string , and a null torrent_file_t variable
  88.  
  89.  torrent_file_t torrent_structure ;
  90.  string torrent_string;

  91.  cout << "input your torrent file content" << endl ;
  92.  cin >> torrent_string ;
  93.  
  94.  TorrentFile::encode ( torrent_string, torrent_structure ) ;
  95.  
  96.  return 0 ;    
  97. }

github address:
end

阅读(1579) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~