Sfoglia il codice sorgente

Use std::unique_ptr for ValueBase object hierarchy

Tatsuhiro Tsujikawa 12 anni fa
parent
commit
7c06b903f3
77 ha cambiato i file con 1173 aggiunte e 1194 eliminazioni
  1. 2 2
      src/BtPostDownloadHandler.cc
  2. 1 1
      src/DHTAnnouncePeerMessage.cc
  3. 1 1
      src/DHTAnnouncePeerMessage.h
  4. 2 2
      src/DHTAnnouncePeerReplyMessage.cc
  5. 1 1
      src/DHTAnnouncePeerReplyMessage.h
  6. 1 1
      src/DHTFindNodeMessage.cc
  7. 1 1
      src/DHTFindNodeMessage.h
  8. 1 1
      src/DHTFindNodeReplyMessage.cc
  9. 1 1
      src/DHTFindNodeReplyMessage.h
  10. 1 1
      src/DHTGetPeersMessage.cc
  11. 1 1
      src/DHTGetPeersMessage.h
  12. 2 2
      src/DHTGetPeersReplyMessage.cc
  13. 1 1
      src/DHTGetPeersReplyMessage.h
  14. 1 1
      src/DHTPingMessage.cc
  15. 1 1
      src/DHTPingMessage.h
  16. 1 1
      src/DHTPingReplyMessage.cc
  17. 1 1
      src/DHTPingReplyMessage.h
  18. 1 1
      src/DHTQueryMessage.h
  19. 1 1
      src/DHTResponseMessage.h
  20. 3 4
      src/DefaultBtAnnounce.cc
  21. 1 1
      src/GenericParser.h
  22. 2 2
      src/HandshakeExtensionMessage.cc
  23. 7 10
      src/HttpServerBodyCommand.cc
  24. 0 6
      src/HttpServerBodyCommand.h
  25. 6 7
      src/RpcMethod.cc
  26. 3 3
      src/RpcMethod.h
  27. 215 226
      src/RpcMethodImpl.cc
  28. 46 48
      src/RpcMethodImpl.h
  29. 11 23
      src/RpcRequest.cc
  30. 8 13
      src/RpcRequest.h
  31. 24 38
      src/RpcResponse.cc
  32. 4 12
      src/RpcResponse.h
  33. 97 80
      src/ValueBase.cc
  34. 61 57
      src/ValueBase.h
  35. 1 1
      src/ValueBaseDiskWriter.h
  36. 17 15
      src/ValueBaseStructParserStateMachine.cc
  37. 8 7
      src/ValueBaseStructParserStateMachine.h
  38. 8 9
      src/WebSocketSession.cc
  39. 2 2
      src/WebSocketSession.h
  40. 6 6
      src/WebSocketSessionMan.cc
  41. 4 4
      src/XmlRpcDiskWriter.cc
  42. 1 1
      src/XmlRpcDiskWriter.h
  43. 23 12
      src/XmlRpcRequestParserController.cc
  44. 7 8
      src/XmlRpcRequestParserController.h
  45. 9 3
      src/XmlRpcRequestParserStateMachine.cc
  46. 3 2
      src/XmlRpcRequestParserStateMachine.h
  47. 5 10
      src/bencode2.cc
  48. 5 7
      src/bencode2.h
  49. 20 23
      src/bittorrent_helper.cc
  50. 1 8
      src/bittorrent_helper.h
  51. 6 5
      src/download_helper.cc
  52. 1 1
      src/download_helper.h
  53. 2 2
      src/json.cc
  54. 7 14
      src/json.h
  55. 5 6
      src/magnet.cc
  56. 5 6
      src/magnet.h
  57. 22 22
      src/rpc_helper.cc
  58. 2 2
      src/rpc_helper.h
  59. 6 6
      test/Bencode2Test.cc
  60. 26 26
      test/BittorrentHelperTest.cc
  61. 1 1
      test/DHTAnnouncePeerMessageTest.cc
  62. 2 2
      test/DHTAnnouncePeerReplyMessageTest.cc
  63. 1 1
      test/DHTFindNodeMessageTest.cc
  64. 4 4
      test/DHTFindNodeReplyMessageTest.cc
  65. 1 1
      test/DHTGetPeersMessageTest.cc
  66. 12 11
      test/DHTGetPeersReplyMessageTest.cc
  67. 14 16
      test/DHTMessageFactoryImplTest.cc
  68. 1 1
      test/DHTPingMessageTest.cc
  69. 2 2
      test/DHTPingReplyMessageTest.cc
  70. 25 26
      test/DefaultBtAnnounceTest.cc
  71. 12 12
      test/JsonTest.cc
  72. 2 2
      test/MagnetTest.cc
  73. 2 2
      test/MockDHTMessage.h
  74. 285 239
      test/RpcMethodTest.cc
  75. 28 29
      test/RpcResponseTest.cc
  76. 51 71
      test/ValueBaseJsonParserTest.cc
  77. 18 14
      test/ValueBaseTest.cc

+ 2 - 2
src/BtPostDownloadHandler.cc

@@ -71,7 +71,7 @@ void BtPostDownloadHandler::getNextRequestGroups
 {
   A2_LOG_INFO(fmt("Generating RequestGroups for Torrent file %s",
                   requestGroup->getFirstFilePath().c_str()));
-  std::shared_ptr<ValueBase> torrent;
+  std::unique_ptr<ValueBase> torrent;
   if(requestGroup->inMemoryDownload()) {
     auto& dw = static_cast<AbstractSingleDiskAdaptor*>
       (requestGroup->getPieceStorage()->getDiskAdaptor().get())
@@ -104,7 +104,7 @@ void BtPostDownloadHandler::getNextRequestGroups
   createRequestGroupForBitTorrent(newRgs, requestGroup->getOption(),
                                   std::vector<std::string>(),
                                   "",
-                                  torrent);
+                                  torrent.get());
   requestGroup->followedBy(newRgs.begin(), newRgs.end());
   std::shared_ptr<MetadataInfo> mi =
     createMetadataInfoFromFirstFileEntry(requestGroup->getGroupId(),

+ 1 - 1
src/DHTAnnouncePeerMessage.cc

@@ -86,7 +86,7 @@ void DHTAnnouncePeerMessage::doReceivedAction()
      (getRemoteNode(), getTransactionID()));
 }
 
-std::shared_ptr<Dict> DHTAnnouncePeerMessage::getArgument()
+std::unique_ptr<Dict> DHTAnnouncePeerMessage::getArgument()
 {
   auto aDict = Dict::g();
   aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));

+ 1 - 1
src/DHTAnnouncePeerMessage.h

@@ -67,7 +67,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getArgument() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getArgument() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 2 - 2
src/DHTAnnouncePeerReplyMessage.cc

@@ -50,9 +50,9 @@ DHTAnnouncePeerReplyMessage::~DHTAnnouncePeerReplyMessage() {}
 
 void DHTAnnouncePeerReplyMessage::doReceivedAction() {}
 
-std::shared_ptr<Dict> DHTAnnouncePeerReplyMessage::getResponse()
+std::unique_ptr<Dict> DHTAnnouncePeerReplyMessage::getResponse()
 {
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto 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() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getResponse() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getResponse() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTFindNodeMessage.cc

@@ -69,7 +69,7 @@ void DHTFindNodeMessage::doReceivedAction()
      (getRemoteNode(), std::move(nodes), getTransactionID()));
 }
 
-std::shared_ptr<Dict> DHTFindNodeMessage::getArgument()
+std::unique_ptr<Dict> DHTFindNodeMessage::getArgument()
 {
   auto aDict = Dict::g();
   aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));

+ 1 - 1
src/DHTFindNodeMessage.h

@@ -53,7 +53,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getArgument() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getArgument() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTFindNodeReplyMessage.cc

@@ -71,7 +71,7 @@ void DHTFindNodeReplyMessage::doReceivedAction()
   }
 }
 
-std::shared_ptr<Dict> DHTFindNodeReplyMessage::getResponse()
+std::unique_ptr<Dict> DHTFindNodeReplyMessage::getResponse()
 {
   auto aDict = Dict::g();
   aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));

+ 1 - 1
src/DHTFindNodeReplyMessage.h

@@ -55,7 +55,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getResponse() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getResponse() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTGetPeersMessage.cc

@@ -80,7 +80,7 @@ void DHTGetPeersMessage::doReceivedAction()
       getTransactionID()));
 }
 
-std::shared_ptr<Dict> DHTGetPeersMessage::getArgument()
+std::unique_ptr<Dict> DHTGetPeersMessage::getArgument()
 {
   auto aDict = Dict::g();
   aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));

+ 1 - 1
src/DHTGetPeersMessage.h

@@ -61,7 +61,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getArgument() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getArgument() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 2 - 2
src/DHTGetPeersReplyMessage.cc

@@ -75,7 +75,7 @@ void DHTGetPeersReplyMessage::doReceivedAction()
   // Returned peers and nodes are handled in DHTPeerLookupTask.
 }
 
-std::shared_ptr<Dict> DHTGetPeersReplyMessage::getResponse()
+std::unique_ptr<Dict> DHTGetPeersReplyMessage::getResponse()
 {
   auto rDict = Dict::g();
   rDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));
@@ -136,7 +136,7 @@ std::shared_ptr<Dict> DHTGetPeersReplyMessage::getResponse()
         valuesList->append(String::g(compact, compactlen));
       }
     }
-    rDict->put(VALUES, valuesList);
+    rDict->put(VALUES, std::move(valuesList));
   }
   return rDict;
 }

+ 1 - 1
src/DHTGetPeersReplyMessage.h

@@ -65,7 +65,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getResponse() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getResponse() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTPingMessage.cc

@@ -57,7 +57,7 @@ void DHTPingMessage::doReceivedAction()
      (getRemoteNode(), getLocalNode()->getID(), getTransactionID()));
 }
 
-std::shared_ptr<Dict> DHTPingMessage::getArgument()
+std::unique_ptr<Dict> DHTPingMessage::getArgument()
 {
   auto aDict = Dict::g();
   aDict->put(DHTMessage::ID, String::g(getLocalNode()->getID(), DHT_ID_LENGTH));

+ 1 - 1
src/DHTPingMessage.h

@@ -48,7 +48,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getArgument() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getArgument() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTPingReplyMessage.cc

@@ -55,7 +55,7 @@ DHTPingReplyMessage::DHTPingReplyMessage
 
 void DHTPingReplyMessage::doReceivedAction() {}
 
-std::shared_ptr<Dict> DHTPingReplyMessage::getResponse()
+std::unique_ptr<Dict> DHTPingReplyMessage::getResponse()
 {
   auto rDict = Dict::g();
   rDict->put(DHTMessage::ID, String::g(id_, DHT_ID_LENGTH));

+ 1 - 1
src/DHTPingReplyMessage.h

@@ -51,7 +51,7 @@ public:
 
   virtual void doReceivedAction() CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getResponse() CXX11_OVERRIDE;
+  virtual std::unique_ptr<Dict> getResponse() CXX11_OVERRIDE;
 
   virtual const std::string& getMessageType() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTQueryMessage.h

@@ -55,7 +55,7 @@ public:
 
   virtual void fillMessage(Dict* msgDict) CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getArgument() = 0;
+  virtual std::unique_ptr<Dict> getArgument() = 0;
 
   virtual bool isReply() const CXX11_OVERRIDE;
 

+ 1 - 1
src/DHTResponseMessage.h

@@ -57,7 +57,7 @@ public:
 
   virtual void fillMessage(Dict* msgDict) CXX11_OVERRIDE;
 
-  virtual std::shared_ptr<Dict> getResponse() = 0;
+  virtual std::unique_ptr<Dict> getResponse() = 0;
 
   virtual bool isReply() const CXX11_OVERRIDE;
 

+ 3 - 4
src/DefaultBtAnnounce.cc

@@ -283,8 +283,7 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
                                            size_t trackerResponseLength)
 {
   A2_LOG_DEBUG("Now processing tracker response.");
-  std::shared_ptr<ValueBase> decodedValue =
-    bencode2::decode(trackerResponse, trackerResponseLength);
+  auto decodedValue = bencode2::decode(trackerResponse, trackerResponseLength);
   const Dict* dict = downcast<Dict>(decodedValue);
   if(!dict) {
     throw DL_ABORT_EX(MSG_NULL_TRACKER_RESPONSE);
@@ -327,7 +326,7 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
     incomplete_ = incomp->i();
     A2_LOG_DEBUG(fmt("Incomplete:%d", incomplete_));
   }
-  const std::shared_ptr<ValueBase>& peerData = dict->get(BtAnnounce::PEERS);
+  auto peerData = dict->get(BtAnnounce::PEERS);
   if(!peerData) {
     A2_LOG_INFO(MSG_NO_PEER_LIST_RECEIVED);
   } else {
@@ -337,7 +336,7 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
       peerStorage_->addPeer(peers);
     }
   }
-  const std::shared_ptr<ValueBase>& peer6Data = dict->get(BtAnnounce::PEERS6);
+  auto peer6Data = dict->get(BtAnnounce::PEERS6);
   if(!peer6Data) {
     A2_LOG_INFO("No peers6 received.");
   } else {

+ 1 - 1
src/GenericParser.h

@@ -45,7 +45,7 @@ template<typename Parser, typename ParserStateMachine>
 class GenericParser {
 public:
   GenericParser()
-    : parser_(&psm_)
+    : parser_{&psm_}
   {}
 
   ~GenericParser()

+ 2 - 2
src/HandshakeExtensionMessage.cc

@@ -64,14 +64,14 @@ std::string HandshakeExtensionMessage::getPayload()
   if(tcpPort_ > 0) {
     dict.put("p", Integer::g(tcpPort_));
   }
-  std::shared_ptr<Dict> extDict = Dict::g();
+  auto extDict = Dict::g();
   for(int i = 0; i < ExtensionMessageRegistry::MAX_EXTENSION; ++i) {
     int id = extreg_.getExtensionMessageID(i);
     if(id) {
       extDict->put(strBtExtension(i), Integer::g(id));
     }
   }
-  dict.put("m", extDict);
+  dict.put("m", std::move(extDict));
   if(metadataSize_) {
     dict.put("metadata_size", Integer::g(metadataSize_));
   }

+ 7 - 10
src/HttpServerBodyCommand.cc

@@ -226,10 +226,9 @@ bool HttpServerBodyCommand::execute()
             addHttpServerResponseCommand();
             return true;
           }
-          std::shared_ptr<rpc::RpcMethod> method =
-            rpc::RpcMethodFactory::create(req.methodName);
+          auto method = rpc::RpcMethodFactory::create(req.methodName);
           A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str()));
-          rpc::RpcResponse res = method->execute(req, e_);
+          rpc::RpcResponse res = method->execute(std::move(req), e_);
           bool gzip = httpServer_->supportsGZip();
           std::string responseData = rpc::toXml(res, gzip);
           httpServer_->feedResponse(std::move(responseData), "text/xml");
@@ -243,7 +242,7 @@ bool HttpServerBodyCommand::execute()
         case RPC_TYPE_JSON:
         case RPC_TYPE_JSONP: {
           std::string callback;
-          std::shared_ptr<ValueBase> json;
+          std::unique_ptr<ValueBase> json;
           ssize_t error = 0;
           if(httpServer_->getRequestType() == RPC_TYPE_JSONP) {
             json::JsonGetParam param = json::decodeGetParams(query);
@@ -272,22 +271,20 @@ bool HttpServerBodyCommand::execute()
             sendJsonRpcResponse(res, callback);
             return true;
           }
-          const Dict* jsondict = downcast<Dict>(json);
+          Dict* jsondict = downcast<Dict>(json);
           if(jsondict) {
             rpc::RpcResponse res = rpc::processJsonRpcRequest(jsondict, e_);
             sendJsonRpcResponse(res, callback);
           } else {
-            const List* jsonlist = downcast<List>(json);
+            List* jsonlist = downcast<List>(json);
             if(jsonlist) {
               // This is batch call
               std::vector<rpc::RpcResponse> results;
               for(List::ValueType::const_iterator i = jsonlist->begin(),
                     eoi = jsonlist->end(); i != eoi; ++i) {
-                const Dict* jsondict = downcast<Dict>(*i);
+                Dict* jsondict = downcast<Dict>(*i);
                 if(jsondict) {
-                  rpc::RpcResponse r =
-                    rpc::processJsonRpcRequest(jsondict, e_);
-                  results.push_back(r);
+                  results.push_back(rpc::processJsonRpcRequest(jsondict, e_));
                 }
               }
               sendJsonRpcBatchResponse(results, callback);

+ 0 - 6
src/HttpServerBodyCommand.h

@@ -57,12 +57,6 @@ private:
   Timer timeoutTimer_;
   bool writeCheck_;
 
-  void sendJsonRpcErrorResponse
-  (const std::string& httpStatus,
-   int code,
-   const std::string& message,
-   const std::shared_ptr<ValueBase>& id,
-   const std::string& callback);
   void sendJsonRpcResponse
   (const rpc::RpcResponse& res,
    const std::string& callback);

+ 6 - 7
src/RpcMethod.cc

@@ -59,23 +59,22 @@ RpcMethod::RpcMethod()
 
 RpcMethod::~RpcMethod() {}
 
-std::shared_ptr<ValueBase> RpcMethod::createErrorResponse
+std::unique_ptr<ValueBase> RpcMethod::createErrorResponse
 (const Exception& e, const RpcRequest& req)
 {
-  std::shared_ptr<Dict> params = Dict::g();
+  auto params = Dict::g();
   params->put((req.jsonRpc ? "code" : "faultCode"), Integer::g(1));
   params->put((req.jsonRpc ? "message" : "faultString"), std::string(e.what()));
-  return params;
+  return std::move(params);
 }
 
-RpcResponse RpcMethod::execute
-(const RpcRequest& req, DownloadEngine* e)
+RpcResponse RpcMethod::execute(RpcRequest req, DownloadEngine* e)
 {
   try {
-    return RpcResponse(0, process(req, e), req.id);
+    return RpcResponse(0, process(req, e), std::move(req.id));
   } catch(RecoverableException& ex) {
     A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, ex);
-    return RpcResponse(1, createErrorResponse(ex, req), req.id);
+    return RpcResponse(1, createErrorResponse(ex, req), std::move(req.id));
   }
 }
 

+ 3 - 3
src/RpcMethod.h

@@ -69,7 +69,7 @@ protected:
   // Subclass must implement this function to fulfil RpcRequest req.
   // The return value of this method is used as a return value of RPC
   // request.
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) = 0;
 
   void gatherRequestOption(Option* option, const Dict* optionsDict);
@@ -81,7 +81,7 @@ protected:
 
   void gatherChangeableGlobalOption(Option* option, const Dict* optionDict);
 
-  std::shared_ptr<ValueBase> createErrorResponse
+  std::unique_ptr<ValueBase> createErrorResponse
   (const Exception& e, const RpcRequest& req);
 
   const std::shared_ptr<OptionParser>& getOptionParser() const
@@ -95,7 +95,7 @@ public:
 
   // Do work to fulfill RpcRequest req and returns its result as
   // RpcResponse. This method delegates to process() method.
-  RpcResponse execute(const RpcRequest& req, DownloadEngine* e);
+  RpcResponse execute(RpcRequest req, DownloadEngine* e);
 };
 
 } // namespace rpc

File diff suppressed because it is too large
+ 215 - 226
src/RpcMethodImpl.cc


+ 46 - 48
src/RpcMethodImpl.h

@@ -127,7 +127,7 @@ void toStringList(OutputIterator out, const List* src)
 
 class AddUriRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -138,7 +138,7 @@ public:
 
 class RemoveRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -149,7 +149,7 @@ public:
 
 class ForceRemoveRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -160,7 +160,7 @@ public:
 
 class PauseRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -171,7 +171,7 @@ public:
 
 class ForcePauseRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -182,7 +182,7 @@ public:
 
 class PauseAllRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -193,7 +193,7 @@ public:
 
 class ForcePauseAllRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -204,7 +204,7 @@ public:
 
 class UnpauseRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -215,7 +215,7 @@ public:
 
 class UnpauseAllRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -227,7 +227,7 @@ public:
 #ifdef ENABLE_BITTORRENT
 class AddTorrentRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -240,7 +240,7 @@ public:
 #ifdef ENABLE_METALINK
 class AddMetalinkRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -252,7 +252,7 @@ public:
 
 class PurgeDownloadResultRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -263,7 +263,7 @@ public:
 
 class RemoveDownloadResultRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -274,7 +274,7 @@ public:
 
 class GetUrisRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -285,7 +285,7 @@ public:
 
 class GetFilesRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -297,7 +297,7 @@ public:
 #ifdef ENABLE_BITTORRENT
 class GetPeersRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -309,7 +309,7 @@ public:
 
 class GetServersRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -320,7 +320,7 @@ public:
 
 class TellStatusRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -331,7 +331,7 @@ public:
 
 class TellActiveRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -376,7 +376,7 @@ private:
 protected:
   typedef IndexedList<a2_gid_t, std::shared_ptr<T> > ItemListType;
 
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE
   {
     const Integer* offsetParam = checkRequiredParam<Integer>(req, 0);
@@ -388,25 +388,24 @@ protected:
     std::vector<std::string> keys;
     toStringList(std::back_inserter(keys), keysParam);
     const ItemListType& items = getItems(e);
-    std::pair<typename ItemListType::const_iterator,
-              typename ItemListType::const_iterator> range =
-      getPaginationRange(offset, num, items.begin(), items.end());
-    std::shared_ptr<List> list = List::g();
+    auto range = getPaginationRange(offset, num,
+                                    std::begin(items), std::end(items));
+    auto list = List::g();
     for(; range.first != range.second; ++range.first) {
-      std::shared_ptr<Dict> entryDict = Dict::g();
-      createEntry(entryDict, *range.first, e, keys);
-      list->append(entryDict);
+      auto entryDict = Dict::g();
+      createEntry(entryDict.get(), *range.first, e, keys);
+      list->append(std::move(entryDict));
     }
     if(offset < 0) {
       std::reverse(list->begin(), list->end());
     }
-    return list;
+    return std::move(list);
   }
 
   virtual const ItemListType& getItems(DownloadEngine* e) const = 0;
 
   virtual void createEntry
-  (const std::shared_ptr<Dict>& entryDict,
+  (Dict* entryDict,
    const std::shared_ptr<T>& item,
    DownloadEngine* e,
    const std::vector<std::string>& keys) const = 0;
@@ -419,7 +418,7 @@ protected:
     CXX11_OVERRIDE;
 
   virtual void createEntry
-  (const std::shared_ptr<Dict>& entryDict,
+  (Dict* entryDict,
    const std::shared_ptr<RequestGroup>& item,
    DownloadEngine* e,
    const std::vector<std::string>& keys) const CXX11_OVERRIDE;
@@ -437,7 +436,7 @@ protected:
     CXX11_OVERRIDE;
 
   virtual void createEntry
-  (const std::shared_ptr<Dict>& entryDict,
+  (Dict* entryDict,
    const std::shared_ptr<DownloadResult>& item,
    DownloadEngine* e,
    const std::vector<std::string>& keys) const CXX11_OVERRIDE;
@@ -450,7 +449,7 @@ public:
 
 class ChangeOptionRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -461,7 +460,7 @@ public:
 
 class ChangeGlobalOptionRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -472,7 +471,7 @@ public:
 
 class GetVersionRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -483,7 +482,7 @@ public:
 
 class GetOptionRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -494,7 +493,7 @@ public:
 
 class GetGlobalOptionRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -505,7 +504,7 @@ public:
 
 class ChangePositionRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -516,7 +515,7 @@ public:
 
 class ChangeUriRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -527,7 +526,7 @@ public:
 
 class GetSessionInfoRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -538,7 +537,7 @@ public:
 
 class ShutdownRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -549,7 +548,7 @@ public:
 
 class GetGlobalStatRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -560,7 +559,7 @@ public:
 
 class ForceShutdownRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -571,7 +570,7 @@ public:
 
 class SystemMulticallRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 public:
   static const char* getMethodName()
@@ -582,26 +581,25 @@ public:
 
 class NoSuchMethodRpcMethod:public RpcMethod {
 protected:
-  virtual std::shared_ptr<ValueBase> process
+  virtual std::unique_ptr<ValueBase> process
   (const RpcRequest& req, DownloadEngine* e) CXX11_OVERRIDE;
 };
 
 // Helper function to store data to entryDict from ds. This function
 // is used by tellStatus method.
 void gatherStoppedDownload
-(const std::shared_ptr<Dict>& entryDict, const std::shared_ptr<DownloadResult>& ds,
+(Dict* entryDict, const std::shared_ptr<DownloadResult>& ds,
  const std::vector<std::string>& keys);
 
 // Helper function to store data to entryDict from group. This
 // function is used by tellStatus/tellActive/tellWaiting method
 void gatherProgressCommon
-(const std::shared_ptr<Dict>& entryDict, const std::shared_ptr<RequestGroup>& group,
+(Dict* entryDict, const std::shared_ptr<RequestGroup>& group,
  const std::vector<std::string>& keys);
 
 #ifdef ENABLE_BITTORRENT
 // Helper function to store BitTorrent metadata from torrentAttrs.
-void gatherBitTorrentMetadata
-(const std::shared_ptr<Dict>& btDict, TorrentAttribute* torrentAttrs);
+void gatherBitTorrentMetadata(Dict* btDict, TorrentAttribute* torrentAttrs);
 #endif // ENABLE_BITTORRENT
 
 } // namespace rpc

+ 11 - 23
src/RpcRequest.cc

@@ -39,35 +39,23 @@ namespace aria2 {
 namespace rpc {
 
 RpcRequest::RpcRequest()
-  : jsonRpc(false)
+  : jsonRpc{false}
 {}
 
-RpcRequest::RpcRequest(const std::string& methodName,
-                       const std::shared_ptr<List>& params)
-  : methodName(methodName), params(params), jsonRpc(false)
+RpcRequest::RpcRequest(std::string methodName,
+                       std::unique_ptr<List> params)
+  : methodName{std::move(methodName)}, params{std::move(params)},
+    jsonRpc{false}
 {}
 
-RpcRequest::RpcRequest(const std::string& methodName,
-                       const std::shared_ptr<List>& params,
-                       const std::shared_ptr<ValueBase>& id)
-  : methodName(methodName), params(params), id(id), jsonRpc(false)
+RpcRequest::RpcRequest(std::string methodName,
+                       std::unique_ptr<List> params,
+                       std::unique_ptr<ValueBase> id,
+                       bool jsonRpc)
+  : methodName{std::move(methodName)}, params{std::move(params)},
+    id{std::move(id)}, jsonRpc{jsonRpc}
 {}
 
-RpcRequest::RpcRequest(const RpcRequest& c)
-  : methodName(c.methodName), params(c.params), id(c.id), jsonRpc(c.jsonRpc)
-{}
-
-RpcRequest::~RpcRequest() {}
-
-RpcRequest& RpcRequest::operator=(const RpcRequest& c)
-{
-  if(this != &c) {
-    methodName = c.methodName;
-    params = c.params;
-  }
-  return *this;
-}
-
 } // namespace rpc
 
 } // namespace aria2

+ 8 - 13
src/RpcRequest.h

@@ -47,24 +47,19 @@ namespace rpc {
 
 struct RpcRequest {
   std::string methodName;
-  std::shared_ptr<List> params;
-  std::shared_ptr<ValueBase> id;
+  std::unique_ptr<List> params;
+  std::unique_ptr<ValueBase> id;
   bool jsonRpc;
 
   RpcRequest();
 
-  RpcRequest(const std::string& methodName,
-             const std::shared_ptr<List>& params);
+  RpcRequest(std::string methodName,
+             std::unique_ptr<List> params);
 
-  RpcRequest(const std::string& methodName,
-             const std::shared_ptr<List>& params,
-             const std::shared_ptr<ValueBase>& id);
-
-  ~RpcRequest();
-
-  RpcRequest(const RpcRequest& c);
-
-  RpcRequest& operator=(const RpcRequest& c);
+  RpcRequest(std::string methodName,
+             std::unique_ptr<List> params,
+             std::unique_ptr<ValueBase> id,
+             bool jsonRpc = false);
 };
 
 } // namespace rpc

+ 24 - 38
src/RpcResponse.cc

@@ -49,7 +49,7 @@ namespace rpc {
 
 namespace {
 template<typename OutputStream>
-void encodeValue(const std::shared_ptr<ValueBase>& value, OutputStream& o)
+void encodeValue(const ValueBase* value, OutputStream& o)
 {
   class XmlValueBaseVisitor:public ValueBaseVisitor {
   private:
@@ -104,7 +104,7 @@ void encodeValue(const std::shared_ptr<ValueBase>& value, OutputStream& o)
 namespace {
 template<typename OutputStream>
 std::string encodeAll
-(OutputStream& o, int code, const std::shared_ptr<ValueBase>& param)
+(OutputStream& o, int code, const ValueBase* param)
 {
   o << "<?xml version=\"1.0\"?>" << "<methodResponse>";
   if(code == 0) {
@@ -123,41 +123,24 @@ std::string encodeAll
 
 RpcResponse::RpcResponse
 (int code,
- const std::shared_ptr<ValueBase>& param,
- const std::shared_ptr<ValueBase>& id)
-  : code(code), param(param), id(id)
+ std::unique_ptr<ValueBase> param,
+ std::unique_ptr<ValueBase> id)
+  : code{code}, param{std::move(param)}, id{std::move(id)}
 {}
 
-RpcResponse::RpcResponse(const RpcResponse& c)
-  : code(c.code),
-    param(c.param),
-    id(c.id)
-{}
-
-RpcResponse::~RpcResponse() {}
-
-RpcResponse& RpcResponse::operator=(const RpcResponse& c)
-{
-  if(this != &c) {
-    code = c.code;
-    param = c.param;
-  }
-  return *this;
-}
-
 std::string toXml(const RpcResponse& res, bool gzip)
 {
   if(gzip) {
 #ifdef HAVE_ZLIB
     GZipEncoder o;
     o.init();
-    return encodeAll(o, res.code, res.param);
+    return encodeAll(o, res.code, res.param.get());
 #else // !HAVE_ZLIB
     abort();
 #endif // !HAVE_ZLIB
   } else {
     std::stringstream o;
-    return encodeAll(o, res.code, res.param);
+    return encodeAll(o, res.code, res.param.get());
   }
 }
 
@@ -166,22 +149,23 @@ template<typename OutputStream>
 OutputStream& encodeJsonAll
 (OutputStream& o,
  int code,
- const std::shared_ptr<ValueBase>& param,
- const std::shared_ptr<ValueBase>& id,
+ const ValueBase* param,
+ const ValueBase* id,
  const std::string& callback = A2STR::NIL)
 {
   if(!callback.empty()) {
     o << callback << "(";
   }
-  std::shared_ptr<Dict> dict = Dict::g();
-  dict->put("jsonrpc", "2.0");
-  dict->put("id", id);
+  o << "{\"id\":";
+  json::encode(o, id);
+  o << ",\"jsonrpc\":\"2.0\",";
   if(code == 0) {
-    dict->put("result", param);
+    o << "\"result\":";
   } else {
-    dict->put("error", param);
+    o << "\"error\":";
   }
-  json::encode(o, dict);
+  json::encode(o, param);
+  o << "}";
   if(!callback.empty()) {
     o << ")";
   }
@@ -196,13 +180,15 @@ std::string toJson
 #ifdef HAVE_ZLIB
     GZipEncoder o;
     o.init();
-    return encodeJsonAll(o, res.code, res.param, res.id, callback).str();
+    return encodeJsonAll(o, res.code, res.param.get(), res.id.get(),
+                         callback).str();
 #else // !HAVE_ZLIB
     abort();
 #endif // !HAVE_ZLIB
   } else {
     std::stringstream o;
-    return encodeJsonAll(o, res.code, res.param, res.id, callback).str();
+    return encodeJsonAll(o, res.code, res.param.get(), res.id.get(),
+                         callback).str();
   }
 }
 
@@ -218,12 +204,12 @@ OutputStream& encodeJsonBatchAll
   }
   o << "[";
   if(!results.empty()) {
-    encodeJsonAll(o, results[0].code, results[0].param, results[0].id);
+    encodeJsonAll(o, results[0].code, results[0].param.get(),
+                  results[0].id.get());
   }
-  for(std::vector<RpcResponse>::const_iterator i = results.begin()+1,
-        eoi = results.end(); i != eoi; ++i) {
+  for(auto i = std::begin(results)+1, eoi = std::end(results); i != eoi; ++i) {
     o << ",";
-    encodeJsonAll(o, (*i).code, (*i).param, (*i).id);
+    encodeJsonAll(o, (*i).code, (*i).param.get(), (*i).id.get());
   }
   o << "]";
   if(!callback.empty()) {

+ 4 - 12
src/RpcResponse.h

@@ -49,21 +49,13 @@ namespace rpc {
 struct RpcResponse {
   // 0 for success, non-zero for error
   int code;
-
-  std::shared_ptr<ValueBase> param;
-
-  std::shared_ptr<ValueBase> id;
+  std::unique_ptr<ValueBase> param;
+  std::unique_ptr<ValueBase> id;
 
   RpcResponse
   (int code,
-   const std::shared_ptr<ValueBase>& param,
-   const std::shared_ptr<ValueBase>& id);
-
-  RpcResponse(const RpcResponse& c);
-
-  ~RpcResponse();
-
-  RpcResponse& operator=(const RpcResponse& c);
+   std::unique_ptr<ValueBase> param,
+   std::unique_ptr<ValueBase> id);
 };
 
 std::string toXml(const RpcResponse& response, bool gzip = false);

+ 97 - 80
src/ValueBase.cc

@@ -36,39 +36,49 @@
 
 namespace aria2 {
 
-const std::shared_ptr<ValueBase> ValueBase::none;
+String::String(const ValueType& string):str_{string} {}
+String::String(ValueType&& string):str_{std::move(string)} {}
 
-String::String(const ValueType& string):str_(string) {}
+String::String(const char* cstring):str_{cstring} {}
 
-String::String(const char* cstring):str_(cstring) {}
+String::String(const char* data, size_t length)
+  : str_{&data[0], &data[length]}
+ {}
 
-String::String(const char* data, size_t length):str_(&data[0], &data[length]) {}
-
-String::String(const unsigned char* data, size_t length):
-  str_(&data[0], &data[length]) {}
+String::String(const unsigned char* data, size_t length)
+  : str_{&data[0], &data[length]}
+ {}
 
 String::String() {}
 
-String::~String() {}
-
 const String::ValueType& String::s() const
 {
   return str_;
 }
 
+String::ValueType String::popValue() const
+{
+  return std::move(str_);
+}
+
 const unsigned char* String::uc() const
 {
   return reinterpret_cast<const unsigned char*>(str_.data());
 }
 
-std::shared_ptr<String> String::g(const ValueType& string)
+std::unique_ptr<String> String::g(const ValueType& string)
 {
-  return std::shared_ptr<String>(new String(string));
+  return make_unique<String>(string);
 }
 
-std::shared_ptr<String> String::g(const unsigned char* data, size_t length)
+std::unique_ptr<String> String::g(ValueType&& string)
 {
-  return std::shared_ptr<String>(new String(data, length));
+  return make_unique<String>(std::move(string));
+}
+
+std::unique_ptr<String> String::g(const unsigned char* data, size_t length)
+{
+  return make_unique<String>(data, length);
 }
 
 void String::accept(ValueBaseVisitor& v) const
@@ -76,20 +86,18 @@ void String::accept(ValueBaseVisitor& v) const
   v.visit(*this);
 }
 
-Integer::Integer(ValueType integer):integer_(integer) {}
-
-Integer::Integer():integer_(0) {}
+Integer::Integer(ValueType integer) : integer_{integer} {}
 
-Integer::~Integer() {}
+Integer::Integer() : integer_{0} {}
 
 Integer::ValueType Integer::i() const
 {
   return integer_;
 }
 
-std::shared_ptr<Integer> Integer::g(ValueType integer)
+std::unique_ptr<Integer> Integer::g(ValueType integer)
 {
-  return std::shared_ptr<Integer>(new Integer(integer));
+  return make_unique<Integer>(integer);
 }
 
 void Integer::accept(ValueBaseVisitor& v) const
@@ -97,17 +105,16 @@ void Integer::accept(ValueBaseVisitor& v) const
   v.visit(*this);
 }
 
-const std::shared_ptr<Bool> Bool::trueValue_(new Bool(true));
-const std::shared_ptr<Bool> Bool::falseValue_(new Bool(false));
+Bool::Bool(bool val):val_{val} {}
 
-std::shared_ptr<Bool> Bool::gTrue()
+std::unique_ptr<Bool> Bool::gTrue()
 {
-  return trueValue_;
+  return make_unique<Bool>(true);
 }
 
-std::shared_ptr<Bool> Bool::gFalse()
+std::unique_ptr<Bool> Bool::gFalse()
 {
-  return falseValue_;
+  return make_unique<Bool>(false);
 }
 
 bool Bool::val() const
@@ -120,13 +127,11 @@ void Bool::accept(ValueBaseVisitor& v) const
   v.visit(*this);
 }
 
-Bool::Bool(bool val):val_(val) {}
-
-const std::shared_ptr<Null> Null::nullValue_(new Null());
+Null::Null() {}
 
-std::shared_ptr<Null> Null::g()
+std::unique_ptr<Null> Null::g()
 {
-  return nullValue_;
+  return make_unique<Null>();
 }
 
 void Null::accept(ValueBaseVisitor& v) const
@@ -134,41 +139,37 @@ void Null::accept(ValueBaseVisitor& v) const
   v.visit(*this);
 }
 
-Null::Null() {}
-
 List::List() {}
 
-List::~List() {}
-
-const std::shared_ptr<ValueBase>& List::get(size_t index) const
+ValueBase* List::get(size_t index) const
 {
-  return list_[index];
+  return list_[index].get();
 }
 
-void List::set(size_t index, const std::shared_ptr<ValueBase>& v)
+void List::set(size_t index, std::unique_ptr<ValueBase> v)
 {
-  list_[index] = v;
+  list_[index] = std::move(v);
 }
 
-void List::append(const std::shared_ptr<ValueBase>& v)
+void List::append(std::unique_ptr<ValueBase> v)
 {
-  list_.push_back(v);
+  list_.push_back(std::move(v));
 }
 
-void List::append(const String::ValueType& string)
+void List::append(String::ValueType string)
 {
-  list_.push_back(String::g(string));
+  list_.push_back(String::g(std::move(string)));
 }
 
-List& List::operator<<(const std::shared_ptr<ValueBase>& v)
+List& List::operator<<(std::unique_ptr<ValueBase> v)
 {
-  list_.push_back(v);
+  list_.push_back(std::move(v));
   return *this;
 }
 
-const std::shared_ptr<ValueBase>& List::operator[](size_t index) const
+ValueBase* List::operator[](size_t index) const
 {
-  return list_[index];
+  return list_[index].get();
 }
 
 List::ValueType::iterator List::begin()
@@ -191,6 +192,16 @@ List::ValueType::const_iterator List::end() const
   return list_.end();
 }
 
+List::ValueType::const_iterator List::cbegin() const
+{
+  return list_.cbegin();
+}
+
+List::ValueType::const_iterator List::cend() const
+{
+  return list_.cend();
+}
+
 size_t List::size() const
 {
   return list_.size();
@@ -201,9 +212,9 @@ bool List::empty() const
   return list_.empty();
 }
 
-std::shared_ptr<List> List::g()
+std::unique_ptr<List> List::g()
 {
-  return std::shared_ptr<List>(new List());
+  return make_unique<List>();
 }
 
 void List::accept(ValueBaseVisitor& v) const
@@ -213,55 +224,38 @@ void List::accept(ValueBaseVisitor& v) const
 
 Dict::Dict() {}
 
-Dict::~Dict() {}
-
-void Dict::put(const std::string& key, const std::shared_ptr<ValueBase>& vlb)
+void Dict::put(std::string key, std::unique_ptr<ValueBase> vlb)
 {
-  ValueType::value_type p = std::make_pair(key, vlb);
-  std::pair<ValueType::iterator, bool> r = dict_.insert(p);
+  auto p = std::make_pair(std::move(key), std::move(vlb));
+  auto r = dict_.insert(std::move(p));
   if(!r.second) {
-    (*r.first).second = vlb;
+    (*r.first).second = std::move(vlb);
   }
 }
 
-void Dict::put(const std::string& key, const String::ValueType& string)
+void Dict::put(std::string key, String::ValueType string)
 {
-  put(key, String::g(string));
+  put(std::move(key), String::g(std::move(string)));
 }
 
-const std::shared_ptr<ValueBase>& Dict::get(const std::string& key) const
+ValueBase* Dict::get(const std::string& key) const
 {
-  ValueType::const_iterator itr = dict_.find(key);
-  if(itr == dict_.end()) {
-    return ValueBase::none;
+  auto itr = dict_.find(key);
+  if(itr == std::end(dict_)) {
+    return nullptr;
   } else {
-    return (*itr).second;
+    return (*itr).second.get();
   }
 }
 
-std::shared_ptr<ValueBase>& Dict::get(const std::string& key)
-{
-  ValueType::iterator itr = dict_.find(key);
-  if(itr == dict_.end()) {
-    return dict_[key];
-  } else {
-    return (*itr).second;
-  }
-}
-
-std::shared_ptr<ValueBase>& Dict::operator[](const std::string& key)
-{
-  return get(key);
-}
-
-const std::shared_ptr<ValueBase>& Dict::operator[](const std::string& key) const
+ValueBase* Dict::operator[](const std::string& key) const
 {
   return get(key);
 }
 
 bool Dict::containsKey(const std::string& key) const
 {
-  return dict_.count(key) == 1;
+  return dict_.count(key);
 }
 
 void Dict::removeKey(const std::string& key)
@@ -269,6 +263,18 @@ void Dict::removeKey(const std::string& key)
   dict_.erase(key);
 }
 
+std::unique_ptr<ValueBase> Dict::popValue(const std::string& key)
+{
+  auto i = dict_.find(key);
+  if(i == std::end(dict_)) {
+    return nullptr;
+  } else {
+    auto res = std::move((*i).second);
+    dict_.erase(i);
+    return res;
+  }
+}
+
 Dict::ValueType::iterator Dict::begin()
 {
   return dict_.begin();
@@ -289,6 +295,16 @@ Dict::ValueType::const_iterator Dict::end() const
   return dict_.end();
 }
 
+Dict::ValueType::const_iterator Dict::cbegin() const
+{
+  return dict_.cbegin();
+}
+
+Dict::ValueType::const_iterator Dict::cend() const
+{
+  return dict_.cend();
+}
+
 size_t Dict::size() const
 {
   return dict_.size();
@@ -299,10 +315,11 @@ bool Dict::empty() const
   return dict_.empty();
 }
 
-std::shared_ptr<Dict> Dict::g()
+std::unique_ptr<Dict> Dict::g()
 {
-  return std::shared_ptr<Dict>(new Dict());
+  return make_unique<Dict>();
 }
+
 void Dict::accept(ValueBaseVisitor& v) const
 {
   v.visit(*this);

+ 61 - 57
src/ValueBase.h

@@ -42,6 +42,8 @@
 #include <map>
 #include <memory>
 
+#include "a2functional.h"
+
 namespace aria2 {
 
 class ValueBaseVisitor;
@@ -51,8 +53,6 @@ public:
   virtual ~ValueBase() {}
 
   virtual void accept(ValueBaseVisitor& visitor) const = 0;
-
-  static const std::shared_ptr<ValueBase> none;
 };
 
 class String;
@@ -78,6 +78,7 @@ public:
   typedef std::string ValueType;
 
   String(const ValueType& string);
+  String(ValueType&& string);
 
   explicit String(const char* cstring);
 
@@ -92,26 +93,27 @@ public:
 
   String();
 
-  ~String();
-
   // Don't allow copying
-  String(const String&);
-  String& operator=(const String&);
+  String(const String&) = delete;
+  String& operator=(const String&) = delete;
 
   const ValueType& s() const;
 
+  ValueType popValue() const;
+
   // Returns std::string.data() casted to unsigned char*.
   // Use s().size() to get length.
   const unsigned char* uc() const;
 
-  static std::shared_ptr<String> g(const ValueType& string);
+  static std::unique_ptr<String> g(const ValueType& string);
+  static std::unique_ptr<String> g(ValueType&& string);
 
-  static std::shared_ptr<String> g(const unsigned char* data, size_t length);
+  static std::unique_ptr<String> g(const unsigned char* data, size_t length);
 
   template<typename InputIterator>
-  static std::shared_ptr<String> g(InputIterator first, InputIterator last)
+  static std::unique_ptr<String> g(InputIterator first, InputIterator last)
   {
-    return std::shared_ptr<String>(new String(first, last));
+    return make_unique<String>(first, last);
   }
 
   virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE;
@@ -127,16 +129,14 @@ public:
 
   Integer();
 
-  ~Integer();
-
   // Don't allow copying
-  Integer(const Integer&);
-  Integer& operator=(const Integer&);
+  Integer(const Integer&) = delete;
+  Integer& operator=(const Integer&) = delete;
 
   // Returns Integer.
   ValueType i() const;
 
-  static std::shared_ptr<Integer> g(ValueType integer);
+  static std::unique_ptr<Integer> g(ValueType integer);
 
   virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE;
 private:
@@ -145,61 +145,56 @@ private:
 
 class Bool:public ValueBase {
 public:
-  static std::shared_ptr<Bool> gTrue();
-  static std::shared_ptr<Bool> gFalse();
+  static std::unique_ptr<Bool> gTrue();
+  static std::unique_ptr<Bool> gFalse();
+  Bool(bool val);
   bool val() const;
   virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE;
 private:
-  Bool(bool val);
   // Don't allow copying
-  Bool(const Bool&);
-  Bool& operator=(const Bool&);
+  Bool(const Bool&) = delete;
+  Bool& operator=(const Bool&) = delete;
   bool val_;
-  static const std::shared_ptr<Bool> trueValue_;
-  static const std::shared_ptr<Bool> falseValue_;
 };
 
 class Null:public ValueBase {
 public:
-  static std::shared_ptr<Null> g();
+  static std::unique_ptr<Null> g();
+  Null();
   virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE;
 private:
-  Null();
   // Don't allow copying
   Null(const Null&);
   Null& operator=(const Null&);
-  static const std::shared_ptr<Null> nullValue_;
 };
 
 class List:public ValueBase {
 public:
-  typedef std::vector<std::shared_ptr<ValueBase> > ValueType;
+  typedef std::vector<std::unique_ptr<ValueBase>> ValueType;
 
   List();
 
-  ~List();
-
   // Don't allow copying
-  List(const List&);
-  List& operator=(const List&);
+  List(const List&) = delete;
+  List& operator=(const List&) = delete;
 
   // Appends given v to list.
-  void append(const std::shared_ptr<ValueBase>& v);
+  void append(std::unique_ptr<ValueBase> v);
 
   // Appeding string is so common that we provide shortcut function.
-  void append(const String::ValueType& string);
+  void append(String::ValueType string);
 
   // Alias for append()
-  List& operator<<(const std::shared_ptr<ValueBase>& v);
+  List& operator<<(std::unique_ptr<ValueBase> v);
 
   // Returns the object at given index.
-  const std::shared_ptr<ValueBase>& get(size_t index) const;
+  ValueBase* get(size_t index) const;
 
   // Set the object at given index.
-  void set(size_t index, const std::shared_ptr<ValueBase>& v);
+  void set(size_t index, std::unique_ptr<ValueBase> v);
 
   // Returns the const reference of the object at the given index.
-  const std::shared_ptr<ValueBase>& operator[](size_t index) const;
+  ValueBase* operator[](size_t index) const;
 
   // Returns a read/write iterator that points to the first object in
   // list.
@@ -217,13 +212,21 @@ public:
   // past the last object in list.
   ValueType::const_iterator end() const;
 
+  // Returns a read/write read-only iterator that points to the first
+  // object in list.
+  ValueType::const_iterator cbegin() const;
+
+  // Returns a read/write read-only iterator that points to the one
+  // past the last object in list.
+  ValueType::const_iterator cend() const;
+
   // Returns size of list.
   size_t size() const;
 
   // Returns true if size of list is 0.
   bool empty() const;
 
-  static std::shared_ptr<List> g();
+  static std::unique_ptr<List> g();
 
   virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE;
 private:
@@ -232,34 +235,24 @@ private:
 
 class Dict:public ValueBase {
 public:
-  typedef std::map<std::string, std::shared_ptr<ValueBase> > ValueType;
+  typedef std::map<std::string, std::unique_ptr<ValueBase>> ValueType;
 
   Dict();
 
-  ~Dict();
-
   // Don't allow copying
-  Dict(const Dict&);
-  Dict& operator=(const Dict&);
+  Dict(const Dict&) = delete;
+  Dict& operator=(const Dict&) = delete;
 
-  void put(const std::string& key, const std::shared_ptr<ValueBase>& vlb);
+  void put(std::string key, std::unique_ptr<ValueBase> vlb);
 
   // Putting string is so common that we provide shortcut function.
-  void put(const std::string& key, const String::ValueType& string);
+  void put(std::string key, String::ValueType string);
 
-  const std::shared_ptr<ValueBase>& get(const std::string& key) const;
-
-  std::shared_ptr<ValueBase>& get(const std::string& key);
+  ValueBase* get(const std::string& key) const;
 
   // Returns the reference to 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[].
-  std::shared_ptr<ValueBase>& operator[](const std::string& key);
-
-  // Returns the const reference to ojbect associated with given key.
-  // If the key is not found, ValueBase::none is returned.
-  const std::shared_ptr<ValueBase>& operator[](const std::string& key) const;
+  // the key is not found, nullptr is returned.
+  ValueBase* operator[](const std::string& key) const;
 
   // Returns true if the given key is found in dict.
   bool containsKey(const std::string& key) const;
@@ -267,6 +260,9 @@ public:
   // Removes specified key from dict.
   void removeKey(const std::string& key);
 
+  // Removes specified key from dict and return its associated value.
+  std::unique_ptr<ValueBase> popValue(const std::string& key);
+
   // Returns a read/write iterator that points to the first pair in
   // the dict.
   ValueType::iterator begin();
@@ -283,13 +279,21 @@ public:
   // the last pair in the dict.
   ValueType::const_iterator end() const;
 
+  // Returns a read/write read-only iterator that points to the first
+  // pair in the dict.
+  ValueType::const_iterator cbegin() const;
+
+  // Returns a read/write read-only iterator that points to one past
+  // the last pair in the dict.
+  ValueType::const_iterator cend() const;
+
   // Returns size of Dict.
   size_t size() const;
 
   // Returns true if size of Dict is 0.
   bool empty() const;
 
-  static std::shared_ptr<Dict> g();
+  static std::unique_ptr<Dict> g();
 
   virtual void accept(ValueBaseVisitor& visitor) const CXX11_OVERRIDE;
 private:
@@ -310,7 +314,7 @@ public:
 template<typename T>
 class DowncastValueBaseVisitor:public EmptyDowncastValueBaseVisitor {
 public:
-  DowncastValueBaseVisitor():result_(0) {}
+  DowncastValueBaseVisitor() : result_{nullptr} {}
 
   virtual void visit(const T& t) CXX11_OVERRIDE
   {

+ 1 - 1
src/ValueBaseDiskWriter.h

@@ -94,7 +94,7 @@ public:
     return parser_.parseFinal(0, 0);
   }
 
-  std::shared_ptr<ValueBase> getResult() const
+  std::unique_ptr<ValueBase> getResult()
   {
     return psm_.getResult();
   }

+ 17 - 15
src/ValueBaseStructParserStateMachine.cc

@@ -65,22 +65,20 @@ NullValueBaseStructParserState* nullState =
   new NullValueBaseStructParserState();
 } // namespace
 
-const std::shared_ptr<ValueBase>&
+std::unique_ptr<ValueBase>
 ValueBaseStructParserStateMachine::noResult()
 {
-  return ValueBase::none;
+  return nullptr;
 }
 
 ValueBaseStructParserStateMachine::ValueBaseStructParserStateMachine()
-  : ctrl_(new rpc::XmlRpcRequestParserController())
+  : ctrl_{make_unique<rpc::XmlRpcRequestParserController>()}
 {
   stateStack_.push(valueState);
 }
 
 ValueBaseStructParserStateMachine::~ValueBaseStructParserStateMachine()
-{
-  delete ctrl_;
-}
+{}
 
 void ValueBaseStructParserStateMachine::reset()
 {
@@ -102,10 +100,9 @@ void ValueBaseStructParserStateMachine::endElement(int elementType)
   stateStack_.pop();
 }
 
-std::shared_ptr<ValueBase>
-ValueBaseStructParserStateMachine::getResult() const
+std::unique_ptr<ValueBase> ValueBaseStructParserStateMachine::getResult()
 {
-  return getCurrentFrameValue();
+  return popCurrentFrameValue();
 }
 
 void ValueBaseStructParserStateMachine::charactersCallback
@@ -159,21 +156,26 @@ void ValueBaseStructParserStateMachine::pushFrame()
 }
 
 void ValueBaseStructParserStateMachine::setCurrentFrameValue
-(const std::shared_ptr<ValueBase>& value)
+(std::unique_ptr<ValueBase> value)
 {
-  ctrl_->setCurrentFrameValue(value);
+  ctrl_->setCurrentFrameValue(std::move(value));
 }
 
-const std::shared_ptr<ValueBase>&
+const std::unique_ptr<ValueBase>&
 ValueBaseStructParserStateMachine::getCurrentFrameValue() const
 {
   return ctrl_->getCurrentFrameValue();
 }
 
-void ValueBaseStructParserStateMachine::setCurrentFrameName
-(const std::string& name)
+std::unique_ptr<ValueBase>
+ValueBaseStructParserStateMachine::popCurrentFrameValue()
+{
+  return ctrl_->popCurrentFrameValue();
+}
+
+void ValueBaseStructParserStateMachine::setCurrentFrameName(std::string name)
 {
-  ctrl_->setCurrentFrameName(name);
+  ctrl_->setCurrentFrameName(std::move(name));
 }
 
 void ValueBaseStructParserStateMachine::pushDictState()

+ 8 - 7
src/ValueBaseStructParserStateMachine.h

@@ -55,8 +55,8 @@ class ValueBaseStructParserState;
 // value holder.
 class ValueBaseStructParserStateMachine : public StructParserStateMachine {
 public:
-  typedef std::shared_ptr<ValueBase> ResultType;
-  static const std::shared_ptr<ValueBase>& noResult();
+  typedef std::unique_ptr<ValueBase> ResultType;
+  static std::unique_ptr<ValueBase> noResult();
 
   struct NumberData {
     int64_t number;
@@ -82,7 +82,7 @@ public:
     CXX11_OVERRIDE;
   virtual void boolCallback(bool bval) CXX11_OVERRIDE;
 
-  std::shared_ptr<ValueBase> getResult() const;
+  std::unique_ptr<ValueBase> getResult();
 
   virtual void reset() CXX11_OVERRIDE;
 
@@ -93,9 +93,10 @@ public:
   void popArrayFrame();
   void popDictFrame();
   void pushFrame();
-  void setCurrentFrameValue(const std::shared_ptr<ValueBase>& value);
-  const std::shared_ptr<ValueBase>& getCurrentFrameValue() const;
-  void setCurrentFrameName(const std::string& name);
+  void setCurrentFrameValue(std::unique_ptr<ValueBase> value);
+  const std::unique_ptr<ValueBase>& getCurrentFrameValue() const;
+  std::unique_ptr<ValueBase> popCurrentFrameValue();
+  void setCurrentFrameName(std::string name);
 
   void pushDictState();
   void pushDictKeyState();
@@ -107,7 +108,7 @@ public:
   void pushBoolState();
   void pushNullState();
 private:
-  rpc::XmlRpcRequestParserController* ctrl_;
+  std::unique_ptr<rpc::XmlRpcRequestParserController> ctrl_;
   std::stack<ValueBaseStructParserState*> stateStack_;
   SessionData sessionData_;
 };

+ 8 - 9
src/WebSocketSession.cc

@@ -160,7 +160,7 @@ void onMsgRecvCallback(wslay_event_context_ptr wsctx,
   if(!wslay_is_ctrl_frame(arg->opcode)) {
     // TODO Only process text frame
     ssize_t error = 0;
-    std::shared_ptr<ValueBase> json = wsSession->parseFinal(0, 0, error);
+    auto json = wsSession->parseFinal(0, 0, error);
     if(error < 0) {
       A2_LOG_INFO("Failed to parse JSON-RPC request");
       RpcResponse res
@@ -168,23 +168,22 @@ void onMsgRecvCallback(wslay_event_context_ptr wsctx,
       addResponse(wsSession, res);
       return;
     }
-    const Dict* jsondict = downcast<Dict>(json);
+    Dict* jsondict = downcast<Dict>(json);
     if(jsondict) {
       RpcResponse res = processJsonRpcRequest(jsondict,
                                               wsSession->getDownloadEngine());
       addResponse(wsSession, res);
     } else {
-      const List* jsonlist = downcast<List>(json);
+      List* jsonlist = downcast<List>(json);
       if(jsonlist) {
         // This is batch call
         std::vector<RpcResponse> results;
         for(List::ValueType::const_iterator i = jsonlist->begin(),
               eoi = jsonlist->end(); i != eoi; ++i) {
-          const Dict* jsondict = downcast<Dict>(*i);
+          Dict* jsondict = downcast<Dict>(*i);
           if(jsondict) {
-            RpcResponse r = processJsonRpcRequest
-              (jsondict, wsSession->getDownloadEngine());
-            results.push_back(r);
+            results.push_back(processJsonRpcRequest
+                              (jsondict, wsSession->getDownloadEngine()));
           }
         }
         addResponse(wsSession, results);
@@ -292,10 +291,10 @@ ssize_t WebSocketSession::parseUpdate(const uint8_t* data, size_t len)
   return parser_.parseUpdate(reinterpret_cast<const char*>(data), len);
 }
 
-std::shared_ptr<ValueBase> WebSocketSession::parseFinal
+std::unique_ptr<ValueBase> WebSocketSession::parseFinal
 (const uint8_t* data, size_t len, ssize_t& error)
 {
-  std::shared_ptr<ValueBase> res =
+  auto res =
     parser_.parseFinal(reinterpret_cast<const char*>(data), len, error);
   receivedLength_ = 0;
   return res;

+ 2 - 2
src/WebSocketSession.h

@@ -86,8 +86,8 @@ public:
   // |error| will be the number of bytes processed if this function
   // succeeds, or negative error code. Whether success or failure,
   // this function resets parser state and receivedLength_.
-  std::shared_ptr<ValueBase> parseFinal(const uint8_t* data, size_t len,
-                                     ssize_t& error);
+  std::unique_ptr<ValueBase> parseFinal(const uint8_t* data, size_t len,
+                                        ssize_t& error);
 
   const std::shared_ptr<SocketCore>& getSocket() const
   {

+ 6 - 6
src/WebSocketSessionMan.cc

@@ -68,15 +68,15 @@ void WebSocketSessionMan::removeSession
 void WebSocketSessionMan::addNotification
 (const std::string& method, const RequestGroup* group)
 {
-  std::shared_ptr<Dict> dict = Dict::g();
+  auto dict = Dict::g();
   dict->put("jsonrpc", "2.0");
   dict->put("method", method);
-  std::shared_ptr<Dict> eventSpec = Dict::g();
+  auto eventSpec = Dict::g();
   eventSpec->put("gid", GroupId::toHex((group->getGID())));
-  std::shared_ptr<List> params = List::g();
-  params->append(eventSpec);
-  dict->put("params", params);
-  std::string msg = json::encode(dict);
+  auto params = List::g();
+  params->append(std::move(eventSpec));
+  dict->put("params", std::move(params));
+  std::string msg = json::encode(dict.get());
   for(WebSocketSessions::const_iterator i = sessions_.begin(),
         eoi = sessions_.end(); i != eoi; ++i) {
     (*i)->addTextMessage(msg);

+ 4 - 4
src/XmlRpcDiskWriter.cc

@@ -65,15 +65,15 @@ int XmlRpcDiskWriter::finalize()
   return parser_.parseFinal(0, 0);
 }
 
-RpcRequest XmlRpcDiskWriter::getResult() const
+RpcRequest XmlRpcDiskWriter::getResult()
 {
-  std::shared_ptr<List> params;
+  std::unique_ptr<List> params;
   if(downcast<List>(psm_.getCurrentFrameValue())) {
-    params = std::static_pointer_cast<List>(psm_.getCurrentFrameValue());
+    params.reset(static_cast<List*>(psm_.popCurrentFrameValue().release()));
   } else {
     params = List::g();
   }
-  return RpcRequest(psm_.getMethodName(), params);
+  return RpcRequest{psm_.getMethodName(), std::move(params)};
 }
 
 int XmlRpcDiskWriter::reset()

+ 1 - 1
src/XmlRpcDiskWriter.h

@@ -83,7 +83,7 @@ public:
   }
 
   int finalize();
-  RpcRequest getResult() const;
+  RpcRequest getResult();
   int reset();
 private:
   XmlRpcRequestParserStateMachine psm_;

+ 23 - 12
src/XmlRpcRequestParserController.cc

@@ -42,7 +42,7 @@ namespace rpc {
 
 void XmlRpcRequestParserController::pushFrame()
 {
-  frameStack_.push(currentFrame_);
+  frameStack_.push(std::move(currentFrame_));
   currentFrame_ = StateFrame();
 }
 
@@ -50,48 +50,54 @@ void XmlRpcRequestParserController::popStructFrame()
 {
   assert(!frameStack_.empty());
 
-  StateFrame parentFrame = frameStack_.top();
+  StateFrame parentFrame = std::move(frameStack_.top());
   Dict* dict = downcast<Dict>(parentFrame.value_);
   assert(dict);
   frameStack_.pop();
   if(currentFrame_.validMember()) {
-    dict->put(currentFrame_.name_, currentFrame_.value_);
+    dict->put(std::move(currentFrame_.name_), std::move(currentFrame_.value_));
   }
-  currentFrame_ = parentFrame;
+  currentFrame_ = std::move(parentFrame);
 }
 
 void XmlRpcRequestParserController::popArrayFrame()
 {
   assert(!frameStack_.empty());
 
-  StateFrame parentFrame = frameStack_.top();
+  StateFrame parentFrame = std::move(frameStack_.top());
   List* list = downcast<List>(parentFrame.value_);
   assert(list);
   frameStack_.pop();
   if(currentFrame_.value_) {
-    list->append(currentFrame_.value_);
+    list->append(std::move(currentFrame_.value_));
   }
-  currentFrame_ = parentFrame;
+  currentFrame_ = std::move(parentFrame);
 }
 
 void XmlRpcRequestParserController::setCurrentFrameValue
-(const std::shared_ptr<ValueBase>& value)
+(std::unique_ptr<ValueBase> value)
 {
-  currentFrame_.value_ = value;
+  currentFrame_.value_ = std::move(value);
 }
 
 void XmlRpcRequestParserController::setCurrentFrameName
-(const std::string& name)
+(std::string name)
 {
-  currentFrame_.name_ = name;
+  currentFrame_.name_ = std::move(name);
 }
 
-const std::shared_ptr<ValueBase>&
+const std::unique_ptr<ValueBase>&
 XmlRpcRequestParserController::getCurrentFrameValue() const
 {
   return currentFrame_.value_;
 }
 
+std::unique_ptr<ValueBase>
+XmlRpcRequestParserController::popCurrentFrameValue()
+{
+  return std::move(currentFrame_.value_);
+}
+
 void XmlRpcRequestParserController::reset()
 {
   while(!frameStack_.empty()) {
@@ -101,6 +107,11 @@ void XmlRpcRequestParserController::reset()
   methodName_.clear();
 }
 
+void XmlRpcRequestParserController::setMethodName(std::string methodName)
+{
+  methodName_ = std::move(methodName);
+}
+
 } // namespace rpc
 
 } // namespace aria2

+ 7 - 8
src/XmlRpcRequestParserController.h

@@ -50,7 +50,7 @@ class XmlRpcRequestParserController {
 private:
 
   struct StateFrame {
-    std::shared_ptr<ValueBase> value_;
+    std::unique_ptr<ValueBase> value_;
     std::string name_;
 
     bool validMember() const
@@ -81,16 +81,15 @@ public:
   // to p and currentFrame_ = p;
   void popArrayFrame();
 
-  void setCurrentFrameValue(const std::shared_ptr<ValueBase>& value);
+  void setCurrentFrameValue(std::unique_ptr<ValueBase> value);
 
-  void setCurrentFrameName(const std::string& name);
+  void setCurrentFrameName(std::string name);
 
-  const std::shared_ptr<ValueBase>& getCurrentFrameValue() const;
+  const std::unique_ptr<ValueBase>& getCurrentFrameValue() const;
 
-  void setMethodName(const std::string& methodName)
-  {
-    methodName_ = methodName;
-  }
+  std::unique_ptr<ValueBase> popCurrentFrameValue();
+
+  void setMethodName(std::string methodName);
 
   const std::string& getMethodName() const { return methodName_; }
 

+ 9 - 3
src/XmlRpcRequestParserStateMachine.cc

@@ -166,17 +166,23 @@ void XmlRpcRequestParserStateMachine::pushFrame()
 }
 
 void XmlRpcRequestParserStateMachine::setCurrentFrameValue
-(const std::shared_ptr<ValueBase>& value)
+(std::unique_ptr<ValueBase> value)
 {
-  controller_->setCurrentFrameValue(value);
+  controller_->setCurrentFrameValue(std::move(value));
 }
 
-const std::shared_ptr<ValueBase>&
+const std::unique_ptr<ValueBase>&
 XmlRpcRequestParserStateMachine::getCurrentFrameValue() const
 {
   return controller_->getCurrentFrameValue();
 }
 
+std::unique_ptr<ValueBase>
+XmlRpcRequestParserStateMachine::popCurrentFrameValue()
+{
+  return controller_->popCurrentFrameValue();
+}
+
 void XmlRpcRequestParserStateMachine::setCurrentFrameName
 (const std::string& name)
 {

+ 3 - 2
src/XmlRpcRequestParserStateMachine.h

@@ -77,8 +77,9 @@ public:
   void popArrayFrame();
   void popStructFrame();
   void pushFrame();
-  void setCurrentFrameValue(const std::shared_ptr<ValueBase>& value);
-  const std::shared_ptr<ValueBase>& getCurrentFrameValue() const;
+  void setCurrentFrameValue(std::unique_ptr<ValueBase> value);
+  const std::unique_ptr<ValueBase>& getCurrentFrameValue() const;
+  std::unique_ptr<ValueBase> popCurrentFrameValue();
   void setCurrentFrameName(const std::string& name);
 
   void pushUnknownElementState();

+ 5 - 10
src/bencode2.cc

@@ -47,25 +47,25 @@ namespace aria2 {
 
 namespace bencode2 {
 
-std::shared_ptr<ValueBase> decode(const unsigned char* data, size_t len)
+std::unique_ptr<ValueBase> decode(const unsigned char* data, size_t len)
 {
   size_t end;
   return decode(data, len, end);
 }
 
-std::shared_ptr<ValueBase> decode(const std::string& data)
+std::unique_ptr<ValueBase> decode(const std::string& data)
 {
   size_t end;
   return decode(reinterpret_cast<const unsigned char*>(data.c_str()),
                 data.size(), end);
 }
 
-std::shared_ptr<ValueBase> decode(const unsigned char* data, size_t len,
-                               size_t& end)
+std::unique_ptr<ValueBase> decode(const unsigned char* data, size_t len,
+                                  size_t& end)
 {
   ssize_t error;
   bittorrent::ValueBaseBencodeParser parser;
-  std::shared_ptr<ValueBase> res =
+  auto res =
     parser.parseFinal(reinterpret_cast<const char*>(data), len, error);
   if(error < 0) {
     throw DL_ABORT_EX2(fmt("Bencode decoding failed: error=%d",
@@ -130,11 +130,6 @@ std::string encode(const ValueBase* vlb)
   return visitor.getResult();
 }
 
-std::string encode(const std::shared_ptr<ValueBase>& vlb)
-{
-  return encode(vlb.get());
-}
-
 } // namespace bencode2
 
 } // namespace aria2

+ 5 - 7
src/bencode2.h

@@ -46,21 +46,19 @@ namespace aria2 {
 namespace bencode2 {
 
 // Decode the data whose length is len.
-std::shared_ptr<ValueBase> decode(const unsigned char* data, size_t len);
+std::unique_ptr<ValueBase> decode(const unsigned char* data, size_t len);
 
-std::shared_ptr<ValueBase> decode(const std::string& data);
+std::unique_ptr<ValueBase> decode(const std::string& data);
 
 // Decode the data whose length is len. After decode is done
 // successfully, return the bencoded string length in end.
-std::shared_ptr<ValueBase> decode(const unsigned char* data, size_t len,
-                               size_t& end);
+std::unique_ptr<ValueBase> decode(const unsigned char* data, size_t len,
+                                  size_t& end);
 
-std::shared_ptr<ValueBase> decodeFromFile(const std::string& filename);
+std::unique_ptr<ValueBase> decodeFromFile(const std::string& filename);
 
 std::string encode(const ValueBase* vlb);
 
-std::string encode(const std::shared_ptr<ValueBase>& vlb);
-
 } // namespace bencode2
 
 } // namespace aria2

+ 20 - 23
src/bittorrent_helper.cc

@@ -406,7 +406,7 @@ void extractNodes(TorrentAttribute* torrent, const ValueBase* nodesListSrc)
 namespace {
 void processRootDictionary
 (const std::shared_ptr<DownloadContext>& ctx,
- const std::shared_ptr<ValueBase>& root,
+ const ValueBase* root,
  const std::shared_ptr<Option>& option,
  const std::string& defaultName,
  const std::string& overrideName,
@@ -422,7 +422,7 @@ void processRootDictionary
     throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_INFO.c_str()),
                        error_code::BITTORRENT_PARSE_ERROR);
   }
-  std::unique_ptr<TorrentAttribute> torrent(new TorrentAttribute());
+  auto torrent = make_unique<TorrentAttribute>();
 
   // retrieve infoHash
   std::string encodedInfoDict = bencode2::encode(infoDict);
@@ -475,7 +475,7 @@ void processRootDictionary
   // This implemantation obeys HTTP-Seeding specification:
   // see http://www.getright.com/seedtorrent.html
   std::vector<std::string> urlList;
-  extractUrlList(torrent.get(), urlList, rootDict->get(C_URL_LIST).get());
+  extractUrlList(torrent.get(), urlList, rootDict->get(C_URL_LIST));
   urlList.insert(urlList.end(), uris.begin(), uris.end());
   std::sort(urlList.begin(), urlList.end());
   urlList.erase(std::unique(urlList.begin(), urlList.end()), urlList.end());
@@ -490,7 +490,7 @@ void processRootDictionary
   // retrieve announce
   extractAnnounce(torrent.get(), rootDict);
   // retrieve nodes
-  extractNodes(torrent.get(), rootDict->get(C_NODES).get());
+  extractNodes(torrent.get(), rootDict->get(C_NODES));
 
   const Integer* creationDate = downcast<Integer>(rootDict->get(C_CREATION_DATE));
   if(creationDate) {
@@ -521,7 +521,7 @@ void load(const std::string& torrentFile,
 {
   ValueBaseBencodeParser parser;
   processRootDictionary(ctx,
-                        parseFile(parser, torrentFile),
+                        parseFile(parser, torrentFile).get(),
                         option,
                         torrentFile,
                         overrideName,
@@ -536,7 +536,7 @@ void load(const std::string& torrentFile,
 {
   ValueBaseBencodeParser parser;
   processRootDictionary(ctx,
-                        parseFile(parser, torrentFile),
+                        parseFile(parser, torrentFile).get(),
                         option,
                         torrentFile,
                         overrideName,
@@ -551,7 +551,7 @@ void loadFromMemory(const unsigned char* content,
                     const std::string& overrideName)
 {
   processRootDictionary(ctx,
-                        bencode2::decode(content, length),
+                        bencode2::decode(content, length).get(),
                         option,
                         defaultName,
                         overrideName,
@@ -567,7 +567,7 @@ void loadFromMemory(const unsigned char* content,
                     const std::string& overrideName)
 {
   processRootDictionary(ctx,
-                        bencode2::decode(content, length),
+                        bencode2::decode(content, length).get(),
                         option,
                         defaultName,
                         overrideName,
@@ -582,7 +582,7 @@ void loadFromMemory(const std::string& context,
 {
   processRootDictionary
     (ctx,
-     bencode2::decode(context),
+     bencode2::decode(context).get(),
      option,
      defaultName, overrideName,
      std::vector<std::string>());
@@ -597,13 +597,13 @@ void loadFromMemory(const std::string& context,
 {
   processRootDictionary
     (ctx,
-     bencode2::decode(context),
+     bencode2::decode(context).get(),
      option,
      defaultName, overrideName,
      uris);
 }
 
-void loadFromMemory(const std::shared_ptr<ValueBase>& torrent,
+void loadFromMemory(const ValueBase* torrent,
                     const std::shared_ptr<DownloadContext>& ctx,
                     const std::shared_ptr<Option>& option,
                     const std::vector<std::string>& uris,
@@ -905,7 +905,7 @@ void assertID
 
 std::unique_ptr<TorrentAttribute> parseMagnet(const std::string& magnet)
 {
-  std::shared_ptr<Dict> r = magnet::parse(magnet);
+  auto r = magnet::parse(magnet);
   if(!r) {
     throw DL_ABORT_EX2("Bad BitTorrent Magnet URI.",
                        error_code::MAGNET_PARSE_ERROR);
@@ -917,8 +917,8 @@ std::unique_ptr<TorrentAttribute> parseMagnet(const std::string& magnet)
   }
   auto attrs = make_unique<TorrentAttribute>();
   std::string infoHash;
-  for(List::ValueType::const_iterator xtiter = xts->begin(),
-        eoi = xts->end(); xtiter != eoi && infoHash.empty(); ++xtiter) {
+  for(auto xtiter = xts->begin(), eoi = xts->end();
+      xtiter != eoi && infoHash.empty(); ++xtiter) {
     const String* xt = downcast<String>(*xtiter);
     if(util::startsWith(xt->s(), "urn:btih:")) {
       size_t size = xt->s().end()-xt->s().begin()-9;
@@ -942,8 +942,7 @@ std::unique_ptr<TorrentAttribute> parseMagnet(const std::string& magnet)
   }
   const List* trs = downcast<List>(r->get("tr"));
   if(trs) {
-    for(List::ValueType::const_iterator i = trs->begin(), eoi = trs->end();
-        i != eoi; ++i) {
+    for(auto i = trs->begin(), eoi = trs->end(); i != eoi; ++i) {
       std::vector<std::string> tier;
       tier.push_back(util::encodeNonUtf8(downcast<String>(*i)->s()));
       attrs->announceList.push_back(tier);
@@ -974,16 +973,14 @@ std::string metadata2Torrent
   std::string torrent = "d";
 
   List announceList;
-  for(std::vector<std::vector<std::string> >::const_iterator tierIter =
-        attrs->announceList.begin(),
+  for(auto tierIter = attrs->announceList.begin(),
         eoi = attrs->announceList.end(); tierIter != eoi; ++tierIter) {
-    std::shared_ptr<List> tier = List::g();
-    for(std::vector<std::string>::const_iterator uriIter = (*tierIter).begin(),
-          eoi2 = (*tierIter).end(); uriIter != eoi2; ++uriIter) {
-      tier->append(String::g(*uriIter));
+    auto tier = List::g();
+    for(auto& uri : *tierIter) {
+      tier->append(uri);
     }
     if(!tier->empty()) {
-      announceList.append(tier);
+      announceList.append(std::move(tier));
     }
   }
   if(!announceList.empty()) {

+ 1 - 8
src/bittorrent_helper.h

@@ -101,7 +101,7 @@ void loadFromMemory(const std::string& context,
                     const std::string& defaultName,
                     const std::string& overrideName = "");
 
-void loadFromMemory(const std::shared_ptr<ValueBase>& torrent,
+void loadFromMemory(const ValueBase* torrent,
                     const std::shared_ptr<DownloadContext>& ctx,
                     const std::shared_ptr<Option>& option,
                     const std::vector<std::string>& uris,
@@ -328,13 +328,6 @@ void extractPeer(const ValueBase* peerData, int family, OutputIterator dest)
   }
 }
 
-template<typename OutputIterator>
-void extractPeer
-(const std::shared_ptr<ValueBase>& peerData, int family, OutputIterator dest)
-{
-  return extractPeer(peerData.get(), family, dest);
-}
-
 int getCompactLength(int family);
 
 // Returns textual representation of the |mode|.

+ 6 - 5
src/download_helper.cc

@@ -185,7 +185,7 @@ std::shared_ptr<RequestGroup>
 createBtRequestGroup(const std::string& metaInfoUri,
                      const std::shared_ptr<Option>& optionTemplate,
                      const std::vector<std::string>& auxUris,
-                     const std::shared_ptr<ValueBase>& torrent,
+                     const ValueBase* torrent,
                      bool adjustAnnounceUri = true)
 {
   auto option = util::copy(optionTemplate);
@@ -264,7 +264,7 @@ void createRequestGroupForBitTorrent
  const std::string& torrentData,
  bool adjustAnnounceUri)
 {
-  std::shared_ptr<ValueBase> torrent;
+  std::unique_ptr<ValueBase> torrent;
   bittorrent::ValueBaseBencodeParser parser;
   if(torrentData.empty()) {
     torrent = parseFile(parser, metaInfoUri);
@@ -277,7 +277,8 @@ void createRequestGroupForBitTorrent
     throw DL_ABORT_EX2("Bencode decoding failed",
                        error_code::BENCODE_PARSE_ERROR);
   }
-  createRequestGroupForBitTorrent(result, option, uris, metaInfoUri, torrent);
+  createRequestGroupForBitTorrent(result, option, uris, metaInfoUri,
+                                  torrent.get());
 }
 
 void createRequestGroupForBitTorrent
@@ -285,7 +286,7 @@ void createRequestGroupForBitTorrent
  const std::shared_ptr<Option>& option,
  const std::vector<std::string>& uris,
  const std::string& metaInfoUri,
- const std::shared_ptr<ValueBase>& torrent,
+ const ValueBase* torrent,
  bool adjustAnnounceUri)
 {
   std::vector<std::string> nargs;
@@ -369,7 +370,7 @@ public:
                              error_code::BENCODE_PARSE_ERROR);
         }
         requestGroups_.push_back
-          (createBtRequestGroup(uri, option_, {}, torrent));
+          (createBtRequestGroup(uri, option_, {}, torrent.get()));
       } catch(RecoverableException& e) {
         if(throwOnError_) {
           throw;

+ 1 - 1
src/download_helper.h

@@ -76,7 +76,7 @@ void createRequestGroupForBitTorrent
  const std::shared_ptr<Option>& option,
  const std::vector<std::string>& uris,
  const std::string& metaInfoUri,
- const std::shared_ptr<ValueBase>& torrent,
+ const ValueBase* torrent,
  bool adjustAnnounceUri = true);
 
 #endif // ENABLE_BITTORRENT

+ 2 - 2
src/json.cc

@@ -85,10 +85,10 @@ std::string jsonEscape(const std::string& s)
 }
 
 // Serializes JSON object or array.
-std::string encode(const std::shared_ptr<ValueBase>& json)
+std::string encode(const ValueBase* json)
 {
   std::ostringstream out;
-  return encode(out, json.get()).str();
+  return encode(out, json).str();
 }
 
 JsonGetParam::JsonGetParam

+ 7 - 14
src/json.h

@@ -47,7 +47,7 @@ std::string jsonEscape(const std::string& s);
 template<typename OutputStream>
 OutputStream& encode(OutputStream& out, const ValueBase* vlb)
 {
-  class JsonValueBaseVisitor:public ValueBaseVisitor {
+  class JsonValueBaseVisitor : public ValueBaseVisitor {
   public:
     JsonValueBaseVisitor(OutputStream& out):out_(out) {}
 
@@ -74,11 +74,11 @@ OutputStream& encode(OutputStream& out, const ValueBase* vlb)
     virtual void visit(const List& list) CXX11_OVERRIDE
     {
       out_ << "[";
-      List::ValueType::const_iterator i = list.begin();
       if(!list.empty()) {
+        auto i = list.begin();
         (*i)->accept(*this);
         ++i;
-        for(List::ValueType::const_iterator eoi = list.end(); i != eoi; ++i){
+        for(auto eoi = list.end(); i != eoi; ++i){
           out_ << ",";
           (*i)->accept(*this);
         }
@@ -89,13 +89,13 @@ OutputStream& encode(OutputStream& out, const ValueBase* vlb)
     virtual void visit(const Dict& dict) CXX11_OVERRIDE
     {
       out_ << "{";
-      Dict::ValueType::const_iterator i = dict.begin();
       if(!dict.empty()) {
+        auto i = dict.begin();
         encodeString((*i).first);
         out_ << ":";
         (*i).second->accept(*this);
         ++i;
-        for(Dict::ValueType::const_iterator eoi = dict.end(); i != eoi; ++i){
+        for(auto eoi = dict.end(); i != eoi; ++i){
           out_ << ",";
           encodeString((*i).first);
           out_ << ":";
@@ -107,8 +107,7 @@ OutputStream& encode(OutputStream& out, const ValueBase* vlb)
   private:
     void encodeString(const std::string& s)
     {
-      std::string t = jsonEscape(s);
-      out_ << "\"" << t << "\"";
+      out_ << "\"" << jsonEscape(s) << "\"";
     }
     OutputStream& out_;
   };
@@ -117,14 +116,8 @@ OutputStream& encode(OutputStream& out, const ValueBase* vlb)
   return out;
 }
 
-template<typename OutputStream>
-OutputStream& encode(OutputStream& out, const std::shared_ptr<ValueBase>& vlb)
-{
-  return encode(out, vlb.get());
-}
-
 // Serializes JSON object or array.
-std::string encode(const std::shared_ptr<ValueBase>& json);
+std::string encode(const ValueBase* json);
 
 struct JsonGetParam {
   std::string request;

+ 5 - 6
src/magnet.cc

@@ -40,13 +40,12 @@ namespace aria2 {
 
 namespace magnet {
 
-std::shared_ptr<Dict> parse(const std::string& magnet)
+std::unique_ptr<Dict> parse(const std::string& magnet)
 {
-  std::shared_ptr<Dict> dict;
   if(!util::startsWith(magnet, "magnet:?")) {
-    return dict;
+    return nullptr;
   }
-  dict.reset(new Dict());
+  auto dict = Dict::g();
   std::vector<Scip> queries;
   util::splitIter(magnet.begin()+8, magnet.end(), std::back_inserter(queries),
                   '&');
@@ -59,9 +58,9 @@ std::shared_ptr<Dict> parse(const std::string& magnet)
     if(l) {
       l->append(String::g(value));
     } else {
-      std::shared_ptr<List> l = List::g();
+      auto l = List::g();
       l->append(String::g(value));
-      dict->put(name, l);
+      dict->put(name, std::move(l));
     }
   }
   return dict;

+ 5 - 6
src/magnet.h

@@ -42,12 +42,11 @@ namespace aria2 {
 
 namespace magnet {
 
-// Parses Magnet URI magnet and stores parameters in
-// std::shared_ptr<Dict>.  Because same parameter name can appear more
-// than once, the value associated with a key is std::shared_ptr<List>. A
-// parameter value is stored in a list. If parsing operation failed,
-// std::shared_ptr<Dict>() is returned.
-std::shared_ptr<Dict> parse(const std::string& magnet);
+// Parses Magnet URI magnet and returns the result.  Because same
+// parameter name can appear more than once, the value associated with
+// a key is std::unique_ptr<List>. A parameter value is stored in a
+// list. If parsing operation failed, nullptr is returned.
+std::unique_ptr<Dict> parse(const std::string& magnet);
 
 } // namespace magnet
 

+ 22 - 22
src/rpc_helper.cc

@@ -56,59 +56,59 @@ RpcRequest xmlParseMemory(const char* xml, size_t size)
   if(xml::XmlParser(&psm).parseFinal(xml, size) < 0) {
     throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
   }
-  std::shared_ptr<List> params;
+  std::unique_ptr<List> params;
   if(downcast<List>(psm.getCurrentFrameValue())) {
-    params = std::static_pointer_cast<List>(psm.getCurrentFrameValue());
+    params.reset(static_cast<List*>(psm.popCurrentFrameValue().release()));
   } else {
     params = List::g();
   }
-  return RpcRequest(psm.getMethodName(), params);
+  return {psm.getMethodName(), std::move(params)};
 }
 #endif // ENABLE_XML_RPC
 
 RpcResponse createJsonRpcErrorResponse(int code,
                                        const std::string& msg,
-                                       const std::shared_ptr<ValueBase>& id)
+                                       std::unique_ptr<ValueBase> id)
 {
-  std::shared_ptr<Dict> params = Dict::g();
+  auto params = Dict::g();
   params->put("code", Integer::g(code));
   params->put("message", msg);
-  rpc::RpcResponse res(code, params, id);
-  return res;
+  return rpc::RpcResponse{code, std::move(params), std::move(id)};
 }
 
-RpcResponse processJsonRpcRequest(const Dict* jsondict, DownloadEngine* e)
+RpcResponse processJsonRpcRequest(Dict* jsondict, DownloadEngine* e)
 {
-  std::shared_ptr<ValueBase> id = jsondict->get("id");
+  auto id = jsondict->popValue("id");
   if(!id) {
     return createJsonRpcErrorResponse(-32600, "Invalid Request.", Null::g());
   }
   const String* methodName = downcast<String>(jsondict->get("method"));
   if(!methodName) {
-    return createJsonRpcErrorResponse(-32600, "Invalid Request.", id);
+    return createJsonRpcErrorResponse(-32600, "Invalid Request.",
+                                      std::move(id));
   }
-  std::shared_ptr<List> params;
-  const std::shared_ptr<ValueBase>& tempParams = jsondict->get("params");
+  std::unique_ptr<List> params;
+  auto tempParams = jsondict->popValue("params");
   if(downcast<List>(tempParams)) {
-    params = std::static_pointer_cast<List>(tempParams);
+    params.reset(static_cast<List*>(tempParams.release()));
   } else if(!tempParams) {
     params = List::g();
   } else {
     // TODO No support for Named params
-    return createJsonRpcErrorResponse(-32602, "Invalid params.", id);
+    return createJsonRpcErrorResponse(-32602, "Invalid params.",
+                                      std::move(id));
   }
-  rpc::RpcRequest req(methodName->s(), params, id);
-  req.jsonRpc = true;
-  std::shared_ptr<rpc::RpcMethod> method;
+  std::shared_ptr<RpcMethod> method;
   try {
-    method = rpc::RpcMethodFactory::create(req.methodName);
+    method = rpc::RpcMethodFactory::create(methodName->s());
   } catch(RecoverableException& e) {
     A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
-    return createJsonRpcErrorResponse(-32601, "Method not found.", id);
+    return createJsonRpcErrorResponse(-32601, "Method not found.",
+                                      std::move(id));
   }
-  A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str()));
-  rpc::RpcResponse res = method->execute(req, e);
-  return res;
+  A2_LOG_INFO(fmt("Executing RPC method %s", methodName->s().c_str()));
+  return method->execute({methodName->s(), std::move(params),
+                          std::move(id), true}, e);
 }
 
 } // namespace rpc

+ 2 - 2
src/rpc_helper.h

@@ -60,10 +60,10 @@ RpcRequest xmlParseMemory(const char* xml, size_t size);
 // |msg| is the error message. The |id| is the id of the request .
 RpcResponse createJsonRpcErrorResponse(int code,
                                        const std::string& msg,
-                                       const std::shared_ptr<ValueBase>& id);
+                                       std::unique_ptr<ValueBase> id);
 
 // Processes JSON-RPC request |jsondict| and returns the result.
-RpcResponse processJsonRpcRequest(const Dict* jsondict, DownloadEngine* e);
+RpcResponse processJsonRpcRequest(Dict* jsondict, DownloadEngine* e);
 
 } // namespace rpc
 

+ 6 - 6
test/Bencode2Test.cc

@@ -23,14 +23,14 @@ void Bencode2Test::testEncode()
 {
   {
     Dict dict;
-    dict["name"] = String::g("aria2");
-    dict["loc"] = Integer::g(80000);
-    std::shared_ptr<List> files = List::g();
+    dict.put("name", String::g("aria2"));
+    dict.put("loc", Integer::g(80000));
+    auto files = List::g();
     files->append(String::g("aria2c"));
-    dict["files"] = files;
-    std::shared_ptr<Dict> attrs = Dict::g();
+    dict.put("files", std::move(files));
+    auto attrs = Dict::g();
     attrs->put("license", String::g("GPL"));
-    dict["attrs"] = attrs;
+    dict.put("attrs", std::move(attrs));
 
     CPPUNIT_ASSERT_EQUAL(std::string("d"
                                      "5:attrsd7:license3:GPLe"

+ 26 - 26
test/BittorrentHelperTest.cc

@@ -412,25 +412,25 @@ void BittorrentHelperTest::testGetFileEntries_singleFileUrlListEndsWithSlash() {
 
 void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
 {
-  std::shared_ptr<List> path = List::g();
+  auto path = List::g();
   path->append("path");
   path->append(fromHex("90a28a")+"E");
-  std::shared_ptr<Dict> file = Dict::g();
+  auto file = Dict::g();
   file->put("length", Integer::g(1024));
-  file->put("path", path);
-  std::shared_ptr<List> files = List::g();
-  files->append(file);
-  std::shared_ptr<Dict> info = Dict::g();
-  info->put("files", files);
+  file->put("path", std::move(path));
+  auto files = List::g();
+  files->append(std::move(file));
+  auto info = Dict::g();
+  info->put("files", std::move(files));
   info->put("piece length", Integer::g(1024));
   info->put("pieces", "01234567890123456789");
   info->put("name", fromHex("1b")+"$B%O%m!<"+fromHex("1b")+"(B");
   Dict dict;
-  dict.put("info", info);
-  std::shared_ptr<DownloadContext> dctx(new DownloadContext());
+  dict.put("info", std::move(info));
+  auto dctx = std::make_shared<DownloadContext>();
   loadFromMemory(bencode2::encode(&dict), dctx, option_, "default");
 
-  const std::shared_ptr<FileEntry>& fe = dctx->getFirstFileEntry();
+  auto& fe = dctx->getFirstFileEntry();
   CPPUNIT_ASSERT_EQUAL
     (std::string("./%1B%24B%25O%25m%21%3C%1B%28B/path/%90%A2%8AE"),
      fe->getPath());
@@ -440,14 +440,14 @@ void BittorrentHelperTest::testLoadFromMemory_multiFileNonUtf8Path()
 
 void BittorrentHelperTest::testLoadFromMemory_singleFileNonUtf8Path()
 {
-  std::shared_ptr<Dict> info = Dict::g();
+  auto info = Dict::g();
   info->put("piece length", Integer::g(1024));
   info->put("pieces", "01234567890123456789");
   info->put("name", fromHex("90a28a")+"E");
   info->put("length", Integer::g(1024));
   Dict dict;
-  dict.put("info", info);
-  std::shared_ptr<DownloadContext> dctx(new DownloadContext());
+  dict.put("info", std::move(info));
+  auto dctx = std::make_shared<DownloadContext>();
   loadFromMemory(bencode2::encode(&dict), dctx, option_, "default");
 
   const std::shared_ptr<FileEntry>& fe = dctx->getFirstFileEntry();
@@ -740,11 +740,11 @@ void BittorrentHelperTest::testCheckBitfield()
 }
 
 void BittorrentHelperTest::testMetadata() {
-  std::shared_ptr<DownloadContext> dctx(new DownloadContext());
+  auto dctx = std::make_shared<DownloadContext>();
   load(A2_TEST_DIR"/test.torrent", dctx, option_);
   std::string torrentData = readFile(A2_TEST_DIR"/test.torrent");
-  std::shared_ptr<ValueBase> tr = bencode2::decode(torrentData);
-  std::shared_ptr<ValueBase> infoDic = downcast<Dict>(tr)->get("info");
+  auto tr = bencode2::decode(torrentData);
+  auto infoDic = downcast<Dict>(tr)->get("info");
   std::string metadata = bencode2::encode(infoDic);
   auto attrs = getTorrentAttrs(dctx);
   CPPUNIT_ASSERT(metadata == attrs->metadata);
@@ -827,9 +827,9 @@ void BittorrentHelperTest::testExtractPeerFromString()
   std::string hextext = "100210354527354678541237324732171ae1";
   hextext += "20010db8bd0501d2288a1fc0000110ee1ae2";
   std::string peersstr = "36:"+fromHex(hextext);
-  std::shared_ptr<ValueBase> str = bencode2::decode(peersstr);
-  std::deque<std::shared_ptr<Peer> > peers;
-  extractPeer(str, AF_INET6, std::back_inserter(peers));
+  auto str = bencode2::decode(peersstr);
+  std::deque<std::shared_ptr<Peer>> peers;
+  extractPeer(str.get(), AF_INET6, std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
   CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"),
                        peers[0]->getIPAddress());
@@ -843,7 +843,7 @@ void BittorrentHelperTest::testExtractPeerFromString()
   peersstr = "12:"+fromHex(hextext);
   str = bencode2::decode(peersstr);
   peers.clear();
-  extractPeer(str, AF_INET, std::back_inserter(peers));
+  extractPeer(str.get(), AF_INET, std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peers[0]->getIPAddress());
   CPPUNIT_ASSERT_EQUAL((uint16_t)6881, peers[0]->getPort());
@@ -857,12 +857,12 @@ void BittorrentHelperTest::testExtractPeerFromList()
     "d5:peersld2:ip11:192.168.0.17:peer id20:aria2-00000000000000"
     "4:porti2006eeee";
 
-  std::shared_ptr<ValueBase> dict = bencode2::decode(peersString);
+  auto dict = bencode2::decode(peersString);
 
-  std::deque<std::shared_ptr<Peer> > peers;
+  std::deque<std::shared_ptr<Peer>> peers;
   extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
-  std::shared_ptr<Peer> peer = *peers.begin();
+  auto& peer = *peers.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
   CPPUNIT_ASSERT_EQUAL((uint16_t)2006, peer->getPort());
 }
@@ -874,12 +874,12 @@ void BittorrentHelperTest::testExtract2PeersFromList()
     "4:porti65535eed2:ip11:192.168.0.27:peer id20:aria2-00000000000000"
     "4:porti2007eeee";
 
-  std::shared_ptr<ValueBase> dict = bencode2::decode(peersString);
+  auto dict = bencode2::decode(peersString);
 
-  std::deque<std::shared_ptr<Peer> > peers;
+  std::deque<std::shared_ptr<Peer>> peers;
   extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
-  std::shared_ptr<Peer> peer = *peers.begin();
+  auto& peer = *peers.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
   CPPUNIT_ASSERT_EQUAL((uint16_t)65535, peer->getPort());
 

+ 1 - 1
test/DHTAnnouncePeerMessageTest.cc

@@ -76,7 +76,7 @@ void DHTAnnouncePeerMessageTest::testGetBencodedMessage()
   aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
   aDict->put("port", Integer::g(port));
   aDict->put("token", token);
-  dict.put("a", aDict);
+  dict.put("a", std::move(aDict));
 
   CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
                        util::percentEncode(msgbody));

+ 2 - 2
test/DHTAnnouncePeerReplyMessageTest.cc

@@ -42,9 +42,9 @@ void DHTAnnouncePeerReplyMessageTest::testGetBencodedMessage()
   dict.put("t", transactionID);
   dict.put("v", "A200");
   dict.put("y", "r");
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto rDict = Dict::g();
   rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
-  dict.put("r", rDict);
+  dict.put("r", std::move(rDict));
 
   CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }

+ 1 - 1
test/DHTFindNodeMessageTest.cc

@@ -74,7 +74,7 @@ void DHTFindNodeMessageTest::testGetBencodedMessage()
   auto 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);
+  dict.put("a", std::move(aDict));
 
   CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }

+ 4 - 4
test/DHTFindNodeReplyMessageTest.cc

@@ -64,10 +64,10 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage()
   dict.put("t", transactionID);
   dict.put("v", "A200");
   dict.put("y", "r");
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto rDict = Dict::g();
   rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
   rDict->put("nodes", compactNodeInfo);
-  dict.put("r", rDict);
+  dict.put("r", std::move(rDict));
 
   CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }
@@ -106,10 +106,10 @@ void DHTFindNodeReplyMessageTest::testGetBencodedMessage6()
   dict.put("t", transactionID);
   dict.put("v", "A200");
   dict.put("y", "r");
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto rDict = Dict::g();
   rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
   rDict->put("nodes6", compactNodeInfo);
-  dict.put("r", rDict);
+  dict.put("r", std::move(rDict));
 
   CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }

+ 1 - 1
test/DHTGetPeersMessageTest.cc

@@ -81,7 +81,7 @@ void DHTGetPeersMessageTest::testGetBencodedMessage()
   auto 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);
+  dict.put("a", std::move(aDict));
 
   CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
                        util::percentEncode(msgbody));

+ 12 - 11
test/DHTGetPeersReplyMessageTest.cc

@@ -49,10 +49,9 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
   dict.put("t", transactionID);
   dict.put("v", "A200");
   dict.put("y", "r");
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto rDict = Dict::g();
   rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
   rDict->put("token", token);
-  dict.put("r", rDict);
   {
     std::string compactNodeInfo;
     std::shared_ptr<DHTNode> nodes[8];
@@ -74,10 +73,11 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
       (std::vector<std::shared_ptr<DHTNode> >(&nodes[0], &nodes[DHTBucket::K]));
     rDict->put("nodes", compactNodeInfo);
 
-    std::vector<std::shared_ptr<Peer> > peers;
-    std::shared_ptr<List> valuesList = List::g();
+    std::vector<std::shared_ptr<Peer>> peers;
+    auto valuesList = List::g();
     for(size_t i = 0; i < 4; ++i) {
-      std::shared_ptr<Peer> peer(new Peer("192.168.0."+util::uitos(i+1), 6881+i));
+      auto peer = std::make_shared<Peer>("192.168.0."+util::uitos(i+1),
+                                         6881+i);
       unsigned char buffer[COMPACT_LEN_IPV6];
       CPPUNIT_ASSERT_EQUAL
         (COMPACT_LEN_IPV4,
@@ -87,7 +87,8 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage()
       peers.push_back(peer);
     }
     msg.setValues(peers);
-    rDict->put("values", valuesList);
+    rDict->put("values", std::move(valuesList));
+    dict.put("r", std::move(rDict));
 
     std::string msgbody = msg.getBencodedMessage();
     CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),
@@ -113,10 +114,9 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage6()
   dict.put("t", transactionID);
   dict.put("v", "A200");
   dict.put("y", "r");
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto rDict = Dict::g();
   rDict->put("id", String::g(localNode->getID(), DHT_ID_LENGTH));
   rDict->put("token", token);
-  dict.put("r", rDict);
   {
     std::string compactNodeInfo;
     std::shared_ptr<DHTNode> nodes[8];
@@ -138,9 +138,9 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage6()
     rDict->put("nodes6", compactNodeInfo);
 
     std::vector<std::shared_ptr<Peer> > peers;
-    std::shared_ptr<List> valuesList = List::g();
+    auto valuesList = List::g();
     for(size_t i = 0; i < 4; ++i) {
-      std::shared_ptr<Peer> peer(new Peer("2001::100"+util::uitos(i+1), 6881+i));
+      auto peer = std::make_shared<Peer>("2001::100"+util::uitos(i+1), 6881+i);
       unsigned char buffer[COMPACT_LEN_IPV6];
       CPPUNIT_ASSERT_EQUAL
         (COMPACT_LEN_IPV6,
@@ -150,7 +150,8 @@ void DHTGetPeersReplyMessageTest::testGetBencodedMessage6()
       peers.push_back(peer);
     }
     msg.setValues(peers);
-    rDict->put("values", valuesList);
+    rDict->put("values", std::move(valuesList));
+    dict.put("r", std::move(rDict));
 
     std::string msgbody = msg.getBencodedMessage();
     CPPUNIT_ASSERT_EQUAL(util::percentEncode(bencode2::encode(&dict)),

+ 14 - 16
test/DHTMessageFactoryImplTest.cc

@@ -98,7 +98,7 @@ void DHTMessageFactoryImplTest::testCreatePingMessage()
   dict.put("q", "ping");
   auto aDict = Dict::g();
   aDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
-  dict.put("a", aDict);
+  dict.put("a", std::move(aDict));
 
   auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6881);
   auto m = dynamic_cast<DHTPingMessage*>(r.get());
@@ -116,7 +116,7 @@ void DHTMessageFactoryImplTest::testCreatePingReplyMessage()
   dict.put("y", "r");
   auto rDict = Dict::g();
   rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
-  dict.put("r", rDict);
+  dict.put("r", std::move(rDict));
 
   auto r = factory->createResponseMessage("ping", &dict,
                                           remoteNode_->getIPAddress(),
@@ -140,7 +140,7 @@ void DHTMessageFactoryImplTest::testCreateFindNodeMessage()
   unsigned char targetNodeID[DHT_ID_LENGTH];
   memset(targetNodeID, 0x11, DHT_ID_LENGTH);
   aDict->put("target", String::g(targetNodeID, DHT_ID_LENGTH));
-  dict.put("a", aDict);
+  dict.put("a", std::move(aDict));
 
   auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6881);
   auto m = dynamic_cast<DHTFindNodeMessage*>(r.get());
@@ -178,7 +178,7 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
         std::string(&buf[0], &buf[COMPACT_LEN_IPV4]);
     }
     rDict->put("nodes", compactNodeInfo);
-    dict.put("r", rDict);
+    dict.put("r", std::move(rDict));
 
     auto r = factory->createResponseMessage("find_node", &dict,
                                             remoteNode_->getIPAddress(),
@@ -225,7 +225,7 @@ void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage6()
         std::string(&buf[0], &buf[COMPACT_LEN_IPV6]);
     }
     rDict->put("nodes6", compactNodeInfo);
-    dict.put("r", rDict);
+    dict.put("r", std::move(rDict));
 
     auto r = factory->createResponseMessage("find_node", &dict,
                                             remoteNode_->getIPAddress(),
@@ -255,7 +255,7 @@ void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
   unsigned char infoHash[DHT_ID_LENGTH];
   memset(infoHash, 0x11, DHT_ID_LENGTH);
   aDict->put("info_hash", String::g(infoHash, DHT_ID_LENGTH));
-  dict.put("a", aDict);
+  dict.put("a", std::move(aDict));
 
   auto r = factory->createQueryMessage(&dict, "192.168.0.1", 6881);
   auto m = dynamic_cast<DHTGetPeersMessage*>(r.get());
@@ -295,7 +295,7 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage()
     rDict->put("nodes", compactNodeInfo);
 
     std::deque<std::shared_ptr<Peer> > peers;
-    std::shared_ptr<List> valuesList = List::g();
+    auto valuesList = List::g();
     for(size_t i = 0; i < 4; ++i) {
       auto peer = std::make_shared<Peer>("192.168.0."+util::uitos(i+1),
                                          6881+i);
@@ -307,10 +307,9 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage()
       valuesList->append(String::g(buffer, COMPACT_LEN_IPV4));
       peers.push_back(peer);
     }
-    rDict->put("values", valuesList);
-
+    rDict->put("values", std::move(valuesList));
     rDict->put("token", "token");
-    dict.put("r", rDict);
+    dict.put("r", std::move(rDict));
 
     auto r = factory->createResponseMessage("get_peers", &dict,
                                             remoteNode_->getIPAddress(),
@@ -377,10 +376,9 @@ void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage6()
       valuesList->append(String::g(buffer, COMPACT_LEN_IPV6));
       peers.push_back(peer);
     }
-    rDict->put("values", valuesList);
-
+    rDict->put("values", std::move(valuesList));
     rDict->put("token", "token");
-    dict.put("r", rDict);
+    dict.put("r", std::move(rDict));
 
     auto r = factory->createResponseMessage("get_peers", &dict,
                                             remoteNode_->getIPAddress(),
@@ -422,7 +420,7 @@ void DHTMessageFactoryImplTest::testCreateAnnouncePeerMessage()
     uint16_t port = 6881;
     aDict->put("port", Integer::g(port));
     aDict->put("token", token);
-    dict.put("a", aDict);
+    dict.put("a", std::move(aDict));
 
     remoteNode_->setPort(6882);
 
@@ -449,7 +447,7 @@ void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
   dict.put("y", "r");
   auto rDict = Dict::g();
   rDict->put("id", String::g(remoteNodeID, DHT_ID_LENGTH));
-  dict.put("r", rDict);
+  dict.put("r", std::move(rDict));
 
   auto r = factory->createResponseMessage("announce_peer", &dict,
                                           remoteNode_->getIPAddress(),
@@ -470,7 +468,7 @@ void DHTMessageFactoryImplTest::testReceivedErrorMessage()
   auto list = List::g();
   list->append(Integer::g(404));
   list->append("Not found");
-  dict.put("e", list);
+  dict.put("e", std::move(list));
 
   try {
     factory->createResponseMessage("announce_peer", &dict,

+ 1 - 1
test/DHTPingMessageTest.cc

@@ -69,7 +69,7 @@ void DHTPingMessageTest::testGetBencodedMessage()
   dict.put("q", "ping");
   auto aDict = Dict::g();
   aDict->put("id", String::g(localNode_->getID(), DHT_ID_LENGTH));
-  dict.put("a", aDict);
+  dict.put("a", std::move(aDict));
 
   CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }

+ 2 - 2
test/DHTPingReplyMessageTest.cc

@@ -45,9 +45,9 @@ void DHTPingReplyMessageTest::testGetBencodedMessage()
   dict.put("t", transactionID);
   dict.put("v", "A200");
   dict.put("y", "r");
-  std::shared_ptr<Dict> rDict = Dict::g();
+  auto rDict = Dict::g();
   rDict->put("id", String::g(id, DHT_ID_LENGTH));
-  dict.put("r", rDict);
+  dict.put("r", std::move(rDict));
 
   CPPUNIT_ASSERT_EQUAL(bencode2::encode(&dict), msgbody);
 }

+ 25 - 26
test/DefaultBtAnnounceTest.cc

@@ -103,10 +103,10 @@ CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtAnnounceTest);
 
 namespace {
 template<typename InputIterator>
-std::shared_ptr<List> createAnnounceTier
+std::unique_ptr<List> createAnnounceTier
 (InputIterator first, InputIterator last)
 {
-  std::shared_ptr<List> announceTier = List::g();
+  auto announceTier = List::g();
   for(; first != last; ++first) {
     announceTier->append(String::g(*first));
   }
@@ -115,9 +115,9 @@ std::shared_ptr<List> createAnnounceTier
 } // namespace
 
 namespace {
-std::shared_ptr<List> createAnnounceTier(const std::string& uri)
+std::unique_ptr<List> createAnnounceTier(const std::string& uri)
 {
-  std::shared_ptr<List> announceTier = List::g();
+  auto announceTier = List::g();
   announceTier->append(String::g(uri));
   return announceTier;
 }
@@ -125,19 +125,19 @@ std::shared_ptr<List> createAnnounceTier(const std::string& uri)
 
 namespace {
 void setAnnounceList(const std::shared_ptr<DownloadContext>& dctx,
-                     const std::shared_ptr<List>& announceList)
+                     const List* announceList)
 {
-  std::vector<std::vector<std::string> > dest;
-  for(List::ValueType::const_iterator tierIter = announceList->begin(),
-        eoi = announceList->end(); tierIter != eoi; ++tierIter) {
+  std::vector<std::vector<std::string>> dest;
+  for(auto tierIter = announceList->begin(), eoi = announceList->end();
+      tierIter != eoi; ++tierIter) {
     std::vector<std::string> ntier;
     const List* tier = downcast<List>(*tierIter);
-    for(List::ValueType::const_iterator uriIter = tier->begin(),
-          eoi2 = tier->end(); uriIter != eoi2; ++uriIter) {
+    for(auto uriIter = tier->begin(), eoi2 = tier->end(); uriIter != eoi2;
+        ++uriIter) {
       const String* uri = downcast<String>(*uriIter);
       ntier.push_back(uri->s());
     }
-    dest.push_back(ntier);
+    dest.push_back(std::move(ntier));
   }
   bittorrent::getTorrentAttrs(dctx)->announceList.swap(dest);
 }
@@ -145,11 +145,11 @@ void setAnnounceList(const std::shared_ptr<DownloadContext>& dctx,
 
 void DefaultBtAnnounceTest::testNoMoreAnnounce()
 {
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier("http://localhost/announce"));
   announceList->append(createAnnounceTier("http://backup/announce"));
 
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
   btAnnounce.setPieceStorage(pieceStorage_);
@@ -195,10 +195,9 @@ void DefaultBtAnnounceTest::testNoMoreAnnounce()
 
 void DefaultBtAnnounceTest::testGetAnnounceUrl()
 {
-
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier("http://localhost/announce"));
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
   btAnnounce.setPieceStorage(pieceStorage_);
@@ -253,9 +252,9 @@ void DefaultBtAnnounceTest::testGetAnnounceUrl()
 
 void DefaultBtAnnounceTest::testGetAnnounceUrl_withQuery()
 {
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier("http://localhost/announce?k=v"));
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
   btAnnounce.setPieceStorage(pieceStorage_);
@@ -276,9 +275,9 @@ void DefaultBtAnnounceTest::testGetAnnounceUrl_withQuery()
 
 void DefaultBtAnnounceTest::testGetAnnounceUrl_externalIP()
 {
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier("http://localhost/announce"));
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   option_->put(PREF_BT_EXTERNAL_IP, "192.168.1.1");
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
@@ -307,10 +306,10 @@ void DefaultBtAnnounceTest::testGetAnnounceUrl_externalIP()
 
 void DefaultBtAnnounceTest::testIsAllAnnounceFailed()
 {
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier("http://localhost/announce"));
   announceList->append(createAnnounceTier("http://backup/announce"));
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
   btAnnounce.setPieceStorage(pieceStorage_);
@@ -341,9 +340,9 @@ void DefaultBtAnnounceTest::testURLOrderInStoppedEvent()
   const char* urls[] = { "http://localhost1/announce",
                          "http://localhost2/announce" };
 
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier(std::begin(urls), std::end(urls)));
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
   btAnnounce.setPieceStorage(pieceStorage_);
@@ -372,9 +371,9 @@ void DefaultBtAnnounceTest::testURLOrderInCompletedEvent()
   const char* urls[] = { "http://localhost1/announce",
                          "http://localhost2/announce" };
 
-  std::shared_ptr<List> announceList = List::g();
+  auto announceList = List::g();
   announceList->append(createAnnounceTier(std::begin(urls), std::end(urls)));
-  setAnnounceList(dctx_, announceList);
+  setAnnounceList(dctx_, announceList.get());
 
   DefaultBtAnnounce btAnnounce(dctx_.get(), option_);
   btAnnounce.setPieceStorage(pieceStorage_);

+ 12 - 12
test/JsonTest.cc

@@ -27,43 +27,43 @@ CPPUNIT_TEST_SUITE_REGISTRATION( JsonTest );
 void JsonTest::testEncode()
 {
   {
-    std::shared_ptr<Dict> dict = Dict::g();
+    auto dict = Dict::g();
     dict->put("name", String::g("aria2"));
     dict->put("loc", Integer::g(80000));
-    std::shared_ptr<List> files = List::g();
+    auto files = List::g();
     files->append(String::g("aria2c"));
-    dict->put("files", files);
-    std::shared_ptr<Dict> attrs = Dict::g();
+    dict->put("files", std::move(files));
+    auto attrs = Dict::g();
     attrs->put("license", String::g("GPL"));
-    dict->put("attrs", attrs);
+    dict->put("attrs", std::move(attrs));
 
     CPPUNIT_ASSERT_EQUAL(std::string("{\"attrs\":{\"license\":\"GPL\"},"
                                      "\"files\":[\"aria2c\"],"
                                      "\"loc\":80000,"
                                      "\"name\":\"aria2\"}"),
-                         json::encode(dict));
+                         json::encode(dict.get()));
   }
   {
-    std::shared_ptr<List> list = List::g();
+    auto list = List::g();
     list->append("\"\\/\b\f\n\r\t");
     CPPUNIT_ASSERT_EQUAL(std::string("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]"),
-                         json::encode(list));
+                         json::encode(list.get()));
   }
   {
-    std::shared_ptr<List> list = List::g();
+    auto list = List::g();
     std::string s;
     s += 0x1Fu;
     list->append(s);
     CPPUNIT_ASSERT_EQUAL(std::string("[\"\\u001F\"]"),
-                         json::encode(list));
+                         json::encode(list.get()));
   }
   {
-    std::shared_ptr<List> list = List::g();
+    auto list = List::g();
     list->append(Bool::gTrue());
     list->append(Bool::gFalse());
     list->append(Null::g());
     CPPUNIT_ASSERT_EQUAL(std::string("[true,false,null]"),
-                         json::encode(list));
+                         json::encode(list.get()));
   }
 }
 

+ 2 - 2
test/MagnetTest.cc

@@ -21,7 +21,7 @@ public:
 CPPUNIT_TEST_SUITE_REGISTRATION(MagnetTest);
 
 namespace {
-const std::string& nthStr(const std::shared_ptr<ValueBase>& v, size_t index)
+const std::string& nthStr(const ValueBase* v, size_t index)
 {
   return downcast<String>(downcast<List>(v)->get(index))->s();
 }
@@ -29,7 +29,7 @@ const std::string& nthStr(const std::shared_ptr<ValueBase>& v, size_t index)
 
 void MagnetTest::testParse()
 {
-  std::shared_ptr<Dict> r = parse
+  auto r = parse
     ("magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c&dn=aria2"
      "&tr=http%3A%2F%2Ftracker1&tr=http://tracker2");
   CPPUNIT_ASSERT_EQUAL

+ 2 - 2
test/MockDHTMessage.h

@@ -80,7 +80,7 @@ public:
   virtual std::string toString() const CXX11_OVERRIDE
   { return "MockDHTMessage"; }
 
-  virtual std::shared_ptr<Dict> getArgument() CXX11_OVERRIDE
+  virtual std::unique_ptr<Dict> getArgument() CXX11_OVERRIDE
   { return Dict::g(); }
 };
 
@@ -115,7 +115,7 @@ public:
   virtual std::string toString() const CXX11_OVERRIDE
   { return "MockDHTMessage"; }
 
-  virtual std::shared_ptr<Dict> getResponse() CXX11_OVERRIDE
+  virtual std::unique_ptr<Dict> getResponse() CXX11_OVERRIDE
   { return Dict::g(); }
 
   virtual void accept(DHTMessageCallback* callback) CXX11_OVERRIDE {}

File diff suppressed because it is too large
+ 285 - 239
test/RpcMethodTest.cc


+ 28 - 29
test/RpcResponseTest.cc

@@ -26,18 +26,17 @@ void RpcResponseTest::testToJson()
 {
   std::vector<RpcResponse> results;
   {
-    std::shared_ptr<List> param = List::g();
+    auto param = List::g();
     param->append(Integer::g(1));
-    std::shared_ptr<String> id = String::g("9");
-    RpcResponse res(0, param, id);
-    results.push_back(res);
-    std::string s = toJson(res, "", false);
+    RpcResponse res(0, std::move(param), String::g("9"));
+    results.push_back(std::move(res));
+    std::string s = toJson(results.back(), "", false);
     CPPUNIT_ASSERT_EQUAL(std::string("{\"id\":\"9\","
                                      "\"jsonrpc\":\"2.0\","
                                      "\"result\":[1]}"),
                          s);
     // with callback
-    s = toJson(res, "cb", false);
+    s = toJson(results.back(), "cb", false);
     CPPUNIT_ASSERT_EQUAL(std::string("cb({\"id\":\"9\","
                                      "\"jsonrpc\":\"2.0\","
                                      "\"result\":[1]})"),
@@ -45,24 +44,24 @@ void RpcResponseTest::testToJson()
   }
   {
     // error response
-    std::shared_ptr<Dict> param = Dict::g();
+    auto param = Dict::g();
     param->put("code", Integer::g(1));
     param->put("message", "HELLO ERROR");
-    RpcResponse res(1, param, Null::g());
-    results.push_back(res);
-    std::string s = toJson(res, "", false);
-    CPPUNIT_ASSERT_EQUAL(std::string("{\"error\":{\"code\":1,"
-                                     "\"message\":\"HELLO ERROR\"},"
-                                     "\"id\":null,"
-                                     "\"jsonrpc\":\"2.0\""
+    RpcResponse res(1, std::move(param), Null::g());
+    results.push_back(std::move(res));
+    std::string s = toJson(results.back(), "", false);
+    CPPUNIT_ASSERT_EQUAL(std::string("{\"id\":null,"
+                                     "\"jsonrpc\":\"2.0\","
+                                     "\"error\":{\"code\":1,"
+                                     "\"message\":\"HELLO ERROR\"}"
                                      "}"),
                          s);
     // with callback
-    s = toJson(res, "cb", false);
-    CPPUNIT_ASSERT_EQUAL(std::string("cb({\"error\":{\"code\":1,"
-                                     "\"message\":\"HELLO ERROR\"},"
-                                     "\"id\":null,"
-                                     "\"jsonrpc\":\"2.0\""
+    s = toJson(results.back(), "cb", false);
+    CPPUNIT_ASSERT_EQUAL(std::string("cb({\"id\":null,"
+                                     "\"jsonrpc\":\"2.0\","
+                                     "\"error\":{\"code\":1,"
+                                     "\"message\":\"HELLO ERROR\"}"
                                      "})"),
                          s);
   }
@@ -73,10 +72,10 @@ void RpcResponseTest::testToJson()
                                      "{\"id\":\"9\","
                                      "\"jsonrpc\":\"2.0\","
                                      "\"result\":[1]},"
-                                     "{\"error\":{\"code\":1,"
-                                     "\"message\":\"HELLO ERROR\"},"
-                                     "\"id\":null,"
-                                     "\"jsonrpc\":\"2.0\""
+                                     "{\"id\":null,"
+                                     "\"jsonrpc\":\"2.0\","
+                                     "\"error\":{\"code\":1,"
+                                     "\"message\":\"HELLO ERROR\"}"
                                      "}"
                                      "]"),
                          s);
@@ -86,10 +85,10 @@ void RpcResponseTest::testToJson()
                                      "{\"id\":\"9\","
                                      "\"jsonrpc\":\"2.0\","
                                      "\"result\":[1]},"
-                                     "{\"error\":{\"code\":1,"
-                                     "\"message\":\"HELLO ERROR\"},"
-                                     "\"id\":null,"
-                                     "\"jsonrpc\":\"2.0\""
+                                     "{\"id\":null,"
+                                     "\"jsonrpc\":\"2.0\","
+                                     "\"error\":{\"code\":1,"
+                                     "\"message\":\"HELLO ERROR\"}"
                                      "}"
                                      "])"),
                          s);
@@ -99,10 +98,10 @@ void RpcResponseTest::testToJson()
 #ifdef ENABLE_XML_RPC
 void RpcResponseTest::testToXml()
 {
-  std::shared_ptr<Dict> param = Dict::g();
+  auto param = Dict::g();
   param->put("faultCode", Integer::g(1));
   param->put("faultString", "No such method: make.hamburger");
-  RpcResponse res(1, param, Null::g());
+  RpcResponse res(1, std::move(param), Null::g());
   std::string s = toXml(res, false);
   CPPUNIT_ASSERT_EQUAL
     (std::string("<?xml version=\"1.0\"?>"

+ 51 - 71
test/ValueBaseJsonParserTest.cc

@@ -30,102 +30,91 @@ void ValueBaseJsonParserTest::testParseUpdate()
   {
     // empty object
     std::string src = "{}";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const Dict* dict = downcast<Dict>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
   }
   {
     // empty object
     std::string src = "{  }";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const Dict* dict = downcast<Dict>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
   }
   {
     // empty array
     std::string src = "[]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
   }
   {
     // empty array
     std::string src = "[ ]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
   }
   {
     // empty string
     std::string src = "[\"\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string(), s->s());
   }
   {
     // string
     std::string src = "[\"foobar\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foobar"), s->s());
   }
   {
     // string with escape
     std::string src = "[\"\\\\foo\\\"\\\"bar\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("\\foo\"\"bar"), s->s());
   }
   {
     // string with escape
     std::string src = "[\"foo\\\"\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foo\""), s->s());
   }
   {
     // string: utf-8 1 to 3 bytes.
     std::string src = "[\"\\u0024\\u00A2\\u20AC\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("$¢€"), s->s());
   }
   {
     // string: utf-8 4 bytes
     std::string src = "[\"\\uD852\\uDF62\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     const unsigned char arr[] = { 0xF0u, 0xA4u, 0xADu, 0xA2u };
     CPPUNIT_ASSERT_EQUAL(std::string(std::begin(arr), std::end(arr)), s->s());
   }
   {
     // null
     std::string src = "[null]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
     const Null* s = downcast<Null>(list->get(0));
     CPPUNIT_ASSERT(s);
@@ -133,9 +122,8 @@ void ValueBaseJsonParserTest::testParseUpdate()
   {
     // true, false
     std::string src = "[true, false]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
     const Bool* trueValue = downcast<Bool>(list->get(0));
     CPPUNIT_ASSERT(trueValue);
@@ -147,38 +135,35 @@ void ValueBaseJsonParserTest::testParseUpdate()
   {
     // object: 1 member
     std::string src = "{\"foo\":[\"bar\"]}";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
     const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
-    const List* list = downcast<List>(dict->get("foo"));
+    auto list = downcast<List>(dict->get("foo"));
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
   }
   {
     // object: 2 members
     // TODO ValueBaseJsonParser does not allow empty dict key
     std::string src = "{\"foo\":[\"bar\"], \"alpha\" : \"bravo\"}";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
     const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
-    const List* list = downcast<List>(dict->get("foo"));
+    auto list = downcast<List>(dict->get("foo"));
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
-    const String* str = downcast<String>(dict->get("alpha"));
+    auto str = downcast<String>(dict->get("alpha"));
     CPPUNIT_ASSERT_EQUAL(std::string("bravo"), str->s());
   }
   {
     // array: 2 values
     std::string src = "[\"foo\", {}]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foo"), s->s());
     const Dict* dict = downcast<Dict>(list->get(1));
     CPPUNIT_ASSERT(dict);
@@ -186,9 +171,8 @@ void ValueBaseJsonParserTest::testParseUpdate()
   {
     // Number: currently we ignore frac and exp
     std::string src = "[0,-1,1.2,-1.2e-10,-1e10]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
     const Integer* i = downcast<Integer>(list->get(0));
     CPPUNIT_ASSERT_EQUAL((Integer::ValueType)0, i->i());
@@ -204,28 +188,25 @@ void ValueBaseJsonParserTest::testParseUpdate()
   {
     // escape chars: ", \, /, \b, \f, \n, \r, \t
     std::string src = "[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
-    const String* s = downcast<String>(list->get(0));
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("\"\\/\b\f\n\r\t"), s->s());
   }
   {
     // string: literal + escaped chars.
     std::string src = "[\"foo\\u0024b\\u00A2\\u20ACbaz\"]";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = downcast<String>(list->get(0));
+    auto s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foo$b¢€baz"), s->s());
   }
   {
     // ignore garbage at the end of the input.
     std::string src = "[]trail";
-    std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                  error);
-    const List* list = downcast<List>(r);
+    auto r = parser.parseFinal(src.c_str(), src.size(), error);
+    auto list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
     CPPUNIT_ASSERT_EQUAL((ssize_t)2, error);
   }
@@ -236,8 +217,7 @@ void checkDecodeError(const std::string& src)
 {
   json::ValueBaseJsonParser parser;
   ssize_t error;
-  std::shared_ptr<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
-                                                error);
+  auto r = parser.parseFinal(src.c_str(), src.size(), error);
   CPPUNIT_ASSERT(!r);
   CPPUNIT_ASSERT(error < 0);
 }

+ 18 - 14
test/ValueBaseTest.cc

@@ -87,8 +87,8 @@ void ValueBaseTest::testDict()
   Dict dict;
   CPPUNIT_ASSERT(dict.empty());
 
-  dict["ki"] = Integer::g(7);
-  dict["ks"] = String::g("abc");
+  dict.put("ki", Integer::g(7));
+  dict.put("ks", String::g("abc"));
 
   CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), dict.size());
   CPPUNIT_ASSERT(dict.containsKey("ki"));
@@ -98,27 +98,31 @@ void ValueBaseTest::testDict()
   CPPUNIT_ASSERT_EQUAL(std::string("abc"),
                        downcast<String>(dict["ks"])->s());
 
-  CPPUNIT_ASSERT(!dict["kn"]); // This adds kn key with default value.
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), dict.size());
-  CPPUNIT_ASSERT(dict.containsKey("kn"));
+  CPPUNIT_ASSERT(!dict["kn"]); // This does not adds kn key
+  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), dict.size());
 
-  const Dict& ref = dict;
+  auto& ref = dict;
   ref["kn2"]; // This doesn't add kn2 key.
-  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), ref.size());
+  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), 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"));
+  dict.removeKey("ks");
+  CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), dict.size());
+  CPPUNIT_ASSERT(!dict.containsKey("ks"));
+
+  auto ki = dict.popValue("ki");
+  CPPUNIT_ASSERT_EQUAL(Integer::ValueType{7}, downcast<Integer>(ki)->i());
+  CPPUNIT_ASSERT(dict.empty());
+  CPPUNIT_ASSERT(!dict.containsKey("ki"));
 }
 
 void ValueBaseTest::testDictIter()
 {
   Dict dict;
-  dict["alpha2"] = String::g("alpha2");
-  dict["charlie"] = String::g("charlie");
-  dict["bravo"] = String::g("bravo");
-  dict["alpha"] = String::g("alpha");
+  dict.put("alpha2", String::g("alpha2"));
+  dict.put("charlie", String::g("charlie"));
+  dict.put("bravo", String::g("bravo"));
+  dict.put("alpha", String::g("alpha"));
 
   Dict::ValueType::iterator i = dict.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("alpha"), (*i++).first);

Some files were not shown because too many files changed in this diff