- 性别
- 保密
- 积分
- 0
- 积分
- 74
- 精华
- 1
- 阅读权限
- 20
- 注册时间
- 2013-10-14
- 最后登录
- 2013-12-18
- 帖子
- 15
- 性别
- 保密
|
源代码
- /*
- * resolvermetafile.cpp
- * 对resolverMetafile类的具体实现
- * Created on: 2013-8-6
- * Author: tmfish
- */
- #include "resolverMetafile.h"
- #ifdef DEBUG
- //测试函数
- void ResolverMetafile::Test()
- {
- cout << "测试函数" << endl;
- //合格测试
- //*successful
- cout << "filetype: " << m_metaInfo.fileType << endl;
- cout << "piecelen: " << m_metaInfo.pieceLen << endl;
- if (ISSIMPLE == m_metaInfo.fileType)
- {
- cout << "filename: " << m_metaInfo.fileName << endl;
- }else if (ISMULTIPLE == m_metaInfo.fileType)
- {
- cout << "dirname: " << m_metaInfo.dirName << endl;
- }
- cout << "multiple files number: " << m_metaInfo.multiFiles.size() << endl;
- for (int i=0; i<int(m_metaInfo.multiFiles.size()); i++)
- {
- cout << "path: " << m_metaInfo.multiFiles[i].path << endl;
- cout << "length: " << m_metaInfo.multiFiles[i].length << endl;
- }
- cout << "fileLen: " << m_metaInfo.fileLength<< endl;
- for(int i=0; i<int(m_metaInfo.trackerList.size()); i++)
- {
- cout << "trackerList" << i << ": " << m_metaInfo.trackerList[i] << endl;
- }
- cout << "test for add " << endl;
- char url[] = "一个URL地址,随意填";
- AddTracker(url);
- for(int i=0; i<int(m_metaInfo.trackerList.size()); i++)
- {
- cout << "trackerList" << i << ": " << m_metaInfo.trackerList[i] << endl;
- }
- }
- #endif
- //构造函数
- ResolverMetafile::ResolverMetafile(string path)
- {
- memset(&m_metaInfo, 0, sizeof(m_metaInfo));
- m_metafile = NULL;
- m_metafilePath = path;
- m_metafileLen = 0;
- ReadMetafile();
- FileType();
- ResTracker();
- ResPieceLen();
- ResPieces();
- ResFileName();
- ResFilePathLen();
- ResFileLength();
- CalcInfoHash();
- }
- //析构函数
- ResolverMetafile::~ResolverMetafile()
- {
- /*某些释放*/
- ReleaseMem();
- }
- /********************************************************************
- *功能:获取共享文件信息
- *返回:函数返回存储种子文件信息的m_metaInfo结构体对象
- *参数:pst_info是一个MetafileInfo类型的指针的指针,用于接收种子文件信息
- 存放点地址
- *********************************************************************/
- MetafileInfo ResolverMetafile::GetMetafileInfo(pMetaInfo*const ppst_info)
- {
- *ppst_info = &m_metaInfo;
- return m_metaInfo;
- }
- /*
- * 功能:向tracker列表添加一个tracker服务器地址
- * 返回:成功添加tracker返回1,tracker已经存在返回0
- * 函数成功执行失败返回-1
- * 参数:strTracker指定添加的tracker地址,如果该地址存在与tracker
- * 列表中,则函数退出
- * 附注:当连接某些tarcker地址的时候,服务器会返回一个重定向地址,函数用于
- * 添加该类地址
- */
- STATE ResolverMetafile::AddTracker(const char* url)
- {
- char* bufTmp = new char[strlen(url)+1];
- memcpy(bufTmp,url,strlen(url)+1);
- int size = m_metaInfo.trackerList.size();
- //若地址存在,则无需添加
- for (int i=0; i<size; i++)
- {
- if (0 == strcmp(m_metaInfo.trackerList.at(i),url))
- {
- return OK;
- }
- }
- //于末尾追加元素
- m_metaInfo.trackerList.push_back(bufTmp);
- return OK;
- }
- /*
- * 功能:判断种子文件类型
- * 返回:单文件返回ISSIMPLE,多文件返回ISMULTIPLE,m_metafile为空返回2
- * 附注:ISSIMPLE值为1,ISMULTIPLE值为2
- */
- FILETYPE ResolverMetafile::FileType()
- {
- // cout << m_metafile << endl;
- long long index;
- //种子文件中files代表多文件
- if (1 == FindWord("5:files",index))
- {
- m_metaInfo.fileType = ISMULTIPLE;
- return ISMULTIPLE;
- }else
- {
- m_metaInfo.fileType = ISSIMPLE;
- return ISSIMPLE;
- }
- return ERROR;
- }
- /*
- * 功能:读取m_metafilePath指定的种子文件,将文件内容保存到m_metafile中
- * 返回:函数成功执行返回0,m_metafilePath为空返回2,失败返回-1
- * 附注:文件读取方式为二进制读取
- */
- STATE ResolverMetafile::ReadMetafile()
- {
- if (m_metafilePath.empty())
- {
- cerr << "文件路径为空!" << endl;
- return ERROR;
- }
- /*
- ifstream fin(m_metafilePath.c_str(), ios_base::in | ios_base::binary);
- // fin.open("in");
- if (!fin.is_open())
- {
- cerr<< "文件打开失败!" << endl;
- return ERROR;
- }
- //获取种子文件长度
- fin.seekg(0,ios::end);
- m_metafileLen = fin.tellg();
- m_metafile = new char[m_metafileLen+1];
- // fin.read(m_metafile, m_metafileLen);]
- fin >> m_metafile;
- if (NULL == m_metafile)
- {
- cerr << "文件读取失败" << endl;
- return ERROR;
- }
- m_metafile[m_metafileLen] = '\0';
- cout << m_metafile[3] << endl;
- fin.close();
- */
- //以二进制、只读方式打开文件
- FILE* fp = fopen(m_metafilePath.c_str(), "rb");
- if (NULL == fp)
- {
- cout << "文件打开失败" << endl;
- return -1;
- }
- //获取种子文件的长度,
- fseek(fp, 0, SEEK_END);
- m_metafileLen = ftell(fp);
- if (-1 == m_metafileLen)
- {
- cout << "文件长度错误" << endl;
- return -1;
- }
- m_metafile = new unsigned char[m_metafileLen+1];
- if (NULL == m_metafile)
- {
- cout << "内存分配失败" << endl;
- return -1;
- }
- //读取种子文件的内容到m_metafile
- fseek(fp, 0, SEEK_SET);
- long i;
- for ( i=0; i<m_metafileLen; i++)
- {
- m_metafile[i] = fgetc(fp);
- }
- m_metafile[i] = '\0';
- fclose(fp);
- return OK;
- }
- /*
- *功能:在m_metafile中查找指定关键字
- *返回:函数查找到指定的关键字返回1,没有找到返回0,函数执行出错返回-1
- *参数:word为需要查找的指定关键字,index为查找到的字符串的起始下标的引用
- */
- STATE ResolverMetafile::FindWord(const char* word, long long& index)
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return ERROR;
- }
- for (long long int i=0; i<(m_metafileLen-long(strlen(word))); i++)
- {
- if (0 == memcmp(&m_metafile[i], word, strlen(word)))
- {
- index = i;
- return 1;
- }
- }
- //未找到
- return 0;
- }
- /*
- * 功能:解析种子文件的tracker服务器列表,将其放入m_metaInfo.trackerList
- * 返回:函数成功执行返回0,失败返回-1
- * 附注:m_metaInfo.trackerList第一个值为主tracker服务器
- */
- STATE ResolverMetafile::ResTracker()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return ERROR;
- }
- long long index = 0;
- if (0 == FindWord("13:announce-list",index)) //单文件处理
- {
- if (1 == FindWord("8:annouce",index))
- {
- int len = 0; //tracker长度
- index = index + strlen("8:announce"); //跳过"8:announce"
- while (isdigit(m_metafile[index]))
- {
- len = len*10 + (m_metafile[index] - '0');
- index++;
- }
- index ++; //跳过':'
- //填充m_metaInfo.trackerList数据成员
- char* tmpBuf = new char[len+1];
- memcpy(tmpBuf, &m_metafile[index], len);
- tmpBuf[len] = '\0';
- if(!m_metaInfo.trackerList.empty())
- {
- m_metaInfo.trackerList.clear();
- }
- m_metaInfo.trackerList.push_back(tmpBuf);
- }//end if
- }else //如果有“13:announce-list”关键字,则不用处理"8:annoucne"关键字
- {
- index+=strlen("13:announce-list"); //跳过"13:announce-list"
- index++;//跳过'l'
- index++;//跳过'l'
- int len = 0;
- while('e' != m_metafile[index])
- {
- while(isdigit(m_metafile[index]))
- {
- len = len*10 + (m_metafile[index]-'0');
- index++;
- }
- index++;//跳过':'
- //提取tracker 放入m_metafile.trackerList容器
- //只处理"http"开头的地址
- if (0 == memcmp(&m_metafile[index],"http",4))
- {
- char* tmpBuf = new char[len+1];
- memcpy(tmpBuf, &m_metafile[index], len);
- tmpBuf[len] = '\0';
- m_metaInfo.trackerList.push_back(tmpBuf);
- }
- //准备读取下一个tracker地址
- index = index + len;
- len =0;
- } //end while 1
- } //end if else
- return OK;
- }
- /*
- * 功能:解析piece快大小,将其放入m_metaInfo.pieceLen
- * 返回:成功执行返回0,失败返回-1,m_metafile为空返回2
- */
- STATE ResolverMetafile::ResPieceLen()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return ERROR;
- }
- m_metaInfo.pieceLen = 0;
- long long index =0;
- if (1 == FindWord("12:piece length", index))
- {
- index += strlen("12:piece length"); //跳过"12:piece length"
- index ++; //跳过':'
- //填充m_metaInfo.pieceLen
- while(isdigit(m_metafile[index]))
- {
- m_metaInfo.pieceLen = 10*(m_metaInfo.pieceLen) + (m_metafile[index]-'0');
- index++;
- }
- }else
- {
- return ERROR;
- }
- return OK;
- }
- /*
- * 功能:解析每个块对应的hash值字符串,将其放入m_metaInfo.pieces
- * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2
- */
- STATE ResolverMetafile::ResPieces()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return ERROR;
- }
- long long index = 0;
- if (1 == FindWord("6:pieces", index))
- {
- index += strlen("6:pieces");
- long len = 0;
- while (isdigit(m_metafile[index]))
- {
- len = len*10 + (m_metafile[index]-'0');
- index++;
- }
- //填充m_metaInfo.pieces
- index++;//跳过':'
- m_metaInfo.pieces = new char[len+1];
- memcpy(m_metaInfo.pieces, &m_metafile[index], len);
- m_metaInfo.pieces[len] = '\0';
- }else
- {
- return ERROR;
- }
- return OK;
- }
- /*
- * 功能:解析文件名,对于多文件而言解析目录名,
- * 若解析单文件,放入m_metaInfo.filename,若解析多文件,放入dirName
- * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2
- */
- STATE ResolverMetafile::ResFileName()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return ERROR;
- }
- long long index;
- int count = 0;
- if (1 == FindWord("4:name", index))
- {
- index = index + 6; //跳过'4:name'
- while (':' != m_metafile[index] )
- {
- count = count*10+(m_metafile[index]-'0');
- index++;
- }
- index++;//跳过':'
- if (ISSIMPLE == m_metaInfo.fileType)
- {
- m_metaInfo.fileName = new char[count+1];
- memcpy(m_metaInfo.fileName,&m_metafile[index], count);
- m_metaInfo.fileName[count] ='\0';
- }else if(ISMULTIPLE == m_metaInfo.fileType)
- {
- m_metaInfo.dirName = new char[count+1];
- memcpy(m_metaInfo.dirName,&m_metafile[index], count);
- m_metaInfo.dirName[count] ='\0';
- }
- }else
- {
- return ERROR;
- }
- return OK;
- }
- /*
- * 功能:解析总文件大小,填充m_metaInfo.fileLength
- * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2
- */
- STATE ResolverMetafile::ResFileLength()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return ERROR;
- }
- long long index = 0;
- long long size = 0;
- if (ISSIMPLE == m_metaInfo.fileType )
- {
- cout << "enter simple file process " << endl;
- if (1 == FindWord("6:length",index)) //单文件
- {
- index = index+strlen("6:length"); //跳过"6:length"
- index ++ ; //跳过'i'
- while(isdigit(m_metafile[index]))
- {
- size = size*10 + (m_metafile[index]-'0');
- index++;
- }
- m_metaInfo.fileLength = size;
- } //end if
- }else if(ISMULTIPLE == m_metaInfo.fileType)
- {
- for(int i=0; i<int(m_metaInfo.multiFiles.size()); i++)
- {
- m_metaInfo.fileLength = m_metaInfo.fileLength +
- m_metaInfo.multiFiles[i].length;
- }
- }else
- {
- return ERROR;
- }
- return OK;
- }
- /*
- * 功能:解析文件大小和路径,仅对多文件有效,填充m_metaInfo.multiFiles结构体
- * 并将files填充,代表多文件的文件个数
- * 返回:函数成功执行返回0,失败返回-1,m_metafile为空返回2
- */
- STATE ResolverMetafile::ResFilePathLen()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return NOFILE;
- }
- //不是多文件该函数无效
- if (ISMULTIPLE != m_metaInfo.fileType)
- {
- return ERROR;
- }
- int length = 0;
- // char* path = NULL;
- int pathSize = 0;
- Files mfBuf ;
- memset(&mfBuf, 0, sizeof(mfBuf));
- for(long i=0; i<(m_metafileLen-8); i++) //-8预留空间,防内存溢出
- {
- //获取多文件中各个文件的大小
- if (0 == memcmp(&m_metafile[i], "6:length", 8))
- {
- i+=8; //跳过"6:length"
- i++; //跳过'i'
- length = 0;
- while('e' != m_metafile[i])
- {
- length = length*10 + (m_metafile[i]-'0');
- i++;
- }
- mfBuf.length = length;
- //填充m_metaInfo.multiFiles成员,于末尾追加
- m_metaInfo.multiFiles.push_back(mfBuf);
- }//end if
- //获取多文件中文件路径
- if (0 == memcmp(&m_metafile[i], "4:path", 4))
- {
- i+=6; //跳过"4:path"
- i++; //跳过 'l'
- pathSize = 0;
- while(':' != m_metafile[i])
- {
- pathSize = pathSize*10 + (m_metafile[i] - '0');
- i++;
- }
- i++; //跳过':'
- //填充m_metaInfo.multiFiles成员,于末尾追加
- int end = m_metaInfo.multiFiles.size();
- (m_metaInfo.multiFiles[end-1]).path = new char[pathSize+1];
- memcpy((m_metaInfo.multiFiles[end-1]).path, &m_metafile[i], pathSize);
- (m_metaInfo.multiFiles[end-1]).path[pathSize] = '\0';
- }//end if
- } //end for
- return OK;
- }
- /*
- * 功能:更具info关键字的值计算其对应的哈希值,将其填充与m_metaInfo.info_hash内
- * 返回:成功返回0,失败返回-1
- * 附注:info关键字对应的值为一个字典。
- */
- STATE ResolverMetafile::CalcInfoHash()
- {
- if (NULL == m_metafile)
- {
- cerr << "种子内容为空" << endl;
- return NOFILE;
- }
- //begin 为info关键字值开始下标,end为结束
- int push_pop = 0;
- long long index=0,begin=0,end=0;
- if (1 == FindWord("4:info", index))
- {
- begin = index+6;
- }else
- {
- return ERROR;
- }
- index +=6; //跳过"4:info"
- /*
- * 核心算法: 遍历info关键字后的值,当遇到d,l时push_pop++,
- * 如果遇到e,则push_pop--当push_pop为0的时候,
- * 则证明info关键字后的字典结束,遇见i则直接遍历
- * i的内容,遇见数字则直接计算其后字串内容
- */
- for (;index<m_metafileLen;)
- {
- if ('d' == m_metafile[index])
- {
- push_pop++;
- index++;
- }else if ('l' == m_metafile[index])
- {
- push_pop++;
- index++;
- }else if ('i' == m_metafile[index])
- {
- index++;//跳过'i'
- if (index > m_metafileLen)
- {
- return ERROR;
- }
- while ('e' != m_metafile[index])
- {
- if (index+1 == m_metafileLen)
- {
- return ERROR;
- }else
- {
- index ++;
- }
- }//end while
- index ++; //跳过'e'
- }else if(('0'<=m_metafile[index]) && (m_metafile[index] <= '9'))
- {
- int len =0;
- while (isdigit(m_metafile[index]))
- {
- len = len*10 + (m_metafile[index]-'0');
- index++;
- }
- index++; //跳过':'
- index+=len;
- }else if ('e' == m_metafile[index])
- {
- push_pop --;
- if (0 == push_pop)
- {
- end = index; break;
- }
- index++;
- }else
- {
- return ERROR;
- }
- }//end for
- //计算hash值
- SHA1_CTX context;
- SHA1Init(&context);
- SHA1Update(&context,&m_metafile[begin], end-begin+1);
- SHA1Final(m_metaInfo.info_hash,&context);
- cout << endl;
- return OK;
- }
- /*
- * 功能:释放类资源
- */
- void ResolverMetafile::ReleaseMem()
- {
- if (NULL != m_metafile)
- {
- delete[] m_metafile;
- m_metafile = NULL;
- }
- if (NULL != m_metaInfo.pieces)
- {
- delete[] m_metaInfo.pieces;
- }
- if (!m_metaInfo.trackerList.empty())
- {
- for (int i=0; i< int(m_metaInfo.trackerList.size()); i++)
- {
- delete[] m_metaInfo.trackerList.at(i);
- m_metaInfo.trackerList.at(i) = NULL;
- }
- }
- m_metaInfo.trackerList.clear();
- if (!m_metaInfo.multiFiles.empty())
- {
- for (int i=0; i<int(m_metaInfo.multiFiles.size()); i++)
- {
- if (NULL != (m_metaInfo.multiFiles.at(i).path))
- delete[] m_metaInfo.multiFiles.at(i).path;
- m_metaInfo.multiFiles.at(i).path = NULL;
- }
- }
- m_metaInfo.multiFiles.clear();
- memset(&m_metaInfo, 0, sizeof(m_metaInfo));
- }
复制代码 |
|