Bencode编码

    技术2022-05-11  63

     Torrent文件采用Bencode编码,Bencode编码由以下四种类型组成对于字符串,首先是一个字符串的长度,然后是冒号,后面跟着实际的字符串,例如:4:spam,就是“ spam” 整数编码如下,以 ‘i’ 开始,然后10进制的整数值,最后以’e’结尾。例如,i3e表示3,I-3e表示-3。整数没有大小限制。I-0e是无效的。除了 i0e外,所以以0起始的整数都无效。I0e当然表示0。 列表编码如下,以’l’开始,接下来是列表值的编码(也采用bencoded编码),最后以’e’结束。例如:l4:spam4:eggse 表示 [‘spam’, ‘eggs’]。 字典编码如下,以’d’开始,接下来是可选的keys和它对应的值,最户以’e’结束。例如:d3:cow3:moo4:spam4:eggse,表示{‘cow’:’moo’,’spam’:’eggs’},而d4:spaml1:al:bee 表示 {‘spam’:[‘a’,’b’]}。键值必须是字符串,而且已经排序(并非是按照字母顺序排序,而是根据原始的字符串进行排序)。enum BTItemType {  BT_ITEEM_UNKNOWN = 0, BT_ITEEM_INT,  BT_ITEEM_STR,  BT_ITEEM_LIST,  BT_ITEEM_DIC, };class CBTBaseItem{public: CBTBaseItem( ); virtual ~CBTBaseItem();public: void SetItemType(BTItemType ItemType); BTItemType GetItemType();protected: BTItemType m_ItemType;};

    class CBTIntItem : public CBTBaseItem{public: CBTIntItem(BTItemType ItemType); ~CBTIntItem();public: int GetValue(); void SetValue(int iValue);private: int m_Value;};

    class CBTStrItem : public CBTBaseItem{public: CBTStrItem(BTItemType ItemType); ~CBTStrItem();public: string GetValue(); void   SetValue(string strVal);private: string m_strValue;};

    class CBTListItem : public CBTBaseItem{public: CBTListItem(BTItemType ItemType); ~CBTListItem();public: int GetSize(); CBTBaseItem* GetValue(int index); void AddValue(CBTBaseItem* pBaseItem);private: void Destroy();private: vector<CBTBaseItem*>    m_ListValue;};

    class CBTDicItem : public CBTBaseItem{ typedef map<string, CBTBaseItem*> Map;public: CBTDicItem(BTItemType ItemType); ~CBTDicItem();public: int GetSize(); CBTBaseItem* GetValue(string strKey); void AddValue(string strKey, CBTBaseItem* pBaseItem);private: void Destroy();private: Map   m_MapValue;};实现就很简单了CBTBaseItem::CBTBaseItem(){

    }CBTBaseItem::~CBTBaseItem(){

    }void CBTBaseItem::SetItemType(BTItemType ItemType){ m_ItemType = ItemType;}

    BTItemType CBTBaseItem::GetItemType(){ return m_ItemType;}

    CBTIntItem::CBTIntItem(BTItemType ItemType){ m_ItemType = ItemType; m_Value  = 0;}CBTIntItem::~CBTIntItem(){

    }int CBTIntItem::GetValue(){ return m_Value;}void CBTIntItem::SetValue(int iValue){ m_Value = iValue;}

    //

    CBTStrItem ::CBTStrItem(BTItemType ItemType){ m_ItemType  = ItemType; m_strValue = string("");}CBTStrItem::~CBTStrItem(){

    }void CBTStrItem::SetValue(string strVal){ m_strValue = strVal;}string CBTStrItem::GetValue(){ return m_strValue;}CBTListItem::CBTListItem(BTItemType ItemType){ m_ItemType = ItemType;}

    CBTListItem::~CBTListItem(){ Destroy();}

    int CBTListItem::GetSize(){ return m_ListValue.size();}CBTBaseItem* CBTListItem::GetValue(int index){ if (index < 0 || index >= GetSize())  return NULL; return m_ListValue[index];}void CBTListItem::AddValue(CBTBaseItem* pBaseItem){ if (NULL != pBaseItem)  m_ListValue.push_back(pBaseItem);}void CBTListItem::Destroy(){ for (int index = 0; index < m_ListValue.size(); ++index) {  CBTBaseItem* pItem = m_ListValue[index];  if (pItem)   delete pItem; }}

    CBTDicItem::CBTDicItem(BTItemType ItemType){ m_ItemType = ItemType;}

    CBTDicItem::~CBTDicItem(){ Destroy();}

    int CBTDicItem::GetSize(){ return m_MapValue.size();}

    CBTBaseItem* CBTDicItem::GetValue(string strKey){ Map::iterator pos = m_MapValue.find(strKey); if (pos != m_MapValue.end())  return pos->second; return NULL;}

    void CBTDicItem::AddValue(string strKey, CBTBaseItem* pBaseItem){ if (strKey.size() > 0 && pBaseItem)  m_MapValue.insert(make_pair(strKey, pBaseItem));}

    void CBTDicItem::Destroy(){ Map::iterator pos = m_MapValue.begin(); for (; pos != m_MapValue.end(); ++pos) {  CBTBaseItem* pItem = pos->second;  if (pItem)   delete pItem; }}


    最新回复(0)