diff --git a/src/BtPieceMessage.cc b/src/BtPieceMessage.cc index 5abc35dc..fb57a171 100644 --- a/src/BtPieceMessage.cc +++ b/src/BtPieceMessage.cc @@ -214,16 +214,13 @@ void BtPieceMessage::send() void BtPieceMessage::pushPieceData(int64_t offset, int32_t length) const { assert(length <= 16*1024); - array_ptr buf - (new unsigned char[length+MESSAGE_HEADER_LENGTH]); - createMessageHeader(buf); + auto buf = make_unique(length+MESSAGE_HEADER_LENGTH); + createMessageHeader(buf.get()); ssize_t r; - r = getPieceStorage()->getDiskAdaptor()->readData(buf+MESSAGE_HEADER_LENGTH, - length, offset); + r = getPieceStorage()->getDiskAdaptor()->readData + (buf.get()+MESSAGE_HEADER_LENGTH, length, offset); if(r == length) { - unsigned char* dbuf = buf; - buf.reset(0); - getPeerConnection()->pushBytes(dbuf, length+MESSAGE_HEADER_LENGTH, + getPeerConnection()->pushBytes(buf.release(), length+MESSAGE_HEADER_LENGTH, make_unique (getPeer(), MESSAGE_HEADER_LENGTH)); // To avoid upload rate overflow, we update the length here at diff --git a/src/DefaultBtProgressInfoFile.cc b/src/DefaultBtProgressInfoFile.cc index 5f5c2ca9..ed5fd8f8 100644 --- a/src/DefaultBtProgressInfoFile.cc +++ b/src/DefaultBtProgressInfoFile.cc @@ -242,18 +242,17 @@ void DefaultBtProgressInfoFile::load() throw DL_ABORT_EX(fmt("Invalid info hash length: %d", infoHashLength)); } if(infoHashLength > 0) { - array_ptr savedInfoHash(new unsigned char[infoHashLength]); - READ_CHECK(fp, static_cast(savedInfoHash), - infoHashLength); + auto savedInfoHash = make_unique((size_t)infoHashLength); + READ_CHECK(fp, savedInfoHash.get(), infoHashLength); #ifdef ENABLE_BITTORRENT if(infoHashCheckEnabled) { const unsigned char* infoHash = bittorrent::getInfoHash(dctx_); if(infoHashLength != INFO_HASH_LENGTH || - memcmp(savedInfoHash, infoHash, INFO_HASH_LENGTH) != 0) { + memcmp(savedInfoHash.get(), infoHash, INFO_HASH_LENGTH) != 0) { throw DL_ABORT_EX (fmt("info hash mismatch. expected: %s, actual: %s", util::toHex(infoHash, INFO_HASH_LENGTH).c_str(), - util::toHex(savedInfoHash, infoHashLength).c_str() + util::toHex(savedInfoHash.get(), infoHashLength).c_str() )); } } @@ -302,11 +301,10 @@ void DefaultBtProgressInfoFile::load() bitfieldLength)); } - array_ptr savedBitfield(new unsigned char[bitfieldLength]); - READ_CHECK(fp, static_cast(savedBitfield), - bitfieldLength); + auto savedBitfield = make_unique((size_t)bitfieldLength); + READ_CHECK(fp, savedBitfield.get(), bitfieldLength); if(pieceLength == static_cast(dctx_->getPieceLength())) { - pieceStorage_->setBitfield(savedBitfield, bitfieldLength); + pieceStorage_->setBitfield(savedBitfield.get(), bitfieldLength); uint32_t numInFlightPiece; READ_CHECK(fp, &numInFlightPiece, sizeof(numInFlightPiece)); @@ -345,11 +343,10 @@ void DefaultBtProgressInfoFile::load() static_cast(piece->getBitfieldLength()), bitfieldLength)); } - array_ptr pieceBitfield - (new unsigned char[bitfieldLength]); - READ_CHECK(fp, static_cast(pieceBitfield), - bitfieldLength); - piece->setBitfield(pieceBitfield, bitfieldLength); + auto pieceBitfield = make_unique + ((size_t)bitfieldLength); + READ_CHECK(fp, pieceBitfield.get(), bitfieldLength); + piece->setBitfield(pieceBitfield.get(), bitfieldLength); #ifdef ENABLE_MESSAGE_DIGEST @@ -367,7 +364,7 @@ void DefaultBtProgressInfoFile::load() numInFlightPiece = ntohl(numInFlightPiece); } BitfieldMan src(pieceLength, totalLength); - src.setBitfield(savedBitfield, bitfieldLength); + src.setBitfield(savedBitfield.get(), bitfieldLength); if((src.getCompletedLength() || numInFlightPiece) && !option_->getAsBool(PREF_ALLOW_PIECE_LENGTH_CHANGE)) { throw DOWNLOAD_FAILURE_EXCEPTION2 diff --git a/src/DefaultBtRequestFactory.cc b/src/DefaultBtRequestFactory.cc index 277f28b7..a7cd4838 100644 --- a/src/DefaultBtRequestFactory.cc +++ b/src/DefaultBtRequestFactory.cc @@ -197,9 +197,9 @@ DefaultBtRequestFactory::createRequestMessagesOnEndGame(size_t max) itr != eoi && requests.size() < max; ++itr) { auto& piece = *itr; const size_t mislen = piece->getBitfieldLength(); - array_ptr misbitfield(new unsigned char[mislen]); + auto misbitfield = make_unique(mislen); - piece->getAllMissingBlockIndexes(misbitfield, mislen); + piece->getAllMissingBlockIndexes(misbitfield.get(), mislen); auto missingBlockIndexes = std::vector{}; size_t blockIndex = 0; diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc index cee96df9..9fc33367 100644 --- a/src/DefaultPieceStorage.cc +++ b/src/DefaultPieceStorage.cc @@ -185,12 +185,12 @@ void DefaultPieceStorage::getMissingPiece cuid_t cuid) { const size_t mislen = bitfieldMan_->getBitfieldLength(); - array_ptr misbitfield(new unsigned char[mislen]); + auto misbitfield = make_unique(mislen); size_t blocks = bitfieldMan_->countBlock(); size_t misBlock = 0; if(isEndGame()) { bool r = bitfieldMan_->getAllMissingIndexes - (misbitfield, mislen, bitfield, length); + (misbitfield.get(), mislen, bitfield, length); if(!r) { return; } @@ -214,15 +214,15 @@ void DefaultPieceStorage::getMissingPiece } } else { bool r = bitfieldMan_->getAllMissingUnusedIndexes - (misbitfield, mislen, bitfield, length); + (misbitfield.get(), mislen, bitfield, length); if(!r) { return; } while(misBlock < minMissingBlocks) { size_t index; - if(pieceSelector_->select(index, misbitfield, blocks)) { + if(pieceSelector_->select(index, misbitfield.get(), blocks)) { pieces.push_back(checkOutPiece(index, cuid)); - bitfield::flipBit(misbitfield, blocks, index); + bitfield::flipBit(misbitfield.get(), blocks, index); misBlock += pieces.back()->countMissingBlock(); } else { break; diff --git a/src/MSEHandshake.cc b/src/MSEHandshake.cc index a6e43f21..332e8cfa 100644 --- a/src/MSEHandshake.cc +++ b/src/MSEHandshake.cc @@ -128,15 +128,13 @@ void MSEHandshake::sendPublicKey() { A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Sending public key.", cuid_)); - unsigned char* buf = new unsigned char[KEY_LENGTH+MAX_PAD_LENGTH]; - array_ptr bufp(buf); - dh_->getPublicKey(buf, KEY_LENGTH); + auto buf = make_unique(KEY_LENGTH+MAX_PAD_LENGTH); + dh_->getPublicKey(buf.get(), KEY_LENGTH); size_t padLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1); - dh_->generateNonce(buf+KEY_LENGTH, padLength); - socketBuffer_.pushBytes(buf, KEY_LENGTH+padLength); - bufp.reset(0); + dh_->generateNonce(buf.get()+KEY_LENGTH, padLength); + socketBuffer_.pushBytes(buf.release(), KEY_LENGTH+padLength); } void MSEHandshake::read() @@ -271,23 +269,23 @@ void MSEHandshake::sendInitiatorStep2() { A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Sending negotiation step2.", cuid_)); // Assuming no exception - unsigned char* md = new unsigned char[20]; - createReq1Hash(md); - socketBuffer_.pushBytes(md, 20); + auto md = make_unique((size_t)20); + createReq1Hash(md.get()); + socketBuffer_.pushBytes(md.release(), 20); // Assuming no exception - md = new unsigned char[20]; - createReq23Hash(md, infoHash_); - socketBuffer_.pushBytes(md, 20); + md = make_unique((size_t)20); + createReq23Hash(md.get(), infoHash_); + socketBuffer_.pushBytes(md.release(), 20); // buffer is filled in this order: // VC(VC_LENGTH bytes), // crypto_provide(CRYPTO_BITFIELD_LENGTH bytes), // len(padC)(2 bytes), // padC(len(padC) bytes <= MAX_PAD_LENGTH), // len(IA)(2 bytes) - unsigned char* buffer = new unsigned char - [40+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH+2]; - array_ptr bufp(buffer); - unsigned char* ptr = buffer; + auto buffer = make_unique(40+VC_LENGTH+ + CRYPTO_BITFIELD_LENGTH+2+ + MAX_PAD_LENGTH+2); + unsigned char* ptr = buffer.get(); // VC memcpy(ptr, VC, sizeof(VC)); ptr += sizeof(VC); @@ -317,8 +315,8 @@ void MSEHandshake::sendInitiatorStep2() memcpy(ptr, &iaLengthBE, sizeof(iaLengthBE)); } ptr += 2; - encryptAndSendData(buffer, ptr-buffer); - bufp.reset(0); + size_t buflen = ptr-buffer.get(); + encryptAndSendData(buffer.release(), buflen); } // This function reads exactly until the end of VC marker is reached. @@ -522,10 +520,10 @@ void MSEHandshake::sendReceiverStep2() // cryptoSelect(CRYPTO_BITFIELD_LENGTH bytes), // len(padD)(2bytes), // padD(len(padD)bytes <= MAX_PAD_LENGTH) - unsigned char* buffer = new unsigned char - [VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH]; - array_ptr bufp(buffer); - unsigned char* ptr = buffer; + auto buffer = make_unique(VC_LENGTH+ + CRYPTO_BITFIELD_LENGTH+2+ + MAX_PAD_LENGTH); + unsigned char* ptr = buffer.get(); // VC memcpy(ptr, VC, sizeof(VC)); ptr += sizeof(VC); @@ -542,8 +540,8 @@ void MSEHandshake::sendReceiverStep2() // padD, all zeroed memset(ptr, 0, padDLength); ptr += padDLength; - encryptAndSendData(buffer, ptr-buffer); - bufp.reset(0); + size_t buflen = ptr - buffer.get(); + encryptAndSendData(buffer.release(), buflen); } uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const char* padName) diff --git a/src/MessageDigest.cc b/src/MessageDigest.cc index 01189c7f..725c56c8 100644 --- a/src/MessageDigest.cc +++ b/src/MessageDigest.cc @@ -186,10 +186,9 @@ void MessageDigest::digest(unsigned char* md) std::string MessageDigest::digest() { size_t length = pImpl_->getDigestLength(); - array_ptr buf(new unsigned char[length]); - pImpl_->digest(buf); - std::string hd(&buf[0], &buf[length]); - return hd; + auto buf = make_unique(length); + pImpl_->digest(buf.get()); + return std::string(&buf[0], &buf[length]); } } // namespace aria2 diff --git a/src/OptionParser.cc b/src/OptionParser.cc index bf472ba2..bcb900cb 100644 --- a/src/OptionParser.cc +++ b/src/OptionParser.cc @@ -152,11 +152,11 @@ void OptionParser::parseArg size_t numPublicOption = countPublicOption(handlers_.begin(), handlers_.end()); int lopt; - array_ptr longOpts(new struct option[numPublicOption+1]); - putOptions(longOpts, &lopt, handlers_.begin(), handlers_.end()); + auto longOpts = make_unique(numPublicOption+1); + putOptions(longOpts.get(), &lopt, handlers_.begin(), handlers_.end()); std::string optstring = createOptstring(handlers_.begin(), handlers_.end()); while(1) { - int c = getopt_long(argc, argv, optstring.c_str(), longOpts, 0); + int c = getopt_long(argc, argv, optstring.c_str(), longOpts.get(), 0); if(c == -1) { break; } diff --git a/src/a2functional.h b/src/a2functional.h index dc13a443..11391e51 100644 --- a/src/a2functional.h +++ b/src/a2functional.h @@ -186,6 +186,12 @@ std::unique_ptr make_unique(U&&... u) return std::unique_ptr(new T(std::forward(u)...)); } +template +std::unique_ptr make_unique(size_t size) +{ + return std::unique_ptr(new typename std::remove_extent::type[size]()); +} + } // namespace aria2 #endif // D_A2_FUNCTIONAL_H diff --git a/src/array_fun.h b/src/array_fun.h index ed562ed8..b8054c36 100644 --- a/src/array_fun.h +++ b/src/array_fun.h @@ -53,45 +53,6 @@ char (&char_array_ref_fun(T (&)[0u]))[0u]; // To calculate size of array at compile time, we use macro here. #define A2_ARRAY_LEN(X) sizeof(char_array_ref_fun(X)) -template -class array_ptr { -private: - T* array_; - - // Copies are not allowed. Let's make them private. - array_ptr(const array_ptr& s); - - array_ptr& operator=(const array_ptr& s); - - template - array_ptr& operator=(const array_ptr& s); - -public: - array_ptr():array_(0) {} - - explicit array_ptr(T* array):array_(array) {} - - ~array_ptr() - { - delete [] array_; - } - - operator T*() - { - return array_; - } - - operator const T*() const - { - return array_; - } - - void reset(T* array) - { - array_ = array; - } -}; - template class array_wrapper { private: diff --git a/src/util.cc b/src/util.cc index b59fecbc..a671447d 100644 --- a/src/util.cc +++ b/src/util.cc @@ -129,16 +129,15 @@ int wCharToAnsi(char* out, size_t outLength, const wchar_t* src) std::wstring utf8ToWChar(const char* src) { int len = utf8ToWChar(0, 0, src); - if(len == 0) { + if(len <= 0) { abort(); } - array_ptr buf(new wchar_t[len]); - len = utf8ToWChar(buf, len, src); - if(len == 0) { + auto buf = make_unique((size_t)len); + len = utf8ToWChar(buf.get(), len, src); + if(len <= 0) { abort(); } else { - std::wstring dest(buf); - return dest; + return buf.get(); } } @@ -151,47 +150,45 @@ std::string utf8ToNative(const std::string& src) { std::wstring wsrc = utf8ToWChar(src); int len = wCharToAnsi(0, 0, wsrc.c_str()); - if(len == 0) { + if(len <= 0) { abort(); } - array_ptr buf(new char[len]); - len = wCharToAnsi(buf, len, wsrc.c_str()); - if(len == 0) { + auto buf = make_unique((size_t)len); + len = wCharToAnsi(buf.get(), len, wsrc.c_str()); + if(len <= 0) { abort(); } else { - std::string dest(buf); - return dest; + return buf.get(); } } std::string wCharToUtf8(const std::wstring& wsrc) { int len = wCharToUtf8(0, 0, wsrc.c_str()); - if(len == 0) { + if(len <= 0) { abort(); } - array_ptr buf(new char[len]); - len = wCharToUtf8(buf, len, wsrc.c_str()); - if(len == 0) { + auto buf = make_unique((size_t)len); + len = wCharToUtf8(buf.get(), len, wsrc.c_str()); + if(len <= 0) { abort(); } else { - std::string dest(buf); - return dest; + return buf.get(); } } std::string nativeToUtf8(const std::string& src) { int len = ansiToWChar(0, 0, src.c_str()); - if(len == 0) { + if(len <= 0) { abort(); } - array_ptr buf(new wchar_t[len]); - len = ansiToWChar(buf, len, src.c_str()); - if(len == 0) { + auto buf = make_unique((size_t)len); + len = ansiToWChar(buf.get(), len, src.c_str()); + if(len <= 0) { abort(); } else { - return wCharToUtf8(std::wstring(buf)); + return wCharToUtf8(std::wstring(buf.get())); } } #endif // __MINGW32__ @@ -1770,12 +1767,12 @@ void executeHook } int cmdlineLen = utf8ToWChar(0, 0, cmdline.c_str()); assert(cmdlineLen > 0); - array_ptr wcharCmdline(new wchar_t[cmdlineLen]); - cmdlineLen = utf8ToWChar(wcharCmdline, cmdlineLen, cmdline.c_str()); + auto wcharCmdline = std::unique_ptr(new wchar_t[cmdlineLen]); + cmdlineLen = utf8ToWChar(wcharCmdline.get(), cmdlineLen, cmdline.c_str()); assert(cmdlineLen > 0); A2_LOG_INFO(fmt("Executing user command: %s", cmdline.c_str())); DWORD rc = CreateProcessW(batch ? utf8ToWChar(cmdexe).c_str() : NULL, - wcharCmdline, + wcharCmdline.get(), NULL, NULL, true, diff --git a/test/array_funTest.cc b/test/array_funTest.cc index 1158d577..ae796c8c 100644 --- a/test/array_funTest.cc +++ b/test/array_funTest.cc @@ -11,7 +11,6 @@ class array_funTest:public CppUnit::TestFixture { CPPUNIT_TEST(testArray_negate); CPPUNIT_TEST(testArray_and); CPPUNIT_TEST(testArrayLength); - CPPUNIT_TEST(testArrayPtr); CPPUNIT_TEST(testArrayWrapper); CPPUNIT_TEST_SUITE_END(); @@ -21,7 +20,6 @@ public: void testArray_negate(); void testArray_and(); void testArrayLength(); - void testArrayPtr(); void testArrayWrapper(); struct X{ @@ -70,15 +68,6 @@ void array_funTest::testArrayLength() // CPPUNIT_ASSERT_EQUAL((size_t)0, A2_ARRAY_LEN(zeroLengthArray)); } -namespace { -// Check operator[] in const context. -void arrayPtrConst(const array_ptr& ax) -{ - CPPUNIT_ASSERT_EQUAL(100, ax[3].m); - CPPUNIT_ASSERT_EQUAL(99, ax[2].m); -} -} // namespace - namespace { void arrayPtrCast(struct array_funTest::X* x) {} } // namespace @@ -87,19 +76,6 @@ namespace { void arrayPtrConstCast(const struct array_funTest::X* x) {} } // namespace -void array_funTest::testArrayPtr() -{ - array_ptr ax(new struct X[10]); - ax[3].m = 100; - ax[2].m = 99; - CPPUNIT_ASSERT_EQUAL(100, ax[3].m); - CPPUNIT_ASSERT_EQUAL(99, ax[2].m); - arrayPtrConst(ax); - - arrayPtrCast(ax); - arrayPtrConstCast(ax); -} - namespace { void arrayWrapperConst(const array_wrapper& array) {