📄 entry.cpp
字号:
//// This file is part of the aMule Project.//// Copyright (c) 2008 Dévai Tamás ( gonosztopi@amule.org )// Copyright (c) 2004-2008 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (c) 2003 Barry Dunne (http://www.emule-project.net)//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA//// Note To Mods ///*Please do not change anything here and release it..There is going to be a new forum created just for the Kademlia side of the client..If you feel there is an error or a way to improve something, pleasepost it in the forum first and let us look at it.. If it is a real improvement,it will be added to the offical client.. Changing something without knowingwhat all it does can cause great harm to the network if released in mass form..Any mod that changes anything within the Kademlia side will not be allowed to advertisethere client on the eMule forum..*/#include "Entry.h"#include <common/Macros.h>#include <tags/FileTags.h>#include <protocol/kad/Constants.h>#include "Indexed.h"#include "../../SafeFile.h"#include "../../GetTickCount.h"#include "../../Logger.h"#include "../../NetworkFunctions.h"using namespace Kademlia;CKeyEntry::GlobalPublishIPMap CKeyEntry::s_globalPublishIPs;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CEntryCEntry::~CEntry(){ for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { delete *it; }}CEntry* CEntry::Copy() const{ CEntry* entry = new CEntry(); for (FileNameList::const_iterator it = m_filenames.begin(); it != m_filenames.end(); ++it) { entry->m_filenames.push_back(*it); } entry->m_uIP = m_uIP; entry->m_uKeyID.SetValue(m_uKeyID); entry->m_tLifeTime = m_tLifeTime; entry->m_uSize = m_uSize; entry->m_bSource = m_bSource; entry->m_uSourceID.SetValue(m_uSourceID); entry->m_uTCPport = m_uTCPport; entry->m_uUDPport = m_uUDPport; for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { entry->m_taglist.push_back((*it)->CloneTag()); } return entry;}uint64_t CEntry::GetIntTagValue(const wxString& tagname, bool includeVirtualTags) const{ uint64_t result = 0; GetIntTagValue(tagname, result, includeVirtualTags); return result;}bool CEntry::GetIntTagValue(const wxString& tagname, uint64_t& value, bool includeVirtualTags) const{ for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if ((*it)->IsInt() && ((*it)->GetName() == tagname)) { value = (*it)->GetInt(); return true; } } if (includeVirtualTags) { // SizeTag is not stored anymore, but queried in some places if (tagname == TAG_FILESIZE) { value = m_uSize; return true; } } value = 0; return false;}wxString CEntry::GetStrTagValue(const wxString& tagname) const{ for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if (((*it)->GetName() == tagname) && (*it)->IsStr()) { return (*it)->GetStr(); } } return wxEmptyString;}void CEntry::SetFileName(const wxString& name){ if (!m_filenames.empty()) { wxFAIL; m_filenames.clear(); } sFileNameEntry sFN = { name, 1 }; m_filenames.push_front(sFN);}wxString CEntry::GetCommonFileName() const{ // return the filename on which most publishers seem to agree on // due to the counting, this doesn't has to be excact, we just want to make sure to not use a filename which just // a few bad publishers used and base or search matching and answering on this, instead of the most popular name // Note: The Index values are not the acutal numbers of publishers, but just a relativ number to compare to other entries FileNameList::const_iterator result = m_filenames.end(); uint32_t highestPopularityIndex = 0; for (FileNameList::const_iterator it = m_filenames.begin(); it != m_filenames.end(); ++it) { if (it->m_popularityIndex > highestPopularityIndex) { highestPopularityIndex = it->m_popularityIndex; result = it; } } wxString strResult(result != m_filenames.end() ? result->m_filename : wxString(wxEmptyString)); wxASSERT(!strResult.IsEmpty() || m_filenames.empty()); return strResult;}void CEntry::WriteTagListInc(CFileDataIO* data, uint32_t increaseTagNumber){ // write taglist and add name + size tag wxCHECK_RET(data != NULL, wxT("data must not be NULL")); uint32_t count = GetTagCount() + increaseTagNumber; // will include name and size tag in the count if needed wxASSERT(count <= 0xFF); data->WriteUInt8((uint8_t)count); if (!GetCommonFileName().IsEmpty()){ wxASSERT(count > m_taglist.size()); data->WriteTag(CTagString(TAG_FILENAME, GetCommonFileName())); } if (m_uSize != 0){ wxASSERT(count > m_taglist.size()); data->WriteTag(CTagVarInt(TAG_FILESIZE, m_uSize)); } for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { data->WriteTag(**it); }}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CKeyEntryCKeyEntry::CKeyEntry(){ m_publishingIPs = NULL; m_trustValue = 0; m_lastTrustValueCalc = 0;}CKeyEntry::~CKeyEntry(){ if (m_publishingIPs != NULL) { for (PublishingIPList::const_iterator it = m_publishingIPs->begin(); it != m_publishingIPs->end(); ++it) { AdjustGlobalPublishTracking(it->m_ip, false, wxT("instance delete")); } delete m_publishingIPs; m_publishingIPs = NULL; }}bool CKeyEntry::SearchTermsMatch(const SSearchTerm* searchTerm) const{ // boolean operators if (searchTerm->type == SSearchTerm::AND) { return SearchTermsMatch(searchTerm->left) && SearchTermsMatch(searchTerm->right); } if (searchTerm->type == SSearchTerm::OR) { return SearchTermsMatch(searchTerm->left) || SearchTermsMatch(searchTerm->right); } if (searchTerm->type == SSearchTerm::NOT) { return SearchTermsMatch(searchTerm->left) && !SearchTermsMatch(searchTerm->right); } // word which is to be searched in the file name (and in additional meta data as done by some ed2k servers???) if (searchTerm->type == SSearchTerm::String) { int strSearchTerms = searchTerm->astr->GetCount(); if (strSearchTerms == 0) { return false; } // if there are more than one search strings specified (e.g. "aaa bbb ccc") the entire string is handled // like "aaa AND bbb AND ccc". search all strings from the string search term in the tokenized list of // the file name. all strings of string search term have to be found (AND) wxString commonFileNameLower(GetCommonFileNameLowerCase()); for (int i = 0; i < strSearchTerms; i++) { // this will not give the same results as when tokenizing the filename string, but it is 20 times faster. if (commonFileNameLower.Find((*(searchTerm->astr))[i]) == -1) { return false; } } return true; } if (searchTerm->type == SSearchTerm::MetaTag) { if (searchTerm->tag->GetType() == 2) { // meta tags with string values if (searchTerm->tag->GetName() == TAG_FILEFORMAT) { // 21-Sep-2006 []: Special handling for TAG_FILEFORMAT which is already part // of the filename and thus does not need to get published nor stored explicitly, wxString commonFileName(GetCommonFileName()); int ext = commonFileName.Find(wxT('.'), true); if (ext != wxNOT_FOUND) { return commonFileName.Mid(ext + 1).CmpNoCase(searchTerm->tag->GetStr()) == 0; } } else { for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if ((*it)->IsStr() && searchTerm->tag->GetName() == (*it)->GetName()) { return (*it)->GetStr().CmpNoCase(searchTerm->tag->GetStr()) == 0; } } } } } else if (searchTerm->type == SSearchTerm::OpGreaterEqual) { if (searchTerm->tag->IsInt()) { // meta tags with integer values uint64_t value; if (GetIntTagValue(searchTerm->tag->GetName(), value, true)) { return value >= searchTerm->tag->GetInt(); } } else if (searchTerm->tag->IsFloat()) { // meta tags with float values for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if ((*it)->IsFloat() && searchTerm->tag->GetName() == (*it)->GetName()) { return (*it)->GetFloat() >= searchTerm->tag->GetFloat(); } } } } else if (searchTerm->type == SSearchTerm::OpLessEqual) { if (searchTerm->tag->IsInt()) { // meta tags with integer values uint64_t value; if (GetIntTagValue(searchTerm->tag->GetName(), value, true)) { return value <= searchTerm->tag->GetInt(); } } else if (searchTerm->tag->IsFloat()) { // meta tags with float values for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if ((*it)->IsFloat() && searchTerm->tag->GetName() == (*it)->GetName()) { return (*it)->GetFloat() <= searchTerm->tag->GetFloat(); } } } } else if (searchTerm->type == SSearchTerm::OpGreater) { if (searchTerm->tag->IsInt()) { // meta tags with integer values uint64_t value; if (GetIntTagValue(searchTerm->tag->GetName(), value, true)) { return value > searchTerm->tag->GetInt(); } } else if (searchTerm->tag->IsFloat()) { // meta tags with float values for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if ((*it)->IsFloat() && searchTerm->tag->GetName() == (*it)->GetName()) { return (*it)->GetFloat() > searchTerm->tag->GetFloat(); } } } } else if (searchTerm->type == SSearchTerm::OpLess) { if (searchTerm->tag->IsInt()) { // meta tags with integer values uint64_t value; if (GetIntTagValue(searchTerm->tag->GetName(), value, true)) { return value < searchTerm->tag->GetInt(); } } else if (searchTerm->tag->IsFloat()) { // meta tags with float values for (TagPtrList::const_iterator it = m_taglist.begin(); it != m_taglist.end(); ++it) { if ((*it)->IsFloat() && searchTerm->tag->GetName() == (*it)->GetName()) { return (*it)->GetFloat() < searchTerm->tag->GetFloat(); } } } } else if (searchTerm->type == SSearchTerm::OpEqual) { if (searchTerm->tag->IsInt()) { // meta tags with integer values uint64_t value; if (GetIntTagValue(searchTerm->tag->GetName(), value, true)) { return value == searchTerm->tag->GetInt(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -