Use std::unique_ptr instead of array_ptr

pull/103/head
Tatsuhiro Tsujikawa 2013-07-03 23:23:22 +09:00
parent df0034f1cd
commit 7e6db8d801
11 changed files with 81 additions and 150 deletions

View File

@ -214,16 +214,13 @@ void BtPieceMessage::send()
void BtPieceMessage::pushPieceData(int64_t offset, int32_t length) const
{
assert(length <= 16*1024);
array_ptr<unsigned char> buf
(new unsigned char[length+MESSAGE_HEADER_LENGTH]);
createMessageHeader(buf);
auto buf = make_unique<unsigned char[]>(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<PieceSendUpdate>
(getPeer(), MESSAGE_HEADER_LENGTH));
// To avoid upload rate overflow, we update the length here at

View File

@ -242,18 +242,17 @@ void DefaultBtProgressInfoFile::load()
throw DL_ABORT_EX(fmt("Invalid info hash length: %d", infoHashLength));
}
if(infoHashLength > 0) {
array_ptr<unsigned char> savedInfoHash(new unsigned char[infoHashLength]);
READ_CHECK(fp, static_cast<unsigned char*>(savedInfoHash),
infoHashLength);
auto savedInfoHash = make_unique<unsigned char[]>((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<unsigned char> savedBitfield(new unsigned char[bitfieldLength]);
READ_CHECK(fp, static_cast<unsigned char*>(savedBitfield),
bitfieldLength);
auto savedBitfield = make_unique<unsigned char[]>((size_t)bitfieldLength);
READ_CHECK(fp, savedBitfield.get(), bitfieldLength);
if(pieceLength == static_cast<uint32_t>(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<unsigned long>(piece->getBitfieldLength()),
bitfieldLength));
}
array_ptr<unsigned char> pieceBitfield
(new unsigned char[bitfieldLength]);
READ_CHECK(fp, static_cast<unsigned char*>(pieceBitfield),
bitfieldLength);
piece->setBitfield(pieceBitfield, bitfieldLength);
auto pieceBitfield = make_unique<unsigned char[]>
((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

View File

@ -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<unsigned char> misbitfield(new unsigned char[mislen]);
auto misbitfield = make_unique<unsigned char[]>(mislen);
piece->getAllMissingBlockIndexes(misbitfield, mislen);
piece->getAllMissingBlockIndexes(misbitfield.get(), mislen);
auto missingBlockIndexes = std::vector<size_t>{};
size_t blockIndex = 0;

View File

@ -185,12 +185,12 @@ void DefaultPieceStorage::getMissingPiece
cuid_t cuid)
{
const size_t mislen = bitfieldMan_->getBitfieldLength();
array_ptr<unsigned char> misbitfield(new unsigned char[mislen]);
auto misbitfield = make_unique<unsigned char[]>(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;

View File

@ -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<unsigned char> bufp(buf);
dh_->getPublicKey(buf, KEY_LENGTH);
auto buf = make_unique<unsigned char[]>(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<unsigned char[]>((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<unsigned char[]>((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<unsigned char> bufp(buffer);
unsigned char* ptr = buffer;
auto buffer = make_unique<unsigned char[]>(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<unsigned char> bufp(buffer);
unsigned char* ptr = buffer;
auto buffer = make_unique<unsigned char[]>(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)

View File

@ -186,10 +186,9 @@ void MessageDigest::digest(unsigned char* md)
std::string MessageDigest::digest()
{
size_t length = pImpl_->getDigestLength();
array_ptr<unsigned char> buf(new unsigned char[length]);
pImpl_->digest(buf);
std::string hd(&buf[0], &buf[length]);
return hd;
auto buf = make_unique<unsigned char[]>(length);
pImpl_->digest(buf.get());
return std::string(&buf[0], &buf[length]);
}
} // namespace aria2

View File

@ -152,11 +152,11 @@ void OptionParser::parseArg
size_t numPublicOption = countPublicOption(handlers_.begin(),
handlers_.end());
int lopt;
array_ptr<struct option> longOpts(new struct option[numPublicOption+1]);
putOptions(longOpts, &lopt, handlers_.begin(), handlers_.end());
auto longOpts = make_unique<struct option[]>(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;
}

View File

@ -186,6 +186,12 @@ std::unique_ptr<T> make_unique(U&&... u)
return std::unique_ptr<T>(new T(std::forward<U>(u)...));
}
template<typename T>
std::unique_ptr<T> make_unique(size_t size)
{
return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
}
} // namespace aria2
#endif // D_A2_FUNCTIONAL_H

View File

@ -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<typename T>
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<typename S>
array_ptr& operator=(const array_ptr<S>& 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<typename T, size_t N>
class array_wrapper {
private:

View File

@ -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<wchar_t> buf(new wchar_t[len]);
len = utf8ToWChar(buf, len, src);
if(len == 0) {
auto buf = make_unique<wchar_t[]>((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<char> buf(new char[len]);
len = wCharToAnsi(buf, len, wsrc.c_str());
if(len == 0) {
auto buf = make_unique<char[]>((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<char> buf(new char[len]);
len = wCharToUtf8(buf, len, wsrc.c_str());
if(len == 0) {
auto buf = make_unique<char[]>((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<wchar_t> buf(new wchar_t[len]);
len = ansiToWChar(buf, len, src.c_str());
if(len == 0) {
auto buf = make_unique<wchar_t[]>((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<wchar_t> wcharCmdline(new wchar_t[cmdlineLen]);
cmdlineLen = utf8ToWChar(wcharCmdline, cmdlineLen, cmdline.c_str());
auto wcharCmdline = std::unique_ptr<wchar_t[]>(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,

View File

@ -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<struct array_funTest::X>& 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<struct X> 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<int, 10>& array)
{