Bdecode.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:5k
源码类别:
P2P编程
开发平台:
Visual C++
- // Bdecode.cpp: implementation of the CBdecode class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "testBT.h"
- #include "Bdecode.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CBdecode::CBdecode()
- {
- m_lsize = 0;
- m_pBuf = 0;
- }
- CBdecode::~CBdecode()
- {
- }
- CVal* CBdecode::decode_int(long &lPos)
- {
- //*
- long lOldPos = lPos;
- for (; lPos<m_lsize; lPos++)
- {
- if (m_pBuf[lPos] == 'e')
- {
- lPos ++;
- break;
- }
- }
- if (lPos > m_lsize)
- return 0;
- char* pstrStop = 0;
- long l = strtol(m_pBuf+lOldPos, &pstrStop, 10);
- if (pstrStop[0] != 'e')
- return 0;
- return new CVal(l);
- }
- CVal* CBdecode::decode_string(long &lPos)
- {
- long lOldPos = lPos;
- for (; lPos<m_lsize; lPos++)
- {
- if (m_pBuf[lPos] == ':')
- {
- lPos ++;
- break;
- }
- }
- if (lPos > m_lsize)
- return 0;
- char* pstrStop = 0;
- long len = strtol(m_pBuf+lOldPos, &pstrStop, 10);
- if (pstrStop[0] != ':')
- return 0;
- if ((lPos+len) > m_lsize)
- return 0;
- CVal* pVal = new CVal(m_pBuf+lPos, len);
- lPos += len;
- return pVal;
- }
- void ClearList(VALLIST* pls)
- {
- VALLIST::iterator iter = pls->begin();
- while(iter != pls->end())
- {
- delete *iter;
- iter++;
- }
- }
- CVal* CBdecode::decode_list(long &lPos)
- {
- VALLIST* ls = new VALLIST();
- for (; lPos<m_lsize; )
- {
- if (m_pBuf[lPos] == 'e')
- {
- lPos++;
- break;
- }
- CVal* pRet = bdecode_rec(lPos);
- if (!pRet)
- {
- ClearList(ls);
- delete ls;
- return 0;
- }
- ls->push_back(pRet);
- }
- if (lPos > m_lsize)
- {
- ClearList(ls);
- delete ls;
- return 0;
- }
- return new CVal(ls);
- }
- void ClearMap(VALMAP* pmap)
- {
- VALMAP::iterator iter = pmap->begin();
- while(iter != pmap->end())
- {
- delete (*iter).second;
- iter++;
- }
- }
- CVal* CBdecode::decode_dict(long& lPos)
- {
- VALMAP* pmap = new VALMAP();
- string strLast;
- for (; lPos<m_lsize;)
- {
- if (m_pBuf[lPos] == 'e')
- {
- lPos++;
- break;
- }
- CVal* pRet = decode_string(lPos);
- if (!pRet)
- {
- ClearMap(pmap);
- delete pmap;
- return 0;
- }
- string strCur = pRet->pstrVal;
- delete pRet;
- if (strLast.size() > 0)
- {
- if (strCur <= strLast)
- {
- ClearMap(pmap);
- delete pmap;
- return 0;
- }
- }
- strLast = strCur;
- CVal* pRetVal = bdecode_rec(lPos);
- if (!pRetVal)
- {
- ClearMap(pmap);
- delete pmap;
- return 0;
- }
- (*pmap)[strLast] = pRetVal;
- }
- if (lPos > m_lsize)
- {
- ClearMap(pmap);
- delete pmap;
- return 0;
- }
- return new CVal(pmap);
- }
- CVal* CBdecode::bdecode_rec(long& lPos)
- {
- CVal* pRet = 0;
- char t = m_pBuf[lPos];
- switch (t)
- {
- case 'i':
- return decode_int(++lPos);
- case 'l':
- return decode_list(++lPos);
- case 'd':
- return decode_dict(++lPos);
- default:
- return decode_string(lPos);
- }
- }
- CVal* CBdecode::bdecode(char *pbuf, long lsize)
- {
- if (lsize <= 0)
- {
- // assert(false);
- return 0;
- }
- m_lsize = lsize;
- m_pBuf = pbuf;
- long lPos = 0;
- CVal* v = bdecode_rec(lPos);
- if (lPos > m_lsize)
- {
- if (v)
- delete v;
- return 0;
- }
- return v;
- }
- void CBdecode::bencode(CVal *pVal, memstream& memRet)
- {
- bencode_rec(pVal, memRet);
- }
- void CBdecode::bencode_rec(CVal *pVal, memstream &strRet)
- {
- char temp[100] = {0};
- switch (pVal->vt)
- {
- case VT_LONG:
- sprintf(temp, "%d", pVal->lVal);
- strRet += string("i") + temp + "e";
- break;
- case VT_PSTR:
- sprintf(temp, "%d", pVal->lstrLen);
- strRet += string(temp) + ":";
- // strRet += string(temp) + ":" + pVal->pstrVal;
- strRet.write(pVal->pstrVal, pVal->lstrLen);
- break;
- case VT_PLIST:
- {
- strRet += "l";
- for (int i=0; i<pVal->plistVal->size(); i++)
- bencode_rec((*pVal->plistVal)[i], strRet);
- strRet += "e";
- }
- break;
- case VT_PMAP:
- {
- strRet += "d";
- for (VALMAP::iterator iter=pVal->pmapVal->begin(); iter != pVal->pmapVal->end(); iter++)
- {
- string strKey = (*iter).first;
- /*
- char* pstrBuf = new char[strKey.size()+1];
- memset(pstrBuf, 0, strKey.size()+1);
- memcpy(pstrBuf, strKey.data(), strKey.size());
- CVal v(pstrBuf, strKey.size());
- //*/
- CVal v(strKey);
- bencode_rec(&v, strRet);
- bencode_rec((*iter).second, strRet);
- }
- strRet += "e";
- }
- break;
- default:
- assert(false);
- break;
- }
- }