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

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

文章分类

全部博文(104)

文章存档

2018年(1)

2016年(1)

2015年(101)

2014年(1)

我的朋友

分类: C/C++

2015-04-16 11:10:06

这篇文章中的代码是在前一篇文章中的代码的基础上进行改进而来的,觉得在前一篇文章中的
TorrentFile::encode 方法中关于 announce-list 列表类型和 
info 字典类型的处理代码语句,
对于一个模块来说所占行实在是太繁琐了,
所以将其中的 announce-list 和 info 的处理代码单独提取出来,
进行重新的封装。

分别在 torrentParser.h 头文件中添加进入了一些额外的方法,以及在 torrentParser.cpp 文件中给出了这些方法的实现,
于是就有了版本 2 , 其余的文件没有太大的变动。


修改之后的流程大概是这样的:
在 TorrentFile::encode 方法中,处理完字段 announce(string type) , comment( string type) , created by(string type)
creation date( integer type ) encoding ( string type ) 之后,将会调用 get_announce_list 方法来单独处理 announce-list ( list type )字段 ;
随后处理 info (dict type) 字段的时候将会调用方法  get_info_dict , 在该方法中将会把对 info 字段的处理分为 2 个部分
1. 公共部分
2. 单文件/多文件 模式

从公共部分中通过对 info 中的关键字 "files" 的查找,来判断 info 中的文件模式, 如果找到(即指向查找方法的指针不为空), 则是多文件模式
接下来调用 get_info_multi_fmode 方法来进行后续的处理。

如果找不到,即调用查找方法的时候,返回的指针为空 ,这种情况说明了 info 对应的是单文件格式,
接下来调用 get_info_single_mode 方法继续后续处理 

// 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.         static void get_announce_list ( ListNode*pAnnounceList , torrent_file_t &torrent_structure ) ;

  138.         static void get_info_dict ( DictNode*pInfoDict , torrent_file_t &torrent_structure ) ;
  139.         
  140.         // this method will be called by get_info_dict
  141.         static void get_info_common( DictNode*pInfoDict , torrent_file_t &torrent_structure ) ;
  142.         
  143.         // this method will be called by get_info_dict when single-file mode
  144.         static void get_info_single_mode ( DictNode* pInfoDict ,torrent_file_t &torrent_structure) ;
  145.         
  146.         // this method will be called by get_info_dict when multi-file mode
  147.         static void get_info_multi_mode ( DictNode* pInfoDict , torrent_file_t &torrent_structure ) ;


  148.         // this method will print out the messages stored inside in the torrent_file_t
  149.         static void show_torrent_content ( torrent_file_t &torrent_structure) ;

  150. } ;

  151. #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. /**
  253.   method : get_announce_list ( ListNode &announce_list , torrent_file_t &torrent_structure)

  254.   descri : this method is used to extract ListNode.StringNode (in b-encoding)
  255.      and transfer it into the std::string
  256.      then push it into the torrent_list.announce_list(vector<string>)
  257. */

  258. void TorrentFile::get_announce_list ( ListNode *announce_list , torrent_file_t &torrent_structure)
  259. {
  260.     string announce_string ;

  261.     for ( vector<AnyNode*>::iterator it_string = announce_list->_value_list.begin () ;
  262.                 it_string != announce_list->_value_list.end () ; it_string++ )
  263.     {
  264.          get_node_value ( dynamic_cast<StringNode*>(*it_string) , announce_string ) ;
  265.         torrent_structure.announce_list.push_back ( announce_string ) ;
  266.     }
  267. }


  268. /*
  269. this method is used as the main method to extract info dict message
  270. call context :
  271.     AnyNode *pAnyNode_info_dict = find_target_node ( pFileDict->_value_map , "info" ) ;
  272.     if ( pAnyNode_info_dict != NULL )
  273.     {
  274.         DictNode *pInfoDict = dynamic_cast<DictNode*>(pAnyNode_info_dict) ;
  275.         get_info_dict( pInfoDict, torrent_structure ) ;
  276.     }

  277. */
  278. void TorrentFile::get_info_dict ( DictNode *pInfoDict, torrent_file_t &torrent_structure )
  279. {
  280.     get_info_common ( pInfoDict , torrent_structure ) ;
  281.     
  282.     if ( torrent_structure.info.is_multi_file )
  283.     {
  284.         // multi-file mode
  285.         get_info_multi_mode ( pInfoDict, torrent_structure ) ;
  286.     }
  287.     else
  288.     {
  289.         // single file mode
  290.         get_info_single_mode ( pInfoDict, torrent_structure) ;
  291.     }

  292. }
  293.         
  294. // this method will be called by get_info_dict
  295. void TorrentFile::get_info_common( DictNode *pInfoDict , torrent_file_t &torrent_structure )
  296. {    
  297.     // find info.pieces from info-dict , type : string type (b-encoding)
  298.     get_node_value ( dynamic_cast<StringNode*>
  299.         (find_target_node( pInfoDict->_value_map , "pieces" )) , torrent_structure.info.pieces ) ;
  300.     
  301.     // find info.piece_length from info-dict , type : integer type (b-encoding)
  302.     get_node_value ( dynamic_cast<IntegerNode*>
  303.             (find_target_node( pInfoDict->_value_map, "piece length")),torrent_structure.info.piece_length) ;
  304.     
  305.     AnyNode *pAnyNode_files_list = find_target_node ( pInfoDict->_value_map , "files" ) ;

  306.     if ( pAnyNode_files_list != NULL )
  307.     {
  308.         torrent_structure.info.is_multi_file = true ;
  309.     }
  310.     
  311.     else
  312.     {
  313.         // single-file
  314.         torrent_structure.info.is_multi_file = false ;
  315.     }    
  316. }
  317.         
  318. // this method will be called by get_info_dict when single-file mode
  319. void TorrentFile::get_info_single_mode ( DictNode*pInfoDict ,torrent_file_t &torrent_structure)
  320. {
  321.   // this is single-mode file
  322.   file_t single_file ;

  323.   // get file name : string type
  324.   get_node_value ( dynamic_cast<StringNode*>
  325.         (find_target_node ( pInfoDict->_value_map , "name" )) , single_file.file_path) ;
  326.     
  327.   get_node_value ( dynamic_cast<IntegerNode*>
  328.         (find_target_node ( pInfoDict->_value_map, "length")) , single_file.file_length ) ;
  329.     
  330.   torrent_structure.info.file_list.push_back ( single_file ) ;    

  331. }
  332.         

  333. // this method will be called by get_info_dict when multi-file mode
  334. void TorrentFile::get_info_multi_mode ( DictNode*pInfoDict,torrent_file_t &torrent_structure )
  335. {
  336.     string main_dir ;

  337.     // multi-file , info.name is the main path name     
  338.     get_node_value ( dynamic_cast<StringNode*>
  339.             (find_target_node(pInfoDict->_value_map , "name")) , main_dir) ;

  340.     // now the main_dir is the name of the main path of all the files

  341.     ListNode *pInfoFiles = dynamic_cast<ListNode*>( find_target_node ( pInfoDict->_value_map , "files" )) ;

  342.     // traverse the files list , each element in list are in type of dict
  343.     for ( vector<AnyNode*>::iterator it_sub_file = pInfoFiles->_value_list.begin () ;
  344.             it_sub_file != pInfoFiles->_value_list.end () ; it_sub_file++ )
  345.     {
  346.         // each element in the list are dict
  347.         DictNode *pInfoFilesSubFile = dynamic_cast<DictNode*>(*it_sub_file) ;
  348.         
  349.         if ( pInfoFilesSubFile != NULL )
  350.         {
  351.             file_t sub_file ;
  352.             
  353.             // get length of each sub file from the dict
  354.             get_node_value ( dynamic_cast<IntegerNode*>
  355.                     ( find_target_node ( pInfoFilesSubFile->_value_map, "length" ) ) ,          sub_file.file_length ) ;

  356.             AnyNode *pAnyNode_sub_path = find_target_node ( pInfoFilesSubFile->_value_map ,"path" ) ;
  357.             if ( pAnyNode_sub_path != NULL )
  358.             {
  359.              ListNode *pSubPathList = dynamic_cast<ListNode*>(pAnyNode_sub_path) ;    
  360.                 
  361.               // traverse the list and extract each sub path and append them together
  362.          for ( vector<AnyNode*>::iterator it_sub_path = pSubPathList->_value_list.begin() ;
  363.              it_sub_path != pSubPathList->_value_list.end () ; it_sub_path++ )            
  364.              {
  365.                 string sub_path ;

  366.                 sub_file.file_path += "//" ;
  367.                 
  368.                 get_node_value ( dynamic_cast<StringNode*>(*it_sub_path) , sub_path ) ;
  369.                 
  370.                 sub_file.file_path += sub_path ;
  371.              }

  372.             }
  373.             else
  374.             {
  375.                 LOG(INFO)<<"[info] sub path list is empty";
  376.             }

  377.             torrent_structure.info.file_list.push_back (sub_file) ;

  378.         }
  379.         else
  380.         {
  381.             LOG(INFO)<<"[info] file dict is empty " ;
  382.         }
  383.     }// for     
  384. }


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

  387. bool TorrentFile::encode ( const string & torrent_file_content , torrent_file_t &torrent_structure )
  388. {
  389.   string file_string = torrent_file_content ;
  390.   DictNode *pFileDict = new DictNode () ;

  391.   pFileDict->parser ( file_string ) ;
  392.   
  393.   // key word : "announce" ; type: string
  394.   get_node_value ( dynamic_cast<StringNode*>
  395.     (find_target_node( pFileDict->_value_map , "announce" )) , torrent_structure.announce ) ;
  396.  
  397.  // key word : "created by" ; type : string
  398.   get_node_value ( dynamic_cast<StringNode*>
  399.     (find_target_node(pFileDict->_value_map, "created by")) , torrent_structure.created_by) ;

  400. // key word : "creatation date" ; type :integer
  401.   get_node_value ( dynamic_cast<IntegerNode*>
  402.     ( find_target_node( pFileDict->_value_map , "creation date")) , torrent_structure.creation_date ) ;
  403.  
  404. // key word : "comment" ; type : string
  405.   get_node_value ( dynamic_cast<StringNode*>
  406.     (find_target_node( pFileDict->_value_map , "comment" ) ), torrent_structure.comment ) ;

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


  410. // key word : "announce-list" ; type : list< contain element type : string >
  411.   AnyNode *pAnyNode_list = find_target_node ( pFileDict->_value_map , "announce-list" ) ;
  412.  
  413.  if ( pAnyNode_list != NULL) // "announce-list" exists in .torrent file
  414.  {
  415.     ListNode *pAnnounceList = dynamic_cast<ListNode*>(pAnyNode_list) ;
  416.     
  417.     // call get_announce_list method
  418.     get_announce_list ( pAnnounceList , torrent_structure);
  419.     
  420.  }
  421.  
  422.  else
  423.  {
  424.     LOG(INFO)<<"[info] no key words : exists in torrent file" ;
  425.  }
  426.  
  427.  // key word : "info" ; type : dictionary
  428. // if single file mode , dictionary elements type : string
  429. // if multi-file mode , dictionary elements type : string , list < element type : dictinary >
  430. //                            dictionary element type : string<length>
  431. //                                 list <element type : string>
  432. //
  433.  
  434. {

  435.     // first get info|type : dict ; from pFileDict
  436.     AnyNode *pAnyNode_dict = find_target_node ( pFileDict->_value_map , "info") ;
  437.     
  438.     if ( pAnyNode_dict != NULL ) // get "info" key word
  439.     {
  440.         DictNode *pInfoDict = dynamic_cast<DictNode*>(pAnyNode_dict) ;
  441.         
  442.         get_info_dict ( pInfoDict, torrent_structure ) ;
  443.     }
  444.     else
  445.     {
  446.         LOG(WARNING)<<"[warnning] .torrent file can not find info ";
  447.         return true ;
  448.     }

  449. } ///info parse end

  450.     
  451.   delete pFileDict ;
  452.   return true ;
  453. }

  454. void TorrentFile::show_torrent_content ( torrent_file_t &torrent_structure)
  455. {
  456.     
  457.     cout << "torrent file contents after analyze"<<endl ;
  458.     cout << "announce: "<< torrent_structure.announce << endl ;
  459.     cout << "created by: "<< torrent_structure.created_by<< endl ;
  460.     cout << "creation date(s):"<< torrent_structure.creation_date << endl ;
  461.     cout << "comment :"<< torrent_structure.comment << endl ;
  462.     cout << "encoding : "<< torrent_structure.encoding << endl ;
  463.     cout << "announce-list:"<<endl ;

  464.     for ( vector<string>::iterator it = torrent_structure.announce_list.begin () ;
  465.                     it != torrent_structure.announce_list.end () ; it++ )
  466.     {
  467.         cout << *it << endl ;
  468.     }

  469.     cout << "info"<< endl;
  470.     cout << "info.pieces" << torrent_structure.info.pieces << endl ;
  471.     cout << "info.piece_length" << torrent_structure.info.piece_length << endl ;
  472.     cout << "info.is_multi_file ? " << endl ;
  473.     
  474.     if ( torrent_structure.info.is_multi_file )
  475.     {
  476.         cout << "yes , it is multi file mode" << endl ;
  477.         cout << "here are the sub file's path and length" <<endl ;
  478.             
  479.         for ( vector<file_t>::iterator it = torrent_structure.info.file_list.begin () ;
  480.                         it != torrent_structure.info.file_list.end () ; it++ )
  481.         {
  482.             cout << "sub file length "<< it->file_length << endl ;
  483.             cout << "sub file path " << it->file_path << endl ;
  484.         }
  485.     }
  486.     else
  487.     {
  488.         cout << "no , it is single file mode " << endl ;
  489.         
  490.         cout << "here is the single file's path and length " <<endl ;
  491.         cout << "single file length "<< torrent_structure.info.file_list[0].file_length << endl ;
  492.         cout << "single file path(name) " << torrent_structure.info.file_list[0].file_path << endl ;
  493.     }


  494. }




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