/* */ #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"); void BtBitfieldMessage::setBitfield(const unsigned char* bitfield, size_t bitfieldLength) { if(this->bitfield == bitfield) { return; } delete [] this->bitfield; this->bitfieldLength = bitfieldLength; this->bitfield = new unsigned char[this->bitfieldLength]; memcpy(this->bitfield, bitfield, this->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(_metadataGetMode) { return; } pieceStorage->updatePieceStats(bitfield, bitfieldLength, peer->getBitfield()); peer->setBitfield(bitfield, bitfieldLength); if(peer->isSeeder() && pieceStorage->downloadFinished()) { throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER); } } const unsigned char* BtBitfieldMessage::getMessage() { if(!msg) { /** * len --- 1+bitfieldLength, 4bytes * id --- 5, 1byte * bitfield --- bitfield, len bytes * total: 5+len bytes */ msgLength = 5+bitfieldLength; msg = new unsigned char[msgLength]; bittorrent::createPeerMessageString(msg, msgLength, 1+bitfieldLength, ID); memcpy(msg+5, bitfield, bitfieldLength); } return msg; } size_t BtBitfieldMessage::getMessageLength() { getMessage(); return msgLength; } std::string BtBitfieldMessage::toString() const { return strconcat(NAME, " ", util::toHex(bitfield, bitfieldLength)); } } // namespace aria2