FileDB.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:8k
源码类别:
P2P编程
开发平台:
Visual C++
- // FileDB.cpp: implementation of the CFileDB class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "testbt.h"
- #include "FileDB.h"
- #include "bdecode.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- void CFileDBItem::SetHave(const memstream& memBuf)
- {
- m_vHave.clear();
- for (int i=0; i<memBuf.size(); i++)
- {
- unsigned char c = memBuf[i];
- for (int j=0; j<8; j++)
- {
- if ((i*8 +j) >= m_lPieceCount)
- break;
- m_vHave.push_back(c & 0x1);
- c >>= 1;
- }
- }
- }
- void CFileDBItem::GetHave(memstream& memBuf)const
- {
- unsigned char c = 0;
- for (int i=0; i<m_vHave.size(); i++)
- {
- unsigned char t = (m_vHave[i] == 1) ? 1:0;
- c |= t << i%8;
- if (!((i+1) % 8))
- {
- memBuf.write((char*)&c, 1);
- c = 0;
- }
- }
- if ((i % 8))
- {
- memBuf.write((char*)&c, 1);
- }
- }
- void CFileDBItem::SetHave(const vector<long>& vHave, float fComplete)
- {
- m_fComplete = fComplete;
- m_vHave.clear();
- if (m_fComplete >= 1 || !m_fComplete )
- return;
- for (int i=0; i<vHave.size(); i++)
- {
- m_vHave.push_back(vHave[i]);
- }
- }
- void CFileDBItem::GetHave(vector<long>& vHave)const
- {
- vHave.clear();
- if (m_fComplete >= 1)
- {
- for (int i=0; i<m_lPieceCount; i++)
- vHave.push_back(1);
- }
- else if (m_fComplete == 0)
- {
- for (int i=0; i<m_lPieceCount; i++)
- vHave.push_back(0);
- }
- else
- {
- for (int i=0; i<m_vHave.size(); i++)
- {
- vHave.push_back(m_vHave[i] != 0);
- }
- }
- }
- CFileDB::CFileDB()
- {
- /*
- memstream m;
- long len = m.size();
- m.write("abc", 3);
- m.TrimLeft(1);
- char szText[100] = {0};
- memcpy(szText, m, m.size());
- memstream m2;
- m2 = m;
- memset(szText, 0, 100);
- memcpy(szText, m2, m2.size());
- // for (int i=0; i<100000; i++)
- // m.write("aaaaaaaaaa", 10);
- try
- {
- //WriteFile("c:\lll.txt");
- vector<CFileDBItem> vFiles;
- for (int i=0; i<200; i++)
- vFiles.push_back(CFileDBItem("hello.a", "a", 100, 234, 567));
- WriteFile("c:\lll.txt", vFiles);
- OpenFile("c:\lll.txt", vFiles);
- string strTemp;
- for (i=0; i<vFiles.size(); i++)
- {
- char szText[100] = {0};
- sprintf(szText, "tim : %d , complete : %d, size : %d",
- vFiles[i].m_tTime,
- vFiles[i].m_lComplete,
- vFiles[i].m_lFileSize);
- strTemp += vFiles[i].m_strTorrentFileName;
- strTemp += vFiles[i].m_strFileName;
- strTemp += szText;
- strTemp += "rn";
- }
- AfxMessageBox("a"); // strTemp.data());
- }
- catch (string& e)
- {
- AfxMessageBox(e.data());
- }
- //*/
- }
- CFileDB::~CFileDB()
- {
- }
- ///////////////////////////////////////////////////////////////////
- //
- // read data from *.torrent
- //
- ///////////////////////////////////////////////////////////////////
- bool CFileDB::OpenFile(string strFileName, vector<CFileDBItem>& vFiles)
- {
- assert(false);
- if (strFileName.empty())
- return false;
- // open file and read data
- FILE* pfile = 0;
- if (!_access(strFileName.data(), 0))
- pfile = fopen(strFileName.data(), "rb");
- else
- pfile = fopen(strFileName.data(), "wb+");
- if (!pfile)
- {
- assert(false);
- throw string("file:") + strFileName + "is not a valid file path";
- }
- fseek(pfile, 0, SEEK_END);
- long lsize = ftell(pfile);
- if (lsize <= 0)
- {
- fclose(pfile);
- return true;
- }
- char * pBuf = new char[lsize];
- auto_ptr<char> autoBuf(pBuf);
- fseek(pfile, 0, SEEK_SET);
- int iRet = fread(pBuf, 1, lsize, pfile);
- if (iRet != lsize)
- throw string("read file ") + strFileName + " fail";
- fclose(pfile);
- // format data
- CBdecode dec;
- CVal* pVal = dec.bdecode(pBuf, lsize);
- auto_ptr<CVal> auVal(pVal);
- if (!pVal)
- {
- pfile = fopen(strFileName.data(), "wb+");
- fclose(pfile);
- throw string("filedb bdecode error");
- }
- // check data
- CheckDB(pVal);
- // let
- vFiles.clear();
- for (int i=0; i<pVal->size(); i++)
- {
- PVALMAP pFileInfoMap = (*pVal)[i]->pmapVal;
- string strComment;
- vFiles.push_back(
- CFileDBItem((*pFileInfoMap)["TFileName"]->pstrVal,
- (*pFileInfoMap)["filename"]->pstrVal,
- (*pFileInfoMap)["size"]->lVal,
- ((float)(*pFileInfoMap)["complete"]->lVal)/100,
- (*pFileInfoMap)["time"]->lVal,
- (*pFileInfoMap)["infohash"]->pstrVal, 0,
- (*pFileInfoMap)["time"]->lVal,
- 0,
- strComment));
- }
- return true;
- }
- void CFileDB::CheckDB(CVal *pVal)
- {
- if (!pVal || pVal->vt!=VT_PLIST)
- throw string("bad metainfo - not a list");
- for (VALLIST::iterator iter=pVal->plistVal->begin(); iter!= pVal->plistVal->end(); iter++)
- {
- CVal* pf = *iter;
- if (!pf || pf->vt != VT_PMAP)
- throw string("bad metainfo - bad file value");
- CVal* pTFileName = (*pf->pmapVal)["TFileName"];
- if (!pTFileName || pTFileName->vt != VT_PSTR)
- throw string("bad metainfo - bad filename");
- CVal* pFileName = (*pf->pmapVal)["filename"];
- if (!pFileName || pFileName->vt != VT_PSTR)
- throw string("bad metainfo - bad filename");
- CVal* pSize = (*pf->pmapVal)["size"];
- if (!pSize || pSize->vt != VT_LONG || pSize->lVal<0)
- throw string("bad metainfo - bad time");
- CVal* pTime = (*pf->pmapVal)["complete"];
- if (!pTime|| pTime->vt != VT_LONG || pTime->lVal<0)
- throw string("bad metainfo - bad time");
- CVal* pComplete = (*pf->pmapVal)["time"];
- if (!pComplete || pComplete->vt != VT_LONG || pComplete->lVal<0)
- throw string("bad metainfo - bad Complete");
- CVal* pInfohash = (*pf->pmapVal)["infohash"];
- if (!pInfohash|| pInfohash->vt != VT_PSTR || pInfohash->lstrLen != 40)
- throw string("bad metainfo - bad infohash");
- }
- }
- bool CFileDB::WriteFile(string strFileName, const vector<CFileDBItem>& vFiles)
- {
- if (strFileName.empty())
- {
- assert(false);
- return false;
- }
- // format data
- PVALLIST pFileList = new VALLIST();
- for (int i=0; i<vFiles.size(); i++)
- {
- const CFileDBItem& item = vFiles[i];
- PVALMAP pFileInfoMap = new VALMAP();
- (*pFileInfoMap)["TFileName"] = new CVal(item.m_strTorrentFileName);
- (*pFileInfoMap)["filename"] = new CVal(item.m_strFileName);
- (*pFileInfoMap)["size"] = new CVal(item.m_lFileSize);
- (*pFileInfoMap)["complete"] = new CVal((long)(((float)item.m_fComplete)*100));
- (*pFileInfoMap)["time"] = new CVal(item.m_tTime);
- (*pFileInfoMap)["infohash"] = new CVal(item.m_strHash);
- pFileList->push_back(new CVal(pFileInfoMap));
- }
- // encode data
- CVal val(pFileList);
- memstream memBuf;
- CBdecode::bencode(&val, memBuf);
- // write data
- FILE* pfile = fopen(strFileName.data(), "wb");
- if (!pfile)
- throw string("file:") + strFileName + "can't find";
- long lret = fwrite(memBuf, 1, memBuf.size(), pfile);
- fclose(pfile);
- if (lret != memBuf.size())
- throw string("write file ") + strFileName + " fail";
- return true;
- }
- CVal* CFileDB::OpenFileEx(string strFileName)
- {
- if (strFileName.empty())
- throw string("strFileName can't empty");
- // open file and read data
- FILE* pfile = 0;
- if (!_access(strFileName.data(), 0))
- pfile = fopen(strFileName.data(), "rb");
- else
- return 0 ;
- if (!pfile)
- {
- assert(false);
- throw string("file:") + strFileName + "is not a valid file path";
- }
- fseek(pfile, 0, SEEK_END);
- long lsize = ftell(pfile);
- if (lsize <= 0)
- {
- fclose(pfile);
- return 0;
- }
- char * pBuf = new char[lsize];
- auto_ptr<char> autoBuf(pBuf);
- fseek(pfile, 0, SEEK_SET);
- int iRet = fread(pBuf, 1, lsize, pfile);
- if (iRet != lsize)
- throw string("read file ") + strFileName + " fail";
- fclose(pfile);
- // format data
- CBdecode dec;
- CVal* pVal = dec.bdecode(pBuf, lsize);
- if (!pVal)
- {
- pfile = fopen(strFileName.data(), "wb+");
- fclose(pfile);
- throw string("filedb bdecode error return val 0");
- }
- return pVal;
- }
- void CFileDB::WriteFileEx(string strFileName, CVal* pVal)
- {
- if (strFileName.empty())
- throw string("strFileName can't empty");
- memstream memBuf;
- CBdecode::bencode(pVal, memBuf);
- // write data
- FILE* pfile = fopen(strFileName.data(), "wb");
- if (!pfile)
- throw string("file:(") + strFileName + ")can't open";
- long lret = fwrite(memBuf, 1, memBuf.size(), pfile);
- fclose(pfile);
- if (lret != memBuf.size())
- throw string("write file (") + strFileName + ") fail";
- }