/* */ #include "BtExtendedMessage.h" #include #include #include "ExtensionMessage.h" #include "ExtensionMessageFactory.h" #include "bittorrent_helper.h" #include "Peer.h" #include "DlAbortEx.h" #include "message.h" #include "util.h" #include "StringFormat.h" #include "a2functional.h" namespace aria2 { const std::string BtExtendedMessage::NAME("extended"); BtExtendedMessage::BtExtendedMessage (const ExtensionMessageHandle& extensionMessage): SimpleBtMessage(ID, NAME), _extensionMessage(extensionMessage), _msg(0), _msgLength(0) {} BtExtendedMessage::~BtExtendedMessage() { delete [] _msg; } const unsigned char* BtExtendedMessage::getMessage() { if(!_msg) { /** * len --- 2+extpayload.length, 4bytes * id --- 20, 1byte * extmsgid --- extmsgid, 1byte * extpayload --- extpayload, nbytes * total: 6+extpayload.length bytes */ std::string payload = _extensionMessage->getPayload(); _msgLength = 6+payload.size(); _msg = new unsigned char[_msgLength]; bittorrent::createPeerMessageString(_msg, _msgLength, 2+payload.size(), ID); *(_msg+5) = _extensionMessage->getExtensionMessageID(); memcpy(_msg+6, payload.c_str(), payload.size()); } return _msg; } size_t BtExtendedMessage::getMessageLength() { getMessage(); return _msgLength; } bool BtExtendedMessage::sendPredicate() const { return peer->isExtendedMessagingEnabled(); } std::string BtExtendedMessage::toString() const { return strconcat(NAME, " ", _extensionMessage->toString()); } BtExtendedMessageHandle BtExtendedMessage::create(const SharedHandle& factory, const PeerHandle& peer, const unsigned char* data, size_t dataLength) { bittorrent::assertPayloadLengthGreater(1, dataLength, NAME); bittorrent::assertID(ID, data, NAME); assert(!factory.isNull()); ExtensionMessageHandle extmsg = factory->createMessage(data+1, dataLength-1); BtExtendedMessageHandle message(new BtExtendedMessage(extmsg)); return message; } void BtExtendedMessage::doReceivedAction() { if(!_extensionMessage.isNull()) { _extensionMessage->doReceivedAction(); } } } // namespace aria2