From 3443349fc3ea9b99a796bf4f2835950f75de729a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 14 May 2016 19:50:58 +0900 Subject: Refactor --- src/DHTGetPeersReplyMessage.cc | 43 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/DHTGetPeersReplyMessage.cc b/src/DHTGetPeersReplyMessage.cc index 80464810..2ae92f3b 100644 --- a/src/DHTGetPeersReplyMessage.cc +++ b/src/DHTGetPeersReplyMessage.cc @@ -35,6 +35,7 @@ #include "DHTGetPeersReplyMessage.h" #include +#include #include "DHTNode.h" #include "DHTBucket.h" @@ -81,24 +82,24 @@ std::unique_ptr DHTGetPeersReplyMessage::getResponse() rDict->put(TOKEN, token_); // TODO want parameter if (!closestKNodes_.empty()) { - unsigned char buffer[DHTBucket::K * 38]; - const int clen = bittorrent::getCompactLength(family_); - const int unit = clen + 20; - size_t offset = 0; + std::array buffer; + const auto clen = bittorrent::getCompactLength(family_); + const auto unit = clen + DHT_ID_LENGTH; + auto last = std::begin(buffer); size_t k = 0; - for (auto i = std::begin(closestKNodes_), eoi = std::end(closestKNodes_); - i != eoi && k < DHTBucket::K; ++i) { - memcpy(buffer + offset, (*i)->getID(), DHT_ID_LENGTH); - unsigned char compact[COMPACT_LEN_IPV6]; - int compactlen = bittorrent::packcompact(compact, (*i)->getIPAddress(), - (*i)->getPort()); + for (auto i = std::begin(closestKNodes_); + i != std::end(closestKNodes_) && k < DHTBucket::K; ++i) { + std::array compact; + auto compactlen = bittorrent::packcompact( + compact.data(), (*i)->getIPAddress(), (*i)->getPort()); if (compactlen == clen) { - memcpy(buffer + 20 + offset, compact, compactlen); - offset += unit; + last = std::copy_n((*i)->getID(), DHT_ID_LENGTH, last); + last = std::copy_n(std::begin(compact), compactlen, last); ++k; } } - rDict->put(family_ == AF_INET ? NODES : NODES6, String::g(buffer, offset)); + rDict->put(family_ == AF_INET ? NODES : NODES6, + String::g(std::begin(buffer), last)); } if (!values_.empty()) { // Limit the size of values list. The maximum size of UDP datagram @@ -123,16 +124,16 @@ std::unique_ptr DHTGetPeersReplyMessage::getResponse() // doesn't specify the maximum size of token, reply message // template may get bigger than 395 bytes. So we use 25 as maximum // number of peer info that a message can carry. - static const size_t MAX_VALUES_SIZE = 25; + constexpr size_t MAX_VALUES_SIZE = 25; auto valuesList = List::g(); - for (auto i = std::begin(values_), eoi = std::end(values_); - i != eoi && valuesList->size() < MAX_VALUES_SIZE; ++i) { - unsigned char compact[COMPACT_LEN_IPV6]; - const int clen = bittorrent::getCompactLength(family_); - int compactlen = bittorrent::packcompact(compact, (*i)->getIPAddress(), - (*i)->getPort()); + for (auto i = std::begin(values_); + i != std::end(values_) && valuesList->size() < MAX_VALUES_SIZE; ++i) { + std::array compact; + const auto clen = bittorrent::getCompactLength(family_); + auto compactlen = bittorrent::packcompact( + compact.data(), (*i)->getIPAddress(), (*i)->getPort()); if (compactlen == clen) { - valuesList->append(String::g(compact, compactlen)); + valuesList->append(String::g(compact.data(), compactlen)); } } rDict->put(VALUES, std::move(valuesList)); -- cgit From 6976ffed9e96ccc70f161aa5a38abddaf9d9befe Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 17:58:01 +0900 Subject: Adjust chromium cookie time --- src/Sqlite3CookieParserImpl.cc | 9 +++++++-- test/chromium_cookies.sqlite | Bin 3072 -> 3072 bytes 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Sqlite3CookieParserImpl.cc b/src/Sqlite3CookieParserImpl.cc index 5d1ce849..751ead1c 100644 --- a/src/Sqlite3CookieParserImpl.cc +++ b/src/Sqlite3CookieParserImpl.cc @@ -59,8 +59,13 @@ Sqlite3ChromiumCookieParser::~Sqlite3ChromiumCookieParser() {} const char* Sqlite3ChromiumCookieParser::getQuery() const { - return "SELECT host_key, path, secure, expires_utc, name, value, " - "last_access_utc" + // chrome's time is microsecond resolution, and its epoc is Jan 1 + // 00:00:00 +0000 1601, so we have to convert it to second from UNIX + // epoc. 11644473600 is the second between chrome's epoc and UNIX + // epoc. e.g., date +%s -d 'Jan 1 00:00:00 +0000 1601' + return "SELECT host_key, path, secure, expires_utc / 1000000 - 11644473600 " + "as expires_utc, name, value, " + "last_access_utc / 1000000 - 11644473600 as last_access_utc" " FROM cookies"; } diff --git a/test/chromium_cookies.sqlite b/test/chromium_cookies.sqlite index c3e98fc8..e653715b 100644 Binary files a/test/chromium_cookies.sqlite and b/test/chromium_cookies.sqlite differ -- cgit From bafbbe7c1d5ea39e67e233f9c32975fda7843874 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 18:40:50 +0900 Subject: Allow subsecond value in ns cookie.txt file's expiry time field --- src/NsCookieParser.cc | 11 ++++++++--- src/util.cc | 27 +++++++++++++++++++++++++++ src/util.h | 4 ++++ test/CookieStorageTest.cc | 4 ++-- test/NsCookieParserTest.cc | 4 ++-- test/UtilTest2.cc | 19 +++++++++++++++++++ test/nscookietest.txt | 4 ++-- 7 files changed, 64 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/NsCookieParser.cc b/src/NsCookieParser.cc index e484df8e..77ca25ab 100644 --- a/src/NsCookieParser.cc +++ b/src/NsCookieParser.cc @@ -69,9 +69,14 @@ std::unique_ptr parseNsCookie(const std::string& cookieStr, return nullptr; } int64_t expiryTime; - if (!util::parseLLIntNoThrow(expiryTime, - std::string(vs[4].first, vs[4].second))) { - return nullptr; + { + // chrome extension uses subsecond resolution for expiry time. + double expiryTimeDouble; + if (!util::parseDoubleNoThrow(expiryTimeDouble, + std::string(vs[4].first, vs[4].second))) { + return nullptr; + } + expiryTime = static_cast(expiryTimeDouble); } if (std::numeric_limits::max() < expiryTime) { expiryTime = std::numeric_limits::max(); diff --git a/src/util.cc b/src/util.cc index a2590235..3c9c19b1 100644 --- a/src/util.cc +++ b/src/util.cc @@ -596,6 +596,33 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base) } } +bool parseDoubleNoThrow(double& res, const std::string& s) +{ + if (s.empty()) { + return false; + } + + errno = 0; + char* endptr; + auto d = strtod(s.c_str(), &endptr); + + if (errno == ERANGE) { + return false; + } + + if (endptr != s.c_str() + s.size()) { + for (auto i = std::begin(s) + (endptr - s.c_str()); i != std::end(s); ++i) { + if (!isspace(*i)) { + return false; + } + } + } + + res = d; + + return true; +} + SegList parseIntSegments(const std::string& src) { SegList sgl; diff --git a/src/util.h b/src/util.h index 25183b5c..76ecb549 100644 --- a/src/util.h +++ b/src/util.h @@ -280,6 +280,10 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base = 10); bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base = 10); +// Parses |s| as floating point number, and stores the result into +// |res|. This function returns true if it succeeds. +bool parseDoubleNoThrow(double& res, const std::string& s); + SegList parseIntSegments(const std::string& src); // Parses string which specifies the range of piece index for higher diff --git a/test/CookieStorageTest.cc b/test/CookieStorageTest.cc index b9e741b6..a9966a64 100644 --- a/test/CookieStorageTest.cc +++ b/test/CookieStorageTest.cc @@ -328,10 +328,10 @@ void CookieStorageTest::testLoad() c = cookies[3]; CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName()); CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue()); - CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime()); + CPPUNIT_ASSERT_EQUAL((time_t)1463304912, c->getExpiryTime()); CPPUNIT_ASSERT(c->getPersistent()); CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath()); - CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain()); CPPUNIT_ASSERT(!c->getSecure()); } diff --git a/test/NsCookieParserTest.cc b/test/NsCookieParserTest.cc index 45d81004..23fb4016 100644 --- a/test/NsCookieParserTest.cc +++ b/test/NsCookieParserTest.cc @@ -69,9 +69,9 @@ void NsCookieParserTest::testParse() c = cookies[3].get(); CPPUNIT_ASSERT_EQUAL(std::string("TAX"), c->getName()); CPPUNIT_ASSERT_EQUAL(std::string("1000"), c->getValue()); - CPPUNIT_ASSERT((time_t)INT32_MAX <= c->getExpiryTime()); + CPPUNIT_ASSERT_EQUAL((time_t)1463304912, c->getExpiryTime()); CPPUNIT_ASSERT(c->getPersistent()); - CPPUNIT_ASSERT_EQUAL(std::string("overflow"), c->getDomain()); + CPPUNIT_ASSERT_EQUAL(std::string("something"), c->getDomain()); CPPUNIT_ASSERT(c->getHostOnly()); CPPUNIT_ASSERT_EQUAL(std::string("/"), c->getPath()); CPPUNIT_ASSERT(!c->getSecure()); diff --git a/test/UtilTest2.cc b/test/UtilTest2.cc index 03a28411..544df0d5 100644 --- a/test/UtilTest2.cc +++ b/test/UtilTest2.cc @@ -66,6 +66,7 @@ class UtilTest2 : public CppUnit::TestFixture { CPPUNIT_TEST(testInPrivateAddress); CPPUNIT_TEST(testSecfmt); CPPUNIT_TEST(testTlsHostnameMatch); + CPPUNIT_TEST(testParseDoubleNoThrow); CPPUNIT_TEST_SUITE_END(); private: @@ -115,6 +116,7 @@ public: void testInPrivateAddress(); void testSecfmt(); void testTlsHostnameMatch(); + void testParseDoubleNoThrow(); }; CPPUNIT_TEST_SUITE_REGISTRATION(UtilTest2); @@ -978,4 +980,21 @@ void UtilTest2::testTlsHostnameMatch() CPPUNIT_ASSERT(!util::tlsHostnameMatch("xn--*.a.b", "xn--c.a.b")); } +void UtilTest2::testParseDoubleNoThrow() +{ + double n; + + CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, " 123 ")); + CPPUNIT_ASSERT_EQUAL(123., n); + + CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, "3.14")); + CPPUNIT_ASSERT_EQUAL(3.14, n); + + CPPUNIT_ASSERT(util::parseDoubleNoThrow(n, "-3.14")); + CPPUNIT_ASSERT_EQUAL(-3.14, n); + + CPPUNIT_ASSERT(!util::parseDoubleNoThrow(n, "")); + CPPUNIT_ASSERT(!util::parseDoubleNoThrow(n, "123x")); +} + } // namespace aria2 diff --git a/test/nscookietest.txt b/test/nscookietest.txt index 7b7d9e84..5eed9f33 100644 --- a/test/nscookietest.txt +++ b/test/nscookietest.txt @@ -5,5 +5,5 @@ expired FALSE / FALSE 1000 user me 192.168.0.1 TRUE /cgi-bin FALSE 0 passwd secret badformat -overflow FALSE / FALSE 9223372036854775807 TAX 1000 -.example.org TRUE / FALSE 2147483647 novalue +something FALSE / FALSE 1463304912.5 TAX 1000 +.example.org TRUE / FALSE 2147483647.123 novalue -- cgit From 2449ee6a760a1857100ff2210e739baf8a4899a4 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 14 May 2016 23:08:42 +0900 Subject: Simplify cache write The previous cache write routine was too complex. I'm sure I can rewrite it to more elegantly. But the primary motivation of this complex logic is for disk activity reduction on Windows 7, and I observed it on my old IDE disk. I checked it again recently, and there is no difference between with and without this complex logic. For this reason, it was removed. Will revert this change if many of users are not happy with this. --- src/AbstractSingleDiskAdaptor.cc | 45 ++----------------- src/MultiDiskAdaptor.cc | 94 ++-------------------------------------- 2 files changed, 6 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/AbstractSingleDiskAdaptor.cc b/src/AbstractSingleDiskAdaptor.cc index 470beb37..57881755 100644 --- a/src/AbstractSingleDiskAdaptor.cc +++ b/src/AbstractSingleDiskAdaptor.cc @@ -96,49 +96,10 @@ ssize_t AbstractSingleDiskAdaptor::readDataDropCache(unsigned char* data, void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry) { - // Write cached data in 4KiB aligned offset. This reduces disk - // activity especially on Windows 7 NTFS. In this code, we assume - // that maximum length of DataCell data is 16KiB to simplify the - // code. - unsigned char buf[16_k]; - int64_t start = 0; - size_t buflen = 0; - size_t buffoffset = 0; - const WrDiskCacheEntry::DataCellSet& dataSet = entry->getDataSet(); - for (auto& d : dataSet) { - if (start + static_cast(buflen) < d->goff) { - A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start, - static_cast(buflen))); - writeData(buf + buffoffset, buflen - buffoffset, start); - start = d->goff; - buflen = buffoffset = 0; - } - if (buflen == 0 && (d->goff & 0xfff) == 0 && (d->len & 0xfff) == 0) { - // Already aligned. Write it without copy. - A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start, - static_cast(d->len))); - writeData(d->data + d->offset, d->len, start); - start += d->len; - } - else { - if (buflen == 0) { - buflen = buffoffset = d->goff & 0xfff; - } - size_t wlen = std::min(sizeof(buf) - buflen, d->len); - memcpy(buf + buflen, d->data + d->offset, wlen); - buflen += wlen; - if (buflen == sizeof(buf)) { - A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start, - static_cast(buflen))); - writeData(buf + buffoffset, buflen - buffoffset, start); - memcpy(buf, d->data + d->offset + wlen, d->len - wlen); - start += sizeof(buf) - buffoffset; - buflen = d->len - wlen; - buffoffset = 0; - } - } + for (auto& d : entry->getDataSet()) { + A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", d->goff, d->len)); + writeData(d->data + d->offset, d->len, d->goff); } - writeData(buf + buffoffset, buflen - buffoffset, start); } bool AbstractSingleDiskAdaptor::fileExists() diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc index 3e6a5ea0..13c7364f 100644 --- a/src/MultiDiskAdaptor.cc +++ b/src/MultiDiskAdaptor.cc @@ -412,98 +412,10 @@ ssize_t MultiDiskAdaptor::readData(unsigned char* data, size_t len, void MultiDiskAdaptor::writeCache(const WrDiskCacheEntry* entry) { - // Write cached data in 4KiB aligned offset. This reduces disk - // activity especially on Windows 7 NTFS. - unsigned char buf[16_k]; - size_t buflen = 0; - size_t buffoffset = 0; - auto& dataSet = entry->getDataSet(); - if (dataSet.empty()) { - return; - } - auto dent = - findFirstDiskWriterEntry(diskWriterEntries_, (*dataSet.begin())->goff), - eod = diskWriterEntries_.cend(); - auto i = std::begin(dataSet), eoi = std::end(dataSet); - size_t celloff = 0; - for (; dent != eod; ++dent) { - int64_t lstart = 0, lp = 0; - auto& fent = (*dent)->getFileEntry(); - if (fent->getLength() == 0) { - continue; - } - for (; i != eoi;) { - if (std::max(fent->getOffset(), - static_cast((*i)->goff + celloff)) < - std::min(fent->getLastOffset(), - static_cast((*i)->goff + (*i)->len))) { - openIfNot((*dent).get(), &DiskWriterEntry::openFile); - if (!(*dent)->isOpen()) { - throwOnDiskWriterNotOpened((*dent).get(), (*i)->goff + celloff); - } - } - else { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, - buflen - buffoffset, lstart); - buflen = buffoffset = 0; - break; - } - int64_t loff = fent->gtoloff((*i)->goff + celloff); - if (static_cast(lstart + buflen) < loff) { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, - buflen - buffoffset, lstart); - lstart = lp = loff; - buflen = buffoffset = 0; - } - // If the position of the cache data is not aligned, offset - // buffer so that next write can be aligned. - if (buflen == 0) { - buflen = buffoffset = loff & 0xfff; - } - assert((*i)->len > celloff); - for (;;) { - size_t wlen = std::min(static_cast((*i)->len - celloff), - fent->getLength() - lp); - wlen = std::min(wlen, sizeof(buf) - buflen); - memcpy(buf + buflen, (*i)->data + (*i)->offset + celloff, wlen); - buflen += wlen; - celloff += wlen; - lp += wlen; - if (lp == fent->getLength() || buflen == sizeof(buf)) { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, - buflen - buffoffset, lstart); - lstart += buflen - buffoffset; - lp = lstart; - buflen = buffoffset = 0; - } - if (lp == fent->getLength() || celloff == (*i)->len) { - break; - } - } - if (celloff == (*i)->len) { - ++i; - celloff = 0; - } - } - if (i == eoi) { - A2_LOG_DEBUG(fmt("%s Cache flush loff=%" PRId64 ", len=%lu", - fent->getPath().c_str(), lstart, - static_cast(buflen - buffoffset))); - (*dent)->getDiskWriter()->writeData(buf + buffoffset, buflen - buffoffset, - lstart); - break; - } + for (auto& d : entry->getDataSet()) { + A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", d->goff, d->len)); + writeData(d->data + d->offset, d->len, d->goff); } - assert(i == eoi); } bool MultiDiskAdaptor::fileExists() -- cgit From cc8375f0b04918ace028bf58e09f9e25a0440c23 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 15 May 2016 22:00:16 +0900 Subject: Refactor BtHandshakeMessage --- src/BtHandshakeMessage.cc | 53 ++++++++++++++++++++++------------------------- src/BtHandshakeMessage.h | 39 +++++++++++++++++----------------- 2 files changed, 44 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/BtHandshakeMessage.cc b/src/BtHandshakeMessage.cc index c7ebfef1..95f99e0d 100644 --- a/src/BtHandshakeMessage.cc +++ b/src/BtHandshakeMessage.cc @@ -37,16 +37,13 @@ #include #include "util.h" -#include "BtConstants.h" #include "a2functional.h" namespace aria2 { +const unsigned char BtHandshakeMessage::BT_PSTR[] = "BitTorrent protocol"; const char BtHandshakeMessage::NAME[] = "handshake"; -const unsigned char* BtHandshakeMessage::BT_PSTR = - reinterpret_cast("BitTorrent protocol"); - BtHandshakeMessage::BtHandshakeMessage() : SimpleBtMessage(ID, NAME) { init(); } BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash, @@ -54,19 +51,17 @@ BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash, : SimpleBtMessage(ID, NAME) { init(); - memcpy(infoHash_, infoHash, INFO_HASH_LENGTH); - memcpy(peerId_, peerId, PEER_ID_LENGTH); + std::copy_n(infoHash, infoHash_.size(), std::begin(infoHash_)); + std::copy_n(peerId, peerId_.size(), std::begin(peerId_)); } +BtHandshakeMessage::~BtHandshakeMessage() {} + void BtHandshakeMessage::init() { pstrlen_ = 19; - pstr_ = new unsigned char[PSTR_LENGTH]; - reserved_ = new unsigned char[RESERVED_LENGTH]; - infoHash_ = new unsigned char[INFO_HASH_LENGTH]; - peerId_ = new unsigned char[PEER_ID_LENGTH]; - memcpy(pstr_, BT_PSTR, PSTR_LENGTH); - memset(reserved_, 0, RESERVED_LENGTH); + std::copy_n(BT_PSTR, pstr_.size(), std::begin(pstr_)); + std::fill(std::begin(reserved_), std::end(reserved_), 0); // fast extension reserved_[7] |= 0x04u; // extended messaging @@ -76,23 +71,25 @@ void BtHandshakeMessage::init() std::unique_ptr BtHandshakeMessage::create(const unsigned char* data, size_t dataLength) { - auto message = make_unique(); - message->pstrlen_ = data[0]; - memcpy(message->pstr_, &data[1], PSTR_LENGTH); - memcpy(message->reserved_, &data[20], RESERVED_LENGTH); - memcpy(message->infoHash_, &data[28], INFO_HASH_LENGTH); - memcpy(message->peerId_, &data[48], PEER_ID_LENGTH); - return message; + auto msg = make_unique(); + msg->pstrlen_ = data[0]; + std::copy_n(&data[1], msg->pstr_.size(), std::begin(msg->pstr_)); + std::copy_n(&data[20], msg->reserved_.size(), std::begin(msg->reserved_)); + std::copy_n(&data[28], msg->infoHash_.size(), std::begin(msg->infoHash_)); + std::copy_n(&data[48], msg->peerId_.size(), std::begin(msg->peerId_)); + + return msg; } unsigned char* BtHandshakeMessage::createMessage() { auto msg = new unsigned char[MESSAGE_LENGTH]; - msg[0] = pstrlen_; - memcpy(msg + 1, pstr_, PSTR_LENGTH); - memcpy(msg + 20, reserved_, RESERVED_LENGTH); - memcpy(msg + 28, infoHash_, INFO_HASH_LENGTH); - memcpy(msg + 48, peerId_, PEER_ID_LENGTH); + auto dst = msg; + *dst++ = pstrlen_; + dst = std::copy(std::begin(pstr_), std::end(pstr_), dst); + dst = std::copy(std::begin(reserved_), std::end(reserved_), dst); + dst = std::copy(std::begin(infoHash_), std::end(infoHash_), dst); + std::copy(std::begin(peerId_), std::end(peerId_), dst); return msg; } @@ -101,8 +98,8 @@ size_t BtHandshakeMessage::getMessageLength() { return MESSAGE_LENGTH; } std::string BtHandshakeMessage::toString() const { return fmt("%s peerId=%s, reserved=%s", NAME, - util::percentEncode(peerId_, PEER_ID_LENGTH).c_str(), - util::toHex(reserved_, RESERVED_LENGTH).c_str()); + util::percentEncode(peerId_.data(), peerId_.size()).c_str(), + util::toHex(reserved_.data(), reserved_.size()).c_str()); } bool BtHandshakeMessage::isFastExtensionSupported() const @@ -119,12 +116,12 @@ bool BtHandshakeMessage::isDHTEnabled() const { return reserved_[7] & 0x01u; } void BtHandshakeMessage::setInfoHash(const unsigned char* infoHash) { - memcpy(infoHash_, infoHash, INFO_HASH_LENGTH); + std::copy_n(infoHash, infoHash_.size(), std::begin(infoHash_)); } void BtHandshakeMessage::setPeerId(const unsigned char* peerId) { - memcpy(peerId_, peerId, PEER_ID_LENGTH); + std::copy_n(peerId, peerId_.size(), std::begin(peerId_)); } } // namespace aria2 diff --git a/src/BtHandshakeMessage.h b/src/BtHandshakeMessage.h index 51893b57..5bbb0b4f 100644 --- a/src/BtHandshakeMessage.h +++ b/src/BtHandshakeMessage.h @@ -37,21 +37,26 @@ #include "SimpleBtMessage.h" +#include + +#include "BtConstants.h" + namespace aria2 { class BtHandshakeMessage : public SimpleBtMessage { public: - static const size_t PSTR_LENGTH = 19; - static const unsigned char* BT_PSTR; - static const size_t RESERVED_LENGTH = 8; - static const size_t MESSAGE_LENGTH = 68; + constexpr static size_t PSTR_LENGTH = 19; + constexpr static size_t RESERVED_LENGTH = 8; + constexpr static size_t MESSAGE_LENGTH = 68; + const static unsigned char BT_PSTR[]; private: uint8_t pstrlen_; - unsigned char* pstr_; - unsigned char* reserved_; - unsigned char* infoHash_; - unsigned char* peerId_; + std::array pstr_; + std::array reserved_; + std::array infoHash_; + std::array peerId_; + void init(); public: @@ -66,17 +71,11 @@ public: static std::unique_ptr create(const unsigned char* data, size_t dataLength); - virtual ~BtHandshakeMessage() - { - delete[] pstr_; - delete[] reserved_; - delete[] infoHash_; - delete[] peerId_; - } + virtual ~BtHandshakeMessage(); static const uint8_t ID = INT8_MAX; - static const char NAME[]; + const static char NAME[]; virtual void doReceivedAction() CXX11_OVERRIDE{}; @@ -104,15 +103,15 @@ public: uint8_t getPstrlen() const { return pstrlen_; } - const unsigned char* getPstr() const { return pstr_; } + const unsigned char* getPstr() const { return pstr_.data(); } - const unsigned char* getReserved() const { return reserved_; } + const unsigned char* getReserved() const { return reserved_.data(); } - const unsigned char* getInfoHash() const { return infoHash_; } + const unsigned char* getInfoHash() const { return infoHash_.data(); } void setInfoHash(const unsigned char* infoHash); - const unsigned char* getPeerId() const { return peerId_; } + const unsigned char* getPeerId() const { return peerId_.data(); } void setPeerId(const unsigned char* peerId); }; -- cgit