Permalink
Browse files

Made util::fromHex and base32::decode function template

  • Loading branch information...
1 parent 6ea1b68 commit 0c162dfbfb4a875fac9374c65cf93382ff9ce4ed @tatsuhiro-t tatsuhiro-t committed Nov 5, 2011
@@ -94,15 +94,16 @@ SharedHandle<LpdMessage> LpdMessageReceiver::receiveMessage()
return msg;
}
SharedHandle<HttpHeader> header = proc.getHttpRequestHeader();
- std::string infoHashString = header->getFirst("Infohash");
+ const std::string& infoHashString = header->getFirst("Infohash");
uint16_t port = header->getFirstAsUInt("Port");
A2_LOG_INFO(fmt("LPD message received infohash=%s, port=%u from %s",
infoHashString.c_str(),
port,
peerAddr.first.c_str()));
std::string infoHash;
if(infoHashString.size() != 40 ||
- (infoHash = util::fromHex(infoHashString)).empty() ||
+ (infoHash = util::fromHex(infoHashString.begin(),
+ infoHashString.end())).empty() ||
port == 0) {
A2_LOG_INFO(fmt("LPD bad request. infohash=%s", infoHashString.c_str()));
msg.reset(new LpdMessage());
@@ -284,7 +284,7 @@ void MetalinkParserController::setHashOfChecksum(const std::string& md)
return;
}
if(MessageDigest::isValidHash(tChecksum_->getHashType(), md)) {
- tChecksum_->setDigest(util::fromHex(md));
+ tChecksum_->setDigest(util::fromHex(md.begin(), md.end()));
} else {
cancelChecksumTransaction();
}
@@ -360,7 +360,7 @@ void MetalinkParserController::addHashOfChunkChecksumV4(const std::string& md)
return;
}
if(MessageDigest::isValidHash(tChunkChecksumV4_->getHashType(), md)) {
- tempChunkChecksumsV4_.push_back(util::fromHex(md));
+ tempChunkChecksumsV4_.push_back(util::fromHex(md.begin(), md.end()));
} else {
cancelChunkChecksumTransactionV4();
}
@@ -463,7 +463,7 @@ void MetalinkParserController::setMessageDigestOfChunkChecksum(const std::string
return;
}
if(MessageDigest::isValidHash(tChunkChecksum_->getHashType(), md)) {
- tempHashPair_.second = util::fromHex(md);
+ tempHashPair_.second = util::fromHex(md.begin(), md.end());
} else {
cancelChunkChecksumTransaction();
}
View
@@ -1130,10 +1130,8 @@ void changeOption
std::pair<Scip, Scip> p;
util::divide(p, checksum.begin(), checksum.end(), '=');
std::string hashType(p.first.first, p.first.second);
- std::string hexDigest(p.second.first, p.second.second);
util::lowercase(hashType);
- util::lowercase(hexDigest);
- dctx->setDigest(hashType, util::fromHex(hexDigest));
+ dctx->setDigest(hashType, util::fromHex(p.second.first, p.second.second));
}
if(option.defined(PREF_SELECT_FILE)) {
SegList<int> sgl;
View
@@ -94,43 +94,6 @@ std::string encode(const std::string& src)
return ret;
}
-std::string decode(const std::string& src)
-{
- std::string ret;
- if(src.size()%8) {
- return ret;
- }
- bool done = false;
- for(size_t i = 0; i < src.size() && !done; i += 8) {
- uint64_t buf = 0;
- size_t bits = 0;
- for(size_t j = 0; j < 8; ++j) {
- char ch = src[i+j];
- unsigned char value;
- if('A' <= ch && ch <= 'Z') {
- value = ch-'A';
- } else if('2' <= ch && ch <= '7') {
- value = ch-'2'+26;
- } else if(ch == '=') {
- done = true;
- break;
- } else {
- ret.clear();
- return ret;
- }
- buf <<= 5;
- buf += value;
- bits += 5;
- }
- buf >>= (bits%8);
- bits = bits/8*8;
- buf = hton64(buf);
- char* p = reinterpret_cast<char*>(&buf);
- ret.append(&p[(64-bits)/8], &p[8]);
- }
- return ret;
-}
-
} // namespace base32
} // namespace aria2
View
@@ -39,13 +39,52 @@
#include <string>
+#include "util.h"
+
namespace aria2 {
namespace base32 {
std::string encode(const std::string& src);
-std::string decode(const std::string& src);
+template<typename InputIterator>
+std::string decode(InputIterator first, InputIterator last)
+{
+ std::string ret;
+ size_t len = last-first;
+ if(len%8) {
+ return ret;
+ }
+ bool done = false;
+ for(; first != last && !done; first += 8) {
+ uint64_t buf = 0;
+ size_t bits = 0;
+ for(size_t i = 0; i < 8; ++i) {
+ char ch = *(first+i);
+ unsigned char value;
+ if('A' <= ch && ch <= 'Z') {
+ value = ch-'A';
+ } else if('2' <= ch && ch <= '7') {
+ value = ch-'2'+26;
+ } else if(ch == '=') {
+ done = true;
+ break;
+ } else {
+ ret.clear();
+ return ret;
+ }
+ buf <<= 5;
+ buf += value;
+ bits += 5;
+ }
+ buf >>= (bits%8);
+ bits = bits/8*8;
+ buf = hton64(buf);
+ char* p = reinterpret_cast<char*>(&buf);
+ ret.append(&p[(64-bits)/8], &p[8]);
+ }
+ return ret;
+}
} // namespace base32
View
@@ -881,15 +881,14 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
const String* xt = downcast<String>(*xtiter);
if(util::startsWith(xt->s().begin(), xt->s().end(),
A2_URN_BTIH, vend(A2_URN_BTIH)-1)) {
- std::string xtarg(xt->s().begin()+9, xt->s().end());
- size_t size = xtarg.size();
+ size_t size = xt->s().end()-xt->s().begin()-9;
if(size == 32) {
- std::string rawhash = base32::decode(xtarg);
+ std::string rawhash = base32::decode(xt->s().begin()+9, xt->s().end());
if(rawhash.size() == 20) {
infoHash.swap(rawhash);
}
} else if(size == 40) {
- std::string rawhash = util::fromHex(xtarg);
+ std::string rawhash = util::fromHex(xt->s().begin()+9, xt->s().end());
if(!rawhash.empty()) {
infoHash.swap(rawhash);
}
View
@@ -486,10 +486,8 @@ std::string toHex(const std::string& src)
return toHex(reinterpret_cast<const unsigned char*>(src.c_str()), src.size());
}
-namespace {
unsigned int hexCharToUInt(unsigned char ch)
{
-
if('a' <= ch && ch <= 'f') {
ch -= 'a';
ch += 10;
@@ -503,25 +501,6 @@ unsigned int hexCharToUInt(unsigned char ch)
}
return ch;
}
-} // namespace
-
-std::string fromHex(const std::string& src)
-{
- std::string dest;
- if(src.size()%2) {
- return dest;
- }
- for(size_t i = 0, eoi = src.size(); i < eoi; i += 2) {
- unsigned char high = hexCharToUInt(src[i]);
- unsigned char low = hexCharToUInt(src[i+1]);
- if(high == 255 || low == 255) {
- dest.clear();
- return dest;
- }
- dest += (high*16+low);
- }
- return dest;
-}
FILE* openFile(const std::string& filename, const std::string& mode) {
FILE* file = fopen(filename.c_str(), mode.c_str());
View
@@ -233,10 +233,30 @@ std::string toHex(const char* src, size_t len);
std::string toHex(const std::string& src);
-// Converts hexadecimal ascii string 'src' into packed binary form and
-// return the result. If src is not well formed, then empty string is
-// returned.
-std::string fromHex(const std::string& src);
+unsigned int hexCharToUInt(unsigned char ch);
+
+// Converts hexadecimal ascii characters in [first, last) into packed
+// binary form and return the result. If characters in given range is
+// not well formed, then empty string is returned.
+template<typename InputIterator>
+std::string fromHex(InputIterator first, InputIterator last)
+{
+ std::string dest;
+ size_t len = last-first;
+ if(len%2) {
+ return dest;
+ }
+ for(; first != last; first += 2) {
+ unsigned char high = hexCharToUInt(*first);
+ unsigned char low = hexCharToUInt(*(first+1));
+ if(high == 255 || low == 255) {
+ dest.clear();
+ return dest;
+ }
+ dest += (high*16+low);
+ }
+ return dest;
+}
FILE* openFile(const std::string& filename, const std::string& mode);
View
@@ -28,18 +28,26 @@ void Base32Test::testEncode()
CPPUNIT_ASSERT_EQUAL(std::string("GEZDG==="), base32::encode("123"));
CPPUNIT_ASSERT_EQUAL(std::string("GEZDGNA="), base32::encode("1234"));
CPPUNIT_ASSERT_EQUAL(std::string("GEZDGNBV"), base32::encode("12345"));
+ std::string s = "248d0a1cd08284";
CPPUNIT_ASSERT_EQUAL(std::string("ESGQUHGQQKCA===="),
- base32::encode(util::fromHex("248d0a1cd08284")));
+ base32::encode(util::fromHex(s.begin(), s.end())));
}
void Base32Test::testDecode()
{
- CPPUNIT_ASSERT_EQUAL(std::string(), base32::decode(""));
- CPPUNIT_ASSERT_EQUAL(std::string("1"), base32::decode("GE======"));
- CPPUNIT_ASSERT_EQUAL(std::string("12"), base32::decode("GEZA===="));
- CPPUNIT_ASSERT_EQUAL(std::string("123"), base32::decode("GEZDG==="));
- CPPUNIT_ASSERT_EQUAL(std::string("1234"), base32::decode("GEZDGNA="));
- CPPUNIT_ASSERT_EQUAL(std::string("12345"), base32::decode("GEZDGNBV"));
+ std::string s = "";
+ CPPUNIT_ASSERT_EQUAL(std::string(), base32::decode(s.begin(), s.end()));
+ s = "GE======";
+ CPPUNIT_ASSERT_EQUAL(std::string("1"), base32::decode(s.begin(), s.end()));
+ s = "GEZA====";
+ CPPUNIT_ASSERT_EQUAL(std::string("12"), base32::decode(s.begin(), s.end()));
+ s = "GEZDG===";
+ CPPUNIT_ASSERT_EQUAL(std::string("123"), base32::decode(s.begin(), s.end()));
+ s = "GEZDGNA=";
+ CPPUNIT_ASSERT_EQUAL(std::string("1234"), base32::decode(s.begin(), s.end()));
+ s = "GEZDGNBV";
+ CPPUNIT_ASSERT_EQUAL(std::string("12345"),
+ base32::decode(s.begin(), s.end()));
}
} // namespace aria2
@@ -417,7 +417,7 @@ void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
{
SharedHandle<List> path = List::g();
path->append("path");
- path->append(util::fromHex("90a28a")+"E");
+ path->append(fromHex("90a28a")+"E");
SharedHandle<Dict> file = Dict::g();
file->put("length", Integer::g(1024));
file->put("path", path);
@@ -427,7 +427,7 @@ void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
info->put("files", files);
info->put("piece length", Integer::g(1024));
info->put("pieces", "01234567890123456789");
- info->put("name", util::fromHex("1b")+"$B%O%m!<"+util::fromHex("1b")+"(B");
+ info->put("name", fromHex("1b")+"$B%O%m!<"+fromHex("1b")+"(B");
Dict dict;
dict.put("info", info);
SharedHandle<DownloadContext> dctx(new DownloadContext());
@@ -446,7 +446,7 @@ void BittorrentHelperTest::testLoadFromMemory_singleFileNonUtf8Path()
SharedHandle<Dict> info = Dict::g();
info->put("piece length", Integer::g(1024));
info->put("pieces", "01234567890123456789");
- info->put("name", util::fromHex("90a28a")+"E");
+ info->put("name", fromHex("90a28a")+"E");
info->put("length", Integer::g(1024));
Dict dict;
dict.put("info", info);
@@ -787,7 +787,7 @@ void BittorrentHelperTest::testParseMagnet()
void BittorrentHelperTest::testParseMagnet_base32()
{
std::string infoHash = "248d0a1cd08284299de78d5c1ed359bb46717d8c";
- std::string base32InfoHash = base32::encode(util::fromHex(infoHash));
+ std::string base32InfoHash = base32::encode(fromHex(infoHash));
std::string magnet = "magnet:?xt=urn:btih:"+base32InfoHash+"&dn=aria2";
SharedHandle<TorrentAttribute> attrs = bittorrent::parseMagnet(magnet);
CPPUNIT_ASSERT_EQUAL
@@ -830,7 +830,7 @@ void BittorrentHelperTest::testExtractPeerFromString()
{
std::string hextext = "100210354527354678541237324732171ae1";
hextext += "20010db8bd0501d2288a1fc0000110ee1ae2";
- std::string peersstr = "36:"+util::fromHex(hextext);
+ std::string peersstr = "36:"+fromHex(hextext);
SharedHandle<ValueBase> str =
bencode2::decode(peersstr.begin(), peersstr.end());
std::deque<SharedHandle<Peer> > peers;
@@ -845,7 +845,7 @@ void BittorrentHelperTest::testExtractPeerFromString()
hextext = "c0a800011ae1";
hextext += "c0a800021ae2";
- peersstr = "12:"+util::fromHex(hextext);
+ peersstr = "12:"+fromHex(hextext);
str = bencode2::decode(peersstr.begin(), peersstr.end());
peers.clear();
extractPeer(str, AF_INET, std::back_inserter(peers));
@@ -4,6 +4,7 @@
#include <cppunit/extensions/HelperMacros.h>
+#include "TestUtil.h"
#include "Option.h"
#include "util.h"
#include "Exception.h"
@@ -391,9 +392,9 @@ void DefaultBtAnnounceTest::testProcessAnnounceResponse()
"8:completei100e"
"10:incompletei200e";
res += "5:peers6:";
- res += util::fromHex("c0a800011ae1");
+ res += fromHex("c0a800011ae1");
res += "6:peers618:";
- res += util::fromHex("100210354527354678541237324732171ae1");
+ res += fromHex("100210354527354678541237324732171ae1");
res += "e";
DefaultBtAnnounce an(dctx_, option_);
@@ -2,6 +2,7 @@
#include <cppunit/extensions/HelperMacros.h>
+#include "TestUtil.h"
#include "DownloadContext.h"
#include "DefaultPieceStorage.h"
#include "Option.h"
@@ -35,7 +36,7 @@ void IteratableChecksumValidatorTest::testValidate() {
SharedHandle<DownloadContext> dctx
(new DownloadContext(100, 250, A2_TEST_DIR"/chunkChecksumTestFile250.txt"));
dctx->setDigest("sha-1",
- util::fromHex("898a81b8e0181280ae2ee1b81e269196d91e869a"));
+ fromHex("898a81b8e0181280ae2ee1b81e269196d91e869a"));
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, &option));
ps->initStorage();
ps->getDiskAdaptor()->enableReadOnly();
@@ -55,7 +56,7 @@ void IteratableChecksumValidatorTest::testValidate_fail() {
SharedHandle<DownloadContext> dctx
(new DownloadContext(100, 250, A2_TEST_DIR"/chunkChecksumTestFile250.txt"));
dctx->setDigest("sha-1",
- util::fromHex(std::string(40, '0'))); // set wrong checksum
+ fromHex(std::string(40, '0'))); // set wrong checksum
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, &option));
ps->initStorage();
ps->getDiskAdaptor()->enableReadOnly();
Oops, something went wrong.

0 comments on commit 0c162df

Please sign in to comment.