⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ectag.cpp

📁 电驴的MAC源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//// This file is part of the aMule Project.//// Copyright (c) 2004-2008 aMule Team ( admin@amule.org / http://www.amule.org )//// 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//#include "ECTag.h"	// Needed for ECTag#include "ECSocket.h"	// Needed for CECSocket/********************************************************** *							  * *	CECTag class					  * *							  * **********************************************************///! Defines the Null tag which may be returned by GetTagByNameSafe.const CECTag CECTag::s_theNullTag(static_cast<NullTagConstructorSelector*>(0));//! Defines the data for the Null tag.  Large enough (16 bytes) for GetMD4Data.const uint32 CECTag::s_theNullTagData[4] = { 0, 0, 0, 0 };/** * Creates a new null-valued CECTag instance * * @see s_theNullTag * @see s_theNullTagData * @see GetTagByNameSafe */CECTag::CECTag(const NullTagConstructorSelector*) :	m_error(0),	m_tagData(s_theNullTagData),	m_tagName(0),	m_dataLen(0),	m_dataType(EC_TAGTYPE_UNKNOWN),	m_dynamic(false),	m_tagList(),	m_haschildren(false){}/** * Creates a new CECTag instance from the given data * * @param name	 TAG name * @param length length of data buffer * @param data	 TAG data * @param copy	 whether to create a copy of the TAG data at \e *data, or should use the provided pointer. * * \note When you set \e copy to \b false, the provided data buffer must exist * in the whole lifetime of the packet. */CECTag::CECTag(ec_tagname_t name, unsigned int length, const void *data, bool copy) : m_tagName(name), m_dynamic(copy), m_haschildren( false ){	m_error = 0;	m_dataLen = length;	if (copy && (data != NULL)) {		m_tagData = malloc(m_dataLen);		if (m_tagData != NULL) {			memcpy((void *)m_tagData, data, m_dataLen);		} else {			m_dataLen = 0;			m_error = 1;		}	} else {		m_tagData = data;	}	m_dataType = EC_TAGTYPE_CUSTOM;}/** * Creates a new CECTag instance for custom data * * @param name	 	TAG name * @param length 	length of data buffer that will be alloc'ed * @param dataptr	pointer to internal TAG data buffer * *  */CECTag::CECTag(ec_tagname_t name, unsigned int length, void **dataptr)  : m_tagName(name), m_dynamic(true), m_haschildren( false ){	m_error = 0;	m_dataLen = length;	m_tagData = malloc(m_dataLen);	if ( !m_tagData ) {		m_dataLen = 0;		m_error = 1;	}	*dataptr = (void *)m_tagData;	m_dataType = EC_TAGTYPE_CUSTOM;}/** * Creates a new CECTag instance, which contains an IPv4 address. * * This function takes care of the endianness of the port number. * * @param name TAG name * @param data The EC_IPv4_t class containing the IPv4 address. * * @see GetIPv4Data() */CECTag::CECTag(ec_tagname_t name, const EC_IPv4_t& data) : m_tagName(name), m_dynamic(true), m_haschildren( false ){	m_dataLen = sizeof(EC_IPv4_t);	m_tagData = malloc(sizeof(EC_IPv4_t));	if (m_tagData != NULL) {		RawPokeUInt32( ((EC_IPv4_t *)m_tagData)->m_ip, RawPeekUInt32( data.m_ip ) );		((EC_IPv4_t *)m_tagData)->m_port = ENDIAN_HTONS(data.m_port);		m_error = 0;		m_dataType = EC_TAGTYPE_IPV4;	} else {		m_error = 1;	}}/** * Creates a new CECTag instance, which contains a MD4 hash. * * This function takes care to store hash in network byte order. * * @param name TAG name * @param data The CMD4Hash class containing the MD4 hash. * * @see GetMD4Data() */CECTag::CECTag(ec_tagname_t name, const CMD4Hash& data) : m_tagName(name), m_dynamic(true), m_haschildren( false ){	m_dataLen = 16;	m_tagData = malloc(16);	if (m_tagData != NULL) {		RawPokeUInt64( (char*)m_tagData,		RawPeekUInt64( data.GetHash() ) );		RawPokeUInt64( (char*)m_tagData + 8,	RawPeekUInt64( data.GetHash() + 8 ) );		m_error = 0;		m_dataType = EC_TAGTYPE_HASH16;	} else {		m_error = 1;	}}/** * Creates a new CECTag instance, which contains a string * * @param name TAG name * @param data wxString object, it's contents are converted to UTF-8. * * @see GetStringDataSTL() */CECTag::CECTag(ec_tagname_t name, const std::string& data) : m_tagName(name), m_dynamic(true), m_haschildren( false ){	ConstructStringTag(name,data);}/** * Creates a new CECTag instance, which contains a string * * @param name TAG name * @param data wxString object, it's contents are converted to UTF-8. * * @see GetStringData() */CECTag::CECTag(ec_tagname_t name, const wxString& data) : m_tagName(name), m_dynamic(true), m_haschildren( false ){	ConstructStringTag(name, (const char*)unicode2UTF8(data));}/** * Copy constructor */CECTag::CECTag(const CECTag& tag) : m_state( tag.m_state ), m_tagName( tag.m_tagName ), m_dynamic( tag.m_dynamic ), m_haschildren( tag.m_haschildren ){	m_error = 0;	m_dataLen = tag.m_dataLen;	m_dataType = tag.m_dataType;	if (m_dataLen != 0) {		if (m_dynamic) {			m_tagData = malloc(m_dataLen);			if (m_tagData != NULL) {				memcpy((void *)m_tagData, tag.m_tagData, m_dataLen);			} else {				m_dataLen = 0;				m_error = 1;				return;			}		} else {			m_tagData = tag.m_tagData;		}	} else m_tagData = NULL;	if (!tag.m_tagList.empty()) {		m_tagList.reserve(tag.m_tagList.size());		for (TagList::size_type i=0; i<tag.m_tagList.size(); i++) {			m_tagList.push_back(tag.m_tagList[i]);			if (m_tagList.back().m_error != 0) {				m_error = m_tagList.back().m_error;#ifndef KEEP_PARTIAL_PACKETS				m_tagList.pop_back();#endif				break;			}		}	}}/** * Creates a new CECTag instance, which contains an int value. * * This takes care of endianness problems with numbers. * * @param name TAG name. * @param data number. * * @see GetInt() */CECTag::CECTag(ec_tagname_t name, uint8 data) : m_tagName(name), m_dynamic(true){	InitInt(data);}CECTag::CECTag(ec_tagname_t name, uint16 data) : m_tagName(name), m_dynamic(true){	InitInt(data);}CECTag::CECTag(ec_tagname_t name, uint32 data) : m_tagName(name), m_dynamic(true){	InitInt(data);}CECTag::CECTag(ec_tagname_t name, uint64 data) : m_tagName(name), m_dynamic(true){	InitInt(data);}void CECTag::InitInt(uint64 data){	if (data <= 0xFF) {		m_dataType = EC_TAGTYPE_UINT8;		m_dataLen = 1;	} else if (data <= 0xFFFF) {		m_dataType = EC_TAGTYPE_UINT16;		m_dataLen = 2;	} else if (data <= 0xFFFFFFFF) {		m_dataType = EC_TAGTYPE_UINT32;		m_dataLen = 4;	} else {		m_dataType = EC_TAGTYPE_UINT64;		m_dataLen = 8;	}			m_tagData = malloc(m_dataLen);		if (m_tagData != NULL) {		switch (m_dataType) {			case EC_TAGTYPE_UINT8:				PokeUInt8( (void*)m_tagData, (uint8) data );				break;			case EC_TAGTYPE_UINT16:				PokeUInt16( (void*)m_tagData, wxUINT16_SWAP_ALWAYS((uint16) data ));				break;			case EC_TAGTYPE_UINT32:				PokeUInt32( (void*)m_tagData, wxUINT32_SWAP_ALWAYS((uint32) data ));				break;			case EC_TAGTYPE_UINT64:				PokeUInt64( (void*)m_tagData, wxUINT64_SWAP_ALWAYS(data) );				break;			default:				/* WTF?*/				EC_ASSERT(0);				free((void*)m_tagData);				m_error = 1;				return;		}		m_error = 0;	} else {		m_error = 1;	}}/** * Creates a new CECTag instance, which contains a double precision floating point number * * @param name TAG name * @param data double number * * @note The actual data is converted to string representation, because we have not found * yet an effective and safe way to transmit floating point numbers. * * @see GetDoubleData() */CECTag::CECTag(ec_tagname_t name, double data) : m_tagName(name), m_dynamic(true){	std::ostringstream double_str;	double_str << data;	m_dataLen = (ec_taglen_t)strlen(double_str.str().c_str()) + 1;	m_tagData = malloc(m_dataLen);	if (m_tagData != NULL) {		memcpy((void *)m_tagData, double_str.str().c_str(), m_dataLen);		m_dataType = EC_TAGTYPE_DOUBLE;		m_error = 0;	} else {		m_error = 1;	}}/** * Destructor - frees allocated data and deletes child TAGs. */CECTag::~CECTag(void){	if (m_dynamic) free((void *)m_tagData);}/** * Copy assignment operator. * * std::vector uses this, but the compiler-supplied version wouldn't properly * handle m_dynamic and m_tagData.  This wouldn't be necessary if m_tagData * was a smart pointer (Hi, Kry!). */CECTag& CECTag::operator=(const CECTag& rhs){	if (&rhs != this)	{		// This is a trick to reuse the implementation of the copy constructor		// so we don't have to duplicate it here.  temp is constructed as a		// copy of rhs, which properly handles m_dynamic and m_tagData.  Then		// temp's members are swapped for this object's members.  So,		// effectively, this object has been made a copy of rhs, which is the		// point.  Then temp is destroyed as it goes out of scope, so its		// destructor cleans up whatever data used to belong to this object.		CECTag temp(rhs);		std::swap(m_error,	temp.m_error);		std::swap(m_tagData,	temp.m_tagData);		std::swap(m_tagName,	temp.m_tagName);		std::swap(m_dataLen,	temp.m_dataLen);		std::swap(m_dynamic,	temp.m_dynamic);		std::swap(m_tagList,	temp.m_tagList);		std::swap(m_state,	temp.m_state);	}	return *this;}/** * Add a child tag to this one. * * Be very careful that this creates a copy of \e tag. Thus, the following code won't work as expected: * \code * { *	CECPacket *p = new CECPacket(whatever); *	CECTag *t1 = new CECTag(whatever); *	CECTag *t2 = new CECTag(whatever); *	p.AddTag(*t1); *	t1.AddTag(*t2);	// t2 won't be part of p !!! * } * \endcode * * To get the desired results, the above should be replaced with something like: * * \code * { *	CECPacket *p = new CECPacket(whatever); *	CECTag *t1 = new CECTag(whatever); *	CECTag *t2 = new CECTag(whatever); *	t1.AddTag(*t2); *	delete t2;	// we can safely delete t2 here, because t1 holds a copy *	p.AddTag(*t1); *	delete t1;	// now p holds a copy of both t1 and t2 * } * \endcode * * Then why copying? The answer is to enable simplifying the code like this: * * \code * { *	CECPacket *p = new CECPacket(whatever); *	CECTag t1(whatever); *	t1.AddTag(CECTag(whatever));	// t2 is now created on-the-fly *	p.AddTag(t1);	// now p holds a copy of both t1 and t2 * } * \endcode * * @param tag a CECTag class instance to add. * @return \b true on succcess, \b false when an error occured */bool CECTag::AddTag(const CECTag& tag){	// cannot have more than 64k tags	wxASSERT(m_tagList.size() < 0xffff);	m_tagList.push_back(tag);	if (m_tagList.back().m_error == 0) {		return true;	} else {		m_error = m_tagList.back().m_error;#ifndef KEEP_PARTIAL_PACKETS		m_tagList.pop_back();#endif		return false;	}}bool CECTag::ReadFromSocket(CECSocket& socket){	if (m_state == bsName) {		ec_tagname_t tmp_tagName;		if (!socket.ReadNumber(&tmp_tagName, sizeof(ec_tagname_t))) {			m_tagName = 0;			return false;		} else {			m_tagName = tmp_tagName >> 1;			m_haschildren = (tmp_tagName & 0x01) ? true : false;			m_state = bsType;		}	}		if (m_state == bsType) {		ec_tagtype_t type;		if (!socket.ReadNumber(&type, sizeof(ec_tagtype_t))) {			m_dataType = EC_TAGTYPE_UNKNOWN;			return false;		} else {			m_dataType = type;			if (m_haschildren) {				m_state = bsLengthChld;			} else {				m_state = bsLength;			}		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -