📄 torrentfile.cpp
字号:
/*************************************************************************** * Copyright (C) 2005-2006 Gao Xianchao * * 2007 Gao Xianchao gnap_an linux_lyb ahlongxp * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************//* * Author: gxc * Create data: 2005-01-29 20:09 */#include <unistd.h>#include <assert.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <iostream>#include "TorrentFile.h"#include "binteger.h"#include "bstring.h"#include "blist.h"#include "bdict.h"#include "sha1.h"#include "log.h"#include "utils.h"CTorrentFile::CTorrentFile(){ _encoding = "UTF-8"; _utf8Valid = true; memset(_infoHash, 0, sizeof(_infoHash)); }CTorrentFile::~CTorrentFile(){}void CTorrentFile::setBTTask(IBTTask* task){ _task = task;}IBTTask* CTorrentFile::getBTTask(){ return _task;}void CTorrentFile::updateUTF8(){ _utf8Valid = true; _commentUTF8 = str_to_utf8(_comment.c_str(), _encoding.c_str()); if(_comment != "" && _commentUTF8 == "") { _utf8Valid = false; } _creatorUTF8 = str_to_utf8(_creator.c_str(), _encoding.c_str()); if(_creator != "" && _creatorUTF8 == "") { _utf8Valid = false; } _topDirUTF8 = str_to_utf8(_topDir.c_str(), _encoding.c_str()); if(_topDir != "" && _topDirUTF8 == "") { _utf8Valid = false; } _nameUTF8 = str_to_utf8(_name.c_str(), _encoding.c_str()); if(_name != "" && _nameUTF8 == "") { _utf8Valid = false; } TFileInfoVector::iterator iter = _fileInfos.begin(); for(; iter!= _fileInfos.end(); ++iter) { iter->pathUTF8 = str_to_utf8(iter->path.c_str(), _encoding.c_str()); if(iter->path != "" && iter->pathUTF8 == "") { _utf8Valid = false; } iter->nameUTF8 = str_to_utf8(iter->name.c_str(), _encoding.c_str()); if(iter->name != "" && iter->nameUTF8 == "") { _utf8Valid = false; } }}void CTorrentFile::setCharacterEncoding(const char* enc){ _encoding = enc; updateUTF8();}bool CTorrentFile::IsUTF8Valid(){ return _utf8Valid;}bool CTorrentFile::load(const char* filePath){ LOG_INFO("try to load torrent file : " << filePath); int fd= open(filePath,O_RDONLY); if(fd==-1) { LOG_ERROR("can not open torrent file : " << filePath); return false; } std::string data; char buf[2048]; bool read_suc=false; int ret=-1; for(;;) { ret=read(fd,buf,sizeof(buf)); if(ret==-1) { break; } if(ret==0) { read_suc=true; break; } else { data.append(&buf[0],ret); } } close(fd); if(!read_suc) { LOG_ERROR("read torrent file error"); return false; } CBDict dict; if(dict.parse(data.c_str(),data.length())<=0) { LOG_ERROR("parse torrent file error"); return false; } if(!parseDict(dict)) { return false; } if(!parseInfoDict(dict)) { return false; } updateUTF8(); LOG_INFO("load torrent file ok"); return true; }unsigned int CTorrentFile::getAnnounceCount(){ return _announces.size();}const char* CTorrentFile::getAnnounce(unsigned int index){ if(index >= _announces.size()) { return NULL; } return _announces[index].c_str();}int CTorrentFile::getCreationDate(){ return _creatDate;}const char* CTorrentFile::getComment(){ return _comment.c_str();}const char* CTorrentFile::getCreator(){ return _creator.c_str();}std::string CTorrentFile::getName(){ return _name;}std::string CTorrentFile::getTopDir(){ return _topDir;}const char* CTorrentFile::getCommentUTF8(){ return _commentUTF8.c_str();}const char* CTorrentFile::getCreatorUTF8(){ return _creatorUTF8.c_str();}std::string CTorrentFile::getNameUTF8(){ return _nameUTF8;}std::string CTorrentFile::getTopDirUTF8(){ return _topDirUTF8;}unsigned int CTorrentFile::getPieceLength(){ return _pieceLength;}unsigned int CTorrentFile::getPieceCount(){ return _pieces.size() / 20;}std::string CTorrentFile::getPieceHash(unsigned int pieceIndex){ return _pieces.substr(pieceIndex*20, 20);}unsigned int CTorrentFile::getFileCount(){ return _fileInfos.size();}TFileInfo CTorrentFile::getFileInfo(unsigned int index){ if(index >= _fileInfos.size()) { TFileInfo fileInfo; fileInfo.offset = 0; fileInfo.size = 0; fileInfo.path = ""; fileInfo.name = ""; return fileInfo; } return _fileInfos[index];}int64_t CTorrentFile::getTotalSize(){ return _totalSize;}const unsigned char* CTorrentFile::getInfoHash(){ return _infoHash;}bool CTorrentFile::parseDict(CBDict& dict){ if(dict.getValue("info")==NULL) { LOG_ERROR("torrent file : no key \"info\""); return false; } CBString* announce=(CBString*)dict.getValue("announce"); if(announce==NULL) { LOG_ERROR("torrent file : no key \"announce\""); return false; } if(announce->getValue().length()==0) { return false; } _announces.push_back(announce->getValue()); CBList* announce_list=(CBList*)dict.getValue("announce-list"); if(announce_list!=NULL) { _announces.clear(); for(unsigned int j=0;j< announce_list->getCount();++j) { CBList* announce_list2=(CBList*)(announce_list->getValue(j)); for(unsigned int k=0;k<announce_list2->getCount();++k) { CBString* announce=(CBString*)(announce_list2->getValue(k)); if(announce!=NULL) { _announces.push_back(announce->getValue()); } } } } LOG_INFO("announce count = " << _announces.size()); CBInteger* creation_date=(CBInteger*)dict.getValue("creation date"); if(creation_date!=NULL) { _creatDate=creation_date->getValue(); } CBString* comment=(CBString*)dict.getValue("comment"); if(comment!=NULL) { _comment=comment->getValue(); } comment=(CBString*)dict.getValue("comment.utf-8"); if(comment!=NULL) { _comment=comment->getValue(); } CBString* created_by=(CBString*)dict.getValue("created by"); if(created_by!=NULL) { _creator=created_by->getValue(); } created_by=(CBString*)dict.getValue("created by.utf-8"); if(created_by!=NULL) { _creator=created_by->getValue(); } return true; }bool CTorrentFile::parseInfoDict(CBDict& dict){ CBDict* info_dict=(CBDict*)dict.getValue("info"); if(info_dict==NULL) { return false; } CBList* files=(CBList*)info_dict->getValue("files"); if(files==NULL) { LOG_INFO("one file"); CBInteger* length=(CBInteger*)info_dict->getValue("length"); if(length==NULL || length->getValue()<=0) { LOG_ERROR("torrent file : no key \"info.length\""); return false; } _topDir = ""; _totalSize= length->getValue(); CBString* name=(CBString*)info_dict->getValue("name.utf-8"); if(name == NULL) { name = (CBString*)info_dict->getValue("name"); } if(name==NULL || name->getValue().length()==0) { LOG_ERROR("torrent file : no key \"info.name\""); return false; } _name = name->getValue(); CBInteger* piece_length=(CBInteger*)info_dict->getValue("piece length"); if(piece_length==NULL) { LOG_ERROR("torrent file : no key \"info.piece length\""); return false; } _pieceLength=piece_length->getValue(); if(_pieceLength<=0) { LOG_ERROR("torrent file : _pieceLength<=0"); return false; } CBString* pieces=(CBString*)info_dict->getValue("pieces"); if(pieces==NULL) { LOG_ERROR("torrent file : no key \"pieces\""); return false; } _pieces=pieces->getValue(); if(_pieces.length()==0) { return false; } TFileInfo fileInfo; fileInfo.offset = 0; fileInfo.size = length->getValue(); fileInfo.path = name->getValue(); fileInfo.name = name->getValue(); _fileInfos.push_back(fileInfo); } else { LOG_INFO("more than one file"); CBString* name=(CBString*)info_dict->getValue("name.utf-8"); if(name == NULL) { name = (CBString*)info_dict->getValue("name"); } if(name==NULL || name->getValue().length()==0) { LOG_ERROR("torrent file : no key \"info.name\""); return false; } _name = name->getValue(); _topDir = name->getValue(); CBInteger* piece_length=(CBInteger*)info_dict->getValue("piece length"); if(piece_length==NULL) { LOG_ERROR("torrent file : no key \"info.piece length\""); return false; } _pieceLength=piece_length->getValue(); if(_pieceLength<=0) { LOG_ERROR("torrent file : _pieceLength<=0"); return false; } CBString* pieces=(CBString*)info_dict->getValue("pieces"); if(pieces==NULL) { LOG_ERROR("torrent file : no key \"pieces\""); return false; } _pieces=pieces->getValue(); if(_pieces.length()==0) { return false; } _totalSize = 0; for(unsigned int i=0;i<files->getCount();++i) { CBDict* file_dict=(CBDict*)files->getValue(i); if(file_dict==NULL) { return false; } int64_t length = 0; CBInteger* bLength=(CBInteger*)file_dict->getValue("length"); if(bLength != NULL && bLength->getValue()>=0) { length = bLength->getValue(); } CBList* path=(CBList*)file_dict->getValue("path.utf-8"); if(path == NULL) { path=(CBList*)file_dict->getValue("path"); } if(path==NULL || path->getCount()==0) { LOG_ERROR("torrent file : path error"); return false; } std::string file_path=_topDir; std::string file_name = ""; for(unsigned int j=0;j<path->getCount();++j) { CBString* dir=(CBString*)path->getValue(j); file_path+="/"+dir->getValue(); if(j == path->getCount() -1) { file_name = dir->getValue(); } } if(file_name == "") { continue; } if(file_path.length()==0) { LOG_ERROR("torrent file : file_path.length()==0"); return false; } TFileInfo fileInfo; fileInfo.offset = _totalSize; fileInfo.size = length; fileInfo.path = file_path; fileInfo.name = file_name; _fileInfos.push_back(fileInfo); _totalSize+=length; } } std::string info_str; info_dict->get_bestr(info_str); sha1_block((unsigned char*)info_str.c_str(),info_str.length(),_infoHash); return true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -