FileDB.cpp
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:8k
源码类别:

P2P编程

开发平台:

Visual C++

  1. // FileDB.cpp: implementation of the CFileDB class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "testbt.h"
  6. #include "FileDB.h"
  7. #include "bdecode.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. void CFileDBItem::SetHave(const memstream& memBuf)
  17. {
  18. m_vHave.clear();
  19. for (int i=0; i<memBuf.size(); i++)
  20. {
  21. unsigned char c = memBuf[i];
  22. for (int j=0; j<8; j++)
  23. {
  24. if ((i*8 +j) >= m_lPieceCount)
  25. break;
  26. m_vHave.push_back(c & 0x1);
  27. c >>= 1;
  28. }
  29. }
  30. }
  31. void CFileDBItem::GetHave(memstream& memBuf)const
  32. {
  33. unsigned char c = 0;
  34. for (int i=0; i<m_vHave.size(); i++)
  35. {
  36. unsigned char t = (m_vHave[i] == 1) ? 1:0;
  37. c |= t << i%8;
  38. if (!((i+1) % 8))
  39. {
  40. memBuf.write((char*)&c, 1);
  41. c = 0;
  42. }
  43. }
  44. if ((i % 8))
  45. {
  46. memBuf.write((char*)&c, 1);
  47. }
  48. }
  49. void CFileDBItem::SetHave(const vector<long>& vHave, float fComplete)
  50. {
  51. m_fComplete = fComplete;
  52. m_vHave.clear();
  53. if (m_fComplete >= 1 || !m_fComplete )
  54. return;
  55. for (int i=0; i<vHave.size(); i++)
  56. {
  57. m_vHave.push_back(vHave[i]);
  58. }
  59. }
  60. void CFileDBItem::GetHave(vector<long>& vHave)const
  61. {
  62. vHave.clear();
  63. if (m_fComplete >= 1)
  64. {
  65. for (int i=0; i<m_lPieceCount; i++)
  66. vHave.push_back(1);
  67. }
  68. else if (m_fComplete == 0)
  69. {
  70. for (int i=0; i<m_lPieceCount; i++)
  71. vHave.push_back(0);
  72. }
  73. else
  74. {
  75. for (int i=0; i<m_vHave.size(); i++)
  76. {
  77. vHave.push_back(m_vHave[i] != 0);
  78. }
  79. }
  80. }
  81. CFileDB::CFileDB()
  82. {
  83. /*
  84. memstream m;
  85. long len = m.size();
  86. m.write("abc", 3);
  87. m.TrimLeft(1);
  88. char szText[100] = {0};
  89. memcpy(szText, m, m.size());
  90. memstream m2;
  91. m2 = m;
  92. memset(szText, 0, 100);
  93. memcpy(szText, m2, m2.size());
  94. // for (int i=0; i<100000; i++)
  95. // m.write("aaaaaaaaaa", 10);
  96. try
  97. {
  98. //WriteFile("c:\lll.txt");
  99. vector<CFileDBItem> vFiles;
  100. for (int i=0; i<200; i++)
  101. vFiles.push_back(CFileDBItem("hello.a", "a", 100, 234, 567));
  102. WriteFile("c:\lll.txt", vFiles);
  103. OpenFile("c:\lll.txt", vFiles);
  104. string strTemp;
  105. for (i=0; i<vFiles.size(); i++)
  106. {
  107. char szText[100] = {0};
  108. sprintf(szText, "tim : %d , complete : %d, size : %d", 
  109. vFiles[i].m_tTime, 
  110. vFiles[i].m_lComplete,
  111. vFiles[i].m_lFileSize);
  112. strTemp += vFiles[i].m_strTorrentFileName;
  113. strTemp += vFiles[i].m_strFileName;
  114. strTemp += szText;
  115. strTemp += "rn";
  116. }
  117. AfxMessageBox("a"); // strTemp.data());
  118. }
  119. catch (string& e)
  120. {
  121. AfxMessageBox(e.data());
  122. }
  123. //*/
  124. }
  125. CFileDB::~CFileDB()
  126. {
  127. }
  128. ///////////////////////////////////////////////////////////////////
  129. //
  130. // read data from *.torrent
  131. //
  132. ///////////////////////////////////////////////////////////////////
  133. bool CFileDB::OpenFile(string strFileName, vector<CFileDBItem>& vFiles)
  134. {
  135. assert(false);
  136. if (strFileName.empty())
  137. return false;
  138. // open file and read data
  139. FILE* pfile = 0;
  140. if (!_access(strFileName.data(), 0))
  141. pfile = fopen(strFileName.data(), "rb");
  142. else
  143. pfile = fopen(strFileName.data(), "wb+");
  144. if (!pfile)
  145. {
  146. assert(false);
  147. throw string("file:") + strFileName + "is not a valid file path";
  148. }
  149. fseek(pfile, 0, SEEK_END);
  150. long lsize = ftell(pfile);
  151. if (lsize <= 0)
  152. {
  153. fclose(pfile);
  154. return true;
  155. }
  156. char * pBuf = new char[lsize];
  157. auto_ptr<char> autoBuf(pBuf);
  158. fseek(pfile, 0, SEEK_SET);
  159. int iRet = fread(pBuf, 1, lsize, pfile);
  160. if (iRet != lsize)
  161. throw string("read file ") + strFileName + " fail";
  162. fclose(pfile);
  163. // format data
  164. CBdecode dec;
  165. CVal* pVal = dec.bdecode(pBuf, lsize);
  166. auto_ptr<CVal> auVal(pVal);
  167. if (!pVal)
  168. {
  169. pfile = fopen(strFileName.data(), "wb+");
  170. fclose(pfile);
  171. throw string("filedb bdecode error");
  172. }
  173. // check data
  174. CheckDB(pVal);
  175. // let 
  176. vFiles.clear();
  177. for (int i=0; i<pVal->size(); i++)
  178. {
  179. PVALMAP pFileInfoMap = (*pVal)[i]->pmapVal; 
  180. string strComment;
  181. vFiles.push_back(
  182. CFileDBItem((*pFileInfoMap)["TFileName"]->pstrVal, 
  183. (*pFileInfoMap)["filename"]->pstrVal,
  184. (*pFileInfoMap)["size"]->lVal,
  185. ((float)(*pFileInfoMap)["complete"]->lVal)/100,
  186. (*pFileInfoMap)["time"]->lVal,
  187. (*pFileInfoMap)["infohash"]->pstrVal, 0, 
  188. (*pFileInfoMap)["time"]->lVal, 
  189. 0,
  190. strComment));
  191. }
  192. return true;
  193. }
  194. void CFileDB::CheckDB(CVal *pVal)
  195. {
  196. if (!pVal || pVal->vt!=VT_PLIST)
  197. throw string("bad metainfo - not a list");
  198. for (VALLIST::iterator iter=pVal->plistVal->begin(); iter!= pVal->plistVal->end(); iter++)
  199. {
  200. CVal* pf = *iter;
  201. if (!pf || pf->vt != VT_PMAP)
  202. throw string("bad metainfo - bad file value");
  203. CVal* pTFileName = (*pf->pmapVal)["TFileName"];
  204. if (!pTFileName || pTFileName->vt != VT_PSTR)
  205. throw string("bad metainfo - bad filename");
  206. CVal* pFileName = (*pf->pmapVal)["filename"];
  207. if (!pFileName || pFileName->vt != VT_PSTR)
  208. throw string("bad metainfo - bad filename");
  209. CVal* pSize = (*pf->pmapVal)["size"];
  210. if (!pSize || pSize->vt != VT_LONG || pSize->lVal<0)
  211. throw string("bad metainfo - bad time");
  212. CVal* pTime = (*pf->pmapVal)["complete"];
  213. if (!pTime|| pTime->vt != VT_LONG || pTime->lVal<0)
  214. throw string("bad metainfo - bad time");
  215. CVal* pComplete = (*pf->pmapVal)["time"];
  216. if (!pComplete || pComplete->vt != VT_LONG || pComplete->lVal<0)
  217. throw string("bad metainfo - bad Complete");
  218. CVal* pInfohash = (*pf->pmapVal)["infohash"];
  219. if (!pInfohash|| pInfohash->vt != VT_PSTR || pInfohash->lstrLen != 40)
  220. throw string("bad metainfo - bad infohash");
  221. }
  222. }
  223. bool CFileDB::WriteFile(string strFileName, const vector<CFileDBItem>& vFiles)
  224. {
  225. if (strFileName.empty())
  226. {
  227. assert(false);
  228. return false;
  229. }
  230. // format data
  231. PVALLIST pFileList = new VALLIST();
  232. for (int i=0; i<vFiles.size(); i++)
  233. {
  234. const CFileDBItem& item = vFiles[i];
  235. PVALMAP pFileInfoMap = new VALMAP();
  236. (*pFileInfoMap)["TFileName"] = new CVal(item.m_strTorrentFileName);
  237. (*pFileInfoMap)["filename"] = new CVal(item.m_strFileName);
  238. (*pFileInfoMap)["size"] = new CVal(item.m_lFileSize);
  239. (*pFileInfoMap)["complete"] = new CVal((long)(((float)item.m_fComplete)*100));
  240. (*pFileInfoMap)["time"] = new CVal(item.m_tTime);
  241. (*pFileInfoMap)["infohash"] = new CVal(item.m_strHash);
  242. pFileList->push_back(new CVal(pFileInfoMap));
  243. }
  244. // encode data
  245. CVal val(pFileList);
  246. memstream memBuf;
  247. CBdecode::bencode(&val, memBuf);
  248. // write data
  249. FILE* pfile = fopen(strFileName.data(), "wb");
  250. if (!pfile)
  251. throw string("file:") + strFileName + "can't find";
  252. long lret = fwrite(memBuf, 1, memBuf.size(), pfile);
  253. fclose(pfile);
  254. if (lret != memBuf.size())
  255. throw string("write file ") + strFileName + " fail";
  256. return true;
  257. }
  258. CVal* CFileDB::OpenFileEx(string strFileName)
  259. {
  260. if (strFileName.empty())
  261. throw string("strFileName can't empty");
  262. // open file and read data
  263. FILE* pfile = 0;
  264. if (!_access(strFileName.data(), 0))
  265. pfile = fopen(strFileName.data(), "rb");
  266. else
  267. return 0 ;
  268. if (!pfile)
  269. {
  270. assert(false);
  271. throw string("file:") + strFileName + "is not a valid file path";
  272. }
  273. fseek(pfile, 0, SEEK_END);
  274. long lsize = ftell(pfile);
  275. if (lsize <= 0)
  276. {
  277. fclose(pfile);
  278. return 0;
  279. }
  280. char * pBuf = new char[lsize];
  281. auto_ptr<char> autoBuf(pBuf);
  282. fseek(pfile, 0, SEEK_SET);
  283. int iRet = fread(pBuf, 1, lsize, pfile);
  284. if (iRet != lsize)
  285. throw string("read file ") + strFileName + " fail";
  286. fclose(pfile);
  287. // format data
  288. CBdecode dec;
  289. CVal* pVal = dec.bdecode(pBuf, lsize);
  290. if (!pVal)
  291. {
  292. pfile = fopen(strFileName.data(), "wb+");
  293. fclose(pfile);
  294. throw string("filedb bdecode error return val 0");
  295. }
  296. return pVal;
  297. }
  298. void CFileDB::WriteFileEx(string strFileName, CVal* pVal)
  299. {
  300. if (strFileName.empty())
  301. throw string("strFileName can't empty");
  302. memstream memBuf;
  303. CBdecode::bencode(pVal, memBuf);
  304. // write data
  305. FILE* pfile = fopen(strFileName.data(), "wb");
  306. if (!pfile)
  307. throw string("file:(") + strFileName + ")can't open";
  308. long lret = fwrite(memBuf, 1, memBuf.size(), pfile);
  309. fclose(pfile);
  310. if (lret != memBuf.size())
  311. throw string("write file (") + strFileName + ") fail";
  312. }