/* */ #include "BtBitfieldMessage.h" #include #include "bittorrent_helper.h" #include "util.h" #include "DlAbortEx.h" #include "message.h" #include "Peer.h" #include "StringFormat.h" #include "PieceStorage.h" #include "a2functional.h" namespace aria2 { const std::string BtBitfieldMessage::NAME("bitfield"); BtBitfieldMessage::BtBitfieldMessage():SimpleBtMessage(ID, NAME), _bitfield(0), _bitfieldLength(0) {} BtBitfieldMessage::BtBitfieldMessage (const unsigned char* bitfield, size_t bitfieldLength): SimpleBtMessage(ID, NAME), _bitfield(0), _bitfieldLength(0) { setBitfield(bitfield, bitfieldLength); } BtBitfieldMessage::~BtBitfieldMessage() { delete [] _bitfield; } void BtBitfieldMessage::setBitfield (const unsigned char* bitfield, size_t bitfieldLength) { if(_bitfield == bitfield) { return; } delete [] _bitfield; _bitfieldLength = bitfieldLength; _bitfield = new unsigned char[_bitfieldLength]; memcpy(_bitfield, bitfield, _bitfieldLength); } BtBitfieldMessageHandle BtBitfieldMessage::create(const unsigned char* data, size_t dataLength) { bittorrent::assertPayloadLengthGreater(1,dataLength, NAME); bittorrent::assertID(ID, data, NAME); BtBitfieldMessageHandle message(new BtBitfieldMessage()); message->setBitfield(data+1, dataLength-1); return message; } void BtBitfieldMessage::doReceivedAction() { if(isMetadataGetMode()) { return; } getPieceStorage()->updatePieceStats(_bitfield, _bitfieldLength, getPeer()->getBitfield()); getPeer()->setBitfield(_bitfield, _bitfieldLength); if(getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) { throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER); } } unsigned char* BtBitfieldMessage::createMessage() { /** * len --- 1+bitfieldLength, 4bytes * id --- 5, 1byte * bitfield --- bitfield, len bytes * total: 5+len bytes */ const size_t msgLength = 5+_bitfieldLength; unsigned char* msg = new unsigned char[msgLength]; bittorrent::createPeerMessageString(msg, msgLength, 1+_bitfieldLength, ID); memcpy(msg+5, _bitfield, _bitfieldLength); return msg; } size_t BtBitfieldMessage::getMessageLength() { return 5+_bitfieldLength; } std::string BtBitfieldMessage::toString() const { return strconcat(NAME, " ", util::toHex(_bitfield, _bitfieldLength)); } } // namespace aria2