summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2008-12-09 14:43:11 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2008-12-09 14:43:11 +0000
commit1b54e64d34f87dca00a9d93bf110207a1098a2a5 (patch)
tree59f1041c47a38945b0cb57a2ca4bcc2e8386847d /src
parentbd8645262ddbff5df280da40953da1fe2bb06cdb (diff)
2008-12-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added bencode helper functions and BDE class. They will replace MetaFileUtil and Dictionary/List/Data classes. * src/Makefile.am * src/bencode.cc * src/bencode.h * test/BencodeTest.cc * test/Makefile.am
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/Makefile.in39
-rw-r--r--src/bencode.cc469
-rw-r--r--src/bencode.h214
4 files changed, 706 insertions, 19 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 80b6f751..270da0fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -193,7 +193,8 @@ SRCS = Socket.h\
NsCookieParser.cc NsCookieParser.h\
CookieStorage.cc CookieStorage.h\
SocketBuffer.cc SocketBuffer.h\
- OptionHandlerException.cc OptionHandlerException.h
+ OptionHandlerException.cc OptionHandlerException.h\
+ bencode.cc bencode.h
if ENABLE_SSL
SRCS += TLSContext.h
diff --git a/src/Makefile.in b/src/Makefile.in
index 09f73dca..a8373ec6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -417,9 +417,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \
CookieStorage.cc CookieStorage.h SocketBuffer.cc \
SocketBuffer.h OptionHandlerException.cc \
- OptionHandlerException.h TLSContext.h LibgnutlsTLSContext.cc \
- LibgnutlsTLSContext.h LibsslTLSContext.cc LibsslTLSContext.h \
- GZipDecoder.cc GZipDecoder.h Sqlite3MozCookieParser.cc \
+ OptionHandlerException.h bencode.cc bencode.h TLSContext.h \
+ LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
+ LibsslTLSContext.cc LibsslTLSContext.h GZipDecoder.cc \
+ GZipDecoder.h Sqlite3MozCookieParser.cc \
Sqlite3MozCookieParser.h AsyncNameResolver.cc \
AsyncNameResolver.h IteratableChunkChecksumValidator.cc \
IteratableChunkChecksumValidator.h \
@@ -813,14 +814,14 @@ am__objects_21 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
ServerStatMan.$(OBJEXT) InOrderURISelector.$(OBJEXT) \
ServerStatURISelector.$(OBJEXT) NsCookieParser.$(OBJEXT) \
CookieStorage.$(OBJEXT) SocketBuffer.$(OBJEXT) \
- OptionHandlerException.$(OBJEXT) $(am__objects_1) \
- $(am__objects_2) $(am__objects_3) $(am__objects_4) \
- $(am__objects_5) $(am__objects_6) $(am__objects_7) \
- $(am__objects_8) $(am__objects_9) $(am__objects_10) \
- $(am__objects_11) $(am__objects_12) $(am__objects_13) \
- $(am__objects_14) $(am__objects_15) $(am__objects_16) \
- $(am__objects_17) $(am__objects_18) $(am__objects_19) \
- $(am__objects_20)
+ OptionHandlerException.$(OBJEXT) bencode.$(OBJEXT) \
+ $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+ $(am__objects_4) $(am__objects_5) $(am__objects_6) \
+ $(am__objects_7) $(am__objects_8) $(am__objects_9) \
+ $(am__objects_10) $(am__objects_11) $(am__objects_12) \
+ $(am__objects_13) $(am__objects_14) $(am__objects_15) \
+ $(am__objects_16) $(am__objects_17) $(am__objects_18) \
+ $(am__objects_19) $(am__objects_20)
am_libaria2c_a_OBJECTS = $(am__objects_21)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@@ -1144,13 +1145,14 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \
CookieStorage.cc CookieStorage.h SocketBuffer.cc \
SocketBuffer.h OptionHandlerException.cc \
- OptionHandlerException.h $(am__append_1) $(am__append_2) \
- $(am__append_3) $(am__append_4) $(am__append_5) \
- $(am__append_6) $(am__append_7) $(am__append_8) \
- $(am__append_9) $(am__append_10) $(am__append_11) \
- $(am__append_12) $(am__append_13) $(am__append_14) \
- $(am__append_15) $(am__append_16) $(am__append_17) \
- $(am__append_18) $(am__append_19) $(am__append_20)
+ OptionHandlerException.h bencode.cc bencode.h $(am__append_1) \
+ $(am__append_2) $(am__append_3) $(am__append_4) \
+ $(am__append_5) $(am__append_6) $(am__append_7) \
+ $(am__append_8) $(am__append_9) $(am__append_10) \
+ $(am__append_11) $(am__append_12) $(am__append_13) \
+ $(am__append_14) $(am__append_15) $(am__append_16) \
+ $(am__append_17) $(am__append_18) $(am__append_19) \
+ $(am__append_20)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@@ -1522,6 +1524,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VersionMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XML2SAXMetalinkProcessor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asctime_r.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bencode.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/download_helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gai_strerror.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getaddrinfo.Po@am__quote@
diff --git a/src/bencode.cc b/src/bencode.cc
new file mode 100644
index 00000000..60a790a2
--- /dev/null
+++ b/src/bencode.cc
@@ -0,0 +1,469 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "bencode.h"
+
+#include <fstream>
+#include <sstream>
+
+#include "StringFormat.h"
+#include "Util.h"
+
+namespace aria2 {
+
+namespace bencode {
+
+const BDE BDE::none;
+
+BDE::BDE() throw():_type(TYPE_NONE) {}
+
+BDE::BDE(Integer integer) throw():_type(TYPE_INTEGER),
+ _integer(new Integer(integer)) {}
+
+
+BDE::BDE(const std::string& string) throw():_type(TYPE_STRING),
+ _string(new std::string(string)) {}
+
+BDE::BDE(const char* cstring) throw():_type(TYPE_STRING),
+ _string(new std::string(cstring)) {}
+
+BDE::BDE(const char* data, size_t length) throw():
+ _type(TYPE_STRING),
+ _string(new std::string(&data[0], &data[length])) {}
+
+BDE::BDE(const unsigned char* data, size_t length) throw():
+ _type(TYPE_STRING),
+ _string(new std::string(&data[0], &data[length])) {}
+
+BDE BDE::dict() throw()
+{
+ BDE bde;
+ bde._type = TYPE_DICT;
+ bde._dict.reset(new Dict());
+ return bde;
+}
+
+BDE BDE::list() throw()
+{
+ BDE bde;
+ bde._type = TYPE_LIST;
+ bde._list.reset(new List());
+ return bde;
+}
+
+// Test for Null data
+bool BDE::isNone() const throw()
+{
+ return _type == TYPE_NONE;
+}
+
+// Integer Interface
+
+bool BDE::isInteger() const throw()
+{
+ return _type == TYPE_INTEGER;
+}
+
+BDE::Integer BDE::i() const throw(RecoverableException)
+{
+ if(isInteger()) {
+ return *_integer.get();
+ } else {
+ throw RecoverableException("Not Integer");
+ }
+}
+
+// String Interface
+
+bool BDE::isString() const throw()
+{
+ return _type == TYPE_STRING;
+}
+
+const std::string& BDE::s() const throw(RecoverableException)
+{
+ if(isString()) {
+ return *_string.get();
+ } else {
+ throw RecoverableException("Not String");
+ }
+}
+
+// Dictionary Interface
+
+bool BDE::isDict() const throw()
+{
+ return _type == TYPE_DICT;
+}
+
+BDE& BDE::operator[](const std::string& key) throw(RecoverableException)
+{
+ if(isDict()) {
+ return (*_dict.get())[key];
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+const BDE& BDE::operator[](const std::string& key) const
+ throw(RecoverableException)
+{
+ if(isDict()) {
+ BDE::Dict::const_iterator i = _dict->find(key);
+ if(i == _dict->end()) {
+ return none;
+ } else {
+ return (*i).second;
+ }
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+bool BDE::containsKey(const std::string& key) const throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->find(key) != _dict->end();
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+
+BDE::Dict::iterator BDE::dictBegin() throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->begin();
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+BDE::Dict::const_iterator BDE::dictBegin() const throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->begin();
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+BDE::Dict::iterator BDE::dictEnd() throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->end();
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+BDE::Dict::const_iterator BDE::dictEnd() const throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->end();
+ } else {
+ throw RecoverableException("Not Dict");
+ }
+}
+
+// List Interface
+
+bool BDE::isList() const throw()
+{
+ return _type == TYPE_LIST;
+}
+
+void BDE::append(const BDE& bde) throw(RecoverableException)
+{
+ if(isList()) {
+ _list->push_back(bde);
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+void BDE::operator<<(const BDE& bde) throw(RecoverableException)
+{
+ if(isList()) {
+ _list->push_back(bde);
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+BDE& BDE::operator[](size_t index) throw(RecoverableException)
+{
+ if(isList()) {
+ return (*_list.get())[index];
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+const BDE& BDE::operator[](size_t index) const throw(RecoverableException)
+{
+ if(isList()) {
+ return (*_list.get())[index];
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+BDE::List::iterator BDE::listBegin() throw(RecoverableException)
+{
+ if(isList()) {
+ return _list->begin();
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+BDE::List::const_iterator BDE::listBegin() const throw(RecoverableException)
+{
+ if(isList()) {
+ return _list->begin();
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+BDE::List::iterator BDE::listEnd() throw(RecoverableException)
+{
+ if(isList()) {
+ return _list->end();
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+BDE::List::const_iterator BDE::listEnd() const throw(RecoverableException)
+{
+ if(isList()) {
+ return _list->end();
+ } else {
+ throw RecoverableException("Not List");
+ }
+}
+
+// Callable from List and Dict
+size_t BDE::size() const throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->size();
+ } else if(isList()) {
+ return _list->size();
+ } else {
+ throw RecoverableException("Not Dict nor List");
+ }
+}
+
+// Callable from List and Dict
+bool BDE::empty() const throw(RecoverableException)
+{
+ if(isDict()) {
+ return _dict->empty();
+ } else if(isList()) {
+ return _list->empty();
+ } else {
+ throw RecoverableException("Not Dict nor List");
+ }
+}
+
+static BDE decodeiter(std::istream& ss) throw(RecoverableException);
+
+static void checkdelim(std::istream& ss, const char delim = ':')
+ throw(RecoverableException)
+{
+ char d;
+ if(!(ss.get(d) && d == delim)) {
+ throw RecoverableException
+ (StringFormat("Delimiter '%c' not found.", delim).str());
+ }
+}
+
+static std::string decoderawstring(std::istream& ss)
+ throw(RecoverableException)
+{
+ size_t length;
+ ss >> length;
+ if(!ss) {
+ throw RecoverableException("Integer expected but none found.");
+ }
+ // TODO check length, it must be less than or equal to INT_MAX
+ checkdelim(ss);
+ char* buf = new char[length];
+ ss.read(buf, length);
+ if(ss.gcount() != static_cast<int>(length)) {
+ throw RecoverableException
+ (StringFormat("Expected %lu bytes of data, but only %d read.",
+ static_cast<unsigned long>(length), ss.gcount()).str());
+ }
+ std::string str(&buf[0], &buf[length]);
+ delete [] buf;
+ return str;
+}
+
+static BDE decodestring(std::istream& ss) throw(RecoverableException)
+{
+ return BDE(decoderawstring(ss));
+}
+
+static BDE decodeinteger(std::istream& ss) throw(RecoverableException)
+{
+ BDE::Integer integer;
+ ss >> integer;
+ if(!ss) {
+ throw RecoverableException("Integer expected but none found");
+ }
+ checkdelim(ss, 'e');
+ return BDE(integer);
+}
+
+static BDE decodedict(std::istream& ss) throw(RecoverableException)
+{
+ BDE dict = BDE::dict();
+ char c;
+ while(ss.get(c)) {
+ if(c == 'e') {
+ return dict;
+ } else {
+ ss.unget();
+ std::string key = decoderawstring(ss);
+ dict[key] = decodeiter(ss);
+ }
+ }
+ throw RecoverableException("Unexpected EOF in dict context. 'e' expected.");
+}
+
+static BDE decodelist(std::istream& ss) throw(RecoverableException)
+{
+ BDE list = BDE::list();
+ char c;
+ while(ss.get(c)) {
+ if(c == 'e') {
+ return list;
+ } else {
+ ss.unget();
+ list << decodeiter(ss);
+ }
+ }
+ throw RecoverableException("Unexpected EOF in list context. 'e' expected.");
+}
+
+static BDE decodeiter(std::istream& ss) throw(RecoverableException)
+{
+ char c;
+ if(!ss.get(c)) {
+ throw RecoverableException("Unexpected EOF in term context."
+ " 'd', 'l', 'i' or digit is expected.");
+ }
+ if(c == 'd') {
+ return decodedict(ss);
+ } else if(c == 'l') {
+ return decodelist(ss);
+ } else if(c == 'i') {
+ return decodeinteger(ss);
+ } else {
+ ss.unget();
+ return decodestring(ss);
+ }
+}
+
+BDE decode(std::istream& in) throw(RecoverableException)
+{
+ return decodeiter(in);
+}
+
+BDE decode(const std::string& s) throw(RecoverableException)
+{
+ if(s.empty()) {
+ return BDE::none;
+ }
+ std::istringstream ss(s);
+
+ return decodeiter(ss);
+}
+
+BDE decode(const unsigned char* data, size_t length) throw(RecoverableException)
+{
+ return decode(std::string(&data[0], &data[length]));
+}
+
+BDE decodeFromFile(const std::string& filename) throw(RecoverableException)
+{
+ std::ifstream f(filename.c_str());
+ if(f) {
+ return decode(f);
+ } else {
+ throw RecoverableException
+ (StringFormat("Cannot open file '%s'.", filename.c_str()).str());
+ }
+}
+
+static void encodeIter(std::ostream& o, const BDE& bde) throw()
+{
+ if(bde.isInteger()) {
+ o << "i" << bde.i() << "e";
+ } else if(bde.isString()) {
+ const std::string& s = bde.s();
+ o << s.size() << ":";
+ o.write(s.data(), s.size());
+ } else if(bde.isDict()) {
+ o << "d";
+ for(BDE::Dict::const_iterator i = bde.dictBegin(); i != bde.dictEnd(); ++i){
+ const std::string& key = (*i).first;
+ o << key.size() << ":";
+ o.write(key.data(), key.size());
+ encodeIter(o, (*i).second);
+ }
+ o << "e";
+ } else if(bde.isList()) {
+ o << "l";
+ for(BDE::List::const_iterator i = bde.listBegin(); i != bde.listEnd(); ++i){
+ encodeIter(o, *i);
+ }
+ o << "e";
+ }
+}
+
+std::string encode(const BDE& bde) throw()
+{
+ std::ostringstream ss;
+ encodeIter(ss, bde);
+ return ss.str();
+}
+
+} // namespace bencode
+
+} // namespace aria2
diff --git a/src/bencode.h b/src/bencode.h
new file mode 100644
index 00000000..2a7fcea3
--- /dev/null
+++ b/src/bencode.h
@@ -0,0 +1,214 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "common.h"
+
+#include <string>
+#include <map>
+#include <deque>
+#include <iosfwd>
+
+#include "SharedHandle.h"
+#include "RecoverableException.h"
+
+namespace aria2 {
+
+namespace bencode {
+
+class BDE;
+
+class BDE {
+public:
+ typedef std::map<std::string, BDE> Dict;
+ typedef std::deque<BDE> List;
+ typedef int64_t Integer;
+private:
+ enum TYPE{
+ TYPE_NONE,
+ TYPE_INTEGER,
+ TYPE_STRING,
+ TYPE_DICT,
+ TYPE_LIST,
+ };
+
+ TYPE _type;
+ SharedHandle<Dict> _dict;
+ SharedHandle<List> _list;
+ SharedHandle<std::string> _string;
+ SharedHandle<Integer> _integer;
+
+public:
+ BDE() throw();
+
+ static BDE dict() throw();
+
+ static BDE list() throw();
+
+ static const BDE none;
+
+ // Test for Null data
+ // Return true if the type of this object is None.
+ bool isNone() const throw();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Integer Interface
+
+ BDE(Integer integer) throw();
+
+ // Returns true if the type of this object is Integer.
+ bool isInteger() const throw();
+
+ // Returns Integer. Requires this object to be Integer.
+ Integer i() const throw(RecoverableException);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // String Interface
+
+ BDE(const std::string& string) throw();
+
+ // Made explicit to avoid ambiguity with BDE(Integer).
+ explicit BDE(const char* cstring) throw();
+
+ BDE(const char* data, size_t length) throw();
+
+ BDE(const unsigned char* data, size_t length) throw();
+
+ // Returns true if the type of this object is String.
+ bool isString() const throw();
+
+ // Returns std::string. Requires this object to be String
+ const std::string& s() const throw(RecoverableException);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Dictionary Interface
+
+ // Returns true if the type of this object is Dict.
+ bool isDict() const throw();
+
+ // Returns the reference to BDE object associated with given key.
+ // If the key is not found, new pair with that key is created using default
+ // values, which is then returned. In other words, this is the same behavior
+ // of std::map's operator[].
+ // Requires this object to be Dict.
+ BDE& operator[](const std::string& key) throw(RecoverableException);
+
+ // Returns the const reference to BDE ojbect associated with given key.
+ // If the key is not found, BDE::none is returned.
+ // Requires this object to be Dict.
+ const BDE& operator[](const std::string& key) const
+ throw(RecoverableException);
+
+ // Returns true if the given key is found in dict.
+ // Requires this object to be Dict.
+ bool containsKey(const std::string& key) const throw(RecoverableException);
+
+ // Returns a read/write iterator that points to the first pair in the dict.
+ // Requires this object to be Dict.
+ Dict::iterator dictBegin() throw(RecoverableException);
+
+ // Returns a read/write read-only iterator that points to the first pair in
+ // the dict.
+ // Requires this object to be Dict.
+ Dict::const_iterator dictBegin() const throw(RecoverableException);
+
+ // Returns a read/write read-only iterator that points to one past the last
+ // pair in the dict.
+ // Requires this object to be Dict.
+ Dict::iterator dictEnd() throw(RecoverableException);
+
+ // Returns a read/write read-only iterator that points to one past the last
+ // pair in the dict.
+ // Requires this object to be Dict.
+ Dict::const_iterator dictEnd() const throw(RecoverableException);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // List Interface
+
+ // Returns true if the type of this object is List.
+ bool isList() const throw();
+
+ // Appends given bde to list. Required the type of this object to be List.
+ void append(const BDE& bde) throw(RecoverableException);
+
+ // Alias for append()
+ void operator<<(const BDE& bde) throw(RecoverableException);
+
+ // Returns the reference of the object at the given index. Required this
+ // object to be List.
+ BDE& operator[](size_t index) throw(RecoverableException);
+
+ // Returns the const reference of the object at the given index.
+ // Required this object to be List.
+ const BDE& operator[](size_t index) const throw(RecoverableException);
+
+ // Returns a read/write iterator that points to the first object in list.
+ // Required this object to be List.
+ List::iterator listBegin() throw(RecoverableException);
+
+ // Returns a read/write read-only iterator that points to the first object
+ // in list. Required this object to be List.
+ List::const_iterator listBegin() const throw(RecoverableException);
+
+ // Returns a read/write iterator that points to the one past the last object
+ // in list. Required this object to be List.
+ List::iterator listEnd() throw(RecoverableException);
+
+ // Returns a read/write read-only iterator that points to the one past the
+ // last object in list. Required this object to be List.
+ List::const_iterator listEnd() const throw(RecoverableException);
+
+ // For List type: Returns size of list.
+ // For Dict type: Returns size of dict.
+ size_t size() const throw(RecoverableException);
+
+ // For List type: Returns true if size of list is 0.
+ // For Dict type: Returns true if size of dict is 0.
+ bool empty() const throw(RecoverableException);
+};
+
+BDE decode(std::istream& in) throw(RecoverableException);
+
+// Decode the data in s.
+BDE decode(const std::string& s) throw(RecoverableException);
+
+BDE decode(const unsigned char* data, size_t length)
+ throw(RecoverableException);
+
+BDE decodeFromFile(const std::string& filename) throw(RecoverableException);
+
+std::string encode(const BDE& bde) throw();
+
+} // namespace bencode
+
+} // namespace aria2