summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2011-11-05 12:01:57 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2011-11-05 12:01:57 +0900
commitd1d49036651012433595357ca31e6f65dbec3a6b (patch)
treea962461fc219fa02458d154eef4e3a354bb99e40 /src
parentd305432ec0015cfc9479331531a78f29c398bd8c (diff)
Rewritten bencode2::decode functions
Diffstat (limited to 'src')
-rw-r--r--src/DHTMessageReceiver.cc2
-rw-r--r--src/DefaultBtAnnounce.cc2
-rw-r--r--src/DefaultExtensionMessageFactory.cc3
-rw-r--r--src/FtpConnection.cc2
-rw-r--r--src/HandshakeExtensionMessage.cc2
-rw-r--r--src/HttpServer.cc7
-rw-r--r--src/OptionParser.cc2
-rw-r--r--src/ParameterizedStringParser.cc2
-rw-r--r--src/UTPexExtensionMessage.cc2
-rw-r--r--src/bencode2.cc189
-rw-r--r--src/bencode2.h25
-rw-r--r--src/bittorrent_helper.cc8
-rw-r--r--src/util.h13
13 files changed, 149 insertions, 110 deletions
diff --git a/src/DHTMessageReceiver.cc b/src/DHTMessageReceiver.cc
index e5558d9d..8b2b98b1 100644
--- a/src/DHTMessageReceiver.cc
+++ b/src/DHTMessageReceiver.cc
@@ -76,7 +76,7 @@ SharedHandle<DHTMessage> DHTMessageReceiver::receiveMessage()
return SharedHandle<DHTMessage>();
}
bool isReply = false;
- SharedHandle<ValueBase> decoded = bencode2::decode(data, length);
+ SharedHandle<ValueBase> decoded = bencode2::decode(data, data+length);
const Dict* dict = downcast<Dict>(decoded);
if(dict) {
const String* y = downcast<String>(dict->get(DHTMessage::Y));
diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc
index 62ba3646..43778ab6 100644
--- a/src/DefaultBtAnnounce.cc
+++ b/src/DefaultBtAnnounce.cc
@@ -220,7 +220,7 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
{
A2_LOG_DEBUG("Now processing tracker response.");
SharedHandle<ValueBase> decodedValue =
- bencode2::decode(trackerResponse, trackerResponseLength);
+ bencode2::decode(trackerResponse, trackerResponse+trackerResponseLength);
const Dict* dict = downcast<Dict>(decodedValue);
if(!dict) {
throw DL_ABORT_EX(MSG_NULL_TRACKER_RESPONSE);
diff --git a/src/DefaultExtensionMessageFactory.cc b/src/DefaultExtensionMessageFactory.cc
index 3d3f9b36..47fa26b3 100644
--- a/src/DefaultExtensionMessageFactory.cc
+++ b/src/DefaultExtensionMessageFactory.cc
@@ -101,7 +101,8 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
static_cast<unsigned long>(length)));
}
size_t end;
- SharedHandle<ValueBase> decoded = bencode2::decode(data+1, length-1, end);
+ SharedHandle<ValueBase> decoded =
+ bencode2::decode(data+1, data+length, end);
const Dict* dict = downcast<Dict>(decoded);
if(!dict) {
throw DL_ABORT_EX("Bad ut_metadata: dictionary not found");
diff --git a/src/FtpConnection.cc b/src/FtpConnection.cc
index d6cd94f0..9fc3ac80 100644
--- a/src/FtpConnection.cc
+++ b/src/FtpConnection.cc
@@ -435,7 +435,7 @@ unsigned int FtpConnection::receiveSizeResponse(uint64_t& size)
std::pair<unsigned int, std::string> response;
if(bulkReceiveResponse(response)) {
if(response.first == 213) {
- std::pair<Scip, Scip> rp;
+ std::pair<Sip, Sip> rp;
util::divide(rp, response.second.begin(), response.second.end(), ' ');
size = util::parseULLInt(rp.second.first, rp.second.second);
}
diff --git a/src/HandshakeExtensionMessage.cc b/src/HandshakeExtensionMessage.cc
index cec3ea2d..3fae69d8 100644
--- a/src/HandshakeExtensionMessage.cc
+++ b/src/HandshakeExtensionMessage.cc
@@ -173,7 +173,7 @@ HandshakeExtensionMessage::create(const unsigned char* data, size_t length)
HandshakeExtensionMessageHandle msg(new HandshakeExtensionMessage());
A2_LOG_DEBUG(fmt("Creating HandshakeExtensionMessage from %s",
util::percentEncode(data, length).c_str()));
- SharedHandle<ValueBase> decoded = bencode2::decode(data+1, length-1);
+ SharedHandle<ValueBase> decoded = bencode2::decode(data+1, data+length);
const Dict* dict = downcast<Dict>(decoded);
if(!dict) {
throw DL_ABORT_EX
diff --git a/src/HttpServer.cc b/src/HttpServer.cc
index cef02a80..318635c6 100644
--- a/src/HttpServer.cc
+++ b/src/HttpServer.cc
@@ -227,10 +227,11 @@ bool HttpServer::authenticate()
}
std::string userpass = Base64::decode(std::string(p.second.first,
p.second.second));
- util::divide(p, userpass.begin(), userpass.end(), ':');
- return util::streq(p.first.first, p.first.second,
+ std::pair<Sip, Sip> up;
+ util::divide(up, userpass.begin(), userpass.end(), ':');
+ return util::streq(up.first.first, up.first.second,
username_.begin(), username_.end()) &&
- util::streq(p.second.first, p.second.second,
+ util::streq(up.second.first, up.second.second,
password_.begin(), password_.end());
}
diff --git a/src/OptionParser.cc b/src/OptionParser.cc
index 157d2adc..a1e4090d 100644
--- a/src/OptionParser.cc
+++ b/src/OptionParser.cc
@@ -184,7 +184,7 @@ void OptionParser::parse(Option& option, std::istream& is) const
if(line.empty() || line[0] == '#') {
continue;
}
- std::pair<Scip, Scip> nv;
+ std::pair<Sip, Sip> nv;
util::divide(nv, line.begin(), line.end(), '=');
if(nv.first.first == nv.first.second) {
continue;
diff --git a/src/ParameterizedStringParser.cc b/src/ParameterizedStringParser.cc
index 2b80d41b..579881fa 100644
--- a/src/ParameterizedStringParser.cc
+++ b/src/ParameterizedStringParser.cc
@@ -124,7 +124,7 @@ ParameterizedStringParser::createLoop(const std::string& src, int& offset)
}
loopStr.erase(colonIndex);
}
- std::pair<Scip, Scip> range;
+ std::pair<Sip, Sip> range;
util::divide(range, loopStr.begin(), loopStr.end(), '-');
if(range.first.first == range.first.second ||
range.second.first == range.second.second) {
diff --git a/src/UTPexExtensionMessage.cc b/src/UTPexExtensionMessage.cc
index a974d8f2..fe0e99c6 100644
--- a/src/UTPexExtensionMessage.cc
+++ b/src/UTPexExtensionMessage.cc
@@ -190,7 +190,7 @@ UTPexExtensionMessage::create(const unsigned char* data, size_t len)
}
UTPexExtensionMessageHandle msg(new UTPexExtensionMessage(*data));
- SharedHandle<ValueBase> decoded = bencode2::decode(data+1, len-1);
+ SharedHandle<ValueBase> decoded = bencode2::decode(data+1, data+len);
const Dict* dict = downcast<Dict>(decoded);
if(dict) {
const String* added = downcast<String>(dict->get("added"));
diff --git a/src/bencode2.cc b/src/bencode2.cc
index 181309a8..1db0ddbe 100644
--- a/src/bencode2.cc
+++ b/src/bencode2.cc
@@ -40,90 +40,92 @@
#include "DlAbortEx.h"
#include "error_code.h"
#include "BufferedFile.h"
+#include "util.h"
namespace aria2 {
namespace bencode2 {
namespace {
-SharedHandle<ValueBase> decodeiter(std::istream& ss, size_t depth);
+template<typename InputIterator>
+std::pair<SharedHandle<ValueBase>, InputIterator>
+decodeiter
+(InputIterator first,
+ InputIterator last,
+ size_t depth);
} // namespace
namespace {
-void checkdelim(std::istream& ss, const char delim = ':')
+template<typename InputIterator>
+std::pair<std::string, InputIterator>
+decoderawstring(InputIterator first, InputIterator last)
{
- char d;
- if(!(ss.get(d) && d == delim)) {
- throw DL_ABORT_EX2
- (fmt("Bencode decoding failed: Delimiter '%c' not found.",
- delim),
- error_code::BENCODE_PARSE_ERROR);
- }
-}
-} // namespace
-
-namespace {
-std::string decoderawstring(std::istream& ss)
-{
- int length;
- ss >> length;
- if(!ss || length < 0) {
+ InputIterator i = first;
+ int32_t len;
+ for(; i != last && *i != ':'; ++i);
+ if(i == last || i == first || !util::parseIntNoThrow(len, first, i) ||
+ len < 0) {
throw DL_ABORT_EX2("Bencode decoding failed:"
" A positive integer expected but none found.",
error_code::BENCODE_PARSE_ERROR);
}
- // TODO check length, it must be less than or equal to INT_MAX
- checkdelim(ss);
- char* buf = new char[length];
- ss.read(buf, length);
- std::string str(&buf[0], &buf[length]);
- delete [] buf;
- if(ss.gcount() != static_cast<int>(length)) {
+ ++i;
+ if(last-i < len) {
throw DL_ABORT_EX2
(fmt("Bencode decoding failed:"
- " Expected %lu bytes of data, but only %ld read.",
- static_cast<unsigned long>(length),
- static_cast<long int>(ss.gcount())),
+ " Expected %d bytes of data, but only %d read.",
+ len, static_cast<int>(last-i)),
error_code::BENCODE_PARSE_ERROR);
}
- return str;
+ return std::make_pair(std::string(i, i+len), i+len);
}
} // namespace
namespace {
-SharedHandle<ValueBase> decodestring(std::istream& ss)
+template<typename InputIterator>
+std::pair<SharedHandle<ValueBase>, InputIterator>
+decodestring(InputIterator first, InputIterator last)
{
- return String::g(decoderawstring(ss));
+ std::pair<std::string, InputIterator> r = decoderawstring(first, last);
+ return std::make_pair(String::g(r.first), r.second);
}
} // namespace
namespace {
-SharedHandle<ValueBase> decodeinteger(std::istream& ss)
+template<typename InputIterator>
+std::pair<SharedHandle<ValueBase>, InputIterator>
+decodeinteger(InputIterator first, InputIterator last)
{
+ InputIterator i = first;
+ for(; i != last && *i != 'e'; ++i);
Integer::ValueType iv;
- ss >> iv;
- if(!ss) {
+ if(i == last || !util::parseLLIntNoThrow(iv, first, i)) {
throw DL_ABORT_EX2("Bencode decoding failed:"
" Integer expected but none found",
error_code::BENCODE_PARSE_ERROR);
}
- checkdelim(ss, 'e');
- return Integer::g(iv);
+ return std::make_pair(Integer::g(iv), ++i);
}
} // namespace
namespace {
-SharedHandle<ValueBase> decodedict(std::istream& ss, size_t depth)
+template<typename InputIterator>
+std::pair<SharedHandle<ValueBase>, InputIterator>
+decodedict
+(InputIterator first,
+ InputIterator last,
+ size_t depth)
{
SharedHandle<Dict> dict = Dict::g();
- char c;
- while(ss.get(c)) {
- if(c == 'e') {
- return dict;
+ while(first != last) {
+ if(*first == 'e') {
+ return std::make_pair(dict, ++first);
} else {
- ss.unget();
- std::string key = decoderawstring(ss);
- dict->put(key, decodeiter(ss, depth));
+ std::pair<std::string, InputIterator> keyp = decoderawstring(first, last);
+ std::pair<SharedHandle<ValueBase>, InputIterator> r =
+ decodeiter(keyp.second, last, depth);
+ dict->put(keyp.first, r.first);
+ first = r.second;
}
}
throw DL_ABORT_EX2("Bencode decoding failed:"
@@ -133,16 +135,22 @@ SharedHandle<ValueBase> decodedict(std::istream& ss, size_t depth)
} // namespace
namespace {
-SharedHandle<ValueBase> decodelist(std::istream& ss, size_t depth)
+template<typename InputIterator>
+std::pair<SharedHandle<ValueBase>, InputIterator>
+decodelist
+(InputIterator first,
+ InputIterator last,
+ size_t depth)
{
SharedHandle<List> list = List::g();
- char c;
- while(ss.get(c)) {
- if(c == 'e') {
- return list;
+ while(first != last) {
+ if(*first == 'e') {
+ return std::make_pair(list, ++first);
} else {
- ss.unget();
- list->append(decodeiter(ss, depth));
+ std::pair<SharedHandle<ValueBase>, InputIterator> r =
+ decodeiter(first, last, depth);
+ list->append(r.first);
+ first = r.second;
}
}
throw DL_ABORT_EX2("Bencode decoding failed:"
@@ -162,60 +170,79 @@ void checkDepth(size_t depth)
} // namespace
namespace {
-SharedHandle<ValueBase> decodeiter(std::istream& ss, size_t depth)
+template<typename InputIterator>
+std::pair<SharedHandle<ValueBase>, InputIterator>
+decodeiter
+(InputIterator first,
+ InputIterator last,
+ size_t depth)
{
checkDepth(depth);
- char c;
- if(!ss.get(c)) {
+ if(first == last) {
throw DL_ABORT_EX2("Bencode decoding failed:"
" Unexpected EOF in term context."
" 'd', 'l', 'i' or digit is expected.",
error_code::BENCODE_PARSE_ERROR);
}
- if(c == 'd') {
- return decodedict(ss, depth+1);
- } else if(c == 'l') {
- return decodelist(ss, depth+1);
- } else if(c == 'i') {
- return decodeinteger(ss);
+ if(*first == 'd') {
+ return decodedict(++first, last, depth+1);
+ } else if(*first == 'l') {
+ return decodelist(++first, last, depth+1);
+ } else if(*first == 'i') {
+ return decodeinteger(++first, last);
} else {
- ss.unget();
- return decodestring(ss);
+ return decodestring(first, last);
}
}
} // namespace
-SharedHandle<ValueBase> decode(std::istream& in)
+namespace {
+template<typename InputIterator>
+SharedHandle<ValueBase> decodegen
+(InputIterator first,
+ InputIterator last,
+ size_t& end)
{
- return decodeiter(in, 0);
+ if(first == last) {
+ return SharedHandle<ValueBase>();
+ }
+ std::pair<SharedHandle<ValueBase>, InputIterator> p =
+ decodeiter(first, last, 0);
+ end = p.second-first;
+ return p.first;
}
+} // namespace
-SharedHandle<ValueBase> decode(const std::string& s)
+SharedHandle<ValueBase> decode
+(std::string::const_iterator first,
+ std::string::const_iterator last)
{
size_t end;
- return decode(s, end);
+ return decodegen(first, last, end);
}
-SharedHandle<ValueBase> decode(const std::string& s, size_t& end)
+SharedHandle<ValueBase> decode
+(std::string::const_iterator first,
+ std::string::const_iterator last,
+ size_t& end)
{
- if(s.empty()) {
- return SharedHandle<ValueBase>();
- }
- std::istringstream ss(s);
-
- SharedHandle<ValueBase> vlb = decodeiter(ss, 0);
- end = ss.tellg();
- return vlb;
+ return decodegen(first, last, end);
}
-SharedHandle<ValueBase> decode(const unsigned char* data, size_t length)
+SharedHandle<ValueBase> decode
+(const unsigned char* first,
+ const unsigned char* last)
{
- return decode(std::string(&data[0], &data[length]));
+ size_t end;
+ return decodegen(first, last, end);
}
-SharedHandle<ValueBase> decode(const unsigned char* data, size_t length, size_t& end)
+SharedHandle<ValueBase> decode
+(const unsigned char* first,
+ const unsigned char* last,
+ size_t& end)
{
- return decode(std::string(&data[0], &data[length]), end);
+ return decodegen(first, last, end);
}
SharedHandle<ValueBase> decodeFromFile(const std::string& filename)
@@ -225,7 +252,9 @@ SharedHandle<ValueBase> decodeFromFile(const std::string& filename)
std::stringstream ss;
fp.transfer(ss);
fp.close();
- return decode(ss);
+ const std::string s = ss.str();
+ size_t end;
+ return decodegen(s.begin(), s.end(), end);
} else {
throw DL_ABORT_EX2
(fmt("Bencode decoding failed: Cannot open file '%s'.",
diff --git a/src/bencode2.h b/src/bencode2.h
index 7f4e226f..bfc95de6 100644
--- a/src/bencode2.h
+++ b/src/bencode2.h
@@ -48,19 +48,26 @@ namespace bencode2 {
const size_t MAX_STRUCTURE_DEPTH = 100;
-SharedHandle<ValueBase> decode(std::istream& in);
-
-// Decode the data in s.
-SharedHandle<ValueBase> decode(const std::string& s);
+// Decode the data in [first, last).
+SharedHandle<ValueBase> decode
+(std::string::const_iterator first,
+ std::string::const_iterator last);
-// Decode the data in s. After decode is done successfully, return the
-// bencoded string length in end.
-SharedHandle<ValueBase> decode(const std::string& s, size_t& end);
+// Decode the data in [first, last). After decode is done
+// successfully, return the bencoded string length in end.
+SharedHandle<ValueBase> decode
+(std::string::const_iterator first,
+ std::string::const_iterator last,
+ size_t& end);
-SharedHandle<ValueBase> decode(const unsigned char* data, size_t length);
+SharedHandle<ValueBase> decode
+(const unsigned char* first,
+ const unsigned char* last);
SharedHandle<ValueBase> decode
-(const unsigned char* data, size_t length, size_t& end);
+(const unsigned char* first,
+ const unsigned char* last,
+ size_t& end);
SharedHandle<ValueBase> decodeFromFile(const std::string& filename);
diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc
index 0346d96b..27f82443 100644
--- a/src/bittorrent_helper.cc
+++ b/src/bittorrent_helper.cc
@@ -544,7 +544,7 @@ void loadFromMemory(const unsigned char* content,
const std::string& overrideName)
{
processRootDictionary(ctx,
- bencode2::decode(content, length),
+ bencode2::decode(content, content+length),
option,
defaultName,
overrideName,
@@ -560,7 +560,7 @@ void loadFromMemory(const unsigned char* content,
const std::string& overrideName)
{
processRootDictionary(ctx,
- bencode2::decode(content, length),
+ bencode2::decode(content, content+length),
option,
defaultName,
overrideName,
@@ -575,7 +575,7 @@ void loadFromMemory(const std::string& context,
{
processRootDictionary
(ctx,
- bencode2::decode(context),
+ bencode2::decode(context.begin(), context.end()),
option,
defaultName, overrideName,
std::vector<std::string>());
@@ -590,7 +590,7 @@ void loadFromMemory(const std::string& context,
{
processRootDictionary
(ctx,
- bencode2::decode(context),
+ bencode2::decode(context.begin(), context.end()),
option,
defaultName, overrideName,
uris);
diff --git a/src/util.h b/src/util.h
index 36cc0504..1af2c86a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -112,7 +112,8 @@ namespace util {
template<typename InputIterator>
void divide
-(std::pair<Scip, Scip>& hp,
+(std::pair<std::pair<InputIterator, InputIterator>,
+ std::pair<InputIterator, InputIterator> >& hp,
InputIterator first,
InputIterator last,
char delim)
@@ -248,7 +249,7 @@ bool parseIntNoThrow
(int32_t& result, InputIterator first, InputIterator last, int base = 10)
{
// Without strip, strtol(" -1 ",..) emits error.
- Scip p = util::stripIter(first, last);
+ std::pair<InputIterator, InputIterator> p = util::stripIter(first, last);
if(p.first == p.second) {
return false;
}
@@ -277,7 +278,7 @@ bool parseUIntNoThrow
(uint32_t& result, InputIterator first, InputIterator last, int base = 10)
{
// Without strip, strtol(" -1 ",..) emits error.
- Scip p = util::stripIter(first, last);
+ std::pair<InputIterator, InputIterator> p = util::stripIter(first, last);
if(p.first == p.second) {
return false;
}
@@ -309,7 +310,7 @@ bool parseLLIntNoThrow
(int64_t& result, InputIterator first, InputIterator last, int base = 10)
{
// Without strip, strtol(" -1 ",..) emits error.
- Scip p = util::stripIter(first, last);
+ std::pair<InputIterator, InputIterator> p = util::stripIter(first, last);
if(p.first == p.second) {
return false;
}
@@ -335,7 +336,7 @@ bool parseLLIntNoThrow
template<typename InputIterator>
int64_t parseLLInt(InputIterator first, InputIterator last, int base = 10)
{
- Scip p = util::stripIter(first, last);
+ std::pair<InputIterator, InputIterator> p = util::stripIter(first, last);
if(p.first == p.second) {
throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"empty string"));
@@ -373,7 +374,7 @@ int32_t parseInt(InputIterator first, InputIterator last, int base = 10)
template<typename InputIterator>
uint64_t parseULLInt(InputIterator first, InputIterator last, int base = 10)
{
- Scip p = util::stripIter(first, last);
+ std::pair<InputIterator, InputIterator> p = util::stripIter(first, last);
if(p.first == p.second) {
throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
"empty string"));