/* */ #include "BtBitfieldMessage.h" #include #include "bittorrent_helper.h" #include "util.h" #include "DlAbortEx.h" #include "message.h" #include "Peer.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