Browse Source

2010-06-20 Tatsuhiro Tsujikawa <[email protected]>

	Removed BDE and bencode
Tatsuhiro Tsujikawa 15 năm trước cách đây
mục cha
commit
cb4e25e4b4
81 tập tin đã thay đổi với 1570 bổ sung2754 xóa
  1. 4 0
      ChangeLog
  2. 0 1
      src/AnnounceList.cc
  3. 0 223
      src/BDE.cc
  4. 0 431
      src/BDE.h
  5. 15 11
      src/DHTAbstractMessage.cc
  6. 2 2
      src/DHTAbstractMessage.h
  7. 6 7
      src/DHTAnnouncePeerMessage.cc
  8. 1 1
      src/DHTAnnouncePeerMessage.h
  9. 3 4
      src/DHTAnnouncePeerReplyMessage.cc
  10. 1 1
      src/DHTAnnouncePeerReplyMessage.h
  11. 4 5
      src/DHTFindNodeMessage.cc
  12. 1 1
      src/DHTFindNodeMessage.h
  13. 4 5
      src/DHTFindNodeReplyMessage.cc
  14. 1 1
      src/DHTFindNodeReplyMessage.h
  15. 4 5
      src/DHTGetPeersMessage.cc
  16. 1 1
      src/DHTGetPeersMessage.h
  17. 9 10
      src/DHTGetPeersReplyMessage.cc
  18. 1 1
      src/DHTGetPeersReplyMessage.h
  19. 3 3
      src/DHTMessageFactory.h
  20. 106 113
      src/DHTMessageFactoryImpl.cc
  21. 7 7
      src/DHTMessageFactoryImpl.h
  22. 7 6
      src/DHTMessageReceiver.cc
  23. 9 8
      src/DHTMessageTracker.cc
  24. 2 2
      src/DHTMessageTracker.h
  25. 3 4
      src/DHTPingMessage.cc
  26. 1 1
      src/DHTPingMessage.h
  27. 8 8
      src/DHTPingReplyMessage.cc
  28. 1 1
      src/DHTPingReplyMessage.h
  29. 3 4
      src/DHTQueryMessage.cc
  30. 3 2
      src/DHTQueryMessage.h
  31. 2 3
      src/DHTResponseMessage.cc
  32. 3 2
      src/DHTResponseMessage.h
  33. 20 17
      src/DefaultExtensionMessageFactory.cc
  34. 5 1
      src/ExpatXmlRpcRequestProcessor.cc
  35. 33 30
      src/HandshakeExtensionMessage.cc
  36. 2 4
      src/Makefile.am
  37. 36 41
      src/Makefile.in
  38. 49 93
      src/PeerListProcessor.h
  39. 6 7
      src/UTMetadataDataExtensionMessage.cc
  40. 1 2
      src/UTMetadataPostDownloadHandler.cc
  41. 5 6
      src/UTMetadataRejectExtensionMessage.cc
  42. 5 6
      src/UTMetadataRequestExtensionMessage.cc
  43. 15 15
      src/UTPexExtensionMessage.cc
  44. 15 0
      src/ValueBase.cc
  45. 8 0
      src/ValueBase.h
  46. 5 1
      src/Xml2XmlRpcRequestProcessor.cc
  47. 38 27
      src/XmlRpcMethod.cc
  48. 9 8
      src/XmlRpcMethod.h
  49. 306 299
      src/XmlRpcMethodImpl.cc
  50. 88 51
      src/XmlRpcMethodImpl.h
  51. 4 3
      src/XmlRpcRequest.h
  52. 25 5
      src/XmlRpcRequestParserController.cc
  53. 6 12
      src/XmlRpcRequestParserController.h
  54. 7 7
      src/XmlRpcRequestParserStateImpl.cc
  55. 3 5
      src/XmlRpcRequestParserStateMachine.h
  56. 44 39
      src/XmlRpcResponse.cc
  57. 4 3
      src/XmlRpcResponse.h
  58. 0 242
      src/bencode.cc
  59. 0 72
      src/bencode.h
  60. 0 1
      src/bittorrent_helper.cc
  61. 0 149
      test/BDETest.cc
  62. 0 202
      test/BencodeTest.cc
  63. 14 14
      test/DHTAnnouncePeerMessageTest.cc
  64. 9 9
      test/DHTAnnouncePeerReplyMessageTest.cc
  65. 12 12
      test/DHTFindNodeMessageTest.cc
  66. 10 10
      test/DHTFindNodeReplyMessageTest.cc
  67. 12 12
      test/DHTGetPeersMessageTest.cc
  68. 16 16
      test/DHTGetPeersReplyMessageTest.cc
  69. 88 88
      test/DHTMessageFactoryImplTest.cc
  70. 9 10
      test/DHTMessageTrackerTest.cc
  71. 10 10
      test/DHTPingMessageTest.cc
  72. 9 9
      test/DHTPingReplyMessageTest.cc
  73. 3 5
      test/Makefile.am
  74. 14 19
      test/Makefile.in
  75. 2 3
      test/MockDHTMessage.h
  76. 4 4
      test/MockDHTMessageFactory.h
  77. 5 5
      test/PeerListProcessorTest.cc
  78. 0 1
      test/UTMetadataDataExtensionMessageTest.cc
  79. 330 265
      test/XmlRpcMethodTest.cc
  80. 39 34
      test/XmlRpcRequestParserControllerTest.cc
  81. 30 6
      test/XmlRpcRequestProcessorTest.cc

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+2010-06-20  Tatsuhiro Tsujikawa  <[email protected]>
+
+	Removed BDE and bencode
+
 2010-06-18  Tatsuhiro Tsujikawa  <[email protected]>
 
 	Introduced ValueBase class, which is a replacement of BDE.  In

+ 0 - 1
src/AnnounceList.cc

@@ -38,7 +38,6 @@
 
 #include "A2STR.h"
 #include "SimpleRandomizer.h"
-#include "bencode.h"
 #include "util.h"
 
 namespace aria2 {

+ 0 - 223
src/BDE.cc

@@ -1,223 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2009 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 "BDE.h"
-
-namespace aria2 {
-
-const BDE BDE::none;
-
-BDE::BDE():_type(TYPE_NONE), _bobject(new BObject()) {}
-
-BDE::BDE(Integer integer):_type(TYPE_INTEGER),
-                          _bobject(new BInteger(integer)) {}
-
-
-BDE::BDE(const std::string& string):_type(TYPE_STRING),
-                                    _bobject(new BString(std::string(string))) {}
-
-BDE::BDE(const char* cstring):_type(TYPE_STRING),
-                              _bobject(new BString(std::string(cstring))) {}
-
-BDE::BDE(const char* data, size_t length):
-  _type(TYPE_STRING),
-  _bobject(new BString(std::string(&data[0], &data[length]))) {}
-
-BDE::BDE(const unsigned char* data, size_t length):
-  _type(TYPE_STRING),
-  _bobject(new BString(std::string(&data[0], &data[length]))) {}
-
-BDE BDE::dict()
-{
-  BDE bde;
-  bde._type = TYPE_DICT;
-  bde._bobject.reset(new BDict());
-  return bde;
-}
-
-BDE BDE::list()
-{
-  BDE bde;
-  bde._type = TYPE_LIST;
-  bde._bobject.reset(new BList());
-  return bde;
-}
-
-// Test for Null data
-bool BDE::isNone() const
-{
-  return _type == TYPE_NONE;
-}
-
-// Integer Interface
-
-bool BDE::isInteger() const
-{
-  return _type == TYPE_INTEGER;
-}
-
-BDE::Integer BDE::i() const
-{
-  return _bobject->i();
-}
-
-// String Interface
-
-bool BDE::isString() const
-{
-  return _type == TYPE_STRING;
-}
-
-const std::string& BDE::s() const
-{
-  return _bobject->s();
-}
-
-const unsigned char* BDE::uc() const
-{
-  return _bobject->uc();
-}
-
-// Dictionary Interface
-
-bool BDE::isDict() const
-{
-  return _type == TYPE_DICT;
-}
-
-BDE& BDE::operator[](const std::string& key)
-{
-  return _bobject->operator[](key);
-}
-
-const BDE& BDE::operator[](const std::string& key) const
-{
-  if(_bobject->containsKey(key)) {
-    return _bobject->operator[](key);
-  } else {
-    return none;
-  }
-}
-
-bool BDE::containsKey(const std::string& key) const
-{
-  return _bobject->containsKey(key);
-}
-
-void BDE::removeKey(const std::string& key)
-{
-  _bobject->removeKey(key);
-}
-
-BDE::Dict::iterator BDE::dictBegin()
-{
-  return _bobject->dictBegin();
-}
-
-BDE::Dict::const_iterator BDE::dictBegin() const
-{
-  return _bobject->dictBegin();
-}
-
-BDE::Dict::iterator BDE::dictEnd()
-{
-  return _bobject->dictEnd();
-}
-
-BDE::Dict::const_iterator BDE::dictEnd() const
-{
-  return _bobject->dictEnd();
-}
-
-// List Interface
-
-bool BDE::isList() const
-{
-  return _type == TYPE_LIST;
-}
-
-void BDE::append(const BDE& bde)
-{
-  _bobject->append(bde);
-}
-
-void BDE::operator<<(const BDE& bde)
-{
-  _bobject->operator<<(bde);
-}
-
-BDE& BDE::operator[](size_t index)
-{
-  return _bobject->operator[](index);
-}
-
-const BDE& BDE::operator[](size_t index) const
-{
-  return _bobject->operator[](index);
-}
-
-BDE::List::iterator BDE::listBegin()
-{
-  return _bobject->listBegin();
-}
-
-BDE::List::const_iterator BDE::listBegin() const
-{
-  return _bobject->listBegin();
-}
-
-BDE::List::iterator BDE::listEnd()
-{
-  return _bobject->listEnd();
-}
-
-BDE::List::const_iterator BDE::listEnd() const
-{
-  return _bobject->listEnd();
-}
-
-// Callable from List and Dict
-size_t BDE::size() const
-{
-  return _bobject->size();
-}
-
-// Callable from List and Dict
-bool BDE::empty() const
-{
-  return _bobject->empty();
-}
-
-} // namespace aria2

+ 0 - 431
src/BDE.h

@@ -1,431 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2009 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 --> */
-#ifndef _D_BDE_H_
-#define _D_BDE_H_
-
-#include "common.h"
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "SharedHandle.h"
-#include "DlAbortEx.h"
-
-namespace aria2 {
-
-class BDE;
-
-class BDE {
-public:
-  typedef std::map<std::string, BDE> Dict;
-  typedef std::vector<BDE> List;
-  typedef int64_t Integer;
-private:
-  enum TYPE{
-    TYPE_NONE,
-    TYPE_INTEGER,
-    TYPE_STRING,
-    TYPE_DICT,
-    TYPE_LIST,
-  };
-
-  class BObject {
-  public:
-    virtual ~BObject() {}
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Integer Interface
-
-    // Returns Integer.
-    virtual Integer i() const
-    {
-      throw DL_ABORT_EX("Not Integer");
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-    // String Interface
-
-    // Returns std::string.
-    virtual const std::string& s() const
-    {
-      throw DL_ABORT_EX("Not String");
-    } 
-
-    // Returns std::string.data() casted to unsigned char*.
-    // Use s().size() to get length.
-    virtual const unsigned char* uc() const
-    {
-      throw DL_ABORT_EX("Not String");
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Dictionary Interface
-
-    // 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[].
-    virtual BDE& operator[](const std::string& key)
-    {
-      throw DL_ABORT_EX("Not Dict");
-    }
-
-    // Returns true if the given key is found in dict.
-    virtual bool containsKey(const std::string& key) const
-    {
-      throw DL_ABORT_EX("Not Dict");
-    }
-
-    // Removes specified key from dict.
-    virtual void removeKey(const std::string& key)
-    {
-      throw DL_ABORT_EX("Not Dict");
-    }
-
-    // Returns a read/write iterator that points to the first pair in
-    // the dict.
-    virtual Dict::iterator dictBegin()
-    {
-      throw DL_ABORT_EX("Not Dict");
-    }
-
-    // Returns a read/write read-only iterator that points to one past
-    // the last pair in the dict.
-    virtual Dict::iterator dictEnd()
-    {
-      throw DL_ABORT_EX("Not Dict");
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-    // List Interface
-    
-    // Appends given bde to list.
-    virtual void append(const BDE& bde)
-    {
-      throw DL_ABORT_EX("Not List");
-    }
-
-    // Alias for append()
-    virtual void operator<<(const BDE& bde)
-    {
-      throw DL_ABORT_EX("Not List");
-    }
-
-    // Returns the reference of the object at the given index.
-    virtual BDE& operator[](size_t index)
-    {
-      throw DL_ABORT_EX("Not List");
-    }
-
-    // Returns a read/write iterator that points to the first object
-    // in list.
-    virtual List::iterator listBegin()
-    {
-      throw DL_ABORT_EX("Not List");
-    }
-
-    // Returns a read/write iterator that points to the one past the
-    // last object in list.
-    virtual List::iterator listEnd()
-    {
-      throw DL_ABORT_EX("Not List");
-    }
-    
-    // Returns size of list or dict.
-    virtual size_t size() const
-    {
-      throw DL_ABORT_EX("Neither Dict nor List");
-    }
-
-    // Returns true if size of list or dict is 0.
-    virtual bool empty() const
-    {
-      throw DL_ABORT_EX("Neither Dict nor List");
-    }
-  };
-
-  class BInteger : public BObject {
-  private:
-    Integer _integer;
-  public:
-    BInteger(Integer i):_integer(i) {}
-
-    virtual BDE::Integer i() const
-    {
-      return _integer;
-    }
-  };
-
-  class BString : public BObject {
-  private:
-    std::string _string;
-  public:
-    BString(const std::string& string):_string(string) {}
-
-    virtual const std::string& s() const
-    {
-      return _string;
-    }
-
-    virtual const unsigned char* uc() const
-    {
-      return reinterpret_cast<const unsigned char*>(_string.data());
-    }
-  };
-
-  class BDict : public BObject {
-  private:
-    Dict _dict;
-  public:
-
-    virtual BDE& operator[](const std::string& key)
-    {
-      return _dict[key];
-    }
-
-    virtual bool containsKey(const std::string& key) const
-    {
-      return _dict.find(key) != _dict.end();
-    }
-
-    virtual void removeKey(const std::string& key)
-    {
-      _dict.erase(key);
-    }
-
-    virtual BDE::Dict::iterator dictBegin()
-    {
-      return _dict.begin();
-    }
-
-    virtual BDE::Dict::iterator dictEnd()
-    {
-      return _dict.end();
-    }
-
-    virtual size_t size() const
-    {
-      return _dict.size();
-    }
-
-    virtual bool empty() const
-    {
-      return _dict.empty();
-    }
-  };
-
-  class BList : public BObject {
-  private:
-    List _list;
-  public:
-    virtual void append(const BDE& bde)
-    {
-      _list.push_back(bde);
-    }
-
-    virtual void operator<<(const BDE& bde)
-    {
-      _list.push_back(bde);
-    }
-
-    virtual BDE& operator[](size_t index)
-    {
-      return _list[index];
-    }
-
-    virtual BDE::List::iterator listBegin()
-    {
-      return _list.begin();
-    }
-
-    virtual BDE::List::iterator listEnd()
-    {
-      return _list.end();
-    }
-
-    virtual size_t size() const
-    {
-      return _list.size();
-    }
-
-    virtual bool empty() const
-    {
-      return _list.empty();
-    }
-  };
-
-  TYPE _type;
-
-  SharedHandle<BObject> _bobject;
-public:
-  BDE();
-
-  static BDE dict();
-
-  static BDE list();
-
-  static const BDE none;
-
-  // Test for Null data
-  // Return true if the type of this object is None.
-  bool isNone() const;
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Integer Interface
-
-  BDE(Integer integer);
-
-  // Returns true if the type of this object is Integer.
-  bool isInteger() const;
-
-  // Returns Integer. Requires this object to be Integer.
-  Integer i() const;
-
-  //////////////////////////////////////////////////////////////////////////////
-  // String Interface
-
-  BDE(const std::string& string);
-
-  // Made explicit to avoid ambiguity with BDE(Integer).
-  explicit BDE(const char* cstring);
-
-  BDE(const char* data, size_t length);
-
-  BDE(const unsigned char* data, size_t length);
-
-  // Returns true if the type of this object is String.
-  bool isString() const;
-
-  // Returns std::string. Requires this object to be String
-  const std::string& s() const;
-
-  // Returns std::string.data() casted to unsigned char*.
-  // Use s().size() to get length.
-  const unsigned char* uc() const;
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Dictionary Interface
-
-  // Returns true if the type of this object is Dict.
-  bool isDict() const;
-
-  // 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);
-
-  // 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;
-
-  // Returns true if the given key is found in dict.
-  // Requires this object to be Dict.
-  bool containsKey(const std::string& key) const;
-
-  // Removes specified key from dict.
-  // Requires this object to be Dict.
-  void removeKey(const std::string& key);
-
-  // Returns a read/write iterator that points to the first pair in the dict.
-  // Requires this object to be Dict.
-  Dict::iterator dictBegin();
-
-  // 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;
-
-  // 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();
-
-  // 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;
-
-  //////////////////////////////////////////////////////////////////////////////
-  // List Interface
-
-  // Returns true if the type of this object is List.
-  bool isList() const;
-
-  // Appends given bde to list. Required the type of this object to be List.
-  void append(const BDE& bde);
-
-  // Alias for append()
-  void operator<<(const BDE& bde);
-
-  // Returns the reference of the object at the given index. Required this
-  // object to be List.
-  BDE& operator[](size_t index);
-
-  // Returns the const reference of the object at the given index.
-  // Required this object to be List.
-  const BDE& operator[](size_t index) const;
-
-  // Returns a read/write iterator that points to the first object in list.
-  // Required this object to be List.
-  List::iterator listBegin();
-
-  // 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;
-
-  // 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();
-
-  // 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;
-
-  // For List type: Returns size of list.
-  // For Dict type: Returns size of dict.
-  size_t size() const;
-
-  // 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;
-};
-
-} // namespace aria2
-
-#endif // _D_BDE_H_

+ 15 - 11
src/DHTAbstractMessage.cc

@@ -42,7 +42,7 @@
 #include "DHTMessageFactory.h"
 #include "DHTRoutingTable.h"
 #include "DHTMessageCallback.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -55,12 +55,12 @@ DHTAbstractMessage::~DHTAbstractMessage() {}
 
 std::string DHTAbstractMessage::getBencodedMessage()
 {
-  BDE msgDict = BDE::dict();
-  msgDict[T] = getTransactionID();
-  msgDict[Y] = getType();
-  msgDict[V] = getVersion();
-  fillMessage(msgDict);
-  return bencode::encode(msgDict);
+  Dict msgDict;
+  msgDict.put(T, getTransactionID());
+  msgDict.put(Y, getType());
+  msgDict.put(V, getVersion());
+  fillMessage(&msgDict);
+  return bencode2::encode(&msgDict);
 }
 
 bool DHTAbstractMessage::send()
@@ -75,22 +75,26 @@ bool DHTAbstractMessage::send()
   return r == static_cast<ssize_t>(message.size());
 }
 
-void DHTAbstractMessage::setConnection(const WeakHandle<DHTConnection>& connection)
+void DHTAbstractMessage::setConnection
+(const WeakHandle<DHTConnection>& connection)
 {
   _connection = connection;
 }
 
-void DHTAbstractMessage::setMessageDispatcher(const WeakHandle<DHTMessageDispatcher>& dispatcher)
+void DHTAbstractMessage::setMessageDispatcher
+(const WeakHandle<DHTMessageDispatcher>& dispatcher)
 {
   _dispatcher = dispatcher;
 }
 
-void DHTAbstractMessage::setMessageFactory(const WeakHandle<DHTMessageFactory>& factory)
+void DHTAbstractMessage::setMessageFactory
+(const WeakHandle<DHTMessageFactory>& factory)
 {
   _factory = factory;
 }
 
-void DHTAbstractMessage::setRoutingTable(const WeakHandle<DHTRoutingTable>& routingTable)
+void DHTAbstractMessage::setRoutingTable
+(const WeakHandle<DHTRoutingTable>& routingTable)
 {
   _routingTable = routingTable;
 }

+ 2 - 2
src/DHTAbstractMessage.h

@@ -37,10 +37,10 @@
 
 #include "DHTMessage.h"
 #include "A2STR.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
-class BDE;
 class DHTConnection;
 class DHTMessageDispatcher;
 class DHTMessageFactory;
@@ -66,7 +66,7 @@ public:
 
   virtual const std::string& getType() const = 0;
 
-  virtual void fillMessage(BDE& msgDict) = 0;
+  virtual void fillMessage(Dict* msgDict) = 0;
 
   std::string getBencodedMessage();
 

+ 6 - 7
src/DHTAnnouncePeerMessage.cc

@@ -47,7 +47,6 @@
 #include "DlAbortEx.h"
 #include "BtConstants.h"
 #include "StringFormat.h"
-#include "bencode.h"
 #include "a2functional.h"
 
 namespace aria2 {
@@ -87,13 +86,13 @@ void DHTAnnouncePeerMessage::doReceivedAction()
   getMessageDispatcher()->addMessageToQueue(reply);
 }
 
-BDE DHTAnnouncePeerMessage::getArgument()
+SharedHandle<Dict> DHTAnnouncePeerMessage::getArgument()
 {
-  BDE aDict = BDE::dict();
-  aDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
-  aDict[INFO_HASH] = BDE(_infoHash, DHT_ID_LENGTH);
-  aDict[PORT] = _tcpPort;
-  aDict[TOKEN] = _token;
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
+  aDict->put(INFO_HASH, String::g(_infoHash, DHT_ID_LENGTH));
+  aDict->put(PORT, Integer::g(_tcpPort));
+  aDict->put(TOKEN, _token);
   return aDict;
 }
 

+ 1 - 1
src/DHTAnnouncePeerMessage.h

@@ -69,7 +69,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getArgument();
+  virtual SharedHandle<Dict> getArgument();
   
   virtual const std::string& getMessageType() const;
 

+ 3 - 4
src/DHTAnnouncePeerReplyMessage.cc

@@ -34,7 +34,6 @@
 /* copyright --> */
 #include "DHTAnnouncePeerReplyMessage.h"
 #include "DHTNode.h"
-#include "bencode.h"
 #include "DHTMessageCallback.h"
 
 namespace aria2 {
@@ -51,10 +50,10 @@ DHTAnnouncePeerReplyMessage::~DHTAnnouncePeerReplyMessage() {}
 
 void DHTAnnouncePeerReplyMessage::doReceivedAction() {}
 
-BDE DHTAnnouncePeerReplyMessage::getResponse()
+SharedHandle<Dict> DHTAnnouncePeerReplyMessage::getResponse()
 {
-  BDE rDict = BDE::dict();
-  rDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
   return rDict;
 }
 

+ 1 - 1
src/DHTAnnouncePeerReplyMessage.h

@@ -49,7 +49,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getResponse();
+  virtual SharedHandle<Dict> getResponse();
 
   virtual const std::string& getMessageType() const;
 

+ 4 - 5
src/DHTFindNodeMessage.cc

@@ -42,7 +42,6 @@
 #include "DHTMessageDispatcher.h"
 #include "DHTMessageCallback.h"
 #include "util.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -71,11 +70,11 @@ void DHTFindNodeMessage::doReceivedAction()
   getMessageDispatcher()->addMessageToQueue(reply);
 }
 
-BDE DHTFindNodeMessage::getArgument()
+SharedHandle<Dict> DHTFindNodeMessage::getArgument()
 {
-  BDE aDict = BDE::dict();
-  aDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
-  aDict[TARGET_NODE] = BDE(_targetNodeID, DHT_ID_LENGTH);
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
+  aDict->put(TARGET_NODE, String::g(_targetNodeID, DHT_ID_LENGTH));
   return aDict;
 }
 

+ 1 - 1
src/DHTFindNodeMessage.h

@@ -55,7 +55,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getArgument();
+  virtual SharedHandle<Dict> getArgument();
   
   virtual const std::string& getMessageType() const;
 

+ 4 - 5
src/DHTFindNodeReplyMessage.cc

@@ -44,7 +44,6 @@
 #include "DHTMessageCallback.h"
 #include "bittorrent_helper.h"
 #include "util.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -70,10 +69,10 @@ void DHTFindNodeReplyMessage::doReceivedAction()
   }
 }
 
-BDE DHTFindNodeReplyMessage::getResponse()
+SharedHandle<Dict> DHTFindNodeReplyMessage::getResponse()
 {
-  BDE aDict = BDE::dict();
-  aDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
   size_t offset = 0;
   unsigned char buffer[DHTBucket::K*26];
   // TODO if _closestKNodes.size() > DHTBucket::K ??
@@ -87,7 +86,7 @@ BDE DHTFindNodeReplyMessage::getResponse()
       offset += 26;
     }
   }
-  aDict[NODES] = BDE(buffer, offset);
+  aDict->put(NODES, String::g(buffer, offset));
   return aDict;
 }
 

+ 1 - 1
src/DHTFindNodeReplyMessage.h

@@ -54,7 +54,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getResponse();
+  virtual SharedHandle<Dict> getResponse();
   
   virtual const std::string& getMessageType() const;
 

+ 4 - 5
src/DHTGetPeersMessage.cc

@@ -45,7 +45,6 @@
 #include "Peer.h"
 #include "DHTTokenTracker.h"
 #include "util.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -86,11 +85,11 @@ void DHTGetPeersMessage::doReceivedAction()
   getMessageDispatcher()->addMessageToQueue(reply);
 }
 
-BDE DHTGetPeersMessage::getArgument()
+SharedHandle<Dict> DHTGetPeersMessage::getArgument()
 {
-  BDE aDict = BDE::dict();
-  aDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
-  aDict[INFO_HASH] = BDE(_infoHash, DHT_ID_LENGTH);
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
+  aDict->put(INFO_HASH, String::g(_infoHash, DHT_ID_LENGTH));
   return aDict;
 }
 

+ 1 - 1
src/DHTGetPeersMessage.h

@@ -63,7 +63,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getArgument();
+  virtual SharedHandle<Dict> getArgument();
   
   virtual const std::string& getMessageType() const;
 

+ 9 - 10
src/DHTGetPeersReplyMessage.cc

@@ -45,7 +45,6 @@
 #include "bittorrent_helper.h"
 #include "Peer.h"
 #include "util.h"
-#include "bencode.h"
 #include "a2functional.h"
 
 namespace aria2 {
@@ -73,11 +72,11 @@ void DHTGetPeersReplyMessage::doReceivedAction()
   // Returned peers and nodes are handled in DHTPeerLookupTask.
 }
 
-BDE DHTGetPeersReplyMessage::getResponse()
+SharedHandle<Dict> DHTGetPeersReplyMessage::getResponse()
 {
-  BDE rDict = BDE::dict();
-  rDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
-  rDict[TOKEN] = _token;
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
+  rDict->put(TOKEN, _token);
   if(_values.empty()) {
     size_t offset = 0;
     unsigned char buffer[DHTBucket::K*26];
@@ -91,7 +90,7 @@ BDE DHTGetPeersReplyMessage::getResponse()
         offset += 26;
       }
     }
-    rDict[NODES] = BDE(buffer, offset);
+    rDict->put(NODES, String::g(buffer, offset));
   } else {
     // Limit the size of values list.  The maxmum size of UDP datagram
     // is limited to 65535 bytes. aria2 uses 20bytes token and 2byte
@@ -113,18 +112,18 @@ BDE DHTGetPeersReplyMessage::getResponse()
     // template may get bigger than 87 bytes. So we use 100 as maximum
     // number of peer info that a message can carry.
     static const size_t MAX_VALUES_SIZE = 100;
-    BDE valuesList = BDE::list();
+    SharedHandle<List> valuesList = List::g();
     for(std::vector<SharedHandle<Peer> >::const_iterator i = _values.begin(),
-          eoi = _values.end(); i != eoi && valuesList.size() < MAX_VALUES_SIZE;
+          eoi = _values.end(); i != eoi && valuesList->size() < MAX_VALUES_SIZE;
         ++i) {
       const SharedHandle<Peer>& peer = *i;
       unsigned char buffer[6];
       if(bittorrent::createcompact
          (buffer, peer->getIPAddress(), peer->getPort())) {
-        valuesList << BDE(buffer, sizeof(buffer));
+        valuesList->append(String::g(buffer, sizeof(buffer)));
       }
     }
-    rDict[VALUES] = valuesList;
+    rDict->put(VALUES, valuesList);
   }
   return rDict;  
 }

+ 1 - 1
src/DHTGetPeersReplyMessage.h

@@ -64,7 +64,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getResponse();
+  virtual SharedHandle<Dict> getResponse();
 
   virtual const std::string& getMessageType() const;
 

+ 3 - 3
src/DHTMessageFactory.h

@@ -42,6 +42,7 @@
 
 #include "SharedHandle.h"
 #include "A2STR.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -50,19 +51,18 @@ class DHTQueryMessage;
 class DHTResponseMessage;
 class DHTNode;
 class Peer;
-class BDE;
 
 class DHTMessageFactory {
 public:
   virtual ~DHTMessageFactory() {}
 
   virtual SharedHandle<DHTQueryMessage>
-  createQueryMessage(const BDE& dict,
+  createQueryMessage(const Dict* dict,
                      const std::string& ipaddr, uint16_t port) = 0;
 
   virtual SharedHandle<DHTResponseMessage>
   createResponseMessage(const std::string& messageType,
-                        const BDE& dict,
+                        const Dict* dict,
                         const std::string& ipaddr, uint16_t port) = 0;
 
   virtual SharedHandle<DHTQueryMessage>

+ 106 - 113
src/DHTMessageFactoryImpl.cc

@@ -61,7 +61,6 @@
 #include "Peer.h"
 #include "Logger.h"
 #include "StringFormat.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -83,11 +82,10 @@ DHTMessageFactoryImpl::getRemoteNode
   return node;
 }
 
-static const BDE& getDictionary(const BDE& dict,
-                                const std::string& key)
+static const Dict* getDictionary(const Dict* dict, const std::string& key)
 {
-  const BDE& d = dict[key];
-  if(d.isDict()) {
+  const Dict* d = asDict(dict->get(key));
+  if(d) {
     return d;
   } else {
     throw DL_ABORT_EX
@@ -95,11 +93,10 @@ static const BDE& getDictionary(const BDE& dict,
   }
 }
 
-static const BDE& getString(const BDE& dict,
-                            const std::string& key)
+static const String* getString(const Dict* dict, const std::string& key)
 {
-  const BDE& c = dict[key];
-  if(c.isString()) {
+  const String* c = asString(dict->get(key));
+  if(c) {
     return c;
   } else {
     throw DL_ABORT_EX
@@ -107,11 +104,10 @@ static const BDE& getString(const BDE& dict,
   }
 }
 
-static const BDE& getInteger(const BDE& dict,
-                             const std::string& key)
+static const Integer* getInteger(const Dict* dict, const std::string& key)
 {
-  const BDE& c = dict[key];
-  if(c.isInteger()) {
+  const Integer* c = asInteger(dict->get(key));
+  if(c) {
     return c;
   } else {
     throw DL_ABORT_EX
@@ -119,10 +115,10 @@ static const BDE& getInteger(const BDE& dict,
   }
 }
 
-static const BDE& getString(const BDE& list, size_t index)
+static const String* getString(const List* list, size_t index)
 {
-  const BDE& c = list[index];
-  if(c.isString()) {
+  const String* c = asString(list->get(index));
+  if(c) {
     return c;
   } else {
     throw DL_ABORT_EX
@@ -131,10 +127,10 @@ static const BDE& getString(const BDE& list, size_t index)
   }
 }
 
-static const BDE& getInteger(const BDE& list, size_t index)
+static const Integer* getInteger(const List* list, size_t index)
 {
-  const BDE& c = list[index];
-  if(c.isInteger()) {
+  const Integer* c = asInteger(list->get(index));
+  if(c) {
     return c;
   } else {
     throw DL_ABORT_EX
@@ -143,11 +139,10 @@ static const BDE& getInteger(const BDE& list, size_t index)
   }
 }
 
-static const BDE& getList(const BDE& dict,
-                          const std::string& key)
+static const List* getList(const Dict* dict, const std::string& key)
 {
-  const BDE& l = dict[key];
-  if(l.isList()) {
+  const List* l = asList(dict->get(key));
+  if(l) {
     return l;
   } else {
     throw DL_ABORT_EX
@@ -155,78 +150,73 @@ static const BDE& getList(const BDE& dict,
   }
 }
 
-void DHTMessageFactoryImpl::validateID(const BDE& id) const
+void DHTMessageFactoryImpl::validateID(const String* id) const
 {
-  if(id.s().size() != DHT_ID_LENGTH) {
+  if(id->s().size() != DHT_ID_LENGTH) {
     throw DL_ABORT_EX
       (StringFormat("Malformed DHT message. Invalid ID length."
                     " Expected:%d, Actual:%d",
-                    DHT_ID_LENGTH, id.s().size()).str());
+                    DHT_ID_LENGTH, id->s().size()).str());
   }
 }
 
-void DHTMessageFactoryImpl::validatePort(const BDE& i) const
+void DHTMessageFactoryImpl::validatePort(const Integer* port) const
 {
-  BDE::Integer port = i.i();
-  if(!(0 < port && port < UINT16_MAX)) {
+  if(!(0 < port->i() && port->i() < UINT16_MAX)) {
     throw DL_ABORT_EX
       (StringFormat("Malformed DHT message. Invalid port=%s",
-                    util::itos(port).c_str()).str());
+                    util::itos(port->i()).c_str()).str());
   }
 }
 
-static void setVersion(const SharedHandle<DHTMessage>& msg, const BDE& dict)
+static void setVersion(const SharedHandle<DHTMessage>& msg, const Dict* dict)
 {
-  const BDE& v = dict[DHTMessage::V];
-  if(v.isString()) {
-    msg->setVersion(v.s());
+  const String* v = asString(dict->get(DHTMessage::V));
+  if(v) {
+    msg->setVersion(v->s());
   } else {
     msg->setVersion(A2STR::NIL);
   }
 }
 
 SharedHandle<DHTQueryMessage> DHTMessageFactoryImpl::createQueryMessage
-(const BDE& dict, const std::string& ipaddr, uint16_t port)
+(const Dict* dict, const std::string& ipaddr, uint16_t port)
 {
-  const BDE& messageType = getString(dict, DHTQueryMessage::Q);
-  const BDE& transactionID = getString(dict, DHTMessage::T);
-  const BDE& y = getString(dict, DHTMessage::Y);
-  const BDE& aDict = getDictionary(dict, DHTQueryMessage::A);
-  if(y.s() != DHTQueryMessage::Q) {
+  const String* messageType = getString(dict, DHTQueryMessage::Q);
+  const String* transactionID = getString(dict, DHTMessage::T);
+  const String* y = getString(dict, DHTMessage::Y);
+  const Dict* aDict = getDictionary(dict, DHTQueryMessage::A);
+  if(y->s() != DHTQueryMessage::Q) {
     throw DL_ABORT_EX("Malformed DHT message. y != q");
   }
-  const BDE& id = getString(aDict, DHTMessage::ID);
+  const String* id = getString(aDict, DHTMessage::ID);
   validateID(id);
-  SharedHandle<DHTNode> remoteNode = getRemoteNode(id.uc(), ipaddr, port);
+  SharedHandle<DHTNode> remoteNode = getRemoteNode(id->uc(), ipaddr, port);
   SharedHandle<DHTQueryMessage> msg;
-  if(messageType.s() == DHTPingMessage::PING) {
-    msg = createPingMessage(remoteNode, transactionID.s());
-  } else if(messageType.s() == DHTFindNodeMessage::FIND_NODE) {
-    const BDE& targetNodeID =
+  if(messageType->s() == DHTPingMessage::PING) {
+    msg = createPingMessage(remoteNode, transactionID->s());
+  } else if(messageType->s() == DHTFindNodeMessage::FIND_NODE) {
+    const String* targetNodeID =
       getString(aDict, DHTFindNodeMessage::TARGET_NODE);
     validateID(targetNodeID);
-    msg = createFindNodeMessage(remoteNode, targetNodeID.uc(),
-                                transactionID.s());
-  } else if(messageType.s() == DHTGetPeersMessage::GET_PEERS) {
-    const BDE& infoHash = 
-      getString(aDict, DHTGetPeersMessage::INFO_HASH);
+    msg = createFindNodeMessage(remoteNode, targetNodeID->uc(),
+                                transactionID->s());
+  } else if(messageType->s() == DHTGetPeersMessage::GET_PEERS) {
+    const String* infoHash =  getString(aDict, DHTGetPeersMessage::INFO_HASH);
     validateID(infoHash);
-    msg = createGetPeersMessage(remoteNode,
-                                infoHash.uc(), transactionID.s());
-  } else if(messageType.s() == DHTAnnouncePeerMessage::ANNOUNCE_PEER) {
-    const BDE& infoHash =
-      getString(aDict, DHTAnnouncePeerMessage::INFO_HASH);
+    msg = createGetPeersMessage(remoteNode, infoHash->uc(), transactionID->s());
+  } else if(messageType->s() == DHTAnnouncePeerMessage::ANNOUNCE_PEER) {
+    const String* infoHash = getString(aDict,DHTAnnouncePeerMessage::INFO_HASH);
     validateID(infoHash);
-    const BDE& port = getInteger(aDict, DHTAnnouncePeerMessage::PORT);
+    const Integer* port = getInteger(aDict, DHTAnnouncePeerMessage::PORT);
     validatePort(port);
-    const BDE& token = getString(aDict, DHTAnnouncePeerMessage::TOKEN);
-    msg = createAnnouncePeerMessage(remoteNode, infoHash.uc(),
-                                    static_cast<uint16_t>(port.i()),
-                                    token.s(), transactionID.s());
+    const String* token = getString(aDict, DHTAnnouncePeerMessage::TOKEN);
+    msg = createAnnouncePeerMessage(remoteNode, infoHash->uc(),
+                                    static_cast<uint16_t>(port->i()),
+                                    token->s(), transactionID->s());
   } else {
-    throw DL_ABORT_EX
-      (StringFormat("Unsupported message type: %s",
-                    messageType.s().c_str()).str());
+    throw DL_ABORT_EX(StringFormat("Unsupported message type: %s",
+                                   messageType->s().c_str()).str());
   }
   setVersion(msg, dict);
   return msg;
@@ -235,20 +225,20 @@ SharedHandle<DHTQueryMessage> DHTMessageFactoryImpl::createQueryMessage
 SharedHandle<DHTResponseMessage>
 DHTMessageFactoryImpl::createResponseMessage
 (const std::string& messageType,
- const BDE& dict,
+ const Dict* dict,
  const std::string& ipaddr,
  uint16_t port)
 {
-  const BDE& transactionID = getString(dict, DHTMessage::T);
-  const BDE& y = getString(dict, DHTMessage::Y);
-  if(y.s() == DHTUnknownMessage::E) {
+  const String* transactionID = getString(dict, DHTMessage::T);
+  const String* y = getString(dict, DHTMessage::Y);
+  if(y->s() == DHTUnknownMessage::E) {
     // for now, just report error message arrived and throw exception.
-    const BDE& e = getList(dict, DHTUnknownMessage::E);
-    if(e.size() == 2) {
+    const List* e = getList(dict, DHTUnknownMessage::E);
+    if(e->size() == 2) {
       if(_logger->info()) {
         _logger->info("Received Error DHT message. code=%s, msg=%s",
-                      util::itos(getInteger(e, 0).i()).c_str(),
-                      util::percentEncode(getString(e, 1).s()).c_str());
+                      util::itos(getInteger(e, 0)->i()).c_str(),
+                      util::percentEncode(getString(e, 1)->s()).c_str());
       }
     } else {
       if(_logger->debug()) {
@@ -256,36 +246,38 @@ DHTMessageFactoryImpl::createResponseMessage
       }
     }
     throw DL_ABORT_EX("Received Error DHT message.");
-  } else if(y.s() != DHTResponseMessage::R) {
+  } else if(y->s() != DHTResponseMessage::R) {
     throw DL_ABORT_EX
       (StringFormat("Malformed DHT message. y != r: y=%s",
-                    util::percentEncode(y.s()).c_str()).str());
+                    util::percentEncode(y->s()).c_str()).str());
   }
-  const BDE& rDict = getDictionary(dict, DHTResponseMessage::R);
-  const BDE& id = getString(rDict, DHTMessage::ID);
+  const Dict* rDict = getDictionary(dict, DHTResponseMessage::R);
+  const String* id = getString(rDict, DHTMessage::ID);
   validateID(id);
-  SharedHandle<DHTNode> remoteNode = getRemoteNode(id.uc(), ipaddr, port);
+  SharedHandle<DHTNode> remoteNode = getRemoteNode(id->uc(), ipaddr, port);
   SharedHandle<DHTResponseMessage> msg;
   if(messageType == DHTPingReplyMessage::PING) {
-    msg = createPingReplyMessage(remoteNode, id.uc(), transactionID.s());
+    msg = createPingReplyMessage(remoteNode, id->uc(), transactionID->s());
   } else if(messageType == DHTFindNodeReplyMessage::FIND_NODE) {
-    msg = createFindNodeReplyMessage(remoteNode, dict, transactionID.s());
+    msg = createFindNodeReplyMessage(remoteNode, dict, transactionID->s());
   } else if(messageType == DHTGetPeersReplyMessage::GET_PEERS) {
-    const BDE& valuesList = rDict[DHTGetPeersReplyMessage::VALUES];
-    if(valuesList.isList()) {
-      msg = createGetPeersReplyMessageWithValues(remoteNode, dict,
-                                                 transactionID.s());
+    const List* valuesList =
+      asList(rDict->get(DHTGetPeersReplyMessage::VALUES));
+    if(valuesList) {
+      msg = createGetPeersReplyMessageWithValues
+        (remoteNode, dict, transactionID->s());
     } else {
-      const BDE& nodes = rDict[DHTGetPeersReplyMessage::NODES];
-      if(nodes.isString()) {
-        msg = createGetPeersReplyMessageWithNodes(remoteNode, dict,
-                                                   transactionID.s());
+      const String* nodes = asString
+        (rDict->get(DHTGetPeersReplyMessage::NODES));
+      if(nodes) {
+        msg = createGetPeersReplyMessageWithNodes
+          (remoteNode, dict, transactionID->s());
       } else {
         throw DL_ABORT_EX("Malformed DHT message: missing nodes/values");
       }
     }
   } else if(messageType == DHTAnnouncePeerReplyMessage::ANNOUNCE_PEER) {
-    msg = createAnnouncePeerReplyMessage(remoteNode, transactionID.s());
+    msg = createAnnouncePeerReplyMessage(remoteNode, transactionID->s());
   } else {
     throw DL_ABORT_EX
       (StringFormat("Unsupported message type: %s", messageType.c_str()).str());
@@ -307,7 +299,8 @@ static const std::string& getDefaultVersion()
   return version;
 }
 
-void DHTMessageFactoryImpl::setCommonProperty(const SharedHandle<DHTAbstractMessage>& m)
+void DHTMessageFactoryImpl::setCommonProperty
+(const SharedHandle<DHTAbstractMessage>& m)
 {
   m->setConnection(_connection);
   m->setMessageDispatcher(_dispatcher);
@@ -320,7 +313,8 @@ void DHTMessageFactoryImpl::setCommonProperty(const SharedHandle<DHTAbstractMess
 SharedHandle<DHTQueryMessage> DHTMessageFactoryImpl::createPingMessage
 (const SharedHandle<DHTNode>& remoteNode, const std::string& transactionID)
 {
-  SharedHandle<DHTPingMessage> m(new DHTPingMessage(_localNode, remoteNode, transactionID));
+  SharedHandle<DHTPingMessage> m
+    (new DHTPingMessage(_localNode, remoteNode, transactionID));
   setCommonProperty(m);
   return m;
 }
@@ -385,14 +379,14 @@ DHTMessageFactoryImpl::extractNodes(const unsigned char* src, size_t length)
 SharedHandle<DHTResponseMessage>
 DHTMessageFactoryImpl::createFindNodeReplyMessage
 (const SharedHandle<DHTNode>& remoteNode,
- const BDE& dict,
+ const Dict* dict,
  const std::string& transactionID)
 {
-  const BDE& nodesData =
+  const String* nodesData =
     getString(getDictionary(dict, DHTResponseMessage::R),
               DHTFindNodeReplyMessage::NODES);
   std::vector<SharedHandle<DHTNode> > nodes =
-    extractNodes(nodesData.uc(), nodesData.s().size());
+    extractNodes(nodesData->uc(), nodesData->s().size());
   return createFindNodeReplyMessage(remoteNode, nodes, transactionID);
 }
 
@@ -413,17 +407,16 @@ DHTMessageFactoryImpl::createGetPeersMessage
 SharedHandle<DHTResponseMessage>
 DHTMessageFactoryImpl::createGetPeersReplyMessageWithNodes
 (const SharedHandle<DHTNode>& remoteNode,
- const BDE& dict,
+ const Dict* dict,
  const std::string& transactionID)
 {
-  const BDE& rDict = getDictionary(dict, DHTResponseMessage::R);
-  const BDE& nodesData = getString(rDict,
-                                   DHTGetPeersReplyMessage::NODES);
-  std::vector<SharedHandle<DHTNode> > nodes =
-    extractNodes(nodesData.uc(), nodesData.s().size());
-  const BDE& token = getString(rDict, DHTGetPeersReplyMessage::TOKEN);
-  return createGetPeersReplyMessage(remoteNode, nodes, token.s(),
-                                    transactionID);
+  const Dict* rDict = getDictionary(dict, DHTResponseMessage::R);
+  const String* nodesData = getString(rDict, DHTGetPeersReplyMessage::NODES);
+  std::vector<SharedHandle<DHTNode> > nodes = extractNodes
+    (nodesData->uc(), nodesData->s().size());
+  const String* token = getString(rDict, DHTGetPeersReplyMessage::TOKEN);
+  return createGetPeersReplyMessage
+    (remoteNode, nodes, token->s(), transactionID);
 }
 
 SharedHandle<DHTResponseMessage>
@@ -443,26 +436,26 @@ DHTMessageFactoryImpl::createGetPeersReplyMessage
 SharedHandle<DHTResponseMessage>
 DHTMessageFactoryImpl::createGetPeersReplyMessageWithValues
 (const SharedHandle<DHTNode>& remoteNode,
- const BDE& dict,
+ const Dict* dict,
  const std::string& transactionID)
 {
-  const BDE& rDict = getDictionary(dict, DHTResponseMessage::R);
-  const BDE& valuesList = getList(rDict,
+  const Dict* rDict = getDictionary(dict, DHTResponseMessage::R);
+  const List* valuesList = getList(rDict,
                                   DHTGetPeersReplyMessage::VALUES);
   std::vector<SharedHandle<Peer> > peers;
-  for(BDE::List::const_iterator i = valuesList.listBegin(),
-        eoi = valuesList.listEnd(); i != eoi; ++i) {
-    const BDE& data = *i;
-    if(data.isString() && data.s().size() == 6) {
+  for(List::ValueType::const_iterator i = valuesList->begin(),
+        eoi = valuesList->end(); i != eoi; ++i) {
+    const String* data = asString(*i);
+    if(data && data->s().size() == 6) {
       std::pair<std::string, uint16_t> addr =
-        bittorrent::unpackcompact(data.uc());
+        bittorrent::unpackcompact(data->uc());
       SharedHandle<Peer> peer(new Peer(addr.first, addr.second));
       peers.push_back(peer);
     }
   }
-  const BDE& token = getString(rDict, DHTGetPeersReplyMessage::TOKEN);
-  return createGetPeersReplyMessage(remoteNode, peers, token.s(),
-                                    transactionID);
+  const String* token = getString(rDict, DHTGetPeersReplyMessage::TOKEN);
+  return createGetPeersReplyMessage
+    (remoteNode, peers, token->s(), transactionID);
 }
 
 SharedHandle<DHTResponseMessage>

+ 7 - 7
src/DHTMessageFactoryImpl.h

@@ -69,9 +69,9 @@ private:
   SharedHandle<DHTNode> getRemoteNode
   (const unsigned char* id, const std::string& ipaddr, uint16_t port) const;
 
-  void validateID(const BDE& id) const;
+  void validateID(const String* id) const;
 
-  void validatePort(const BDE& i) const;
+  void validatePort(const Integer* i) const;
 
   std::vector<SharedHandle<DHTNode> >
   extractNodes(const unsigned char* src, size_t length);
@@ -84,12 +84,12 @@ public:
   virtual ~DHTMessageFactoryImpl();
 
   virtual SharedHandle<DHTQueryMessage>
-  createQueryMessage(const BDE& dict,
+  createQueryMessage(const Dict* dict,
                      const std::string& ipaddr, uint16_t port);
 
   virtual SharedHandle<DHTResponseMessage>
   createResponseMessage(const std::string& messageType,
-                        const BDE& dict,
+                        const Dict* dict,
                         const std::string& ipaddr, uint16_t port);
 
   virtual SharedHandle<DHTQueryMessage>
@@ -108,7 +108,7 @@ public:
 
   SharedHandle<DHTResponseMessage>
   createFindNodeReplyMessage(const SharedHandle<DHTNode>& remoteNode,
-                             const BDE& dict,
+                             const Dict* dict,
                              const std::string& transactionID);
 
 
@@ -132,7 +132,7 @@ public:
 
   SharedHandle<DHTResponseMessage>
   createGetPeersReplyMessageWithNodes(const SharedHandle<DHTNode>& remoteNode,
-                                      const BDE& dict,
+                                      const Dict* dict,
                                       const std::string& transactionID);
 
   virtual SharedHandle<DHTResponseMessage>
@@ -144,7 +144,7 @@ public:
 
   SharedHandle<DHTResponseMessage>
   createGetPeersReplyMessageWithValues(const SharedHandle<DHTNode>& remoteNode,
-                                       const BDE& dict,
+                                       const Dict* dict,
                                        const std::string& transactionID);
 
   virtual SharedHandle<DHTQueryMessage>

+ 7 - 6
src/DHTMessageReceiver.cc

@@ -51,7 +51,7 @@
 #include "LogFactory.h"
 #include "Logger.h"
 #include "util.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -75,11 +75,12 @@ SharedHandle<DHTMessage> DHTMessageReceiver::receiveMessage()
       return SharedHandle<DHTMessage>();
     }
     bool isReply = false;
-    const BDE dict = bencode::decode(data, length);
-    if(dict.isDict()) {
-      const BDE& y = dict[DHTMessage::Y];
-      if(y.isString()) {
-        if(y.s() == DHTResponseMessage::R || y.s() == DHTUnknownMessage::E) {
+    SharedHandle<ValueBase> decoded = bencode2::decode(data, length);
+    const Dict* dict = asDict(decoded);
+    if(dict) {
+      const String* y = asString(dict->get(DHTMessage::Y));
+      if(y) {
+        if(y->s() == DHTResponseMessage::R || y->s() == DHTUnknownMessage::E) {
           isReply = true;
         }
       } else {

+ 9 - 8
src/DHTMessageTracker.cc

@@ -48,7 +48,6 @@
 #include "DlAbortEx.h"
 #include "DHTConstants.h"
 #include "StringFormat.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -65,20 +64,20 @@ void DHTMessageTracker::addMessage(const SharedHandle<DHTMessage>& message, time
 
 std::pair<SharedHandle<DHTResponseMessage>, SharedHandle<DHTMessageCallback> >
 DHTMessageTracker::messageArrived
-(const BDE& dict, const std::string& ipaddr, uint16_t port)
+(const Dict* dict, const std::string& ipaddr, uint16_t port)
 {
-  const BDE& tid = dict[DHTMessage::T];
-  if(!tid.isString()) {
+  const String* tid = asString(dict->get(DHTMessage::T));
+  if(!tid) {
     throw DL_ABORT_EX(StringFormat("Malformed DHT message. From:%s:%u",
                                    ipaddr.c_str(), port).str());
   }
   if(_logger->debug()) {
     _logger->debug("Searching tracker entry for TransactionID=%s, Remote=%s:%u",
-                   util::toHex(tid.s()).c_str(), ipaddr.c_str(), port);
+                   util::toHex(tid->s()).c_str(), ipaddr.c_str(), port);
   }
   for(std::deque<SharedHandle<DHTMessageTrackerEntry> >::iterator i =
         _entries.begin(), eoi = _entries.end(); i != eoi; ++i) {
-    if((*i)->match(tid.s(), ipaddr, port)) {
+    if((*i)->match(tid->s(), ipaddr, port)) {
       SharedHandle<DHTMessageTrackerEntry> entry = *i;
       _entries.erase(i);
       if(_logger->debug()) {
@@ -162,12 +161,14 @@ size_t DHTMessageTracker::countEntry() const
   return _entries.size();
 }
 
-void DHTMessageTracker::setRoutingTable(const SharedHandle<DHTRoutingTable>& routingTable)
+void DHTMessageTracker::setRoutingTable
+(const SharedHandle<DHTRoutingTable>& routingTable)
 {
   _routingTable = routingTable;
 }
 
-void DHTMessageTracker::setMessageFactory(const SharedHandle<DHTMessageFactory>& factory)
+void DHTMessageTracker::setMessageFactory
+(const SharedHandle<DHTMessageFactory>& factory)
 {
   _factory = factory;
 }

+ 2 - 2
src/DHTMessageTracker.h

@@ -42,6 +42,7 @@
 
 #include "SharedHandle.h"
 #include "a2time.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -52,7 +53,6 @@ class DHTRoutingTable;
 class DHTMessageFactory;
 class DHTMessageTrackerEntry;
 class Logger;
-class BDE;
 
 class DHTMessageTracker {
 private:
@@ -74,7 +74,7 @@ public:
                   SharedHandle<DHTMessageCallback>());
 
   std::pair<SharedHandle<DHTResponseMessage>, SharedHandle<DHTMessageCallback> >
-  messageArrived(const BDE& dict,
+  messageArrived(const Dict* dict,
                  const std::string& ipaddr, uint16_t port);
 
   void handleTimeout();

+ 3 - 4
src/DHTPingMessage.cc

@@ -38,7 +38,6 @@
 #include "DHTMessageDispatcher.h"
 #include "DHTMessageFactory.h"
 #include "DHTMessageCallback.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -60,10 +59,10 @@ void DHTPingMessage::doReceivedAction()
   getMessageDispatcher()->addMessageToQueue(reply);
 }
 
-BDE DHTPingMessage::getArgument()
+SharedHandle<Dict> DHTPingMessage::getArgument()
 {
-  BDE aDict = BDE::dict();
-  aDict[DHTMessage::ID] = BDE(getLocalNode()->getID(), DHT_ID_LENGTH);
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
   return aDict;
 }
 

+ 1 - 1
src/DHTPingMessage.h

@@ -50,7 +50,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getArgument();
+  virtual SharedHandle<Dict> getArgument();
 
   virtual const std::string& getMessageType() const;
 

+ 8 - 8
src/DHTPingReplyMessage.cc

@@ -37,17 +37,17 @@
 #include <cstring>
 
 #include "DHTNode.h"
-#include "bencode.h"
 #include "DHTMessageCallback.h"
 
 namespace aria2 {
 
 const std::string DHTPingReplyMessage::PING("ping");
 
-DHTPingReplyMessage::DHTPingReplyMessage(const SharedHandle<DHTNode>& localNode,
-                                         const SharedHandle<DHTNode>& remoteNode,
-                                         const unsigned char* id,
-                                         const std::string& transactionID):
+DHTPingReplyMessage::DHTPingReplyMessage
+(const SharedHandle<DHTNode>& localNode,
+ const SharedHandle<DHTNode>& remoteNode,
+ const unsigned char* id,
+ const std::string& transactionID):
   DHTResponseMessage(localNode, remoteNode, transactionID)
 {
   memcpy(_id, id, DHT_ID_LENGTH);
@@ -57,10 +57,10 @@ DHTPingReplyMessage::~DHTPingReplyMessage() {}
 
 void DHTPingReplyMessage::doReceivedAction() {}
 
-BDE DHTPingReplyMessage::getResponse()
+SharedHandle<Dict> DHTPingReplyMessage::getResponse()
 {
-  BDE rDict = BDE::dict();
-  rDict[DHTMessage::ID] = BDE(_id, DHT_ID_LENGTH);
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put(DHTMessage::ID, String::g(_id, DHT_ID_LENGTH));
   return rDict;
 }
 

+ 1 - 1
src/DHTPingReplyMessage.h

@@ -53,7 +53,7 @@ public:
 
   virtual void doReceivedAction();
 
-  virtual BDE getResponse();
+  virtual SharedHandle<Dict> getResponse();
 
   virtual const std::string& getMessageType() const;
 

+ 3 - 4
src/DHTQueryMessage.cc

@@ -35,7 +35,6 @@
 #include "DHTQueryMessage.h"
 #include "DHTNode.h"
 #include "util.h"
-#include "bencode.h"
 #include "a2functional.h"
 
 namespace aria2 {
@@ -56,10 +55,10 @@ const std::string& DHTQueryMessage::getType() const
   return Q;
 }
 
-void DHTQueryMessage::fillMessage(BDE& msgDict)
+void DHTQueryMessage::fillMessage(Dict* msgDict)
 {
-  msgDict[Q] = getMessageType();
-  msgDict[A] = getArgument();
+  msgDict->put(Q, getMessageType());
+  msgDict->put(A, getArgument());
 }
 
 bool DHTQueryMessage::isReply() const

+ 3 - 2
src/DHTQueryMessage.h

@@ -37,6 +37,7 @@
 
 #include "DHTAbstractMessage.h"
 #include "A2STR.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -52,9 +53,9 @@ public:
 
   virtual const std::string& getType() const;
 
-  virtual void fillMessage(BDE& msgDict);
+  virtual void fillMessage(Dict* msgDict);
 
-  virtual BDE getArgument() = 0;
+  virtual SharedHandle<Dict> getArgument() = 0;
   
   virtual bool isReply() const;
 

+ 2 - 3
src/DHTResponseMessage.cc

@@ -35,7 +35,6 @@
 #include "DHTResponseMessage.h"
 #include "DHTNode.h"
 #include "util.h"
-#include "bencode.h"
 #include "a2functional.h"
 
 namespace aria2 {
@@ -54,9 +53,9 @@ const std::string& DHTResponseMessage::getType() const
   return R;
 }
 
-void DHTResponseMessage::fillMessage(BDE& msgDict)
+void DHTResponseMessage::fillMessage(Dict* msgDict)
 {
-  msgDict[R] = getResponse();
+  msgDict->put(R, getResponse());
 }
 
 bool DHTResponseMessage::isReply() const

+ 3 - 2
src/DHTResponseMessage.h

@@ -37,6 +37,7 @@
 
 #include "DHTAbstractMessage.h"
 #include "A2STR.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -54,9 +55,9 @@ public:
 
   virtual const std::string& getType() const;
 
-  virtual void fillMessage(BDE& msgDict);
+  virtual void fillMessage(Dict* msgDict);
 
-  virtual BDE getResponse() = 0;
+  virtual SharedHandle<Dict> getResponse() = 0;
   
   virtual bool isReply() const;
 

+ 20 - 17
src/DefaultExtensionMessageFactory.cc

@@ -49,10 +49,10 @@
 #include "UTMetadataDataExtensionMessage.h"
 #include "UTMetadataRejectExtensionMessage.h"
 #include "message.h"
-#include "bencode.h"
 #include "PieceStorage.h"
 #include "UTMetadataRequestTracker.h"
 #include "RequestGroup.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -74,7 +74,8 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
   uint8_t extensionMessageID = *data;
   if(extensionMessageID == 0) {
     // handshake
-    HandshakeExtensionMessageHandle m = HandshakeExtensionMessage::create(data, length);
+    HandshakeExtensionMessageHandle m =
+      HandshakeExtensionMessage::create(data, length);
     m->setPeer(_peer);
     m->setDownloadContext(_dctx);
     return m;
@@ -97,23 +98,24 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
                                        "ut_metadata", length).str());
       }
       size_t end;
-      BDE dict = bencode::decode(data+1, length-1, end);
-      if(!dict.isDict()) {
+      SharedHandle<ValueBase> decoded = bencode2::decode(data+1, length-1, end);
+      const Dict* dict = asDict(decoded);
+      if(!dict) {
         throw DL_ABORT_EX("Bad ut_metadata: dictionary not found");
       }
-      const BDE& msgType = dict["msg_type"];
-      if(!msgType.isInteger()) {
+      const Integer* msgType = asInteger(dict->get("msg_type"));
+      if(!msgType) {
         throw DL_ABORT_EX("Bad ut_metadata: msg_type not found");
       }
-      const BDE& index = dict["piece"];
-      if(!index.isInteger()) {
+      const Integer* index = asInteger(dict->get("piece"));
+      if(!index) {
         throw DL_ABORT_EX("Bad ut_metadata: piece not found");
       }
-      switch(msgType.i()) {
+      switch(msgType->i()) {
       case 0: {
         SharedHandle<UTMetadataRequestExtensionMessage> m
           (new UTMetadataRequestExtensionMessage(extensionMessageID));
-        m->setIndex(index.i());
+        m->setIndex(index->i());
         m->setDownloadContext(_dctx);
         m->setPeer(_peer);
         m->setBtMessageFactory(_messageFactory);
@@ -124,14 +126,14 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
         if(end == length) {
           throw DL_ABORT_EX("Bad ut_metadata data: data not found");
         }
-        const BDE& totalSize = dict["total_size"];
-        if(!totalSize.isInteger()) {
+        const Integer* totalSize = asInteger(dict->get("total_size"));
+        if(!totalSize) {
           throw DL_ABORT_EX("Bad ut_metadata data: total_size not found");
         }
         SharedHandle<UTMetadataDataExtensionMessage> m
           (new UTMetadataDataExtensionMessage(extensionMessageID));
-        m->setIndex(index.i());
-        m->setTotalSize(totalSize.i());
+        m->setIndex(index->i());
+        m->setTotalSize(totalSize->i());
         m->setData(std::string(&data[1+end], &data[length]));
         m->setUTMetadataRequestTracker(_tracker);
         m->setPieceStorage(_dctx->getOwnerRequestGroup()->getPieceStorage());
@@ -141,17 +143,18 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
       case 2: {
         SharedHandle<UTMetadataRejectExtensionMessage> m
           (new UTMetadataRejectExtensionMessage(extensionMessageID));
-        m->setIndex(index.i());
+        m->setIndex(index->i());
         // No need to inject tracker because peer will be disconnected.
         return m;
       }
       default:
         throw DL_ABORT_EX(StringFormat("Bad ut_metadata: unknown msg_type=%u",
-                                       msgType.i()).str());
+                                       msgType->i()).str());
       }
     } else {
       throw DL_ABORT_EX
-        (StringFormat("Unsupported extension message received. extensionMessageID=%u, extensionName=%s",
+        (StringFormat("Unsupported extension message received."
+                      " extensionMessageID=%u, extensionName=%s",
                       extensionMessageID, extensionName.c_str()).str());
     }
   }

+ 5 - 1
src/ExpatXmlRpcRequestProcessor.cc

@@ -114,7 +114,11 @@ XmlRpcRequestProcessor::parseMemory(const std::string& xml)
   if(r == XML_STATUS_ERROR) {
     throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
   }
-  return XmlRpcRequest(_stm->getMethodName(), _stm->getCurrentFrameValue());
+  if(!asList(_stm->getCurrentFrameValue())) {
+    throw DL_ABORT_EX("Bad XML-RPC parameter list");
+  }
+  return XmlRpcRequest(_stm->getMethodName(),
+                       static_pointer_cast<List>(_stm->getCurrentFrameValue()));
 }
 
 } // namespace xmlrpc

+ 33 - 30
src/HandshakeExtensionMessage.cc

@@ -40,7 +40,7 @@
 #include "Logger.h"
 #include "message.h"
 #include "StringFormat.h"
-#include "bencode.h"
+#include "bencode2.h"
 #include "DownloadContext.h"
 #include "bittorrent_helper.h"
 #include "RequestGroup.h"
@@ -59,24 +59,24 @@ HandshakeExtensionMessage::~HandshakeExtensionMessage() {}
 
 std::string HandshakeExtensionMessage::getPayload()
 {
-  BDE dict = BDE::dict();
+  Dict dict;
   if(!_clientVersion.empty()) {
-    dict["v"] = _clientVersion;
+    dict.put("v", _clientVersion);
   }
   if(_tcpPort > 0) {
-    dict["p"] = _tcpPort;
+    dict.put("p", Integer::g(_tcpPort));
   }
-  BDE extDict = BDE::dict();
+  SharedHandle<Dict> extDict = Dict::g();
   for(std::map<std::string, uint8_t>::const_iterator itr = _extensions.begin(),
         eoi = _extensions.end(); itr != eoi; ++itr) {
     const std::map<std::string, uint8_t>::value_type& vt = *itr;
-    extDict[vt.first] = vt.second;
+    extDict->put(vt.first, Integer::g(vt.second));
   }
-  dict["m"] = extDict;
+  dict.put("m", extDict);
   if(_metadataSize) {
-    dict["metadata_size"] = _metadataSize;
+    dict.put("metadata_size", Integer::g(_metadataSize));
   }
-  return bencode::encode(dict);
+  return bencode2::encode(&dict);
 }
 
 std::string HandshakeExtensionMessage::toString() const
@@ -168,31 +168,34 @@ HandshakeExtensionMessage::create(const unsigned char* data, size_t length)
       ("Creating HandshakeExtensionMessage from %s",
        util::percentEncode(data, length).c_str());
   }
-  const BDE dict = bencode::decode(data+1, length-1);
-  if(!dict.isDict()) {
-    throw DL_ABORT_EX("Unexpected payload format for extended message handshake");
-  }
-  const BDE& port = dict["p"];
-  if(port.isInteger() && 0 < port.i() && port.i() < 65536) {
-    msg->_tcpPort = port.i();
-  }
-  const BDE& version = dict["v"];
-  if(version.isString()) {
-    msg->_clientVersion = version.s();
-  }
-  const BDE& extDict = dict["m"];
-  if(extDict.isDict()) {
-    for(BDE::Dict::const_iterator i = extDict.dictBegin(),
-          eoi = extDict.dictEnd(); i != eoi; ++i) {
-      if((*i).second.isInteger()) {
-        msg->_extensions[(*i).first] = (*i).second.i();
+  SharedHandle<ValueBase> decoded = bencode2::decode(data+1, length-1);
+  const Dict* dict = asDict(decoded);
+  if(!dict) {
+    throw DL_ABORT_EX
+      ("Unexpected payload format for extended message handshake");
+  }
+  const Integer* port = asInteger(dict->get("p"));
+  if(port && 0 < port->i() && port->i() < 65536) {
+    msg->_tcpPort = port->i();
+  }
+  const String* version = asString(dict->get("v"));
+  if(version) {
+    msg->_clientVersion = version->s();
+  }
+  const Dict* extDict = asDict(dict->get("m"));
+  if(extDict) {
+    for(Dict::ValueType::const_iterator i = extDict->begin(),
+          eoi = extDict->end(); i != eoi; ++i) {
+      const Integer* extId = asInteger((*i).second);
+      if(extId) {
+        msg->_extensions[(*i).first] = extId->i();
       }
     }
   }
-  const BDE& metadataSize = dict["metadata_size"];
+  const Integer* metadataSize = asInteger(dict->get("metadata_size"));
   // Only accept metadata smaller than 1MiB
-  if(metadataSize.isInteger() && metadataSize.i() <= 1024*1024) {
-    msg->_metadataSize = metadataSize.i();
+  if(metadataSize && metadataSize->i() <= 1024*1024) {
+    msg->_metadataSize = metadataSize->i();
   }
   return msg;
 }

+ 2 - 4
src/Makefile.am

@@ -194,7 +194,6 @@ SRCS =  Socket.h\
 	PieceSelector.h\
 	LongestSequencePieceSelector.cc LongestSequencePieceSelector.h\
 	bitfield.cc bitfield.h\
-	BDE.cc BDE.h\
 	CreateRequestCommand.cc CreateRequestCommand.h\
 	DownloadResultCode.h\
 	wallclock.h\
@@ -204,7 +203,6 @@ SRCS =  Socket.h\
 	Event.h\
 	timespec.h\
 	ValueBase.cc ValueBase.h\
-	bencode2.cc bencode2.h\
 	ContextAttribute.h\
 	TorrentAttribute.h
 
@@ -447,7 +445,6 @@ SRCS += PeerAbstractCommand.cc PeerAbstractCommand.h\
 	RangeBtMessageValidator.h\
 	IndexBtMessageValidator.h\
 	ExtensionMessageRegistry.h\
-	bencode.cc bencode.h\
 	bittorrent_helper.cc bittorrent_helper.h\
 	BtStopDownloadCommand.cc BtStopDownloadCommand.h\
 	PriorityPieceSelector.cc PriorityPieceSelector.h\
@@ -455,7 +452,8 @@ SRCS += PeerAbstractCommand.cc PeerAbstractCommand.h\
 	LpdMessageReceiver.cc LpdMessageReceiver.h\
 	LpdMessage.h\
 	LpdReceiveMessageCommand.cc LpdReceiveMessageCommand.h\
-	LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h
+	LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h\
+	bencode2.cc bencode2.h
 endif # ENABLE_BITTORRENT
 
 if ENABLE_METALINK

+ 36 - 41
src/Makefile.in

@@ -241,7 +241,6 @@ bin_PROGRAMS = aria2c$(EXEEXT)
 @ENABLE_BITTORRENT_TRUE@	RangeBtMessageValidator.h\
 @ENABLE_BITTORRENT_TRUE@	IndexBtMessageValidator.h\
 @ENABLE_BITTORRENT_TRUE@	ExtensionMessageRegistry.h\
-@ENABLE_BITTORRENT_TRUE@	bencode.cc bencode.h\
 @ENABLE_BITTORRENT_TRUE@	bittorrent_helper.cc bittorrent_helper.h\
 @ENABLE_BITTORRENT_TRUE@	BtStopDownloadCommand.cc BtStopDownloadCommand.h\
 @ENABLE_BITTORRENT_TRUE@	PriorityPieceSelector.cc PriorityPieceSelector.h\
@@ -249,7 +248,8 @@ bin_PROGRAMS = aria2c$(EXEEXT)
 @ENABLE_BITTORRENT_TRUE@	LpdMessageReceiver.cc LpdMessageReceiver.h\
 @ENABLE_BITTORRENT_TRUE@	LpdMessage.h\
 @ENABLE_BITTORRENT_TRUE@	LpdReceiveMessageCommand.cc LpdReceiveMessageCommand.h\
-@ENABLE_BITTORRENT_TRUE@	LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h
+@ENABLE_BITTORRENT_TRUE@	LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h\
+@ENABLE_BITTORRENT_TRUE@	bencode2.cc bencode2.h
 
 @ENABLE_METALINK_TRUE@am__append_14 = Metalinker.cc Metalinker.h\
 @ENABLE_METALINK_TRUE@	MetalinkEntry.cc MetalinkEntry.h\
@@ -433,13 +433,12 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	SelectEventPoll.cc SelectEventPoll.h SequentialPicker.h \
 	SequentialDispatcherCommand.h PieceSelector.h \
 	LongestSequencePieceSelector.cc LongestSequencePieceSelector.h \
-	bitfield.cc bitfield.h BDE.cc BDE.h CreateRequestCommand.cc \
+	bitfield.cc bitfield.h CreateRequestCommand.cc \
 	CreateRequestCommand.h DownloadResultCode.h wallclock.h \
 	download_helper.cc download_helper.h MetadataInfo.cc \
 	MetadataInfo.h SessionSerializer.cc SessionSerializer.h \
-	Event.h timespec.h ValueBase.cc ValueBase.h bencode2.cc \
-	bencode2.h ContextAttribute.h TorrentAttribute.h \
-	XmlRpcRequestParserController.cc \
+	Event.h timespec.h ValueBase.cc ValueBase.h ContextAttribute.h \
+	TorrentAttribute.h XmlRpcRequestParserController.cc \
 	XmlRpcRequestParserController.h \
 	XmlRpcRequestParserStateMachine.cc \
 	XmlRpcRequestParserStateMachine.h XmlRpcRequestParserState.h \
@@ -586,25 +585,25 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
 	IndexBtMessage.cc IndexBtMessage.h ZeroBtMessage.cc \
 	ZeroBtMessage.h RangeBtMessageValidator.h \
 	IndexBtMessageValidator.h ExtensionMessageRegistry.h \
-	bencode.cc bencode.h bittorrent_helper.cc bittorrent_helper.h \
+	bittorrent_helper.cc bittorrent_helper.h \
 	BtStopDownloadCommand.cc BtStopDownloadCommand.h \
 	PriorityPieceSelector.cc PriorityPieceSelector.h \
 	LpdMessageDispatcher.cc LpdMessageDispatcher.h \
 	LpdMessageReceiver.cc LpdMessageReceiver.h LpdMessage.h \
 	LpdReceiveMessageCommand.cc LpdReceiveMessageCommand.h \
 	LpdDispatchMessageCommand.cc LpdDispatchMessageCommand.h \
-	Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
-	MetalinkResource.cc MetalinkResource.h MetalinkMetaurl.cc \
-	MetalinkMetaurl.h MetalinkProcessor.h \
-	MetalinkParserController.cc MetalinkParserController.h \
-	MetalinkParserStateMachine.cc MetalinkParserStateMachine.h \
-	MetalinkParserState.h MetalinkParserStateImpl.cc \
-	MetalinkParserStateImpl.h MetalinkParserStateV3Impl.cc \
-	MetalinkParserStateV3Impl.h MetalinkParserStateV4Impl.cc \
-	MetalinkParserStateV4Impl.h Metalink2RequestGroup.cc \
-	Metalink2RequestGroup.h MetalinkPostDownloadHandler.cc \
-	MetalinkPostDownloadHandler.h MetalinkHelper.cc \
-	MetalinkHelper.h XML2SAXMetalinkProcessor.cc \
+	bencode2.cc bencode2.h Metalinker.cc Metalinker.h \
+	MetalinkEntry.cc MetalinkEntry.h MetalinkResource.cc \
+	MetalinkResource.h MetalinkMetaurl.cc MetalinkMetaurl.h \
+	MetalinkProcessor.h MetalinkParserController.cc \
+	MetalinkParserController.h MetalinkParserStateMachine.cc \
+	MetalinkParserStateMachine.h MetalinkParserState.h \
+	MetalinkParserStateImpl.cc MetalinkParserStateImpl.h \
+	MetalinkParserStateV3Impl.cc MetalinkParserStateV3Impl.h \
+	MetalinkParserStateV4Impl.cc MetalinkParserStateV4Impl.h \
+	Metalink2RequestGroup.cc Metalink2RequestGroup.h \
+	MetalinkPostDownloadHandler.cc MetalinkPostDownloadHandler.h \
+	MetalinkHelper.cc MetalinkHelper.h XML2SAXMetalinkProcessor.cc \
 	XML2SAXMetalinkProcessor.h ExpatMetalinkProcessor.cc \
 	ExpatMetalinkProcessor.h asctime_r.c asctime_r.h libgen.c \
 	libgen.h getaddrinfo.c getaddrinfo.h gai_strerror.c \
@@ -759,14 +758,14 @@ am__objects_6 =
 @ENABLE_BITTORRENT_TRUE@	RangeBtMessage.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	IndexBtMessage.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	ZeroBtMessage.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@	bencode.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	bittorrent_helper.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	BtStopDownloadCommand.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	PriorityPieceSelector.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	LpdMessageDispatcher.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	LpdMessageReceiver.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	LpdReceiveMessageCommand.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@	LpdDispatchMessageCommand.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@	LpdDispatchMessageCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@	bencode2.$(OBJEXT)
 @ENABLE_METALINK_TRUE@am__objects_14 = Metalinker.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkEntry.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkResource.$(OBJEXT) \
@@ -873,10 +872,9 @@ am__objects_32 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
 	SocketBuffer.$(OBJEXT) OptionHandlerException.$(OBJEXT) \
 	URIResult.$(OBJEXT) SelectEventPoll.$(OBJEXT) \
 	LongestSequencePieceSelector.$(OBJEXT) bitfield.$(OBJEXT) \
-	BDE.$(OBJEXT) CreateRequestCommand.$(OBJEXT) \
-	download_helper.$(OBJEXT) MetadataInfo.$(OBJEXT) \
-	SessionSerializer.$(OBJEXT) ValueBase.$(OBJEXT) \
-	bencode2.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+	CreateRequestCommand.$(OBJEXT) download_helper.$(OBJEXT) \
+	MetadataInfo.$(OBJEXT) SessionSerializer.$(OBJEXT) \
+	ValueBase.$(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) \
@@ -1212,23 +1210,22 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
 	SelectEventPoll.cc SelectEventPoll.h SequentialPicker.h \
 	SequentialDispatcherCommand.h PieceSelector.h \
 	LongestSequencePieceSelector.cc LongestSequencePieceSelector.h \
-	bitfield.cc bitfield.h BDE.cc BDE.h CreateRequestCommand.cc \
+	bitfield.cc bitfield.h CreateRequestCommand.cc \
 	CreateRequestCommand.h DownloadResultCode.h wallclock.h \
 	download_helper.cc download_helper.h MetadataInfo.cc \
 	MetadataInfo.h SessionSerializer.cc SessionSerializer.h \
-	Event.h timespec.h ValueBase.cc ValueBase.h bencode2.cc \
-	bencode2.h ContextAttribute.h TorrentAttribute.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) $(am__append_21) \
-	$(am__append_22) $(am__append_23) $(am__append_24) \
-	$(am__append_25) $(am__append_26) $(am__append_27) \
-	$(am__append_28) $(am__append_29) $(am__append_30) \
-	$(am__append_31)
+	Event.h timespec.h ValueBase.cc ValueBase.h ContextAttribute.h \
+	TorrentAttribute.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) \
+	$(am__append_21) $(am__append_22) $(am__append_23) \
+	$(am__append_24) $(am__append_25) $(am__append_26) \
+	$(am__append_27) $(am__append_28) $(am__append_29) \
+	$(am__append_30) $(am__append_31)
 noinst_LIBRARIES = libaria2c.a
 libaria2c_a_SOURCES = $(SRCS)
 aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@@ -1348,7 +1345,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfig.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigFactory.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AutoSaveCommand.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BDE.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BNode.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldMan.Po@am__quote@
@@ -1631,7 +1627,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ZeroBtMessage.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asctime_r.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base32.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bencode.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bencode2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitfield.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bittorrent_helper.Po@am__quote@

+ 49 - 93
src/PeerListProcessor.h

@@ -40,120 +40,76 @@
 #include <cstring>
 
 #include "a2netcompat.h"
-#include "bencode.h"
 #include "Peer.h"
 #include "ValueBase.h"
 
 namespace aria2 {
 
 class PeerListProcessor {
-private:
+public:
   template<typename OutputIterator>
-  class PeerListValueBaseVisitor:public ValueBaseVisitor {
-    OutputIterator dest_;
-  public:
-    PeerListValueBaseVisitor(OutputIterator dest):dest_(dest) {}
+  void extractPeer(const ValueBase* peerData, OutputIterator dest)
+  {
+    class PeerListValueBaseVisitor:public ValueBaseVisitor {
+    private:
+      OutputIterator dest_;
+    public:
+      PeerListValueBaseVisitor(OutputIterator dest):dest_(dest) {}
 
-    virtual void visit(const String& peerData)
-    {
-      size_t length = peerData.s().size();
-      if(length%6 == 0) {
-        const char* base = peerData.s().data();
-        for(size_t i = 0; i < length; i += 6) {
-          struct in_addr in;
-          memcpy(&in.s_addr, base+i, sizeof(uint32_t));
-          std::string ipaddr = inet_ntoa(in);
-          uint16_t port_nworder;
-          memcpy(&port_nworder, base+i+4, sizeof(uint16_t));
-          uint16_t port = ntohs(port_nworder);
-          *dest_ = SharedHandle<Peer>(new Peer(ipaddr, port));
-          ++dest_;
+      virtual ~PeerListValueBaseVisitor() {}
+
+      virtual void visit(const String& peerData)
+      {
+        size_t length = peerData.s().size();
+        if(length%6 == 0) {
+          const char* base = peerData.s().data();
+          for(size_t i = 0; i < length; i += 6) {
+            struct in_addr in;
+            memcpy(&in.s_addr, base+i, sizeof(uint32_t));
+            std::string ipaddr = inet_ntoa(in);
+            uint16_t port_nworder;
+            memcpy(&port_nworder, base+i+4, sizeof(uint16_t));
+            uint16_t port = ntohs(port_nworder);
+            *dest_ = SharedHandle<Peer>(new Peer(ipaddr, port));
+            ++dest_;
+          }
         }
       }
-    }
 
-    virtual void visit(const Integer& v) {}
+      virtual void visit(const Integer& v) {}
 
-    virtual void visit(const List& peerData)
-    {
-      for(List::ValueType::const_iterator itr = peerData.begin(),
-            eoi = peerData.end(); itr != eoi; ++itr) {
-        const Dict* peerDict = asDict(*itr);
-        if(!peerDict) {
-          continue;
-        }
-        static const std::string IP = "ip";
-        static const std::string PORT = "port";
-        const String* ip = asString(peerDict->get(IP));
-        const Integer* port = asInteger(peerDict->get(PORT));
-        if(!ip || !port || !(0 < port->i() && port->i() < 65536)) {
-          continue;
+      virtual void visit(const List& peerData)
+      {
+        for(List::ValueType::const_iterator itr = peerData.begin(),
+              eoi = peerData.end(); itr != eoi; ++itr) {
+          const Dict* peerDict = asDict(*itr);
+          if(!peerDict) {
+            continue;
+          }
+          static const std::string IP = "ip";
+          static const std::string PORT = "port";
+          const String* ip = asString(peerDict->get(IP));
+          const Integer* port = asInteger(peerDict->get(PORT));
+          if(!ip || !port || !(0 < port->i() && port->i() < 65536)) {
+            continue;
+          }
+          *dest_ = SharedHandle<Peer>(new Peer(ip->s(), port->i()));
+          ++dest_;
         }
-        *dest_ = SharedHandle<Peer>(new Peer(ip->s(), port->i()));
-        ++dest_;
       }
-    }
 
-    virtual void visit(const Dict& v) {}
-  };
-public:
-  template<typename OutputIterator>
-  void extractPeer(const SharedHandle<ValueBase>& peerData, OutputIterator dest)
-  {
-    if(!peerData.isNull()) {
-      PeerListValueBaseVisitor<OutputIterator> visitor(dest);
+      virtual void visit(const Dict& v) {}
+    };
+    if(peerData) {
+      PeerListValueBaseVisitor visitor(dest);
       peerData->accept(visitor);
     }
   }
 
   template<typename OutputIterator>
-  void extractPeer(const BDE& peerData, OutputIterator dest)
-  {
-    if(peerData.isList()) {
-      extractPeerFromList(peerData, dest);
-    } else if(peerData.isString()) {
-      extractPeerFromCompact(peerData, dest);
-    }
-  }
-
-  template<typename OutputIterator>
-  void extractPeerFromList(const BDE& peerData, OutputIterator dest)
-  {
-    for(BDE::List::const_iterator itr = peerData.listBegin(),
-          eoi = peerData.listEnd(); itr != eoi; ++itr) {
-      const BDE& peerDict = *itr;
-      if(!peerDict.isDict()) {
-        continue;
-      }
-      static const std::string IP = "ip";
-      static const std::string PORT = "port";
-      const BDE& ip = peerDict[IP];
-      const BDE& port = peerDict[PORT];
-      if(!ip.isString() || !port.isInteger() ||
-         !(0 < port.i() && port.i() < 65536)) {
-        continue;
-      }
-      *dest = SharedHandle<Peer>(new Peer(ip.s(), port.i()));
-      ++dest;
-    }
-  }
-
-  template<typename OutputIterator>
-  void extractPeerFromCompact(const BDE& peerData, OutputIterator dest)
+  void extractPeer(const SharedHandle<ValueBase>& peerData, OutputIterator dest)
   {
-    size_t length = peerData.s().size();
-    if(length%6 == 0) {
-      for(size_t i = 0; i < length; i += 6) {
-        struct in_addr in;
-        memcpy(&in.s_addr, peerData.s().c_str()+i, sizeof(uint32_t));
-        std::string ipaddr = inet_ntoa(in);
-        uint16_t port_nworder;
-        memcpy(&port_nworder, peerData.s().c_str()+i+4, sizeof(uint16_t));
-        uint16_t port = ntohs(port_nworder);
-        *dest = SharedHandle<Peer>(new Peer(ipaddr, port));
-        ++dest;
-      }
-    }
+    return extractPeer(peerData.get(), dest);
   }
 };
 

+ 6 - 7
src/UTMetadataDataExtensionMessage.cc

@@ -33,8 +33,7 @@
  */
 /* copyright --> */
 #include "UTMetadataDataExtensionMessage.h"
-#include "BDE.h"
-#include "bencode.h"
+#include "bencode2.h"
 #include "util.h"
 #include "a2functional.h"
 #include "DownloadContext.h"
@@ -55,11 +54,11 @@ UTMetadataDataExtensionMessage::UTMetadataDataExtensionMessage
 
 std::string UTMetadataDataExtensionMessage::getPayload()
 {
-  BDE dict = BDE::dict();
-  dict["msg_type"] = 1;
-  dict["piece"] = getIndex();
-  dict["total_size"] = _totalSize;
-  return bencode::encode(dict)+_data;
+  Dict dict;
+  dict.put("msg_type", Integer::g(1));
+  dict.put("piece", Integer::g(getIndex()));
+  dict.put("total_size", Integer::g(_totalSize));
+  return bencode2::encode(&dict)+_data;
 }
 
 std::string UTMetadataDataExtensionMessage::toString() const

+ 1 - 2
src/UTMetadataPostDownloadHandler.cc

@@ -33,7 +33,6 @@
  */
 /* copyright --> */
 #include "UTMetadataPostDownloadHandler.h"
-#include "BDE.h"
 #include "bittorrent_helper.h"
 #include "RequestGroup.h"
 #include "download_helper.h"
@@ -46,7 +45,7 @@
 #include "a2functional.h"
 #include "DiskAdaptor.h"
 #include "PieceStorage.h"
-#include "bencode.h"
+#include "bencode2.h"
 #include "message.h"
 #include "prefs.h"
 #include "Option.h"

+ 5 - 6
src/UTMetadataRejectExtensionMessage.cc

@@ -33,10 +33,9 @@
  */
 /* copyright --> */
 #include "UTMetadataRejectExtensionMessage.h"
-#include "BDE.h"
 #include "a2functional.h"
 #include "util.h"
-#include "bencode.h"
+#include "bencode2.h"
 #include "DlAbortEx.h"
 
 namespace aria2 {
@@ -47,10 +46,10 @@ UTMetadataRejectExtensionMessage::UTMetadataRejectExtensionMessage
 
 std::string UTMetadataRejectExtensionMessage::getPayload()
 {
-  BDE dict = BDE::dict();
-  dict["msg_type"] = 2;
-  dict["piece"] = getIndex();
-  return bencode::encode(dict);
+  Dict dict;
+  dict.put("msg_type", Integer::g(2));
+  dict.put("piece", Integer::g(getIndex()));
+  return bencode2::encode(&dict);
 }
 
 std::string UTMetadataRejectExtensionMessage::toString() const

+ 5 - 6
src/UTMetadataRequestExtensionMessage.cc

@@ -33,8 +33,7 @@
  */
 /* copyright --> */
 #include "UTMetadataRequestExtensionMessage.h"
-#include "BDE.h"
-#include "bencode.h"
+#include "bencode2.h"
 #include "util.h"
 #include "a2functional.h"
 #include "bittorrent_helper.h"
@@ -57,10 +56,10 @@ UTMetadataRequestExtensionMessage::UTMetadataRequestExtensionMessage
 
 std::string UTMetadataRequestExtensionMessage::getPayload()
 {
-  BDE dict = BDE::dict();
-  dict["msg_type"] = 0;
-  dict["piece"] = getIndex();
-  return bencode::encode(dict);
+  Dict dict;
+  dict.put("msg_type", Integer::g(0));
+  dict.put("piece", Integer::g(getIndex()));
+  return bencode2::encode(&dict);
 }
 
 std::string UTMetadataRequestExtensionMessage::toString() const

+ 15 - 15
src/UTPexExtensionMessage.cc

@@ -41,7 +41,7 @@
 #include "DlAbortEx.h"
 #include "message.h"
 #include "StringFormat.h"
-#include "bencode.h"
+#include "bencode2.h"
 #include "a2functional.h"
 #include "wallclock.h"
 
@@ -64,11 +64,11 @@ std::string UTPexExtensionMessage::getPayload()
   std::pair<std::string, std::string> droppedPeerPair =
     createCompactPeerListAndFlag(_droppedPeers);
 
-  BDE dict = BDE::dict();
-  dict["added"] = freshPeerPair.first;
-  dict["added.f"] = freshPeerPair.second;
-  dict["dropped"] = droppedPeerPair.first;
-  return bencode::encode(dict);
+  Dict dict;
+  dict.put("added", freshPeerPair.first);
+  dict.put("added.f", freshPeerPair.second);
+  dict.put("dropped", droppedPeerPair.first);
+  return bencode2::encode(&dict);
 }
 
 std::pair<std::string, std::string>
@@ -158,17 +158,17 @@ UTPexExtensionMessage::create(const unsigned char* data, size_t len)
   }
   UTPexExtensionMessageHandle msg(new UTPexExtensionMessage(*data));
 
-  const BDE dict = bencode::decode(data+1, len-1);
-  if(dict.isDict()) {
+  SharedHandle<ValueBase> decoded = bencode2::decode(data+1, len-1);
+  const Dict* dict = asDict(decoded);
+  if(dict) {
     PeerListProcessor proc;
-    const BDE& added = dict["added"];
-    if(added.isString()) {
-      proc.extractPeerFromCompact(added, std::back_inserter(msg->_freshPeers));
+    const String* added = asString(dict->get("added"));
+    if(added) {
+      proc.extractPeer(added, std::back_inserter(msg->_freshPeers));
     }
-    const BDE& dropped = dict["dropped"];
-    if(dropped.isString()) {
-      proc.extractPeerFromCompact(dropped,
-                                  std::back_inserter(msg->_droppedPeers));
+    const String* dropped = asString(dict->get("dropped"));
+    if(dropped) {
+      proc.extractPeer(dropped, std::back_inserter(msg->_droppedPeers));
     }
   }
   return msg;

+ 15 - 0
src/ValueBase.cc

@@ -64,6 +64,11 @@ SharedHandle<String> String::g(const ValueType& string)
   return SharedHandle<String>(new String(string));
 }
 
+SharedHandle<String> String::g(const unsigned char* data, size_t length)
+{
+  return SharedHandle<String>(new String(data, length));
+}
+
 void String::accept(ValueBaseVisitor& v) const
 {
   v.visit(*this);
@@ -95,11 +100,21 @@ const SharedHandle<ValueBase>& List::get(size_t index) const
   return list_[index];
 }
 
+void List::set(size_t index, const SharedHandle<ValueBase>& v)
+{
+  list_[index] = v;
+}
+
 void List::append(const SharedHandle<ValueBase>& v)
 {
   list_.push_back(v);
 }
 
+void List::append(const String::ValueType& string)
+{
+  list_.push_back(String::g(string));
+}
+
 List& List::operator<<(const SharedHandle<ValueBase>& v)
 {
   list_.push_back(v);

+ 8 - 0
src/ValueBase.h

@@ -96,6 +96,8 @@ public:
 
   static SharedHandle<String> g(const ValueType& string);
 
+  static SharedHandle<String> g(const unsigned char* data, size_t length);
+
   virtual void accept(ValueBaseVisitor& visitor) const;
 private:
   ValueType str_;
@@ -128,12 +130,18 @@ public:
   // Appends given v to list.
   void append(const SharedHandle<ValueBase>& v);
 
+  // Appeding string is so common that we provide shortcut function.
+  void append(const String::ValueType& string);
+
   // Alias for append()
   List& operator<<(const SharedHandle<ValueBase>& v);
 
   // Returns the object at given index.
   const SharedHandle<ValueBase>& get(size_t index) const;
 
+  // Set the object at given index.
+  void set(size_t index, const SharedHandle<ValueBase>& v);
+
   // Returns the const reference of the object at the given index.
   const SharedHandle<ValueBase>& operator[](size_t index) const;
 

+ 5 - 1
src/Xml2XmlRpcRequestProcessor.cc

@@ -145,7 +145,11 @@ XmlRpcRequestProcessor::parseMemory(const std::string& xml)
   if(r != 0) {
     throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
   }
-  return XmlRpcRequest(_stm->getMethodName(), _stm->getCurrentFrameValue());
+  if(!asList(_stm->getCurrentFrameValue())) {
+    throw DL_ABORT_EX("Bad XML-RPC parameter list");
+  }
+  return XmlRpcRequest(_stm->getMethodName(),
+                       static_pointer_cast<List>(_stm->getCurrentFrameValue()));
 }
 
 } // namespace xmlrpc

+ 38 - 27
src/XmlRpcMethod.cc

@@ -34,7 +34,6 @@
 /* copyright --> */
 #include "XmlRpcMethod.h"
 #include "DownloadEngine.h"
-#include "BDE.h"
 #include "LogFactory.h"
 #include "RecoverableException.h"
 #include "message.h"
@@ -52,6 +51,7 @@
 #include "CheckIntegrityEntry.h"
 #include "ServerStatMan.h"
 #include "FileEntry.h"
+#include "DlAbortEx.h"
 
 namespace aria2 {
 
@@ -61,11 +61,12 @@ XmlRpcMethod::XmlRpcMethod():
   _optionParser(OptionParser::getInstance()),
   _logger(LogFactory::getInstance()) {}
 
-BDE XmlRpcMethod::createErrorResponse(const Exception& e)
+SharedHandle<ValueBase> XmlRpcMethod::createErrorResponse
+(const Exception& e)
 {
-  BDE params = BDE::dict();
-  params["faultCode"] = BDE(1);
-  params["faultString"] = BDE(e.what());
+  SharedHandle<Dict> params = Dict::g();
+  params->put("faultCode", Integer::g(1));
+  params->put("faultString", std::string(e.what()));
   return params;
 }
 
@@ -105,29 +106,35 @@ static void gatherOption
            ("We don't know how to deal with %s option",
             optionName.c_str()).str());
       }
-      // header and index-out option can take array as value
-      const BDE& value = (*first).second;
-      if((optionName == PREF_HEADER || optionName == PREF_INDEX_OUT) &&
-         value.isList()){
-        for(BDE::List::const_iterator argiter = value.listBegin(),
-              eoi = value.listEnd(); argiter != eoi; ++argiter) {
-          if((*argiter).isString()) {
-            optionHandler->parse(*option.get(), (*argiter).s());
+      const String* opval = asString((*first).second);
+      if(opval) {
+        optionHandler->parse(*option.get(), opval->s());
+      } else {
+        // header and index-out option can take array as value
+        const List* oplist = asList((*first).second);
+        if(oplist &&
+           (optionName == PREF_HEADER || optionName == PREF_INDEX_OUT)) {
+          for(List::ValueType::const_iterator argiter = oplist->begin(),
+                eoi = oplist->end(); argiter != eoi; ++argiter) {
+            const String* opval = asString(*argiter);
+            if(opval) {
+              optionHandler->parse(*option.get(), opval->s());
+            }
           }
         }
-      } else if(value.isString()) {
-        optionHandler->parse(*option.get(), value.s());
       }
     }
   }  
 }
 
 void XmlRpcMethod::gatherRequestOption
-(const SharedHandle<Option>& option, const BDE& optionsDict)
+(const SharedHandle<Option>& option, const Dict* optionsDict)
 {
-  gatherOption(optionsDict.dictBegin(), optionsDict.dictEnd(),
-               listRequestOptions(),
-               option, _optionParser);
+  if(optionsDict) {
+    gatherOption(optionsDict->begin(), optionsDict->end(),
+                 listRequestOptions(),
+                 option, _optionParser);
+  }
 }
 
 // Copy option in the range [optNameFirst, optNameLast) from src to
@@ -158,11 +165,13 @@ const std::set<std::string>& listChangeableOptions()
 }
 
 void XmlRpcMethod::gatherChangeableOption
-(const SharedHandle<Option>& option, const BDE& optionsDict)
+(const SharedHandle<Option>& option, const Dict* optionsDict)
 {
-  gatherOption(optionsDict.dictBegin(), optionsDict.dictEnd(),
-               listChangeableOptions(),
-               option, _optionParser);
+  if(optionsDict) {
+    gatherOption(optionsDict->begin(), optionsDict->end(),
+                 listChangeableOptions(),
+                 option, _optionParser);
+  }
 }
 
 void XmlRpcMethod::applyChangeableOption(Option* dest, Option* src) const
@@ -183,11 +192,13 @@ const std::set<std::string>& listChangeableGlobalOptions()
 }
 
 void XmlRpcMethod::gatherChangeableGlobalOption
-(const SharedHandle<Option>& option, const BDE& optionsDict)
+(const SharedHandle<Option>& option, const Dict* optionsDict)
 {
-  gatherOption(optionsDict.dictBegin(), optionsDict.dictEnd(),
-               listChangeableGlobalOptions(),
-               option, _optionParser);
+  if(optionsDict) {
+    gatherOption(optionsDict->begin(), optionsDict->end(),
+                 listChangeableGlobalOptions(),
+                 option, _optionParser);
+  }
 }
 
 void XmlRpcMethod::applyChangeableGlobalOption(Option* dest, Option* src) const

+ 9 - 8
src/XmlRpcMethod.h

@@ -40,12 +40,12 @@
 #include <string>
 
 #include "SharedHandle.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
 class DownloadEngine;
 class OptionParser;
-class BDE;
 class Logger;
 class Option;
 class Exception;
@@ -71,26 +71,27 @@ protected:
   // Subclass must implement this function to fulfil XmlRpcRequest
   // req.  The return value of this method is used as a return value
   // of XML-RPC request.
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e) = 0;
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e) = 0;
 
-  void gatherRequestOption(const SharedHandle<Option>& option,
-                           const BDE& optionsDict);
+  void gatherRequestOption
+  (const SharedHandle<Option>& option, const Dict* optionsDict);
 
-  void gatherChangeableOption(const SharedHandle<Option>& option,
-                              const BDE& optionDict);
+  void gatherChangeableOption
+  (const SharedHandle<Option>& option, const Dict* optionDict);
 
   // Copy options which is changeable in XML-RPC changeOption command
   // to dest.
   void applyChangeableOption(Option* dest, Option* src) const;
 
   void gatherChangeableGlobalOption(const SharedHandle<Option>& option,
-                                    const BDE& optionDict);
+                                    const Dict* optionDict);
 
   // Copy options which is changeable in XML-RPC changeGlobalOption
   // command to dest.
   void applyChangeableGlobalOption(Option* dest, Option* src) const;
 
-  BDE createErrorResponse(const Exception& e);
+  SharedHandle<ValueBase> createErrorResponse(const Exception& e);
 
   const SharedHandle<OptionParser>& getOptionParser() const
   {

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 306 - 299
src/XmlRpcMethodImpl.cc


+ 88 - 51
src/XmlRpcMethodImpl.h

@@ -41,10 +41,10 @@
 #include <deque>
 #include <algorithm>
 
-#include "BDE.h"
 #include "XmlRpcRequest.h"
 #include "ValueBase.h"
 #include "TorrentAttribute.h"
+#include "DlAbortEx.h"
 
 namespace aria2 {
 
@@ -55,7 +55,8 @@ namespace xmlrpc {
 
 class AddUriXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -66,7 +67,8 @@ public:
 
 class RemoveXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -77,7 +79,8 @@ public:
 
 class ForceRemoveXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -88,7 +91,8 @@ public:
 
 class PauseXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -99,7 +103,8 @@ public:
 
 class ForcePauseXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -110,7 +115,8 @@ public:
 
 class PauseAllXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -121,7 +127,8 @@ public:
 
 class ForcePauseAllXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -132,7 +139,8 @@ public:
 
 class UnpauseXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -143,7 +151,8 @@ public:
 
 class UnpauseAllXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -155,7 +164,8 @@ public:
 #ifdef ENABLE_BITTORRENT
 class AddTorrentXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -168,7 +178,8 @@ public:
 #ifdef ENABLE_METALINK
 class AddMetalinkXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -180,7 +191,8 @@ public:
 
 class PurgeDownloadResultXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -191,7 +203,8 @@ public:
 
 class GetUrisXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -202,7 +215,8 @@ public:
 
 class GetFilesXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -214,7 +228,8 @@ public:
 #ifdef ENABLE_BITTORRENT
 class GetPeersXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -226,7 +241,8 @@ public:
 
 class GetServersXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -237,7 +253,8 @@ public:
 
 class TellStatusXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -248,7 +265,8 @@ public:
 
 class TellActiveXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -279,7 +297,6 @@ private:
     } else if(size <= (size_t)offset) {
       return std::make_pair(last, last);
     }
-    BDE list = BDE::list();
     size_t lastDistance;
     if(size < offset+num) {
       lastDistance = size;
@@ -292,34 +309,37 @@ private:
     return std::make_pair(first, last);
   }
 
-  void checkPaginationParams(const BDE& params) const
+  void checkPaginationParams(const SharedHandle<List>& params) const
   {
-    assert(params.isList());
-    if(params.size() != 2 ||
-       !params[0].isInteger() || !params[1].isInteger() ||
-       params[1].i() < 0) {
+    if(params->size() != 2) {
+      throw DL_ABORT_EX("Invalid argument. Specify offset and num in integer.");
+    }
+    const Integer* p1 = asInteger(params->get(0));
+    const Integer* p2 = asInteger(params->get(1));
+    if(!p1 || !p2 || p2->i() < 0) {
       throw DL_ABORT_EX("Invalid argument. Specify offset and num in integer.");
     }
   }
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e)
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e)
   {
-    const BDE& params = req.params;
+    const SharedHandle<List>& params = req.params;
     checkPaginationParams(params);
-    ssize_t offset = params[0].i();
-    size_t num = params[1].i();
+    ssize_t offset = asInteger(params->get(0))->i();
+    size_t num = asInteger(params->get(1))->i();
     const std::deque<SharedHandle<T> >& items = getItems(e);
     std::pair<typename std::deque<SharedHandle<T> >::const_iterator,
       typename std::deque<SharedHandle<T> >::const_iterator> range =
       getPaginationRange(offset, num, items.begin(), items.end());
-    BDE list = BDE::list();
+    SharedHandle<List> list = List::g();
     for(; range.first != range.second; ++range.first) {
-      BDE entryDict = BDE::dict();
+      SharedHandle<Dict> entryDict = Dict::g();
       createEntry(entryDict, *range.first, e);
-      list << entryDict;
+      list->append(entryDict);
     }
     if(offset < 0) {
-      std::reverse(list.listBegin(), list.listEnd());
+      std::reverse(list->begin(), list->end());
     }
     return list;
   }
@@ -328,7 +348,9 @@ protected:
   getItems(DownloadEngine* e) const = 0;
 
   virtual void createEntry
-  (BDE& entryDict, const SharedHandle<T>& item, DownloadEngine* e) const = 0;
+  (const SharedHandle<Dict>& entryDict,
+   const SharedHandle<T>& item,
+   DownloadEngine* e) const = 0;
 };
 
 class TellWaitingXmlRpcMethod:
@@ -338,7 +360,8 @@ protected:
   getItems(DownloadEngine* e) const;
 
   virtual void createEntry
-  (BDE& entryDict, const SharedHandle<RequestGroup>& item,
+  (const SharedHandle<Dict>& entryDict,
+   const SharedHandle<RequestGroup>& item,
    DownloadEngine* e) const;
 public:
   static const std::string& getMethodName()
@@ -355,7 +378,8 @@ protected:
    getItems(DownloadEngine* e) const;
 
   virtual void createEntry
-  (BDE& entryDict, const SharedHandle<DownloadResult>& item,
+  (const SharedHandle<Dict>& entryDict,
+   const SharedHandle<DownloadResult>& item,
    DownloadEngine* e) const;
 public:
   static const std::string& getMethodName()
@@ -367,7 +391,8 @@ public:
 
 class ChangeOptionXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -378,7 +403,8 @@ public:
 
 class ChangeGlobalOptionXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -389,7 +415,8 @@ public:
 
 class GetVersionXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -400,7 +427,8 @@ public:
 
 class GetOptionXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -411,7 +439,8 @@ public:
 
 class GetGlobalOptionXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -422,7 +451,8 @@ public:
 
 class ChangePositionXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -433,7 +463,8 @@ public:
 
 class ChangeUriXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -444,7 +475,8 @@ public:
 
 class GetSessionInfoXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -455,7 +487,8 @@ public:
 
 class ShutdownXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -466,7 +499,8 @@ public:
 
 class ForceShutdownXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -477,7 +511,8 @@ public:
 
 class SystemMulticallXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 public:
   static const std::string& getMethodName()
   {
@@ -488,23 +523,25 @@ public:
 
 class NoSuchMethodXmlRpcMethod:public XmlRpcMethod {
 protected:
-  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+  virtual SharedHandle<ValueBase> process
+  (const XmlRpcRequest& req, DownloadEngine* e);
 };
 
 // Helper function to store data to entryDict from ds. This function
 // is used by tellStatus method.
 void gatherStoppedDownload
-(BDE& entryDict, const SharedHandle<DownloadResult>& ds);
+(const SharedHandle<Dict>& entryDict, const SharedHandle<DownloadResult>& ds);
 
 // Helper function to store data to entryDict from group. This
 // function is used by tellStatus/tellActive/tellWaiting method
 void gatherProgressCommon
-(BDE& entryDict, const SharedHandle<RequestGroup>& group);
+(const SharedHandle<Dict>& entryDict, const SharedHandle<RequestGroup>& group);
 
 #ifdef ENABLE_BITTORRENT
 // Helper function to store BitTorrent metadata from torrentAttrs.
 void gatherBitTorrentMetadata
-(BDE& btDict, const SharedHandle<TorrentAttribute>& torrentAttrs);
+(const SharedHandle<Dict>& btDict,
+ const SharedHandle<TorrentAttribute>& torrentAttrs);
 #endif // ENABLE_BITTORRENT
 
 } // namespace xmlrpc

+ 4 - 3
src/XmlRpcRequest.h

@@ -39,7 +39,7 @@
 
 #include <string>
 
-#include "BDE.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -47,9 +47,10 @@ namespace xmlrpc {
 
 struct XmlRpcRequest {
   std::string methodName;
-  BDE params;
+  SharedHandle<List> params;
 
-  XmlRpcRequest(const std::string& methodName, const BDE& params):
+  XmlRpcRequest(const std::string& methodName,
+                const SharedHandle<List>& params):
     methodName(methodName), params(params) {}
 };
 

+ 25 - 5
src/XmlRpcRequestParserController.cc

@@ -51,10 +51,11 @@ void XmlRpcRequestParserController::popStructFrame()
   assert(!_frameStack.empty());
 
   StateFrame parentFrame = _frameStack.top();
-  assert(parentFrame._value.isDict());
+  Dict* dict = asDict(parentFrame._value);
+  assert(dict);
   _frameStack.pop();
   if(_currentFrame.validMember()) {
-    parentFrame._value[_currentFrame._name] = _currentFrame._value;
+    dict->put(_currentFrame._name, _currentFrame._value);
   }
   _currentFrame = parentFrame;
 }
@@ -64,14 +65,33 @@ void XmlRpcRequestParserController::popArrayFrame()
   assert(!_frameStack.empty());
 
   StateFrame parentFrame = _frameStack.top();
-  assert(parentFrame._value.isList());
+  List* list = asList(parentFrame._value);
+  assert(list);
   _frameStack.pop();
-  if(!_currentFrame._value.isNone()) {
-    parentFrame._value << _currentFrame._value;
+  if(!_currentFrame._value.isNull()) {
+    list->append(_currentFrame._value);
   }
   _currentFrame = parentFrame;
 }
 
+void XmlRpcRequestParserController::setCurrentFrameValue
+(const SharedHandle<ValueBase>& value)
+{
+  _currentFrame._value = value;
+}
+
+void XmlRpcRequestParserController::setCurrentFrameName
+(const std::string& name)
+{
+  _currentFrame._name = name;
+}
+
+const SharedHandle<ValueBase>&
+XmlRpcRequestParserController::getCurrentFrameValue() const
+{
+  return _currentFrame._value;
+}
+
 } // namespace xmlrpc
   
 } // namespace aria2

+ 6 - 12
src/XmlRpcRequestParserController.h

@@ -40,7 +40,7 @@
 #include <stack>
 #include <string>
 
-#include "BDE.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -50,12 +50,12 @@ class XmlRpcRequestParserController {
 private:
 
   struct StateFrame {
-    BDE _value;
+    SharedHandle<ValueBase> _value;
     std::string _name;
 
     bool validMember() const
     {
-      return !_value.isNone() && !_name.empty();
+      return !_value.isNull() && !_name.empty();
     }
   };
 
@@ -75,17 +75,11 @@ public:
   // to p and _currentFrame = p;
   void popArrayFrame();
   
-  void setCurrentFrameValue(const BDE& value)
-  {
-    _currentFrame._value = value;
-  }
+  void setCurrentFrameValue(const SharedHandle<ValueBase>& value);
 
-  void setCurrentFrameName(const std::string& name)
-  {
-    _currentFrame._name = name;
-  }
+  void setCurrentFrameName(const std::string& name);
 
-  const BDE& getCurrentFrameValue() const { return _currentFrame._value; }
+  const SharedHandle<ValueBase>& getCurrentFrameValue() const;
 
   void setMethodName(const std::string& methodName)
   {

+ 7 - 7
src/XmlRpcRequestParserStateImpl.cc

@@ -83,7 +83,7 @@ void MethodCallXmlRpcRequestParserState::beginElement
   if(name == elements::METHOD_NAME) {
     stm->pushMethodNameState();
   } else if(name == elements::A2_PARAMS) {
-    stm->setCurrentFrameValue(BDE::list());
+    stm->setCurrentFrameValue(List::g());
     stm->pushParamsState();
   } else {
     stm->pushUnknownElementState();
@@ -155,10 +155,10 @@ void ValueXmlRpcRequestParserState::beginElement
   if(name == elements::I4 || name == elements::INT) {
     stm->pushIntState();
   } else if(name == elements::STRUCT) {
-    stm->setCurrentFrameValue(BDE::dict());
+    stm->setCurrentFrameValue(Dict::g());
     stm->pushStructState();
   } else if(name == elements::ARRAY) {
-    stm->setCurrentFrameValue(BDE::list());
+    stm->setCurrentFrameValue(List::g());
     stm->pushArrayState();
   } else if(name == elements::STRING || name == elements::DOUBLE) {
     stm->pushStringState();
@@ -186,9 +186,9 @@ void IntXmlRpcRequestParserState::endElement
 {
   try {
     int64_t value = util::parseLLInt(characters);
-    stm->setCurrentFrameValue(BDE(value));
+    stm->setCurrentFrameValue(Integer::g(value));
   } catch(RecoverableException& e) {
-    // nothing to do here: We just leave current frame value to BDE::none
+    // nothing to do here: We just leave current frame value to null.
   }
 }
 
@@ -207,7 +207,7 @@ void StringXmlRpcRequestParserState::endElement
  const std::string& name,
  const std::string& characters)
 {
-  stm->setCurrentFrameValue(BDE(characters));
+  stm->setCurrentFrameValue(String::g(characters));
 }
 
 // Base64XmlRpcRequestParserState
@@ -225,7 +225,7 @@ void Base64XmlRpcRequestParserState::endElement
  const std::string& name,
  const std::string& characters)
 {
-  stm->setCurrentFrameValue(BDE(Base64::decode(characters)));
+  stm->setCurrentFrameValue(String::g(Base64::decode(characters)));
 }
 
 // StructXmlRpcRequestParserState

+ 3 - 5
src/XmlRpcRequestParserStateMachine.h

@@ -41,14 +41,12 @@
 #include <map>
 #include <stack>
 
-#include "BDE.h"
 #include "XmlRpcRequestParserController.h"
 #include "XmlRpcRequestParserStateImpl.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
-class BDE;
-
 namespace xmlrpc {
 
 class XmlRpcRequestParserStateMachine {
@@ -116,12 +114,12 @@ public:
     _controller->pushFrame();
   }
 
-  void setCurrentFrameValue(const BDE& value)
+  void setCurrentFrameValue(const SharedHandle<ValueBase>& value)
   {
     _controller->setCurrentFrameValue(value);
   }
 
-  const BDE& getCurrentFrameValue() const
+  const SharedHandle<ValueBase>& getCurrentFrameValue() const
   {
     return _controller->getCurrentFrameValue();
   }

+ 44 - 39
src/XmlRpcResponse.cc

@@ -47,51 +47,56 @@ namespace aria2 {
 namespace xmlrpc {
 
 template<typename OutputStream>
-static void encodeValue(const BDE& value, OutputStream& o);
-
-template<typename InputIterator, typename OutputStream>
-static void encodeArray
-(InputIterator first, InputIterator last, OutputStream& o)
+static void encodeValue(const SharedHandle<ValueBase>& value, OutputStream& o)
 {
-  o << "<array>" << "<data>";
-  for(; first != last; ++first) {
-    encodeValue(*first, o);
-  }
-  o << "</data>" << "</array>";
-}
+  class XmlValueBaseVisitor:public ValueBaseVisitor {
+  private:
+    OutputStream& o_;
+  public:
+    XmlValueBaseVisitor(OutputStream& o):o_(o) {}
 
-template<typename InputIterator, typename OutputStream>
-static void encodeStruct
-(InputIterator first, InputIterator last, OutputStream& o)
-{
-  o << "<struct>";
-  for(; first != last; ++first) {
-    o << "<member>"
-      << "<name>" << util::htmlEscape((*first).first) << "</name>";
-    encodeValue((*first).second, o);
-    o << "</member>";
-  }
-  o << "</struct>";
-}
+    virtual ~XmlValueBaseVisitor() {}
 
-template<typename OutputStream>
-static void encodeValue(const BDE& value, OutputStream& o)
-{
-  o << "<value>";
-  if(value.isString()) {
-    o << "<string>" << util::htmlEscape(value.s()) << "</string>";
-  } else if(value.isInteger()) {
-    o << "<int>" << value.i() << "</int>";
-  } else if(value.isList()) {
-    encodeArray(value.listBegin(), value.listEnd(), o);
-  } else if(value.isDict()) {
-    encodeStruct(value.dictBegin(), value.dictEnd(), o);
-  }
-  o << "</value>";
+    virtual void visit(const String& v)
+    {
+      o_ << "<value><string>" << util::htmlEscape(v.s()) << "</string></value>";
+    }
+
+    virtual void visit(const Integer& v)
+    {
+      o_ << "<value><int>" << v.i() << "</int></value>";
+    }
+
+    virtual void visit(const List& v)
+    {
+      o_ << "<value><array><data>";
+      for(List::ValueType::const_iterator i = v.begin(), eoi = v.end();
+          i != eoi; ++i) {
+        (*i)->accept(*this);
+      }
+      o_ << "</data></array></value>";
+    }
+
+    virtual void visit(const Dict& v)
+    {
+      o_ << "<value><struct>";
+      for(Dict::ValueType::const_iterator i = v.begin(), eoi = v.end();
+          i != eoi; ++i) {
+        o_ << "<member><name>" << util::htmlEscape((*i).first) << "</name>";
+        (*i).second->accept(*this);
+        o_ << "</member>";
+      }
+      o_ << "</struct></value>";
+    }
+  };
+
+  XmlValueBaseVisitor visitor(o);
+  value->accept(visitor);
 }
 
 template<typename OutputStream>
-std::string encodeAll(OutputStream& o, int code, const BDE& param)
+std::string encodeAll
+(OutputStream& o, int code, const SharedHandle<ValueBase>& param)
 {
   o << "<?xml version=\"1.0\"?>" << "<methodResponse>";
   if(code == 0) {

+ 4 - 3
src/XmlRpcResponse.h

@@ -39,7 +39,7 @@
 
 #include <string>
 
-#include "BDE.h"
+#include "ValueBase.h"
 
 namespace aria2 {
 
@@ -49,9 +49,10 @@ struct XmlRpcResponse {
   // 0 for success, non-zero for error
   int code;
   
-  BDE param;
+  SharedHandle<ValueBase> param;
 
-  XmlRpcResponse(int code, const BDE& param):code(code), param(param) {}
+  XmlRpcResponse
+  (int code, const SharedHandle<ValueBase>& param):code(code), param(param) {}
 
   std::string toXml(bool gzip = false) const;
 };

+ 0 - 242
src/bencode.cc

@@ -1,242 +0,0 @@
-/* <!-- 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 "DlAbortEx.h"
-
-namespace aria2 {
-
-namespace bencode {
-
-static BDE decodeiter(std::istream& ss, size_t depth);
-
-static void checkdelim(std::istream& ss, const char delim = ':')
-{
-  char d;
-  if(!(ss.get(d) && d == delim)) {
-    throw DL_ABORT_EX
-      (StringFormat("Bencode decoding failed: Delimiter '%c' not found.",
-                    delim).str());
-  }
-}
-
-static std::string decoderawstring(std::istream& ss)
-{
-  int length;
-  ss >> length;
-  if(!ss || length < 0) {
-    throw DL_ABORT_EX("Bencode decoding failed:"
-                      " A positive 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);
-  std::string str(&buf[0], &buf[length]);
-  delete [] buf;
-  if(ss.gcount() != static_cast<int>(length)) {
-    throw DL_ABORT_EX
-      (StringFormat("Bencode decoding failed:"
-                    " Expected %lu bytes of data, but only %d read.",
-                    static_cast<unsigned long>(length), ss.gcount()).str());
-  }
-  return str;
-}
-
-static BDE decodestring(std::istream& ss)
-{
-  return BDE(decoderawstring(ss));
-}
-
-static BDE decodeinteger(std::istream& ss)
-{
-  BDE::Integer integer;
-  ss >> integer;
-  if(!ss) {
-    throw DL_ABORT_EX("Bencode decoding failed:"
-                      " Integer expected but none found");
-  }
-  checkdelim(ss, 'e');
-  return BDE(integer);
-}
-
-static BDE decodedict(std::istream& ss, size_t depth)
-{
-  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, depth);
-    }
-  }
-  throw DL_ABORT_EX("Bencode decoding failed:"
-                    " Unexpected EOF in dict context. 'e' expected.");
-}
-
-static BDE decodelist(std::istream& ss, size_t depth)
-{
-  BDE list = BDE::list();
-  char c;
-  while(ss.get(c)) {
-    if(c == 'e') {
-      return list;
-    } else {
-      ss.unget();
-      list << decodeiter(ss, depth);
-    }
-  }
-  throw DL_ABORT_EX("Bencode decoding failed:"
-                    " Unexpected EOF in list context. 'e' expected.");
-}
-
-static void checkDepth(size_t depth)
-{
-  if(depth >= MAX_STRUCTURE_DEPTH) {
-    throw DL_ABORT_EX("Bencode decoding failed: Structure is too deep.");
-  }
-}
-
-static BDE decodeiter(std::istream& ss, size_t depth)
-{
-  checkDepth(depth);
-  char c;
-  if(!ss.get(c)) {
-    throw DL_ABORT_EX("Bencode decoding failed:"
-                      " Unexpected EOF in term context."
-                      " 'd', 'l', 'i' or digit is expected.");
-  }
-  if(c == 'd') {
-    return decodedict(ss, depth+1);
-  } else if(c == 'l') {
-    return decodelist(ss, depth+1);
-  } else if(c == 'i') {
-    return decodeinteger(ss);
-  } else {
-    ss.unget();
-    return decodestring(ss);
-  }
-}
-
-BDE decode(std::istream& in)
-{
-  return decodeiter(in, 0);
-}
-
-BDE decode(const std::string& s)
-{
-  size_t end;
-  return decode(s, end);
-}
-
-BDE decode(const std::string& s, size_t& end)
-{
-  if(s.empty()) {
-    return BDE::none;
-  }
-  std::istringstream ss(s);
-
-  BDE bde = decodeiter(ss, 0);
-  end = ss.tellg();
-  return bde;
-}
-
-BDE decode(const unsigned char* data, size_t length)
-{
-  return decode(std::string(&data[0], &data[length]));
-}
-
-BDE decode(const unsigned char* data, size_t length, size_t& end)
-{
-  return decode(std::string(&data[0], &data[length]), end);
-}
-
-BDE decodeFromFile(const std::string& filename)
-{
-  std::ifstream f(filename.c_str(), std::ios::binary);
-  if(f) {
-    return decode(f);
-  } else {
-    throw DL_ABORT_EX
-      (StringFormat("Bencode decoding failed:"
-                    " Cannot open file '%s'.", filename.c_str()).str());
-  }
-}
-
-static void encodeIter(std::ostream& o, const BDE& bde)
-{
-  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(), eoi = bde.dictEnd();
-        i != eoi; ++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(), eoi = bde.listEnd();
-        i != eoi; ++i){
-      encodeIter(o, *i);
-    }
-    o << "e";
-  }
-}
-
-std::string encode(const BDE& bde)
-{
-  std::ostringstream ss;
-  encodeIter(ss, bde);
-  return ss.str();
-}
-
-} // namespace bencode
-
-} // namespace aria2

+ 0 - 72
src/bencode.h

@@ -1,72 +0,0 @@
-/* <!-- 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 --> */
-#ifndef _D_BENCODE_H_
-#define _D_BENCODE_H_
-
-#include "common.h"
-
-#include <string>
-#include <iosfwd>
-
-#include "BDE.h"
-
-namespace aria2 {
-
-namespace bencode {
-
-const size_t MAX_STRUCTURE_DEPTH = 100;
-
-BDE decode(std::istream& in);
-
-// Decode the data in s.
-BDE decode(const std::string& s);
-
-// Decode the data in s. After decode is done successfully, return the
-// bencoded string length in end.
-BDE decode(const std::string& s, size_t& end);
-
-BDE decode(const unsigned char* data, size_t length);
-
-BDE decode(const unsigned char* data, size_t length, size_t& end);
-
-BDE decodeFromFile(const std::string& filename);
-
-std::string encode(const BDE& bde);
-
-} // namespace bencode
-
-} // namespace aria2
-
-#endif // _D_BENCODE_H_

+ 0 - 1
src/bittorrent_helper.cc

@@ -40,7 +40,6 @@
 
 #include "DownloadContext.h"
 #include "Randomizer.h"
-#include "bencode.h"
 #include "util.h"
 #include "DlAbortEx.h"
 #include "message.h"

+ 0 - 149
test/BDETest.cc

@@ -1,149 +0,0 @@
-#include "BDE.h"
-
-#include <cstring>
-
-#include <cppunit/extensions/HelperMacros.h>
-
-#include "util.h"
-
-namespace aria2 {
-
-class BDETest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(BDETest);
-  CPPUNIT_TEST(testString);
-  CPPUNIT_TEST(testInteger);
-  CPPUNIT_TEST(testDict);
-  CPPUNIT_TEST(testDictIter);
-  CPPUNIT_TEST(testList);
-  CPPUNIT_TEST(testListIter);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void testString();
-  void testInteger();
-  void testDict();
-  void testDictIter();
-  void testList();
-  void testListIter();
-  void testDecode();
-  void testEncode();
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( BDETest );
-
-void BDETest::testString()
-{
-  BDE s(std::string("aria2"));
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2"), s.s());
-
-  unsigned char dataWithNull[] = { 0xf0, '\0', 0x0f };
-  BDE sWithNull(dataWithNull, sizeof(dataWithNull));
-  CPPUNIT_ASSERT(memcmp(dataWithNull, sWithNull.s().c_str(),
-                        sizeof(dataWithNull)) == 0);
-
-  BDE zero("");
-  CPPUNIT_ASSERT_EQUAL(std::string(""), zero.s());
-
-  const unsigned char uc[] = { 0x08, 0x19, 0x2a, 0x3b };
-  BDE data(uc, sizeof(uc));
-  CPPUNIT_ASSERT_EQUAL(util::toHex(uc, sizeof(uc)),
-                       util::toHex(data.uc(), data.s().size()));
-}
-
-void BDETest::testInteger()
-{
-  BDE integer(INT64_MAX);
-  CPPUNIT_ASSERT_EQUAL(INT64_MAX, integer.i());
-}
-
-void BDETest::testDict()
-{
-  BDE dict = BDE::dict();
-  CPPUNIT_ASSERT(dict.empty());
-
-  dict["ki"] = 7;
-  dict["ks"] = std::string("abc");
-
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), dict.size());
-  CPPUNIT_ASSERT(dict.containsKey("ki"));
-  CPPUNIT_ASSERT_EQUAL(static_cast<BDE::Integer>(7), dict["ki"].i());
-  CPPUNIT_ASSERT(dict.containsKey("ks"));
-  CPPUNIT_ASSERT_EQUAL(std::string("abc"), dict["ks"].s());
-
-  CPPUNIT_ASSERT(dict["kn"].isNone()); // This adds kn key with default value.
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), dict.size());
-  CPPUNIT_ASSERT(dict.containsKey("kn"));
-
-  const BDE& ref = dict;
-  ref["kn2"]; // This doesn't add kn2 key.
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), ref.size());
-  CPPUNIT_ASSERT(!ref.containsKey("kn2"));
-
-  dict.removeKey("kn");
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), dict.size());
-  CPPUNIT_ASSERT(!dict.containsKey("kn"));
-}
-
-void BDETest::testDictIter()
-{
-  BDE dict = BDE::dict();
-  dict["alpha2"] = std::string("alpha2");
-  dict["charlie"] = std::string("charlie");
-  dict["bravo"] = std::string("bravo");
-  dict["alpha"] = std::string("alpha");
-
-  BDE::Dict::iterator i = dict.dictBegin();
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), (*i++).first); 
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha2"), (*i++).first);
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), (*i++).first);
-  CPPUNIT_ASSERT_EQUAL(std::string("charlie"), (*i++).first);
-  CPPUNIT_ASSERT(dict.dictEnd() == i);
-
-  const BDE& ref = dict;
-  BDE::Dict::const_iterator ci = ref.dictBegin();
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), (*ci++).first);
-  std::advance(ci, 3);
-  CPPUNIT_ASSERT(ref.dictEnd() == ci);
-}
-
-void BDETest::testList()
-{
-  BDE list = BDE::list();
-  CPPUNIT_ASSERT(list.empty());
-  list << 7;
-  list << std::string("aria2");
-
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), list.size());
-  CPPUNIT_ASSERT_EQUAL(static_cast<BDE::Integer>(7), list[0].i());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2"), list[1].s());
-
-  const BDE& ref = list;
-  CPPUNIT_ASSERT_EQUAL(static_cast<BDE::Integer>(7), ref[0].i());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2"), ref[1].s());
-}
-
-void BDETest::testListIter()
-{
-  BDE list = BDE::list();
-  list << std::string("alpha2");
-  list << std::string("charlie");
-  list << std::string("bravo");
-  list << std::string("alpha");
-
-  BDE::List::iterator i = list.listBegin();
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha2"), (*i++).s());
-  CPPUNIT_ASSERT_EQUAL(std::string("charlie"), (*i++).s());
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), (*i++).s());
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), (*i++).s());
-  CPPUNIT_ASSERT(list.listEnd() == i);
-
-  const BDE& ref = list;
-  BDE::List::const_iterator ci = ref.listBegin();
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha2"), (*ci++).s());
-  std::advance(ci, 3);
-  CPPUNIT_ASSERT(ref.listEnd() == ci);
-}
-
-} // namespace aria2

+ 0 - 202
test/BencodeTest.cc

@@ -1,202 +0,0 @@
-#include "bencode.h"
-
-#include <cstdlib>
-
-#include <cppunit/extensions/HelperMacros.h>
-
-#include "RecoverableException.h"
-#include "TimeA2.h"
-
-namespace aria2 {
-
-class BencodeTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(BencodeTest);
-  CPPUNIT_TEST(testDecode);
-  CPPUNIT_TEST(testDecode_overflow);
-  CPPUNIT_TEST(testEncode);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void testDecode();
-  void testDecode_overflow();
-  void testEncode();
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( BencodeTest );
-
-void BencodeTest::testDecode()
-{
-  {
-    // string, integer and list in dict
-    BDE dict =
-      bencode::decode("d4:name5:aria24:sizei12345678900e5:filesl3:bin3:docee");
-    CPPUNIT_ASSERT(dict.isDict());
-    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), dict["name"].s());
-    CPPUNIT_ASSERT_EQUAL(static_cast<BDE::Integer>(12345678900LL),
-                         dict["size"].i());
-    BDE list = dict["files"];
-    CPPUNIT_ASSERT(list.isList());
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), list.size());
-    CPPUNIT_ASSERT_EQUAL(std::string("bin"), list[0].s());
-    CPPUNIT_ASSERT_EQUAL(std::string("doc"), list[1].s());
-  }
-  {
-    // dict in list
-    BDE list = bencode::decode("ld1:ki123eee");
-    CPPUNIT_ASSERT(list.isList());
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), list.size());
-    BDE dict = list[0];
-    CPPUNIT_ASSERT(dict.isDict());
-    CPPUNIT_ASSERT_EQUAL(static_cast<BDE::Integer>(123),
-                         dict["k"].i());
-  }
-  {
-    // empty key is allowed
-    BDE s = bencode::decode("d0:1:ve");
-  }
-  {
-    // empty string
-    BDE s = bencode::decode("0:");
-    CPPUNIT_ASSERT_EQUAL(std::string(""), s.s());
-  }
-  {
-    // empty dict
-    BDE d = bencode::decode("de");
-    CPPUNIT_ASSERT(d.empty());
-  }
-  {
-    // empty list
-    BDE l = bencode::decode("le");
-    CPPUNIT_ASSERT(l.empty());
-  }
-  {
-    // integer, without ending 'e'
-    try {
-      bencode::decode("i3");
-      CPPUNIT_FAIL("exception must be thrown.");
-    } catch(RecoverableException& e) {
-      CPPUNIT_ASSERT_EQUAL(std::string("Bencode decoding failed:"
-                                       " Delimiter 'e' not found."),
-                           std::string(e.what()));
-    }    
-  }
-  {
-    // dict, without ending 'e'
-    try {
-      bencode::decode("d");
-      CPPUNIT_FAIL("exception must be thrown.");
-    } catch(RecoverableException& e) {
-      CPPUNIT_ASSERT_EQUAL(std::string("Bencode decoding failed:"
-                                       " Unexpected EOF in dict context."
-                                       " 'e' expected."),
-                           std::string(e.what()));
-    }          
-  }
-  {
-    // list, without ending 'e'
-    try {
-      bencode::decode("l");
-      CPPUNIT_FAIL("exception must be thrown.");
-    } catch(RecoverableException& e) {
-      CPPUNIT_ASSERT_EQUAL(std::string("Bencode decoding failed:"
-                                       " Unexpected EOF in list context."
-                                       " 'e' expected."),
-                           std::string(e.what()));
-    }          
-  }
-  {
-    // string, less than the specified length.
-    try {
-      bencode::decode("3:ab");
-      CPPUNIT_FAIL("exception must be thrown.");
-    } catch(RecoverableException& e) {
-      CPPUNIT_ASSERT_EQUAL(std::string("Bencode decoding failed:"
-                                       " Expected 3 bytes of data,"
-                                       " but only 2 read."),
-                           std::string(e.what()));
-    }
-  }
-  {
-    // string, but length is invalid
-    try {
-      bencode::decode("x:abc");
-      CPPUNIT_FAIL("exception must be thrown.");
-    } catch(RecoverableException& e) {
-      CPPUNIT_ASSERT_EQUAL(std::string("Bencode decoding failed:"
-                                       " A positive integer expected"
-                                       " but none found."),
-                           std::string(e.what()));
-    }
-  }
-  {
-    // string with minus length
-    try {
-      bencode::decode("-1:a");
-      CPPUNIT_FAIL("exception must be thrown.");
-    } catch(RecoverableException& e) {
-      CPPUNIT_ASSERT_EQUAL(std::string("Bencode decoding failed:"
-                                       " A positive integer expected"
-                                       " but none found."),
-                           std::string(e.what()));
-    }
-  }
-  {
-    // empty encoded data
-    CPPUNIT_ASSERT(bencode::decode("").isNone());
-  }
-  {
-    // ignore trailing garbage at the end of the input.
-    BDE s = bencode::decode("5:aria2trail");
-    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), s.s());
-  }
-  {
-    // Get trailing garbage position
-    size_t end;
-    BDE s = bencode::decode("5:aria2trail", end);
-    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), s.s());
-    CPPUNIT_ASSERT_EQUAL((size_t)7, end);
-  }
-}
-
-void BencodeTest::testDecode_overflow()
-{
-  std::string s;
-  size_t depth = bencode::MAX_STRUCTURE_DEPTH+1;
-  for(size_t i = 0; i < depth; ++i) {
-    s += "l";
-  }
-  for(size_t i = 0; i < depth; ++i) {
-    s += "e";
-  }
-  try {
-    bencode::decode(s);
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(RecoverableException& e) {
-    // success
-  }
-}
-
-void BencodeTest::testEncode()
-{
-  {
-    BDE dict = BDE::dict();
-    dict["name"] = std::string("aria2");
-    dict["loc"] = 80000;
-    dict["files"] = BDE::list();
-    dict["files"] << std::string("aria2c");
-    dict["attrs"] = BDE::dict();
-    dict["attrs"]["license"] = std::string("GPL");
-
-    CPPUNIT_ASSERT_EQUAL(std::string("d"
-                                     "5:attrsd7:license3:GPLe"
-                                     "5:filesl6:aria2ce"
-                                     "3:loci80000e"
-                                     "4:name5:aria2"
-                                     "e"),
-                         bencode::encode(dict));
-  }
-}
-
-} // namespace aria2

+ 14 - 14
test/DHTAnnouncePeerMessageTest.cc

@@ -9,7 +9,7 @@
 #include "MockDHTMessageDispatcher.h"
 #include "MockDHTMessage.h"
 #include "DHTPeerAnnounceStorage.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -61,19 +61,19 @@ void DHTAnnouncePeerMessageTest::testGetBencodedMessage()
   msg.setVersion("A200");
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("announce_peer");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  aDict["info_hash"] = BDE(infoHash, DHT_ID_LENGTH);
-  aDict["port"] = port;
-  aDict["token"] = token;
-  dict["a"] = aDict;
-
-  CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode::encode(dict)),
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "q");
+  dict.put("q", "announce_peer");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
+  aDict->put("port", Integer::g(port));
+  aDict->put("token", token);
+  dict.put("a", aDict);
+
+  CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
                        util::percentEncode(msgbody));
 }
 

+ 9 - 9
test/DHTAnnouncePeerReplyMessageTest.cc

@@ -5,7 +5,7 @@
 #include "DHTNode.h"
 #include "Exception.h"
 #include "util.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -38,15 +38,15 @@ void DHTAnnouncePeerReplyMessageTest::testGetBencodedMessage()
   msg.setVersion("A200");
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("r");
-  BDE rDict = BDE::dict();
-  rDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  dict["r"] = rDict;
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "r");
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  dict.put("r", rDict);
 
-  CPPUNIT_ASSERT_EQUAL(bencode::encode(dict), msgbody);
+  CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }
 
 } // namespace aria2

+ 12 - 12
test/DHTFindNodeMessageTest.cc

@@ -9,7 +9,7 @@
 #include "MockDHTMessage.h"
 #include "MockDHTMessageDispatcher.h"
 #include "DHTRoutingTable.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -62,17 +62,17 @@ void DHTFindNodeMessageTest::testGetBencodedMessage()
   msg.setVersion("A200");
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("find_node");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  aDict["target"] = BDE(targetNode->getID(), DHT_ID_LENGTH);
-  dict["a"] = aDict;
-
-  CPPUNIT_ASSERT_EQUAL(bencode::encode(dict), msgbody);
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "q");
+  dict.put("q", "find_node");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  aDict->put("target", String::g(targetNode->getID(), DHT_ID_LENGTH));
+  dict.put("a", aDict);
+
+  CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }
 
 void DHTFindNodeMessageTest::testDoReceivedAction()

+ 10 - 10
test/DHTFindNodeReplyMessageTest.cc

@@ -7,7 +7,7 @@
 #include "util.h"
 #include "DHTBucket.h"
 #include "bittorrent_helper.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -57,16 +57,16 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage()
 
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("r");
-  BDE rDict = BDE::dict();
-  rDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  rDict["nodes"] = compactNodeInfo;
-  dict["r"] = rDict;
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "r");
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  rDict->put("nodes", compactNodeInfo);
+  dict.put("r", rDict);
 
-  CPPUNIT_ASSERT_EQUAL(bencode::encode(dict), msgbody);
+  CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }
 
 } // namespace aria2

+ 12 - 12
test/DHTGetPeersMessageTest.cc

@@ -11,7 +11,7 @@
 #include "DHTTokenTracker.h"
 #include "DHTPeerAnnounceStorage.h"
 #include "DHTRoutingTable.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -83,17 +83,17 @@ void DHTGetPeersMessageTest::testGetBencodedMessage()
 
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("get_peers");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  aDict["info_hash"] = BDE(infoHash, DHT_ID_LENGTH);
-  dict["a"] = aDict;
-
-  CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode::encode(dict)),
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "q");
+  dict.put("q", "get_peers");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
+  dict.put("a", aDict);
+
+  CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
                        util::percentEncode(msgbody));
 }
 

+ 16 - 16
test/DHTGetPeersReplyMessageTest.cc

@@ -8,7 +8,7 @@
 #include "DHTBucket.h"
 #include "bittorrent_helper.h"
 #include "Peer.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -41,14 +41,14 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
 
   DHTGetPeersReplyMessage msg(localNode, remoteNode, token, transactionID);
   msg.setVersion("A200");
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("r");
-  BDE rDict = BDE::dict();
-  rDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  rDict["token"] = token;
-  dict["r"] = rDict;
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "r");
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  rDict->put("token", token);
+  dict.put("r", rDict);
   {
     std::string compactNodeInfo;
     SharedHandle<DHTNode> nodes[8];
@@ -69,29 +69,29 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
 
     std::string msgbody = msg.getBencodedMessage();
 
-    rDict["nodes"] = compactNodeInfo;
+    rDict->put("nodes", compactNodeInfo);
 
-    CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode::encode(dict)),
+    CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
                          util::percentEncode(msgbody));
   }
-  rDict.removeKey("nodes");
+  rDict->removeKey("nodes");
   {
     std::vector<SharedHandle<Peer> > peers;
-    BDE valuesList = BDE::list();
+    SharedHandle<List> valuesList = List::g();
     for(size_t i = 0; i < 4; ++i) {
       SharedHandle<Peer> peer(new Peer("192.168.0."+util::uitos(i+1), 6881+i));
       unsigned char buffer[6];
       CPPUNIT_ASSERT(bittorrent::createcompact
                      (buffer, peer->getIPAddress(), peer->getPort()));
-      valuesList << BDE(buffer, sizeof(buffer));
+      valuesList->append(String::g(buffer, sizeof(buffer)));
       peers.push_back(peer);
     }
-    rDict["values"] = valuesList;
+    rDict->put("values", valuesList);
 
     msg.setValues(peers);
     std::string msgbody  = msg.getBencodedMessage();
 
-    CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode::encode(dict)),
+    CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
                          util::percentEncode(msgbody));
   }
 }

+ 88 - 88
test/DHTMessageFactoryImplTest.cc

@@ -20,7 +20,7 @@
 #include "DHTGetPeersReplyMessage.h"
 #include "DHTAnnouncePeerMessage.h"
 #include "DHTAnnouncePeerReplyMessage.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -79,17 +79,17 @@ CPPUNIT_TEST_SUITE_REGISTRATION(DHTMessageFactoryImplTest);
 
 void DHTMessageFactoryImplTest::testCreatePingMessage()
 {
-  BDE dict = BDE::dict();
-  dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("ping");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
-  dict["a"] = aDict;
+  Dict dict;
+  dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+  dict.put("y", "q");
+  dict.put("q", "ping");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
+  dict.put("a", aDict);
   
   SharedHandle<DHTPingMessage> m
     (dynamic_pointer_cast<DHTPingMessage>
-     (factory->createQueryMessage(dict, "192.168.0.1", 6881)));
+     (factory->createQueryMessage(&dict, "192.168.0.1", 6881)));
   SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
   remoteNode->setIPAddress("192.168.0.1");
   remoteNode->setPort(6881);
@@ -102,12 +102,12 @@ void DHTMessageFactoryImplTest::testCreatePingMessage()
 
 void DHTMessageFactoryImplTest::testCreatePingReplyMessage()
 {
-  BDE dict = BDE::dict();
-  dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-  dict["y"] = BDE("r");
-  BDE rDict = BDE::dict();
-  rDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
-  dict["r"] = rDict;
+  Dict dict;
+  dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+  dict.put("y", "r");
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
+  dict.put("r", rDict);
 
   SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
   remoteNode->setIPAddress("192.168.0.1");
@@ -115,7 +115,7 @@ void DHTMessageFactoryImplTest::testCreatePingReplyMessage()
   
   SharedHandle<DHTPingReplyMessage> m
     (dynamic_pointer_cast<DHTPingReplyMessage>
-     (factory->createResponseMessage("ping", dict,
+     (factory->createResponseMessage("ping", &dict,
                                      remoteNode->getIPAddress(),
                                      remoteNode->getPort())));
 
@@ -127,20 +127,20 @@ void DHTMessageFactoryImplTest::testCreatePingReplyMessage()
 
 void DHTMessageFactoryImplTest::testCreateFindNodeMessage()
 {
-  BDE dict = BDE::dict();
-  dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("find_node");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
+  Dict dict;
+  dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+  dict.put("y", "q");
+  dict.put("q", "find_node");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
   unsigned char targetNodeID[DHT_ID_LENGTH];
   memset(targetNodeID, 0x11, DHT_ID_LENGTH);
-  aDict["target"] = BDE(targetNodeID, DHT_ID_LENGTH);
-  dict["a"] = aDict;
+  aDict->put("target", String::g(targetNodeID, DHT_ID_LENGTH));
+  dict.put("a", aDict);
   
   SharedHandle<DHTFindNodeMessage> m
     (dynamic_pointer_cast<DHTFindNodeMessage>
-     (factory->createQueryMessage(dict, "192.168.0.1", 6881)));
+     (factory->createQueryMessage(&dict, "192.168.0.1", 6881)));
   SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
   remoteNode->setIPAddress("192.168.0.1");
   remoteNode->setPort(6881);
@@ -156,11 +156,11 @@ void DHTMessageFactoryImplTest::testCreateFindNodeMessage()
 void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
 {
   try {
-    BDE dict = BDE::dict();
-    dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-    dict["y"] = BDE("r");
-    BDE rDict = BDE::dict();
-    rDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
+    Dict dict;
+    dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+    dict.put("y", "r");
+    SharedHandle<Dict> rDict = Dict::g();
+    rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
     std::string compactNodeInfo;
     SharedHandle<DHTNode> nodes[8];
     for(size_t i = 0; i < DHTBucket::K; ++i) {
@@ -175,8 +175,8 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
         std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
         std::string(&buf[0], &buf[sizeof(buf)]);
     }
-    rDict["nodes"] = compactNodeInfo;
-    dict["r"] = rDict;
+    rDict->put("nodes", compactNodeInfo);
+    dict.put("r", rDict);
 
     SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
     remoteNode->setIPAddress("192.168.0.1");
@@ -184,7 +184,7 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
   
     SharedHandle<DHTFindNodeReplyMessage> m
       (dynamic_pointer_cast<DHTFindNodeReplyMessage>
-       (factory->createResponseMessage("find_node", dict,
+       (factory->createResponseMessage("find_node", &dict,
                                        remoteNode->getIPAddress(),
                                        remoteNode->getPort())));
 
@@ -202,20 +202,20 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
 
 void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
 {
-  BDE dict = BDE::dict();
-  dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("get_peers");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
+  Dict dict;
+  dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+  dict.put("y", "q");
+  dict.put("q", "get_peers");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
   unsigned char infoHash[DHT_ID_LENGTH];
   memset(infoHash, 0x11, DHT_ID_LENGTH);
-  aDict["info_hash"] = BDE(infoHash, DHT_ID_LENGTH);
-  dict["a"] = aDict;
+  aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
+  dict.put("a", aDict);
   
   SharedHandle<DHTGetPeersMessage> m
     (dynamic_pointer_cast<DHTGetPeersMessage>
-     (factory->createQueryMessage(dict, "192.168.0.1", 6881)));
+     (factory->createQueryMessage(&dict, "192.168.0.1", 6881)));
   SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
   remoteNode->setIPAddress("192.168.0.1");
   remoteNode->setPort(6881);
@@ -231,11 +231,11 @@ void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
 void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
 {
   try {
-    BDE dict = BDE::dict();
-    dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-    dict["y"] = BDE("r");
-    BDE rDict = BDE::dict();
-    rDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
+    Dict dict;
+    dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+    dict.put("y", "r");
+    SharedHandle<Dict> rDict = Dict::g();
+    rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
     std::string compactNodeInfo;
     SharedHandle<DHTNode> nodes[8];
     for(size_t i = 0; i < DHTBucket::K; ++i) {
@@ -250,9 +250,9 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
         std::string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
         std::string(&buf[0], &buf[sizeof(buf)]);
     }
-    rDict["nodes"] = compactNodeInfo;
-    rDict["token"] = BDE("token");
-    dict["r"] = rDict;
+    rDict->put("nodes", compactNodeInfo);
+    rDict->put("token", "token");
+    dict.put("r", rDict);
 
     SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
     remoteNode->setIPAddress("192.168.0.1");
@@ -260,7 +260,7 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
   
     SharedHandle<DHTGetPeersReplyMessage> m
       (dynamic_pointer_cast<DHTGetPeersReplyMessage>
-       (factory->createResponseMessage("get_peers", dict,
+       (factory->createResponseMessage("get_peers", &dict,
                                        remoteNode->getIPAddress(),
                                        remoteNode->getPort())));
 
@@ -280,25 +280,25 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
 void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
 {
   try {
-    BDE dict = BDE::dict();
-    dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-    dict["y"] = BDE("r");
-    BDE rDict = BDE::dict();
-    rDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
+    Dict dict;
+    dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+    dict.put("y", "r");
+    SharedHandle<Dict> rDict = Dict::g();
+    rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
 
     std::deque<SharedHandle<Peer> > peers;
-    BDE valuesList = BDE::list();
+    SharedHandle<List> valuesList = List::g();
     for(size_t i = 0; i < 4; ++i) {
       SharedHandle<Peer> peer(new Peer("192.168.0."+util::uitos(i+1), 6881+i));
       unsigned char buffer[6];
       CPPUNIT_ASSERT(bittorrent::createcompact
                      (buffer, peer->getIPAddress(), peer->getPort()));
-      valuesList << BDE(buffer, sizeof(buffer));
+      valuesList->append(String::g(buffer, sizeof(buffer)));
       peers.push_back(peer);
     }
-    rDict["values"] = valuesList;
-    rDict["token"] = BDE("token");
-    dict["r"] = rDict;
+    rDict->put("values", valuesList);
+    rDict->put("token", "token");
+    dict.put("r", rDict);
 
     SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
     remoteNode->setIPAddress("192.168.0.1");
@@ -306,7 +306,7 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
   
     SharedHandle<DHTGetPeersReplyMessage> m
       (dynamic_pointer_cast<DHTGetPeersReplyMessage>
-       (factory->createResponseMessage("get_peers", dict,
+       (factory->createResponseMessage("get_peers", &dict,
                                        remoteNode->getIPAddress(),
                                        remoteNode->getPort())));
 
@@ -326,24 +326,24 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
 void DHTMessageFactoryImplTest::testCreateAnnouncePeerMessage()
 {
   try {
-    BDE dict = BDE::dict();
-    dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-    dict["y"] = BDE("q");
-    dict["q"] = BDE("announce_peer");
-    BDE aDict = BDE::dict();
-    aDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
+    Dict dict;
+    dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+    dict.put("y", "q");
+    dict.put("q", "announce_peer");
+    SharedHandle<Dict> aDict = Dict::g();
+    aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
     unsigned char infoHash[DHT_ID_LENGTH];
     memset(infoHash, 0x11, DHT_ID_LENGTH);
-    aDict["info_hash"] = BDE(infoHash, DHT_ID_LENGTH);
+    aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
     std::string token = "ffff";
     uint16_t port = 6881;
-    aDict["port"] = port;
-    aDict["token"] = token;
-    dict["a"] = aDict;
+    aDict->put("port", Integer::g(port));
+    aDict->put("token", token);
+    dict.put("a", aDict);
   
     SharedHandle<DHTAnnouncePeerMessage> m
       (dynamic_pointer_cast<DHTAnnouncePeerMessage>
-       (factory->createQueryMessage(dict, "192.168.0.1", 6882)));
+       (factory->createQueryMessage(&dict, "192.168.0.1", 6882)));
     SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
     remoteNode->setIPAddress("192.168.0.1");
     remoteNode->setPort(6882);
@@ -363,12 +363,12 @@ void DHTMessageFactoryImplTest::testCreateAnnouncePeerMessage()
 
 void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
 {
-  BDE dict = BDE::dict();
-  dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-  dict["y"] = BDE("r");
-  BDE rDict = BDE::dict();
-  rDict["id"] = BDE(remoteNodeID, DHT_ID_LENGTH);
-  dict["r"] = rDict;
+  Dict dict;
+  dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+  dict.put("y", "r");
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
+  dict.put("r", rDict);
 
   SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
   remoteNode->setIPAddress("192.168.0.1");
@@ -376,7 +376,7 @@ void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
   
   SharedHandle<DHTAnnouncePeerReplyMessage> m
     (dynamic_pointer_cast<DHTAnnouncePeerReplyMessage>
-     (factory->createResponseMessage("announce_peer", dict,
+     (factory->createResponseMessage("announce_peer", &dict,
                                      remoteNode->getIPAddress(),
                                      remoteNode->getPort())));
 
@@ -388,20 +388,20 @@ void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
 
 void DHTMessageFactoryImplTest::testReceivedErrorMessage()
 {
-  BDE dict = BDE::dict();
-  dict["t"] = BDE(transactionID, DHT_TRANSACTION_ID_LENGTH);
-  dict["y"] = BDE("e");
-  BDE list = BDE::list();
-  list << 404;
-  list << BDE("Not found");
-  dict["e"] = list;
+  Dict dict;
+  dict.put("t", String::g(transactionID, DHT_TRANSACTION_ID_LENGTH));
+  dict.put("y", "e");
+  SharedHandle<List> list = List::g();
+  list->append(Integer::g(404));
+  list->append("Not found");
+  dict.put("e", list);
 
   SharedHandle<DHTNode> remoteNode(new DHTNode(remoteNodeID));
   remoteNode->setIPAddress("192.168.0.1");
   remoteNode->setPort(6881);
 
   try {
-    factory->createResponseMessage("announce_peer", dict,
+    factory->createResponseMessage("announce_peer", &dict,
                                    remoteNode->getIPAddress(),
                                    remoteNode->getPort());
     CPPUNIT_FAIL("exception must be thrown.");

+ 9 - 10
test/DHTMessageTrackerTest.cc

@@ -10,7 +10,6 @@
 #include "DHTMessageTrackerEntry.h"
 #include "DHTRoutingTable.h"
 #include "MockDHTMessageFactory.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -62,11 +61,11 @@ void DHTMessageTrackerTest::testMessageArrived()
   tracker.addMessage(m3, DHT_MESSAGE_TIMEOUT);
 
   {
-    BDE resDict = BDE::dict();
-    resDict["t"] = m2->getTransactionID();
+    Dict resDict;
+    resDict.put("t", m2->getTransactionID());
     
     std::pair<SharedHandle<DHTMessage>, SharedHandle<DHTMessageCallback> > p =
-      tracker.messageArrived(resDict, m2->getRemoteNode()->getIPAddress(),
+      tracker.messageArrived(&resDict, m2->getRemoteNode()->getIPAddress(),
                              m2->getRemoteNode()->getPort());
     SharedHandle<DHTMessage> reply = p.first;
 
@@ -75,11 +74,11 @@ void DHTMessageTrackerTest::testMessageArrived()
     CPPUNIT_ASSERT_EQUAL((size_t)2, tracker.countEntry());
   }
   {
-    BDE resDict = BDE::dict();
-    resDict["t"] = m3->getTransactionID();
+    Dict resDict;
+    resDict.put("t", m3->getTransactionID());
 
     std::pair<SharedHandle<DHTMessage>, SharedHandle<DHTMessageCallback> > p =
-      tracker.messageArrived(resDict, m3->getRemoteNode()->getIPAddress(),
+      tracker.messageArrived(&resDict, m3->getRemoteNode()->getIPAddress(),
                              m3->getRemoteNode()->getPort());
     SharedHandle<DHTMessage> reply = p.first;
 
@@ -88,11 +87,11 @@ void DHTMessageTrackerTest::testMessageArrived()
     CPPUNIT_ASSERT_EQUAL((size_t)1, tracker.countEntry());
   }
   {
-    BDE resDict = BDE::dict();
-    resDict["t"] = m1->getTransactionID();
+    Dict resDict;
+    resDict.put("t", m1->getTransactionID());
 
     std::pair<SharedHandle<DHTMessage>, SharedHandle<DHTMessageCallback> > p =
-      tracker.messageArrived(resDict, "192.168.1.100", 6889);
+      tracker.messageArrived(&resDict, "192.168.1.100", 6889);
     SharedHandle<DHTMessage> reply = p.first;
 
     CPPUNIT_ASSERT(reply.isNull());

+ 10 - 10
test/DHTPingMessageTest.cc

@@ -8,7 +8,7 @@
 #include "MockDHTMessageFactory.h"
 #include "MockDHTMessageDispatcher.h"
 #include "MockDHTMessage.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -57,16 +57,16 @@ void DHTPingMessageTest::testGetBencodedMessage()
 
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("q");
-  dict["q"] = BDE("ping");
-  BDE aDict = BDE::dict();
-  aDict["id"] = BDE(localNode->getID(), DHT_ID_LENGTH);
-  dict["a"] = aDict;
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "q");
+  dict.put("q", "ping");
+  SharedHandle<Dict> aDict = Dict::g();
+  aDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
+  dict.put("a", aDict);
 
-  CPPUNIT_ASSERT_EQUAL(bencode::encode(dict), msgbody);
+  CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }
 
 void DHTPingMessageTest::testDoReceivedAction()

+ 9 - 9
test/DHTPingReplyMessageTest.cc

@@ -5,7 +5,7 @@
 #include "DHTNode.h"
 #include "Exception.h"
 #include "util.h"
-#include "bencode.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -41,15 +41,15 @@ void DHTPingReplyMessageTest::testGetBencodedMessage()
   msg.setVersion("A200");
   std::string msgbody = msg.getBencodedMessage();
 
-  BDE dict = BDE::dict();
-  dict["t"] = transactionID;
-  dict["v"] = BDE("A200");
-  dict["y"] = BDE("r");
-  BDE rDict = BDE::dict();
-  rDict["id"] = BDE(id, DHT_ID_LENGTH);
-  dict["r"] = rDict;
+  Dict dict;
+  dict.put("t", transactionID);
+  dict.put("v", "A200");
+  dict.put("y", "r");
+  SharedHandle<Dict> rDict = Dict::g();
+  rDict->put("id", String::g(id, DHT_ID_LENGTH));
+  dict.put("r", rDict);
 
-  CPPUNIT_ASSERT_EQUAL(bencode::encode(dict), msgbody);
+  CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }
 
 } // namespace aria2

+ 3 - 5
test/Makefile.am

@@ -70,11 +70,9 @@ aria2c_SOURCES = AllTest.cc\
 	LongestSequencePieceSelectorTest.cc\
 	a2algoTest.cc\
 	bitfieldTest.cc\
-	BDETest.cc\
 	DownloadContextTest.cc\
 	SessionSerializerTest.cc\
-	ValueBaseTest.cc\
-	Bencode2Test.cc
+	ValueBaseTest.cc
 
 if ENABLE_XML_RPC
 aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\
@@ -190,13 +188,13 @@ aria2c_SOURCES += BtAllowedFastMessageTest.cc\
 	MockExtensionMessage.h\
 	MockExtensionMessageFactory.h\
 	MockPieceStorage.h\
-	BencodeTest.cc\
 	BittorrentHelperTest.cc\
 	PriorityPieceSelectorTest.cc\
 	MockPieceSelector.h\
 	extension_message_test_helper.h\
 	LpdMessageDispatcherTest.cc\
-	LpdMessageReceiverTest.cc
+	LpdMessageReceiverTest.cc\
+	Bencode2Test.cc
 endif # ENABLE_BITTORRENT
 
 if ENABLE_METALINK

+ 14 - 19
test/Makefile.in

@@ -137,13 +137,13 @@ check_PROGRAMS = $(am__EXEEXT_1)
 @ENABLE_BITTORRENT_TRUE@	MockExtensionMessage.h\
 @ENABLE_BITTORRENT_TRUE@	MockExtensionMessageFactory.h\
 @ENABLE_BITTORRENT_TRUE@	MockPieceStorage.h\
-@ENABLE_BITTORRENT_TRUE@	BencodeTest.cc\
 @ENABLE_BITTORRENT_TRUE@	BittorrentHelperTest.cc\
 @ENABLE_BITTORRENT_TRUE@	PriorityPieceSelectorTest.cc\
 @ENABLE_BITTORRENT_TRUE@	MockPieceSelector.h\
 @ENABLE_BITTORRENT_TRUE@	extension_message_test_helper.h\
 @ENABLE_BITTORRENT_TRUE@	LpdMessageDispatcherTest.cc\
-@ENABLE_BITTORRENT_TRUE@	LpdMessageReceiverTest.cc
+@ENABLE_BITTORRENT_TRUE@	LpdMessageReceiverTest.cc\
+@ENABLE_BITTORRENT_TRUE@	Bencode2Test.cc
 
 @ENABLE_METALINK_TRUE@am__append_7 = MetalinkerTest.cc\
 @ENABLE_METALINK_TRUE@	MetalinkEntryTest.cc\
@@ -212,9 +212,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 	DNSCacheTest.cc DownloadHelperTest.cc SequentialPickerTest.cc \
 	RarestPieceSelectorTest.cc PieceStatManTest.cc \
 	InOrderPieceSelector.h LongestSequencePieceSelectorTest.cc \
-	a2algoTest.cc bitfieldTest.cc BDETest.cc \
-	DownloadContextTest.cc SessionSerializerTest.cc \
-	ValueBaseTest.cc Bencode2Test.cc \
+	a2algoTest.cc bitfieldTest.cc DownloadContextTest.cc \
+	SessionSerializerTest.cc ValueBaseTest.cc \
 	XmlRpcRequestParserControllerTest.cc \
 	XmlRpcRequestProcessorTest.cc XmlRpcMethodTest.cc \
 	FallocFileAllocationIteratorTest.cc GZipDecoderTest.cc \
@@ -268,10 +267,10 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 	MockDHTMessageDispatcher.h MockDHTMessageFactory.h \
 	MockDHTTask.h MockDHTTaskFactory.h MockDHTTaskQueue.h \
 	MockExtensionMessage.h MockExtensionMessageFactory.h \
-	MockPieceStorage.h BencodeTest.cc BittorrentHelperTest.cc \
+	MockPieceStorage.h BittorrentHelperTest.cc \
 	PriorityPieceSelectorTest.cc MockPieceSelector.h \
 	extension_message_test_helper.h LpdMessageDispatcherTest.cc \
-	LpdMessageReceiverTest.cc MetalinkerTest.cc \
+	LpdMessageReceiverTest.cc Bencode2Test.cc MetalinkerTest.cc \
 	MetalinkEntryTest.cc Metalink2RequestGroupTest.cc \
 	MetalinkPostDownloadHandlerTest.cc MetalinkHelperTest.cc \
 	MetalinkParserControllerTest.cc MetalinkProcessorTest.cc
@@ -359,11 +358,11 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
 @ENABLE_BITTORRENT_TRUE@	DHKeyExchangeTest.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	ARC4Test.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	MSEHandshakeTest.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@	BencodeTest.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	BittorrentHelperTest.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	PriorityPieceSelectorTest.$(OBJEXT) \
 @ENABLE_BITTORRENT_TRUE@	LpdMessageDispatcherTest.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@	LpdMessageReceiverTest.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@	LpdMessageReceiverTest.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@	Bencode2Test.$(OBJEXT)
 @ENABLE_METALINK_TRUE@am__objects_7 = MetalinkerTest.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	MetalinkEntryTest.$(OBJEXT) \
 @ENABLE_METALINK_TRUE@	Metalink2RequestGroupTest.$(OBJEXT) \
@@ -407,12 +406,11 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \
 	DownloadHelperTest.$(OBJEXT) SequentialPickerTest.$(OBJEXT) \
 	RarestPieceSelectorTest.$(OBJEXT) PieceStatManTest.$(OBJEXT) \
 	LongestSequencePieceSelectorTest.$(OBJEXT) \
-	a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) BDETest.$(OBJEXT) \
+	a2algoTest.$(OBJEXT) bitfieldTest.$(OBJEXT) \
 	DownloadContextTest.$(OBJEXT) SessionSerializerTest.$(OBJEXT) \
-	ValueBaseTest.$(OBJEXT) Bencode2Test.$(OBJEXT) \
-	$(am__objects_1) $(am__objects_2) $(am__objects_3) \
-	$(am__objects_4) $(am__objects_5) $(am__objects_6) \
-	$(am__objects_7)
+	ValueBaseTest.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+	$(am__objects_3) $(am__objects_4) $(am__objects_5) \
+	$(am__objects_6) $(am__objects_7)
 aria2c_OBJECTS = $(am_aria2c_OBJECTS)
 am__DEPENDENCIES_1 =
 aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@@ -644,9 +642,8 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \
 	DNSCacheTest.cc DownloadHelperTest.cc SequentialPickerTest.cc \
 	RarestPieceSelectorTest.cc PieceStatManTest.cc \
 	InOrderPieceSelector.h LongestSequencePieceSelectorTest.cc \
-	a2algoTest.cc bitfieldTest.cc BDETest.cc \
-	DownloadContextTest.cc SessionSerializerTest.cc \
-	ValueBaseTest.cc Bencode2Test.cc $(am__append_1) \
+	a2algoTest.cc bitfieldTest.cc DownloadContextTest.cc \
+	SessionSerializerTest.cc ValueBaseTest.cc $(am__append_1) \
 	$(am__append_2) $(am__append_3) $(am__append_4) \
 	$(am__append_5) $(am__append_6) $(am__append_7)
 
@@ -750,12 +747,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AlphaNumberDecoratorTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AnnounceListTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AuthConfigFactoryTest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BDETest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BNodeTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base32Test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Base64Test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Bencode2Test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BencodeTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BitfieldManTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BittorrentHelperTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BtAllowedFastMessageTest.Po@am__quote@

+ 2 - 3
test/MockDHTMessage.h

@@ -9,7 +9,6 @@
 
 #include "DHTNode.h"
 #include "Peer.h"
-#include "BDE.h"
 
 namespace aria2 {
 
@@ -77,7 +76,7 @@ public:
 
   virtual std::string toString() const { return "MockDHTMessage"; }
 
-  virtual BDE getArgument() { return BDE::dict(); }
+  virtual SharedHandle<Dict> getArgument() { return Dict::g(); }
 };
 
 class MockDHTResponseMessage:public DHTResponseMessage {
@@ -109,7 +108,7 @@ public:
 
   virtual std::string toString() const { return "MockDHTMessage"; }
 
-  virtual BDE getResponse() { return BDE::dict(); }
+  virtual SharedHandle<Dict> getResponse() { return Dict::g(); }
 
   virtual void accept(DHTMessageCallback* callback) {}
 };

+ 4 - 4
test/MockDHTMessageFactory.h

@@ -4,7 +4,6 @@
 #include "DHTMessageFactory.h"
 #include "DHTNode.h"
 #include "MockDHTMessage.h"
-#include "bencode.h"
 
 namespace aria2 {
 
@@ -17,7 +16,7 @@ public:
   virtual ~MockDHTMessageFactory() {}
 
   virtual SharedHandle<DHTQueryMessage>
-  createQueryMessage(const BDE& dict,
+  createQueryMessage(const Dict* dict,
                      const std::string& ipaddr, uint16_t port)
   {
     return SharedHandle<DHTQueryMessage>();
@@ -25,7 +24,7 @@ public:
 
   virtual SharedHandle<DHTResponseMessage>
   createResponseMessage(const std::string& messageType,
-                        const BDE& dict,
+                        const Dict* dict,
                         const std::string& ipaddr, uint16_t port)
   {
     SharedHandle<DHTNode> remoteNode(new DHTNode());
@@ -33,7 +32,8 @@ public:
     remoteNode->setIPAddress(ipaddr);
     remoteNode->setPort(port);
     SharedHandle<MockDHTResponseMessage> m
-      (new MockDHTResponseMessage(_localNode, remoteNode, dict["t"].s()));
+      (new MockDHTResponseMessage(_localNode, remoteNode,
+                                  asString(dict->get("t"))->s()));
     return m;
   }
 

+ 5 - 5
test/PeerListProcessorTest.cc

@@ -6,8 +6,8 @@
 
 #include "Exception.h"
 #include "Peer.h"
-#include "bencode.h"
 #include "TimeA2.h"
+#include "bencode2.h"
 
 namespace aria2 {
 
@@ -36,10 +36,10 @@ void PeerListProcessorTest::testExtractPeerFromList() {
     "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
     "4:porti2006eeee";
 
-  const BDE dict = bencode::decode(peersString);
+  SharedHandle<ValueBase> dict = bencode2::decode(peersString);
   
   std::deque<SharedHandle<Peer> > peers;
-  proc.extractPeerFromList(dict["peers"], std::back_inserter(peers));
+  proc.extractPeer(asDict(dict)->get("peers"), std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
   SharedHandle<Peer> peer = *peers.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
@@ -53,10 +53,10 @@ void PeerListProcessorTest::testExtract2PeersFromList() {
     "4:porti65535eed2:ip11:192.168.0.27:peer id20:aria2-00000000000000"
     "4:porti2007eeee";
 
-  const BDE dict = bencode::decode(peersString);
+  SharedHandle<ValueBase> dict = bencode2::decode(peersString);
 
   std::deque<SharedHandle<Peer> > peers;
-  proc.extractPeerFromList(dict["peers"], std::back_inserter(peers));
+  proc.extractPeer(asDict(dict)->get("peers"), std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
   SharedHandle<Peer> peer = *peers.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());

+ 0 - 1
test/UTMetadataDataExtensionMessageTest.cc

@@ -9,7 +9,6 @@
 #include "DownloadContext.h"
 #include "DirectDiskAdaptor.h"
 #include "ByteArrayDiskWriter.h"
-#include "BDE.h"
 #include "DownloadContext.h"
 #include "MockPieceStorage.h"
 #include "UTMetadataRequestTracker.h"

+ 330 - 265
test/XmlRpcMethodTest.cc

@@ -9,7 +9,6 @@
 #include "ServerStatMan.h"
 #include "RequestGroup.h"
 #include "XmlRpcMethodImpl.h"
-#include "BDE.h"
 #include "OptionParser.h"
 #include "OptionHandler.h"
 #include "XmlRpcRequest.h"
@@ -151,12 +150,18 @@ public:
 
 CPPUNIT_TEST_SUITE_REGISTRATION(XmlRpcMethodTest);
 
+static std::string getString(const Dict* dict, const std::string& key)
+{
+  return asString(dict->get(key))->s();
+}
+
 void XmlRpcMethodTest::testAddUri()
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE::list();
-  req.params[0] << BDE("http://localhost/");
+  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam = List::g();
+  urisParam->append("http://localhost/");
+  req.params->append(urisParam);
   {
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
@@ -168,9 +173,9 @@ void XmlRpcMethodTest::testAddUri()
                          getFirstFileEntry()->getRemainingUris().front());
   }
   // with options
-  BDE opt = BDE::dict();
-  opt[PREF_DIR] = BDE("/sink");
-  req.params << opt;
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_DIR, "/sink");
+  req.params->append(opt);
   {
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
@@ -183,7 +188,7 @@ void XmlRpcMethodTest::testAddUri()
 void XmlRpcMethodTest::testAddUri_withoutUri()
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -191,9 +196,10 @@ void XmlRpcMethodTest::testAddUri_withoutUri()
 void XmlRpcMethodTest::testAddUri_notUri()
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE::list();
-  req.params[0] << BDE("not uri");
+  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam = List::g();
+  urisParam->append("not uri");
+  req.params->append(urisParam);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -201,12 +207,13 @@ void XmlRpcMethodTest::testAddUri_notUri()
 void XmlRpcMethodTest::testAddUri_withBadOption()
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE::list();
-  req.params[0] << BDE("http://localhost");
-  BDE opt = BDE::dict();
-  opt[PREF_FILE_ALLOCATION] = BDE("badvalue");
-  req.params << opt;
+  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam = List::g();
+  urisParam->append("http://localhost");
+  req.params->append(urisParam);
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_FILE_ALLOCATION, "badvalue");
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -214,17 +221,19 @@ void XmlRpcMethodTest::testAddUri_withBadOption()
 void XmlRpcMethodTest::testAddUri_withPosition()
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req1(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req1.params << BDE::list();
-  req1.params[0] << BDE("http://uri1");
+  XmlRpcRequest req1(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam1 = List::g();
+  urisParam1->append("http://uri1");
+  req1.params->append(urisParam1);
   XmlRpcResponse res1 = m.execute(req1, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res1.code);
   
-  XmlRpcRequest req2(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req2.params << BDE::list();
-  req2.params[0] << BDE("http://uri2");
-  req2.params << BDE::dict();
-  req2.params << BDE((int64_t)0);
+  XmlRpcRequest req2(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam2 = List::g();
+  urisParam2->append("http://uri2");
+  req2.params->append(urisParam2);
+  req2.params->append(Dict::g());
+  req2.params->append(Integer::g(0));
   m.execute(req2, _e.get());
 
   std::string uri =
@@ -237,11 +246,12 @@ void XmlRpcMethodTest::testAddUri_withPosition()
 void XmlRpcMethodTest::testAddUri_withBadPosition()
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE::list();
-  req.params[0] << BDE("http://localhost/");
-  req.params << BDE::dict();
-  req.params << BDE((int64_t)-1);
+  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam = List::g();
+  urisParam->append("http://localhost/");
+  req.params->append(urisParam);
+  req.params->append(Dict::g());
+  req.params->append(Integer::g(-1));
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -250,15 +260,15 @@ void XmlRpcMethodTest::testAddUri_withBadPosition()
 void XmlRpcMethodTest::testAddTorrent()
 {
   AddTorrentXmlRpcMethod m;
-  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE(readFile("single.torrent"));
-  BDE uris = BDE::list();
-  uris << BDE("http://localhost/aria2-0.8.2.tar.bz2");
-  req.params << uris;
+  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(readFile("single.torrent"));
+  SharedHandle<List> uris = List::g();
+  uris->append("http://localhost/aria2-0.8.2.tar.bz2");
+  req.params->append(uris);
   {
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
-    CPPUNIT_ASSERT_EQUAL(std::string("1"), res.param.s());
+    CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(res.param)->s());
 
     SharedHandle<RequestGroup> group =
       _e->getRequestGroupMan()->findReservedGroup(1);
@@ -273,9 +283,9 @@ void XmlRpcMethodTest::testAddTorrent()
                          getRemainingUris()[0]);
   }
   // with options
-  BDE opt = BDE::dict();
-  opt[PREF_DIR] = BDE("/sink");
-  req.params << opt;
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_DIR, "/sink");
+  req.params->append(opt);
   {
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
@@ -288,7 +298,7 @@ void XmlRpcMethodTest::testAddTorrent()
 void XmlRpcMethodTest::testAddTorrent_withoutTorrent()
 {
   AddTorrentXmlRpcMethod m;
-  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -296,8 +306,8 @@ void XmlRpcMethodTest::testAddTorrent_withoutTorrent()
 void XmlRpcMethodTest::testAddTorrent_notBase64Torrent()
 {
   AddTorrentXmlRpcMethod m;
-  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE("not torrent");
+  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("not torrent");
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -305,18 +315,18 @@ void XmlRpcMethodTest::testAddTorrent_notBase64Torrent()
 void XmlRpcMethodTest::testAddTorrent_withPosition()
 {
   AddTorrentXmlRpcMethod m;
-  XmlRpcRequest req1(AddTorrentXmlRpcMethod::getMethodName(), BDE::list());
-  req1.params << BDE(readFile("test.torrent"));
-  req1.params << BDE::list();
-  req1.params << BDE::dict();
+  XmlRpcRequest req1(AddTorrentXmlRpcMethod::getMethodName(), List::g());
+  req1.params->append(readFile("test.torrent"));
+  req1.params->append(List::g());
+  req1.params->append(Dict::g());
   XmlRpcResponse res1 = m.execute(req1, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res1.code);
 
-  XmlRpcRequest req2(AddTorrentXmlRpcMethod::getMethodName(), BDE::list());
-  req2.params << BDE(readFile("single.torrent"));
-  req2.params << BDE::list();
-  req2.params << BDE::dict();
-  req2.params << BDE((int64_t)0);
+  XmlRpcRequest req2(AddTorrentXmlRpcMethod::getMethodName(), List::g());
+  req2.params->append(readFile("single.torrent"));
+  req2.params->append(List::g());
+  req2.params->append(Dict::g());
+  req2.params->append(Integer::g(0));
   m.execute(req2, _e.get());
 
   CPPUNIT_ASSERT_EQUAL((size_t)1,
@@ -330,14 +340,15 @@ void XmlRpcMethodTest::testAddTorrent_withPosition()
 void XmlRpcMethodTest::testAddMetalink()
 {
   AddMetalinkXmlRpcMethod m;
-  XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE(readFile("2files.metalink"));
+  XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(readFile("2files.metalink"));
   {
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
-    CPPUNIT_ASSERT_EQUAL((size_t)2, res.param.size());
-    CPPUNIT_ASSERT_EQUAL(std::string("1"), res.param[0].s());
-    CPPUNIT_ASSERT_EQUAL(std::string("2"), res.param[1].s());
+    const List* resParams = asList(res.param);
+    CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
+    CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(resParams->get(0))->s());
+    CPPUNIT_ASSERT_EQUAL(std::string("2"), asString(resParams->get(1))->s());
 
     SharedHandle<RequestGroup> tar =
       _e->getRequestGroupMan()->findReservedGroup(1);
@@ -351,9 +362,9 @@ void XmlRpcMethodTest::testAddMetalink()
                          deb->getFirstFilePath());
   }
   // with options
-  BDE opt = BDE::dict();
-  opt[PREF_DIR] = BDE("/sink");
-  req.params << opt;
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_DIR, "/sink");
+  req.params->append(opt);
   {
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
@@ -366,7 +377,7 @@ void XmlRpcMethodTest::testAddMetalink()
 void XmlRpcMethodTest::testAddMetalink_withoutMetalink()
 {
   AddMetalinkXmlRpcMethod m;
-  XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -374,8 +385,8 @@ void XmlRpcMethodTest::testAddMetalink_withoutMetalink()
 void XmlRpcMethodTest::testAddMetalink_notBase64Metalink()
 {
   AddMetalinkXmlRpcMethod m;
-  XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE("not metalink");
+  XmlRpcRequest req(AddMetalinkXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("not metalink");
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -383,17 +394,18 @@ void XmlRpcMethodTest::testAddMetalink_notBase64Metalink()
 void XmlRpcMethodTest::testAddMetalink_withPosition()
 {
   AddUriXmlRpcMethod m1;
-  XmlRpcRequest req1(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req1.params << BDE::list();
-  req1.params[0] << BDE("http://uri");
+  XmlRpcRequest req1(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam1 = List::g();
+  urisParam1->append("http://uri");
+  req1.params->append(urisParam1);
   XmlRpcResponse res1 = m1.execute(req1, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res1.code);
 
   AddMetalinkXmlRpcMethod m2;
-  XmlRpcRequest req2("ari2.addMetalink", BDE::list());
-  req2.params << BDE(readFile("2files.metalink"));
-  req2.params << BDE::dict();
-  req2.params << BDE((int64_t)0);
+  XmlRpcRequest req2("ari2.addMetalink", List::g());
+  req2.params->append(readFile("2files.metalink"));
+  req2.params->append(Dict::g());
+  req2.params->append(Integer::g(0));
   XmlRpcResponse res2 = m2.execute(req2, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res2.code);
 
@@ -410,20 +422,20 @@ void XmlRpcMethodTest::testChangeOption()
   _e->getRequestGroupMan()->addReservedGroup(group);
 
   ChangeOptionXmlRpcMethod m;
-  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE("1");
-  BDE opt = BDE::dict();
-  opt[PREF_MAX_DOWNLOAD_LIMIT] = BDE("100K");
+  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("1");
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_MAX_DOWNLOAD_LIMIT, "100K");
 #ifdef ENABLE_BITTORRENT
-  opt[PREF_BT_MAX_PEERS] = BDE("100");
-  opt[PREF_BT_REQUEST_PEER_SPEED_LIMIT] = BDE("300K");
-  opt[PREF_MAX_UPLOAD_LIMIT] = BDE("50K");
+  opt->put(PREF_BT_MAX_PEERS, "100");
+  opt->put(PREF_BT_REQUEST_PEER_SPEED_LIMIT, "300K");
+  opt->put(PREF_MAX_UPLOAD_LIMIT, "50K");
 
   BtObject btObject;
   btObject._btRuntime = SharedHandle<BtRuntime>(new BtRuntime());
   _e->getBtRegistry()->put(group->getGID(), btObject);
 #endif // ENABLE_BITTORRENT
-  req.params << opt;
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
 
   SharedHandle<Option> option = group->getOption();
@@ -453,11 +465,11 @@ void XmlRpcMethodTest::testChangeOption_withBadOption()
   _e->getRequestGroupMan()->addReservedGroup(group);
 
   ChangeOptionXmlRpcMethod m;
-  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE("1");
-  BDE opt = BDE::dict();
-  opt[PREF_MAX_DOWNLOAD_LIMIT] = BDE("badvalue");
-  req.params << opt;
+  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("1");
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_MAX_DOWNLOAD_LIMIT, "badvalue");
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -468,11 +480,11 @@ void XmlRpcMethodTest::testChangeOption_withNotAllowedOption()
   _e->getRequestGroupMan()->addReservedGroup(group);
 
   ChangeOptionXmlRpcMethod m;
-  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE("1");
-  BDE opt = BDE::dict();
-  opt[PREF_MAX_OVERALL_DOWNLOAD_LIMIT] = BDE("100K");
-  req.params << opt;
+  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("1");
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT, "100K");
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -480,7 +492,7 @@ void XmlRpcMethodTest::testChangeOption_withNotAllowedOption()
 void XmlRpcMethodTest::testChangeOption_withoutGid()
 {
   ChangeOptionXmlRpcMethod m;
-  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(ChangeOptionXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -489,13 +501,13 @@ void XmlRpcMethodTest::testChangeGlobalOption()
 {
   ChangeGlobalOptionXmlRpcMethod m;
   XmlRpcRequest req
-    (ChangeGlobalOptionXmlRpcMethod::getMethodName(), BDE::list());
-  BDE opt = BDE::dict();
-  opt[PREF_MAX_OVERALL_DOWNLOAD_LIMIT] = BDE("100K");
+    (ChangeGlobalOptionXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT, "100K");
 #ifdef ENABLE_BITTORRENT
-  opt[PREF_MAX_OVERALL_UPLOAD_LIMIT] = BDE("50K");
+  opt->put(PREF_MAX_OVERALL_UPLOAD_LIMIT, "50K");
 #endif // ENABLE_BITTORRENT
-  req.params << opt;
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
 
   CPPUNIT_ASSERT_EQUAL(0, res.code);
@@ -517,10 +529,10 @@ void XmlRpcMethodTest::testChangeGlobalOption_withBadOption()
 {
   ChangeGlobalOptionXmlRpcMethod m;
   XmlRpcRequest req
-    (ChangeGlobalOptionXmlRpcMethod::getMethodName(), BDE::list());
-  BDE opt = BDE::dict();
-  opt[PREF_MAX_OVERALL_DOWNLOAD_LIMIT] = BDE("badvalue");
-  req.params << opt;
+    (ChangeGlobalOptionXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT, "badvalue");
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -529,10 +541,10 @@ void XmlRpcMethodTest::testChangeGlobalOption_withNotAllowedOption()
 {
   ChangeGlobalOptionXmlRpcMethod m;
   XmlRpcRequest req
-    (ChangeGlobalOptionXmlRpcMethod::getMethodName(), BDE::list());
-  BDE opt = BDE::dict();
-  opt[PREF_MAX_DOWNLOAD_LIMIT] = BDE("100K");
-  req.params << opt;
+    (ChangeGlobalOptionXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<Dict> opt = Dict::g();
+  opt->put(PREF_MAX_DOWNLOAD_LIMIT, "100K");
+  req.params->append(opt);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -540,11 +552,11 @@ void XmlRpcMethodTest::testChangeGlobalOption_withNotAllowedOption()
 void XmlRpcMethodTest::testNoSuchMethod()
 {
   NoSuchMethodXmlRpcMethod m;
-  XmlRpcRequest req("make.hamburger", BDE::none);
+  XmlRpcRequest req("make.hamburger", List::g());
   XmlRpcResponse res = m.execute(req, 0);
   CPPUNIT_ASSERT_EQUAL(1, res.code);
   CPPUNIT_ASSERT_EQUAL(std::string("No such method: make.hamburger"),
-                       res.param["faultString"].s());
+                       getString(asDict(res.param), "faultString"));
   CPPUNIT_ASSERT_EQUAL
     (std::string("<?xml version=\"1.0\"?>"
                  "<methodResponse>"
@@ -570,7 +582,7 @@ void XmlRpcMethodTest::testNoSuchMethod()
 void XmlRpcMethodTest::testTellStatus_withoutGid()
 {
   TellStatusXmlRpcMethod m;
-  XmlRpcRequest req(TellStatusXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(TellStatusXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -579,9 +591,10 @@ static void addUri(const std::string& uri,
                    const SharedHandle<DownloadEngine>& e)
 {
   AddUriXmlRpcMethod m;
-  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE::list();
-  req.params[0] << BDE(uri);
+  XmlRpcRequest req(AddUriXmlRpcMethod::getMethodName(), List::g());
+  SharedHandle<List> urisParam = List::g();
+  urisParam->append(uri);
+  req.params->append(urisParam);
   CPPUNIT_ASSERT_EQUAL(0, m.execute(req, e.get()).code);
 }
 
@@ -591,8 +604,8 @@ static void addTorrent
 (const std::string& torrentFile, const SharedHandle<DownloadEngine>& e)
 {
   AddTorrentXmlRpcMethod m;
-  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE(readFile(torrentFile));
+  XmlRpcRequest req(AddTorrentXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(readFile(torrentFile));
   XmlRpcResponse res = m.execute(req, e.get());
 }
 
@@ -610,58 +623,69 @@ void XmlRpcMethodTest::testTellWaiting()
 #endif // !ENABLE_BITTORRENT
 
   TellWaitingXmlRpcMethod m;
-  XmlRpcRequest req(TellWaitingXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE((int64_t)1);
-  req.params << BDE((int64_t)2);
+  XmlRpcRequest req(TellWaitingXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(Integer::g(1));
+  req.params->append(Integer::g(2));
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)2, res.param.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("2"), res.param[0]["gid"].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("3"), res.param[1]["gid"].s());
+  const List* resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
+  CPPUNIT_ASSERT_EQUAL(std::string("2"),
+                       getString(asDict(resParams->get(0)), "gid"));
+  CPPUNIT_ASSERT_EQUAL(std::string("3"),
+                       getString(asDict(resParams->get(1)), "gid"));
   // waiting.size() == offset+num 
-  req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE((int64_t)1);
-  req.params << BDE((int64_t)3);
+  req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(Integer::g(1));
+  req.params->append(Integer::g(3));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)3, res.param.size());
+  resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
   // waiting.size() < offset+num 
-  req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE((int64_t)1);
-  req.params << BDE((int64_t)4);
+  req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(Integer::g(1));
+  req.params->append(Integer::g(4));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)3, res.param.size());
+  resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
   // negative offset
-  req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << BDE((int64_t)-1);
-  req.params << BDE((int64_t)2);
+  req = XmlRpcRequest(TellWaitingXmlRpcMethod::getMethodName(), List::g());
+  req.params->append(Integer::g(-1));
+  req.params->append(Integer::g(2));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)2, res.param.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("4"), res.param[0]["gid"].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("3"), res.param[1]["gid"].s());
+  resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
+  CPPUNIT_ASSERT_EQUAL(std::string("4"),
+                       getString(asDict(resParams->get(0)), "gid"));
+  CPPUNIT_ASSERT_EQUAL(std::string("3"),
+                       getString(asDict(resParams->get(1)), "gid"));
   // negative offset and size < num
-  req.params[1] = BDE((int64_t)100);
+  req.params->set(1, Integer::g(100));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)4, res.param.size());
+  resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)4, resParams->size());
   // nagative offset and normalized offset < 0
-  req.params[0] = BDE((int64_t)-5);
+  req.params->set(0, Integer::g(-5));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)0, res.param.size());
+  resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
   // nagative offset and normalized offset == 0
-  req.params[0] = BDE((int64_t)-4);
+  req.params->set(0, Integer::g(-4));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)1, res.param.size());
+  resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)1, resParams->size());
 }
 
 void XmlRpcMethodTest::testTellWaiting_fail()
 {
   TellWaitingXmlRpcMethod m;
-  XmlRpcRequest req(TellWaitingXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(TellWaitingXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
@@ -669,15 +693,18 @@ void XmlRpcMethodTest::testTellWaiting_fail()
 void XmlRpcMethodTest::testGetVersion()
 {
   GetVersionXmlRpcMethod m;
-  XmlRpcRequest req(GetVersionXmlRpcMethod::getMethodName(), BDE::none);
+  XmlRpcRequest req(GetVersionXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL(std::string(PACKAGE_VERSION), res.param["version"].s());
-  const BDE& featureList = res.param["enabledFeatures"];
+  const Dict* resParams = asDict(res.param);
+  CPPUNIT_ASSERT_EQUAL(std::string(PACKAGE_VERSION),
+                       getString(resParams, "version"));
+  const List* featureList = asList(resParams->get("enabledFeatures"));
   std::string features;
-  for(BDE::List::const_iterator i = featureList.listBegin();
-      i != featureList.listEnd(); ++i) {
-    features += (*i).s();
+  for(List::ValueType::const_iterator i = featureList->begin();
+      i != featureList->end(); ++i) {
+    const String* s = asString(*i);
+    features += s->s();
     features += ", ";
   }
   
@@ -700,12 +727,14 @@ void XmlRpcMethodTest::testGatherStoppedDownload()
   d->result = downloadresultcode::FINISHED;
   d->followedBy = followedBy;
   d->belongsTo = 2;
-  BDE entry = BDE::dict();
+  SharedHandle<Dict> entry = Dict::g();
   gatherStoppedDownload(entry, d);
 
-  CPPUNIT_ASSERT_EQUAL(std::string("3"), entry["followedBy"][0].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("4"), entry["followedBy"][1].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("2"), entry["belongsTo"].s());
+  const List* followedByRes = asList(entry->get("followedBy"));
+  CPPUNIT_ASSERT_EQUAL(std::string("3"), asString(followedByRes->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("4"), asString(followedByRes->get(1))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("2"),
+                       asString(entry->get("belongsTo"))->s());
 }
 
 void XmlRpcMethodTest::testGatherProgressCommon()
@@ -724,19 +753,28 @@ void XmlRpcMethodTest::testGatherProgressCommon()
   group->followedBy(followedBy.begin(), followedBy.end());
   group->belongsTo(2);
 
-  BDE entry = BDE::dict();
+  SharedHandle<Dict> entry = Dict::g();
   gatherProgressCommon(entry, group);
   
+  const List* followedByRes = asList(entry->get("followedBy"));
   CPPUNIT_ASSERT_EQUAL(util::itos(followedBy[0]->getGID()),
-                       entry["followedBy"][0].s());
+                       asString(followedByRes->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(util::itos(followedBy[1]->getGID()),
-                       entry["followedBy"][1].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("2"), entry["belongsTo"].s());
-  CPPUNIT_ASSERT_EQUAL((size_t)1, entry["files"].size());
+                       asString(followedByRes->get(1))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("2"),
+                       asString(entry->get("belongsTo"))->s());
+  const List* files = asList(entry->get("files"));
+  CPPUNIT_ASSERT_EQUAL((size_t)1, files->size());
+  const Dict* file = asDict(files->get(0));
   CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"),
-                       entry["files"][0]["path"].s());
-  CPPUNIT_ASSERT_EQUAL(uris[0], entry["files"][0]["uris"][0]["uri"].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), entry["dir"].s());
+                       asString(file->get("path"))->s());
+  CPPUNIT_ASSERT_EQUAL(uris[0],
+                       asString
+                       (asDict
+                        (asList(file->get("uris"))->get(0))
+                        ->get("uri"))
+                       ->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), asString(entry->get("dir"))->s());
 }
 
 #ifdef ENABLE_BITTORRENT
@@ -744,30 +782,41 @@ void XmlRpcMethodTest::testGatherBitTorrentMetadata()
 {
   SharedHandle<DownloadContext> dctx(new DownloadContext());
   bittorrent::load("test.torrent", dctx);
-  BDE btDict = BDE::dict();
+  SharedHandle<Dict> btDict = Dict::g();
   gatherBitTorrentMetadata(btDict, bittorrent::getTorrentAttrs(dctx));
-  CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"), btDict["comment"].s());
-  CPPUNIT_ASSERT_EQUAL((int64_t)1123456789, btDict["creationDate"].i());
-  CPPUNIT_ASSERT_EQUAL(std::string("multi"), btDict["mode"].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("aria2-test"), btDict["info"]["name"].s());
-  const BDE& announceList = btDict["announceList"];
-  CPPUNIT_ASSERT_EQUAL((size_t)3, announceList.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"), announceList[0][0].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"), announceList[1][0].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker3"), announceList[2][0].s());
+  CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"),
+                       asString(btDict->get("comment"))->s());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1123456789,
+                       asInteger(btDict->get("creationDate"))->i());
+  CPPUNIT_ASSERT_EQUAL(std::string("multi"),
+                       asString(btDict->get("mode"))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-test"),
+                       asString
+                       (asDict
+                        (btDict->get("info"))
+                        ->get("name"))
+                       ->s());
+  const List* announceList = asList(btDict->get("announceList"));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, announceList->size());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
+                       asString(asList(announceList->get(0))->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
+                       asString(asList(announceList->get(1))->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker3"),
+                       asString(asList(announceList->get(2))->get(0))->s());
   // Remove some keys
   SharedHandle<TorrentAttribute> modBtAttrs = bittorrent::getTorrentAttrs(dctx);
   modBtAttrs->comment.clear();
   modBtAttrs->creationDate = 0;
   modBtAttrs->mode.clear();
   modBtAttrs->metadata.clear();
-  btDict = BDE::dict();
+  btDict = Dict::g();
   gatherBitTorrentMetadata(btDict, modBtAttrs);
-  CPPUNIT_ASSERT(!btDict.containsKey("comment"));
-  CPPUNIT_ASSERT(!btDict.containsKey("creationDate"));
-  CPPUNIT_ASSERT(!btDict.containsKey("mode"));
-  CPPUNIT_ASSERT(!btDict.containsKey("info"));
-  CPPUNIT_ASSERT(btDict.containsKey("announceList"));
+  CPPUNIT_ASSERT(!btDict->containsKey("comment"));
+  CPPUNIT_ASSERT(!btDict->containsKey("creationDate"));
+  CPPUNIT_ASSERT(!btDict->containsKey("mode"));
+  CPPUNIT_ASSERT(!btDict->containsKey("info"));
+  CPPUNIT_ASSERT(btDict->containsKey("announceList"));
 }
 #endif // ENABLE_BITTORRENT
 
@@ -779,13 +828,13 @@ void XmlRpcMethodTest::testChangePosition()
     (SharedHandle<RequestGroup>(new RequestGroup(_option)));
 
   ChangePositionXmlRpcMethod m;
-  XmlRpcRequest req(ChangePositionXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << std::string("1");
-  req.params << BDE((int64_t)1);
-  req.params << std::string("POS_SET");
+  XmlRpcRequest req(ChangePositionXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("1");
+  req.params->append(Integer::g(1));
+  req.params->append("POS_SET");
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)1, res.param.i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1, asInteger(res.param)->i());
   CPPUNIT_ASSERT_EQUAL
     ((gid_t)1, _e->getRequestGroupMan()->getReservedGroups()[1]->getGID());
 }
@@ -793,13 +842,13 @@ void XmlRpcMethodTest::testChangePosition()
 void XmlRpcMethodTest::testChangePosition_fail()
 {
   ChangePositionXmlRpcMethod m;
-  XmlRpcRequest req(ChangePositionXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(ChangePositionXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 
-  req.params << std::string("1");
-  req.params << BDE((int64_t)2);
-  req.params << std::string("bad keyword");
+  req.params->append("1");
+  req.params->append(Integer::g(2));
+  req.params->append("bad keyword");
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }
 
@@ -819,24 +868,24 @@ void XmlRpcMethodTest::testChangeUri()
   _e->getRequestGroupMan()->addReservedGroup(group);
 
   ChangeUriXmlRpcMethod m;
-  XmlRpcRequest req(ChangeUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << std::string("1"); // GID
-  req.params << 2; // index of FileEntry
-  BDE removeuris = BDE::list();
-  removeuris << std::string("http://example.org/mustremove1");
-  removeuris << std::string("http://example.org/mustremove2");
-  removeuris << std::string("http://example.org/notexist");
-  req.params << removeuris;
-  BDE adduris = BDE::list();
-  adduris << std::string("http://example.org/added1");
-  adduris << std::string("http://example.org/added2");
-  adduris << std::string("baduri");
-  adduris << std::string("http://example.org/added3");
-  req.params << adduris;
+  XmlRpcRequest req(ChangeUriXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("1"); // GID
+  req.params->append(Integer::g(2)); // index of FileEntry
+  SharedHandle<List> removeuris = List::g();
+  removeuris->append("http://example.org/mustremove1");
+  removeuris->append("http://example.org/mustremove2");
+  removeuris->append("http://example.org/notexist");
+  req.params->append(removeuris);
+  SharedHandle<List> adduris = List::g();
+  adduris->append("http://example.org/added1");
+  adduris->append("http://example.org/added2");
+  adduris->append("baduri");
+  adduris->append("http://example.org/added3");
+  req.params->append(adduris);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)2, res.param[0].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)3, res.param[1].i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)2, asInteger(asList(res.param)->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)3, asInteger(asList(res.param)->get(1))->i());
   CPPUNIT_ASSERT_EQUAL((size_t)0, files[0]->getRemainingUris().size());
   CPPUNIT_ASSERT_EQUAL((size_t)0, files[2]->getRemainingUris().size());
   std::deque<std::string> uris = files[1]->getRemainingUris();
@@ -847,29 +896,29 @@ void XmlRpcMethodTest::testChangeUri()
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added3"), uris[3]);
 
   // Change adduris
-  adduris = BDE::list();
-  adduris << std::string("http://example.org/added1-1");
-  adduris << std::string("http://example.org/added1-2");
-  req.params[3] = adduris;
+  adduris = List::g();
+  adduris->append("http://example.org/added1-1");
+  adduris->append("http://example.org/added1-2");
+  req.params->set(3, adduris);
   // Set position parameter
-  req.params << 2;
+  req.params->append(Integer::g(2));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)0, res.param[0].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)2, res.param[1].i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)0, asInteger(asList(res.param)->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)2, asInteger(asList(res.param)->get(1))->i());
   uris = files[1]->getRemainingUris();
   CPPUNIT_ASSERT_EQUAL((size_t)6, uris.size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-1"), uris[2]);
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-2"), uris[3]);
 
   // Change index of FileEntry
-  req.params[1] = 1;
+  req.params->set(1, Integer::g(1));
   // Set position far beyond the size of uris in FileEntry.
-  req.params[4] = 1000;
+  req.params->set(4, Integer::g(1000));
   res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)0, res.param[0].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)2, res.param[1].i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)0, asInteger(asList(res.param)->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)2, asInteger(asList(res.param)->get(1))->i());
   uris = files[0]->getRemainingUris();
   CPPUNIT_ASSERT_EQUAL((size_t)2, uris.size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-1"), uris[0]);
@@ -889,40 +938,40 @@ void XmlRpcMethodTest::testChangeUri_fail()
   _e->getRequestGroupMan()->addReservedGroup(group);
 
   ChangeUriXmlRpcMethod m;
-  XmlRpcRequest req(ChangeUriXmlRpcMethod::getMethodName(), BDE::list());
-  req.params << std::string("1"); // GID
-  req.params << 1; // index of FileEntry
-  BDE removeuris = BDE::list();
-  req.params << removeuris;
-  BDE adduris = BDE::list();
-  req.params << adduris;
+  XmlRpcRequest req(ChangeUriXmlRpcMethod::getMethodName(), List::g());
+  req.params->append("1"); // GID
+  req.params->append(Integer::g(1)); // index of FileEntry
+  SharedHandle<List> removeuris = List::g();
+  req.params->append(removeuris);
+  SharedHandle<List> adduris = List::g();
+  req.params->append(adduris);
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
 
-  req.params[0] = std::string("2");
+  req.params->set(0, String::g("2"));
   res = m.execute(req, _e.get());  
   // RPC request fails because GID#2 does not exist.
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 
-  req.params[0] = std::string("1");
-  req.params[1] = 4;
+  req.params->set(0, String::g("1"));
+  req.params->set(1, Integer::g(4));
   res = m.execute(req, _e.get());  
   // RPC request fails because FileEntry#3 does not exist.
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 
-  req.params[1] = std::string("0");
+  req.params->set(1, String::g("0"));
   res = m.execute(req, _e.get());  
   // RPC request fails because index of FileEntry is string.
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 
-  req.params[1] = 1;
-  req.params[2] = std::string("http://url");
+  req.params->set(1, Integer::g(1));
+  req.params->set(2, String::g("http://url"));
   res = m.execute(req, _e.get());  
   // RPC request fails because 3rd param is not list.
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 
-  req.params[2] = BDE::list();
-  req.params[3] = std::string("http://url");
+  req.params->set(2, List::g());
+  req.params->set(3, String::g("http://url"));
   res = m.execute(req, _e.get());  
   // RPC request fails because 4th param is not list.
   CPPUNIT_ASSERT_EQUAL(1, res.code);
@@ -931,11 +980,11 @@ void XmlRpcMethodTest::testChangeUri_fail()
 void XmlRpcMethodTest::testGetSessionInfo()
 {
   GetSessionInfoXmlRpcMethod m;
-  XmlRpcRequest req(GetSessionInfoXmlRpcMethod::getMethodName(), BDE::list());
+  XmlRpcRequest req(GetSessionInfoXmlRpcMethod::getMethodName(), List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
   CPPUNIT_ASSERT_EQUAL(util::toHex(_e->getSessionId()),
-                       res.param["sessionId"].s());
+                       getString(asDict(res.param), "sessionId"));
 }
 
 void XmlRpcMethodTest::testPause()
@@ -953,23 +1002,23 @@ void XmlRpcMethodTest::testPause()
   _e->getRequestGroupMan()->addReservedGroup(groups);
   {
     PauseXmlRpcMethod m;
-    XmlRpcRequest req(PauseXmlRpcMethod::getMethodName(), BDE::list());
-    req.params << std::string("1");
+    XmlRpcRequest req(PauseXmlRpcMethod::getMethodName(), List::g());
+    req.params->append("1");
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
   }
   CPPUNIT_ASSERT(groups[0]->isPauseRequested());
   {
     UnpauseXmlRpcMethod m;
-    XmlRpcRequest req(UnpauseXmlRpcMethod::getMethodName(), BDE::list());
-    req.params << std::string("1");
+    XmlRpcRequest req(UnpauseXmlRpcMethod::getMethodName(), List::g());
+    req.params->append("1");
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
   }
   CPPUNIT_ASSERT(!groups[0]->isPauseRequested());
   {
     PauseAllXmlRpcMethod m;
-    XmlRpcRequest req(PauseAllXmlRpcMethod::getMethodName(), BDE::list());
+    XmlRpcRequest req(PauseAllXmlRpcMethod::getMethodName(), List::g());
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
   }
@@ -978,7 +1027,7 @@ void XmlRpcMethodTest::testPause()
   }
   {
     UnpauseAllXmlRpcMethod m;
-    XmlRpcRequest req(UnpauseAllXmlRpcMethod::getMethodName(), BDE::list());
+    XmlRpcRequest req(UnpauseAllXmlRpcMethod::getMethodName(), List::g());
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
   }
@@ -987,7 +1036,7 @@ void XmlRpcMethodTest::testPause()
   }
   {
     ForcePauseAllXmlRpcMethod m;
-    XmlRpcRequest req(ForcePauseAllXmlRpcMethod::getMethodName(), BDE::list());
+    XmlRpcRequest req(ForcePauseAllXmlRpcMethod::getMethodName(), List::g());
     XmlRpcResponse res = m.execute(req, _e.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
   }
@@ -999,61 +1048,77 @@ void XmlRpcMethodTest::testPause()
 void XmlRpcMethodTest::testSystemMulticall()
 {
   SystemMulticallXmlRpcMethod m;
-  XmlRpcRequest req("system.multicall", BDE::list());
-  BDE reqparams = BDE::list();
-  req.params << reqparams;
+  XmlRpcRequest req("system.multicall", List::g());
+  SharedHandle<List> reqparams = List::g();
+  req.params->append(reqparams);
   for(int i = 0; i < 2; ++i) {
-    BDE dict = BDE::dict();
-    dict["methodName"] = std::string(AddUriXmlRpcMethod::getMethodName());
-    BDE params = BDE::list();
-    params << BDE::list();
-    params[0] << BDE("http://localhost/"+util::itos(i));
-    dict["params"] = params;
-    reqparams << dict;
+    SharedHandle<Dict> dict = Dict::g();
+    dict->put("methodName", AddUriXmlRpcMethod::getMethodName());
+    SharedHandle<List> params = List::g();
+    SharedHandle<List> urisParam = List::g();
+    urisParam->append("http://localhost/"+util::itos(i));
+    params->append(urisParam);
+    dict->put("params", params);
+    reqparams->append(dict);
   }
   {
-    BDE dict = BDE::dict();
-    dict["methodName"] = std::string("not exists");
-    dict["params"] = BDE::list();
-    reqparams << dict;
+    SharedHandle<Dict> dict = Dict::g();
+    dict->put("methodName", "not exists");
+    dict->put("params", List::g());
+    reqparams->append(dict);
   }
   {
-    reqparams << std::string("not struct");
+    reqparams->append("not struct");
   }
   {
-    BDE dict = BDE::dict();
-    dict["methodName"] = std::string("system.multicall");
-    dict["params"] = BDE::list();
-    reqparams << dict;
+    SharedHandle<Dict> dict = Dict::g();
+    dict->put("methodName", "system.multicall");
+    dict->put("params", List::g());
+    reqparams->append(dict);
   }
   {
     // missing params
-    BDE dict = BDE::dict();
-    dict["methodName"] = std::string(GetVersionXmlRpcMethod::getMethodName());
-    reqparams << dict;
+    SharedHandle<Dict> dict = Dict::g();
+    dict->put("methodName", GetVersionXmlRpcMethod::getMethodName());
+    reqparams->append(dict);
   }
   {
-    BDE dict = BDE::dict();
-    dict["methodName"] = std::string(GetVersionXmlRpcMethod::getMethodName());
-    dict["params"] = BDE::list();
-    reqparams << dict;
+    SharedHandle<Dict> dict = Dict::g();
+    dict->put("methodName", GetVersionXmlRpcMethod::getMethodName());
+    dict->put("params", List::g());
+    reqparams->append(dict);
   }
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((size_t)7, res.param.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("1"), res.param[0][0].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("2"), res.param[1][0].s());
-  CPPUNIT_ASSERT_EQUAL((int64_t)1, res.param[2]["faultCode"].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)1, res.param[3]["faultCode"].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)1, res.param[4]["faultCode"].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)1, res.param[5]["faultCode"].i());
-  CPPUNIT_ASSERT(res.param[6].isList());
+  const List* resParams = asList(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)7, resParams->size());
+  CPPUNIT_ASSERT_EQUAL(std::string("1"),
+                       asString(asList(resParams->get(0))->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("2"),
+                       asString(asList(resParams->get(1))->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1,
+                       asInteger
+                       (asDict(resParams->get(2))->get("faultCode"))
+                       ->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1,
+                       asInteger
+                       (asDict(resParams->get(3))->get("faultCode"))
+                       ->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1,
+                       asInteger
+                       (asDict(resParams->get(4))->get("faultCode"))
+                       ->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1,
+                       asInteger
+                       (asDict(resParams->get(5))->get("faultCode"))
+                       ->i());
+  CPPUNIT_ASSERT(asList(resParams->get(6)));
 }
 
 void XmlRpcMethodTest::testSystemMulticall_fail()
 {
   SystemMulticallXmlRpcMethod m;
-  XmlRpcRequest req("system.multicall", BDE::list());
+  XmlRpcRequest req("system.multicall", List::g());
   XmlRpcResponse res = m.execute(req, _e.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
 }

+ 39 - 34
test/XmlRpcRequestParserControllerTest.cc

@@ -35,59 +35,59 @@ CPPUNIT_TEST_SUITE_REGISTRATION(XmlRpcRequestParserControllerTest);
 void XmlRpcRequestParserControllerTest::testPopStructFrame()
 {
   XmlRpcRequestParserController controller;
-  controller.setCurrentFrameValue(BDE::dict());
+  controller.setCurrentFrameValue(Dict::g());
   controller.pushFrame();
-  controller.setCurrentFrameValue(BDE("Hello, aria2"));
+  controller.setCurrentFrameValue(String::g("Hello, aria2"));
   controller.setCurrentFrameName("greeting");
   controller.popStructFrame();
-  const BDE& structValue = controller.getCurrentFrameValue();
-  CPPUNIT_ASSERT_EQUAL((size_t)1, structValue.size());
+  const Dict* structValue = asDict(controller.getCurrentFrameValue());
+  CPPUNIT_ASSERT_EQUAL((size_t)1, structValue->size());
   CPPUNIT_ASSERT_EQUAL(std::string("Hello, aria2"),
-                       structValue["greeting"].s());
+                       asString(structValue->get("greeting"))->s());
 }
 
 void XmlRpcRequestParserControllerTest::testPopStructFrame_noName()
 {
   XmlRpcRequestParserController controller;
-  controller.setCurrentFrameValue(BDE::dict());
+  controller.setCurrentFrameValue(Dict::g());
   controller.pushFrame();
-  controller.setCurrentFrameValue(BDE("Hello, aria2"));
+  controller.setCurrentFrameValue(String::g("Hello, aria2"));
   controller.popStructFrame();
-  const BDE& structValue = controller.getCurrentFrameValue();
-  CPPUNIT_ASSERT(structValue.empty());
+  const Dict* structValue = asDict(controller.getCurrentFrameValue());
+  CPPUNIT_ASSERT(structValue->empty());
 }
 
 void XmlRpcRequestParserControllerTest::testPopStructFrame_noValue()
 {
   XmlRpcRequestParserController controller;
-  controller.setCurrentFrameValue(BDE::dict());
+  controller.setCurrentFrameValue(Dict::g());
   controller.pushFrame();
   controller.setCurrentFrameName("greeting");
   controller.popStructFrame();
-  const BDE& structValue = controller.getCurrentFrameValue();
-  CPPUNIT_ASSERT(structValue.empty());
+  const Dict* structValue = asDict(controller.getCurrentFrameValue());
+  CPPUNIT_ASSERT(structValue->empty());
 }
 
 void XmlRpcRequestParserControllerTest::testPopArrayFrame()
 {
   XmlRpcRequestParserController controller;
-  controller.setCurrentFrameValue(BDE::list());
+  controller.setCurrentFrameValue(List::g());
   controller.pushFrame();
-  controller.setCurrentFrameValue(BDE(100));
+  controller.setCurrentFrameValue(Integer::g(100));
   controller.popArrayFrame();
-  const BDE& array = controller.getCurrentFrameValue();
-  CPPUNIT_ASSERT_EQUAL((size_t)1, array.size());
-  CPPUNIT_ASSERT_EQUAL((BDE::Integer)100, array[0].i());
+  const List* array = asList(controller.getCurrentFrameValue());
+  CPPUNIT_ASSERT_EQUAL((size_t)1, array->size());
+  CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100, asInteger(array->get(0))->i());
 }
 
 void XmlRpcRequestParserControllerTest::testPopArrayFrame_noValue()
 {
   XmlRpcRequestParserController controller;
-  controller.setCurrentFrameValue(BDE::list());
+  controller.setCurrentFrameValue(List::g());
   controller.pushFrame();
   controller.popArrayFrame();
-  const BDE& array = controller.getCurrentFrameValue();
-  CPPUNIT_ASSERT(array.empty());
+  const List* array = asList(controller.getCurrentFrameValue());
+  CPPUNIT_ASSERT(array->empty());
 }
 
 void XmlRpcRequestParserControllerTest::testPopArrayFrame_compound()
@@ -100,32 +100,32 @@ void XmlRpcRequestParserControllerTest::testPopArrayFrame_compound()
   //     "options":{ "timeout":120 } },
   //   [ "jp","us" ] ]
 
-  controller.setCurrentFrameValue(BDE::list());
+  controller.setCurrentFrameValue(List::g());
   controller.pushFrame();
 
-  controller.setCurrentFrameValue(BDE::dict());
+  controller.setCurrentFrameValue(Dict::g());
   controller.pushFrame();
 
   controller.setCurrentFrameName("uris");
-  controller.setCurrentFrameValue(BDE::list());
+  controller.setCurrentFrameValue(List::g());
   controller.pushFrame();
 
-  controller.setCurrentFrameValue(BDE("http://example.org/aria2"));
+  controller.setCurrentFrameValue(String::g("http://example.org/aria2"));
   controller.popArrayFrame();
   controller.pushFrame();
 
-  controller.setCurrentFrameValue(BDE("http://aria2.sf.net/"));
+  controller.setCurrentFrameValue(String::g("http://aria2.sf.net/"));
   controller.popArrayFrame();
 
   controller.popStructFrame();
   controller.pushFrame();
 
   controller.setCurrentFrameName("options");
-  controller.setCurrentFrameValue(BDE::dict());
+  controller.setCurrentFrameValue(Dict::g());
   controller.pushFrame();
 
   controller.setCurrentFrameName("timeout");
-  controller.setCurrentFrameValue(BDE(120));
+  controller.setCurrentFrameValue(Integer::g(120));
   controller.popStructFrame();
 
   controller.popStructFrame();
@@ -133,23 +133,28 @@ void XmlRpcRequestParserControllerTest::testPopArrayFrame_compound()
   controller.popArrayFrame();
   controller.pushFrame();
 
-  controller.setCurrentFrameValue(BDE::list());
+  controller.setCurrentFrameValue(List::g());
   controller.pushFrame();
 
-  controller.setCurrentFrameValue(BDE("jp"));
+  controller.setCurrentFrameValue(String::g("jp"));
   controller.popArrayFrame();
   controller.pushFrame();
 
-  controller.setCurrentFrameValue(BDE("us"));
+  controller.setCurrentFrameValue(String::g("us"));
   controller.popArrayFrame();
 
   controller.popArrayFrame();
 
-  const BDE& result = controller.getCurrentFrameValue();
+  const List* result = asList(controller.getCurrentFrameValue());
+  const Dict* dict = asDict(result->get(0));
+  const List* uris = asList(dict->get("uris"));
+  const Dict* options = asDict(dict->get("options"));
+  const List* countryList = asList(result->get(1));
   CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sf.net/"),
-                       result[0]["uris"][1].s());
-  CPPUNIT_ASSERT_EQUAL((BDE::Integer)120, result[0]["options"]["timeout"].i());
-  CPPUNIT_ASSERT_EQUAL(std::string("jp"), result[1][0].s());
+                       asString(uris->get(1))->s());
+  CPPUNIT_ASSERT_EQUAL((Integer::ValueType)120,
+                       asInteger(options->get("timeout"))->i());
+  CPPUNIT_ASSERT_EQUAL(std::string("jp"), asString(countryList->get(0))->s());
 }
 
 } // namespace xmlrpc

+ 30 - 6
test/XmlRpcRequestProcessorTest.cc

@@ -3,6 +3,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 
 #include "XmlRpcRequestParserStateMachine.h"
+#include "RecoverableException.h"
 
 namespace aria2 {
 
@@ -65,13 +66,18 @@ void XmlRpcRequestProcessorTest::testParseMemory()
                      "</methodCall>");
 
   CPPUNIT_ASSERT_EQUAL(std::string("aria2.addURI"), req.methodName);
-  CPPUNIT_ASSERT_EQUAL((size_t)3, req.params.size());
-  CPPUNIT_ASSERT_EQUAL((int64_t)100, req.params[0].i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)65535, req.params[1]["max-count"].i());
+  CPPUNIT_ASSERT_EQUAL((size_t)3, req.params->size());
+  CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100,
+                       asInteger(req.params->get(0))->i());
+  const Dict* dict = asDict(req.params->get(1));
+  CPPUNIT_ASSERT_EQUAL((Integer::ValueType)65535,
+                       asInteger(dict->get("max-count"))->i());
   // Current implementation handles double as string.
-  CPPUNIT_ASSERT_EQUAL(std::string("0.99"), req.params[1]["seed-ratio"].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("pudding"), req.params[2][0].s());
-  CPPUNIT_ASSERT_EQUAL(std::string("hello world"), req.params[2][1].s());
+  CPPUNIT_ASSERT_EQUAL(std::string("0.99"),
+                       asString(dict->get("seed-ratio"))->s());
+  const List* list = asList(req.params->get(2));
+  CPPUNIT_ASSERT_EQUAL(std::string("pudding"), asString(list->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("hello world"), asString(list->get(1))->s());
 }
 
 void XmlRpcRequestProcessorTest::testParseMemory_shouldFail()
@@ -88,6 +94,24 @@ void XmlRpcRequestProcessorTest::testParseMemory_shouldFail()
   } catch(RecoverableException& e) {
     // success
   }
+  {
+    XmlRpcRequest req =
+      proc.parseMemory("<methodCall>"
+                       "  <methodName>aria2.addURI</methodName>"
+                     "    <params>"
+                     "    </params>"
+                       "</methodCall>");
+    CPPUNIT_ASSERT(!req.params.isNull());
+  }
+  try {
+    XmlRpcRequest req =
+    proc.parseMemory("<methodCall>"
+                     "  <methodName>aria2.addURI</methodName>"
+                     "</methodCall>");
+    CPPUNIT_FAIL("exception must be thrown.");
+  } catch(RecoverableException& e) {
+    // success
+  }
 }
 
 } // namespace xmlrpc

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác