Browse Source

Removed asString, asList, ... and use downcast<T> instead.

Tatsuhiro Tsujikawa 14 năm trước cách đây
mục cha
commit
05104ba177

+ 11 - 11
src/DHTMessageFactoryImpl.cc

@@ -91,7 +91,7 @@ DHTMessageFactoryImpl::getRemoteNode
 namespace {
 const Dict* getDictionary(const Dict* dict, const std::string& key)
 {
-  const Dict* d = asDict(dict->get(key));
+  const Dict* d = downcast<Dict>(dict->get(key));
   if(d) {
     return d;
   } else {
@@ -104,7 +104,7 @@ const Dict* getDictionary(const Dict* dict, const std::string& key)
 namespace {
 const String* getString(const Dict* dict, const std::string& key)
 {
-  const String* c = asString(dict->get(key));
+  const String* c = downcast<String>(dict->get(key));
   if(c) {
     return c;
   } else {
@@ -117,7 +117,7 @@ const String* getString(const Dict* dict, const std::string& key)
 namespace {
 const Integer* getInteger(const Dict* dict, const std::string& key)
 {
-  const Integer* c = asInteger(dict->get(key));
+  const Integer* c = downcast<Integer>(dict->get(key));
   if(c) {
     return c;
   } else {
@@ -130,7 +130,7 @@ const Integer* getInteger(const Dict* dict, const std::string& key)
 namespace {
 const String* getString(const List* list, size_t index)
 {
-  const String* c = asString(list->get(index));
+  const String* c = downcast<String>(list->get(index));
   if(c) {
     return c;
   } else {
@@ -144,7 +144,7 @@ const String* getString(const List* list, size_t index)
 namespace {
 const Integer* getInteger(const List* list, size_t index)
 {
-  const Integer* c = asInteger(list->get(index));
+  const Integer* c = downcast<Integer>(list->get(index));
   if(c) {
     return c;
   } else {
@@ -158,7 +158,7 @@ const Integer* getInteger(const List* list, size_t index)
 namespace {
 const List* getList(const Dict* dict, const std::string& key)
 {
-  const List* l = asList(dict->get(key));
+  const List* l = downcast<List>(dict->get(key));
   if(l) {
     return l;
   } else {
@@ -191,7 +191,7 @@ void DHTMessageFactoryImpl::validatePort(const Integer* port) const
 namespace {
 void setVersion(const SharedHandle<DHTMessage>& msg, const Dict* dict)
 {
-  const String* v = asString(dict->get(DHTMessage::V));
+  const String* v = downcast<String>(dict->get(DHTMessage::V));
   if(v) {
     msg->setVersion(v->s());
   } else {
@@ -389,7 +389,7 @@ DHTMessageFactoryImpl::createFindNodeReplyMessage
  const std::string& transactionID)
 {
   const String* nodesData =
-    asString(getDictionary(dict, DHTResponseMessage::R)->
+    downcast<String>(getDictionary(dict, DHTResponseMessage::R)->
              get(family_ == AF_INET?DHTFindNodeReplyMessage::NODES:
                  DHTFindNodeReplyMessage::NODES6));
   std::vector<SharedHandle<DHTNode> > nodes;
@@ -421,20 +421,20 @@ DHTMessageFactoryImpl::createGetPeersReplyMessage
 {
   const Dict* rDict = getDictionary(dict, DHTResponseMessage::R);
   const String* nodesData =
-    asString(rDict->get(family_ == AF_INET?DHTGetPeersReplyMessage::NODES:
+    downcast<String>(rDict->get(family_ == AF_INET?DHTGetPeersReplyMessage::NODES:
                         DHTGetPeersReplyMessage::NODES6));
   std::vector<SharedHandle<DHTNode> > nodes;
   if(nodesData) {
     extractNodes(nodes, nodesData->uc(), nodesData->s().size());
   }
   const List* valuesList =
-    asList(rDict->get(DHTGetPeersReplyMessage::VALUES));
+    downcast<List>(rDict->get(DHTGetPeersReplyMessage::VALUES));
   std::vector<SharedHandle<Peer> > peers;
   size_t clen = bittorrent::getCompactLength(family_);
   if(valuesList) {
     for(List::ValueType::const_iterator i = valuesList->begin(),
           eoi = valuesList->end(); i != eoi; ++i) {
-      const String* data = asString(*i);
+      const String* data = downcast<String>(*i);
       if(data && data->s().size() == clen) {
         std::pair<std::string, uint16_t> addr =
           bittorrent::unpackcompact(data->uc(), family_);

+ 2 - 2
src/DHTMessageReceiver.cc

@@ -77,9 +77,9 @@ SharedHandle<DHTMessage> DHTMessageReceiver::receiveMessage()
     }
     bool isReply = false;
     SharedHandle<ValueBase> decoded = bencode2::decode(data, length);
-    const Dict* dict = asDict(decoded);
+    const Dict* dict = downcast<Dict>(decoded);
     if(dict) {
-      const String* y = asString(dict->get(DHTMessage::Y));
+      const String* y = downcast<String>(dict->get(DHTMessage::Y));
       if(y) {
         if(y->s() == DHTResponseMessage::R || y->s() == DHTUnknownMessage::E) {
           isReply = true;

+ 1 - 1
src/DHTMessageTracker.cc

@@ -65,7 +65,7 @@ std::pair<SharedHandle<DHTResponseMessage>, SharedHandle<DHTMessageCallback> >
 DHTMessageTracker::messageArrived
 (const Dict* dict, const std::string& ipaddr, uint16_t port)
 {
-  const String* tid = asString(dict->get(DHTMessage::T));
+  const String* tid = downcast<String>(dict->get(DHTMessage::T));
   if(!tid) {
     throw DL_ABORT_EX(fmt("Malformed DHT message. From:%s:%u",
                           ipaddr.c_str(), port));

+ 8 - 8
src/DefaultBtAnnounce.cc

@@ -221,30 +221,30 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
   A2_LOG_DEBUG("Now processing tracker response.");
   SharedHandle<ValueBase> decodedValue =
     bencode2::decode(trackerResponse, trackerResponseLength);
-  const Dict* dict = asDict(decodedValue);
+  const Dict* dict = downcast<Dict>(decodedValue);
   if(!dict) {
     throw DL_ABORT_EX(MSG_NULL_TRACKER_RESPONSE);
   }
-  const String* failure = asString(dict->get(BtAnnounce::FAILURE_REASON));
+  const String* failure = downcast<String>(dict->get(BtAnnounce::FAILURE_REASON));
   if(failure) {
     throw DL_ABORT_EX
       (fmt(EX_TRACKER_FAILURE, failure->s().c_str()));
   }
-  const String* warn = asString(dict->get(BtAnnounce::WARNING_MESSAGE));
+  const String* warn = downcast<String>(dict->get(BtAnnounce::WARNING_MESSAGE));
   if(warn) {
     A2_LOG_WARN(fmt(MSG_TRACKER_WARNING_MESSAGE, warn->s().c_str()));
   }
-  const String* tid = asString(dict->get(BtAnnounce::TRACKER_ID));
+  const String* tid = downcast<String>(dict->get(BtAnnounce::TRACKER_ID));
   if(tid) {
     trackerId_ = tid->s();
     A2_LOG_DEBUG(fmt("Tracker ID:%s", trackerId_.c_str()));
   }
-  const Integer* ival = asInteger(dict->get(BtAnnounce::INTERVAL));
+  const Integer* ival = downcast<Integer>(dict->get(BtAnnounce::INTERVAL));
   if(ival && ival->i() > 0) {
     interval_ = ival->i();
     A2_LOG_DEBUG(fmt("Interval:%ld", static_cast<long int>(interval_)));
   }
-  const Integer* mival = asInteger(dict->get(BtAnnounce::MIN_INTERVAL));
+  const Integer* mival = downcast<Integer>(dict->get(BtAnnounce::MIN_INTERVAL));
   if(mival && mival->i() > 0) {
     minInterval_ = mival->i();
     A2_LOG_DEBUG(fmt("Min interval:%ld", static_cast<long int>(minInterval_)));
@@ -253,12 +253,12 @@ DefaultBtAnnounce::processAnnounceResponse(const unsigned char* trackerResponse,
     // Use interval as a minInterval if minInterval is not supplied.
     minInterval_ = interval_;
   }
-  const Integer* comp = asInteger(dict->get(BtAnnounce::COMPLETE));
+  const Integer* comp = downcast<Integer>(dict->get(BtAnnounce::COMPLETE));
   if(comp) {
     complete_ = comp->i();
     A2_LOG_DEBUG(fmt("Complete:%d", complete_));
   }
-  const Integer* incomp = asInteger(dict->get(BtAnnounce::INCOMPLETE));
+  const Integer* incomp = downcast<Integer>(dict->get(BtAnnounce::INCOMPLETE));
   if(incomp) {
     incomplete_ = incomp->i();
     A2_LOG_DEBUG(fmt("Incomplete:%d", incomplete_));

+ 4 - 4
src/DefaultExtensionMessageFactory.cc

@@ -102,15 +102,15 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
       }
       size_t end;
       SharedHandle<ValueBase> decoded = bencode2::decode(data+1, length-1, end);
-      const Dict* dict = asDict(decoded);
+      const Dict* dict = downcast<Dict>(decoded);
       if(!dict) {
         throw DL_ABORT_EX("Bad ut_metadata: dictionary not found");
       }
-      const Integer* msgType = asInteger(dict->get("msg_type"));
+      const Integer* msgType = downcast<Integer>(dict->get("msg_type"));
       if(!msgType) {
         throw DL_ABORT_EX("Bad ut_metadata: msg_type not found");
       }
-      const Integer* index = asInteger(dict->get("piece"));
+      const Integer* index = downcast<Integer>(dict->get("piece"));
       if(!index) {
         throw DL_ABORT_EX("Bad ut_metadata: piece not found");
       }
@@ -129,7 +129,7 @@ DefaultExtensionMessageFactory::createMessage(const unsigned char* data, size_t
         if(end == length) {
           throw DL_ABORT_EX("Bad ut_metadata data: data not found");
         }
-        const Integer* totalSize = asInteger(dict->get("total_size"));
+        const Integer* totalSize = downcast<Integer>(dict->get("total_size"));
         if(!totalSize) {
           throw DL_ABORT_EX("Bad ut_metadata data: total_size not found");
         }

+ 1 - 1
src/ExpatXmlRpcRequestProcessor.cc

@@ -122,7 +122,7 @@ XmlRpcRequestProcessor::parseMemory(const std::string& xml)
   if(r == XML_STATUS_ERROR) {
     throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
   }
-  if(!asList(stm_->getCurrentFrameValue())) {
+  if(!downcast<List>(stm_->getCurrentFrameValue())) {
     throw DL_ABORT_EX("Bad XML-RPC parameter list");
   }
   return RpcRequest(stm_->getMethodName(),

+ 6 - 6
src/HandshakeExtensionMessage.cc

@@ -174,30 +174,30 @@ HandshakeExtensionMessage::create(const unsigned char* data, size_t length)
   A2_LOG_DEBUG(fmt("Creating HandshakeExtensionMessage from %s",
                    util::percentEncode(data, length).c_str()));
   SharedHandle<ValueBase> decoded = bencode2::decode(data+1, length-1);
-  const Dict* dict = asDict(decoded);
+  const Dict* dict = downcast<Dict>(decoded);
   if(!dict) {
     throw DL_ABORT_EX
       ("Unexpected payload format for extended message handshake");
   }
-  const Integer* port = asInteger(dict->get("p"));
+  const Integer* port = downcast<Integer>(dict->get("p"));
   if(port && 0 < port->i() && port->i() < 65536) {
     msg->tcpPort_ = port->i();
   }
-  const String* version = asString(dict->get("v"));
+  const String* version = downcast<String>(dict->get("v"));
   if(version) {
     msg->clientVersion_ = version->s();
   }
-  const Dict* extDict = asDict(dict->get("m"));
+  const Dict* extDict = downcast<Dict>(dict->get("m"));
   if(extDict) {
     for(Dict::ValueType::const_iterator i = extDict->begin(),
           eoi = extDict->end(); i != eoi; ++i) {
-      const Integer* extId = asInteger((*i).second);
+      const Integer* extId = downcast<Integer>((*i).second);
       if(extId) {
         msg->extensions_[(*i).first] = extId->i();
       }
     }
   }
-  const Integer* metadataSize = asInteger(dict->get("metadata_size"));
+  const Integer* metadataSize = downcast<Integer>(dict->get("metadata_size"));
   // Only accept metadata smaller than 1MiB
   if(metadataSize && metadataSize->i() <= 1024*1024) {
     msg->metadataSize_ = metadataSize->i();

+ 5 - 5
src/HttpServerBodyCommand.cc

@@ -164,13 +164,13 @@ HttpServerBodyCommand::processJsonRpcRequest(const Dict* jsondict)
   if(!id) {
     return createJsonRpcErrorResponse(-32600, "Invalid Request.", Null::g());
   }
-  const String* methodName = asString(jsondict->get("method"));
+  const String* methodName = downcast<String>(jsondict->get("method"));
   if(!methodName) {
     return createJsonRpcErrorResponse(-32600, "Invalid Request.", id);
   }
   SharedHandle<List> params;
   const SharedHandle<ValueBase>& tempParams = jsondict->get("params");
-  if(asList(tempParams)) {
+  if(downcast<List>(tempParams)) {
     params = static_pointer_cast<List>(tempParams);
   } else if(!tempParams) {
     params = List::g();
@@ -246,18 +246,18 @@ bool HttpServerBodyCommand::execute()
             sendJsonRpcResponse(res, callback);
             return true;
           }
-          const Dict* jsondict = asDict(json);
+          const Dict* jsondict = downcast<Dict>(json);
           if(jsondict) {
             rpc::RpcResponse res = processJsonRpcRequest(jsondict);
             sendJsonRpcResponse(res, callback);
           } else {
-            const List* jsonlist = asList(json);
+            const 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 = asDict(*i);
+                const Dict* jsondict = downcast<Dict>(*i);
                 if(jsondict) {
                   rpc::RpcResponse r = processJsonRpcRequest(jsondict);
                   results.push_back(r);

+ 3 - 3
src/RpcMethod.cc

@@ -100,17 +100,17 @@ void gatherOption
           (fmt("We don't know how to deal with %s option",
                optionName.c_str()));
       }
-      const String* opval = asString((*first).second);
+      const String* opval = downcast<String>((*first).second);
       if(opval) {
         optionHandler->parse(*option.get(), opval->s());
       } else {
         // header and index-out option can take array as value
-        const List* oplist = asList((*first).second);
+        const List* oplist = downcast<List>((*first).second);
         if(oplist &&
            (optionName == PREF_HEADER || optionName == PREF_INDEX_OUT)) {
           for(List::ValueType::const_iterator argiter = oplist->begin(),
                 eoi = oplist->end(); argiter != eoi; ++argiter) {
-            const String* opval = asString(*argiter);
+            const String* opval = downcast<String>(*argiter);
             if(opval) {
               optionHandler->parse(*option.get(), opval->s());
             }

+ 7 - 7
src/RpcMethodImpl.cc

@@ -207,7 +207,7 @@ void extractUris(OutputIterator out, const List* src)
   if(src) {
     for(List::ValueType::const_iterator i = src->begin(), eoi = src->end();
         i != eoi; ++i) {
-      const String* uri = asString(*i);
+      const String* uri = downcast<String>(*i);
       if(uri) {
         out++ = uri->s();
       }
@@ -1355,7 +1355,7 @@ SharedHandle<ValueBase> ChangeUriRpcMethod::process
   size_t delcount = 0;
   for(List::ValueType::const_iterator i = delUrisParam->begin(),
         eoi = delUrisParam->end(); i != eoi; ++i) {
-    const String* uri = asString(*i);
+    const String* uri = downcast<String>(*i);
     if(uri && s->removeUri(uri->s())) {
       ++delcount;
     }
@@ -1364,7 +1364,7 @@ SharedHandle<ValueBase> ChangeUriRpcMethod::process
   if(posGiven) {
     for(List::ValueType::const_iterator i = addUrisParam->begin(),
           eoi = addUrisParam->end(); i != eoi; ++i) {
-      const String* uri = asString(*i);
+      const String* uri = downcast<String>(*i);
       if(uri && s->insertUri(uri->s(), pos)) {
         ++addcount;
         ++pos;
@@ -1373,7 +1373,7 @@ SharedHandle<ValueBase> ChangeUriRpcMethod::process
   } else {
     for(List::ValueType::const_iterator i = addUrisParam->begin(),
           eoi = addUrisParam->end(); i != eoi; ++i) {
-      const String* uri = asString(*i);
+      const String* uri = downcast<String>(*i);
       if(uri && s->addUri(uri->s())) {
         ++addcount;
       }
@@ -1436,13 +1436,13 @@ SharedHandle<ValueBase> SystemMulticallRpcMethod::process
   SharedHandle<List> list = List::g();
   for(List::ValueType::const_iterator i = methodSpecs->begin(),
         eoi = methodSpecs->end(); i != eoi; ++i) {
-    const Dict* methodDict = asDict(*i);
+    const Dict* methodDict = downcast<Dict>(*i);
     if(!methodDict) {
       list->append(createErrorResponse
                    (DL_ABORT_EX("system.multicall expected struct."), req));
       continue;
     }
-    const String* methodName = asString(methodDict->get(KEY_METHOD_NAME));
+    const String* methodName = downcast<String>(methodDict->get(KEY_METHOD_NAME));
     if(!methodName) {
       list->append(createErrorResponse
                    (DL_ABORT_EX("Missing methodName."), req));
@@ -1455,7 +1455,7 @@ SharedHandle<ValueBase> SystemMulticallRpcMethod::process
     }
     const SharedHandle<ValueBase>& tempParamsList = methodDict->get(KEY_PARAMS);
     SharedHandle<List> paramsList;
-    if(asList(tempParamsList)) {
+    if(downcast<List>(tempParamsList)) {
       paramsList = static_pointer_cast<List>(tempParamsList);
     } else {
       paramsList = List::g();

+ 1 - 1
src/RpcMethodImpl.h

@@ -84,7 +84,7 @@ void toStringList(OutputIterator out, const List* src)
   }
   for(List::ValueType::const_iterator i = src->begin(), eoi = src->end();
       i != eoi; ++i) {
-    const String* s = asString(*i);
+    const String* s = downcast<String>(*i);
     if(s) {
       *out++ = s->s();
     }

+ 5 - 5
src/UTPexExtensionMessage.cc

@@ -191,24 +191,24 @@ UTPexExtensionMessage::create(const unsigned char* data, size_t len)
   UTPexExtensionMessageHandle msg(new UTPexExtensionMessage(*data));
 
   SharedHandle<ValueBase> decoded = bencode2::decode(data+1, len-1);
-  const Dict* dict = asDict(decoded);
+  const Dict* dict = downcast<Dict>(decoded);
   if(dict) {
-    const String* added = asString(dict->get("added"));
+    const String* added = downcast<String>(dict->get("added"));
     if(added) {
       bittorrent::extractPeer
         (added, AF_INET,  std::back_inserter(msg->freshPeers_));
     }
-    const String* dropped = asString(dict->get("dropped"));
+    const String* dropped = downcast<String>(dict->get("dropped"));
     if(dropped) {
       bittorrent::extractPeer
         (dropped, AF_INET, std::back_inserter(msg->droppedPeers_));
     }
-    const String* added6 = asString(dict->get("added6"));
+    const String* added6 = downcast<String>(dict->get("added6"));
     if(added6) {
       bittorrent::extractPeer
         (added6, AF_INET6, std::back_inserter(msg->freshPeers_));
     }
-    const String* dropped6 = asString(dict->get("dropped6"));
+    const String* dropped6 = downcast<String>(dict->get("dropped6"));
     if(dropped6) {
       bittorrent::extractPeer
         (dropped6, AF_INET6, std::back_inserter(msg->droppedPeers_));

+ 11 - 145
src/ValueBase.cc

@@ -239,9 +239,19 @@ const SharedHandle<ValueBase>& Dict::get(const std::string& key) const
   }
 }
 
+SharedHandle<ValueBase>& Dict::get(const std::string& key)
+{
+  ValueType::iterator itr = dict_.find(key);
+  if(itr == dict_.end()) {
+    return dict_[key];
+  } else {
+    return (*itr).second;
+  }
+}
+
 SharedHandle<ValueBase>& Dict::operator[](const std::string& key)
 {
-  return dict_[key];
+  return get(key);
 }
 
 const SharedHandle<ValueBase>& Dict::operator[](const std::string& key) const
@@ -298,148 +308,4 @@ void Dict::accept(ValueBaseVisitor& v) const
   v.visit(*this);
 }
 
-const String* asString(const ValueBase* v)
-{
-  if(v) {
-    return downcast<String>(v);
-  } else {
-    return 0;
-  }
-}
-
-String* asString(ValueBase* v)
-{
-  if(v) {
-    return const_cast<String*>(downcast<String>(v));
-  } else {
-    return 0;
-  }
-}
-
-String* asString(const SharedHandle<ValueBase>& v)
-{
-  if(v.get()) {
-    return const_cast<String*>(downcast<String>(v));
-  } else {
-    return 0;
-  }
-}
-
-const Integer* asInteger(const ValueBase* v)
-{
-  if(v) {
-    return downcast<Integer>(v);
-  } else {
-    return 0;
-  }
-}
-
-Integer* asInteger(ValueBase* v)
-{
-  if(v) {
-    return const_cast<Integer*>(downcast<Integer>(v));
-  } else {
-    return 0;
-  }
-}
-
-Integer* asInteger(const SharedHandle<ValueBase>& v)
-{
-  if(v.get()) {
-    return const_cast<Integer*>(downcast<Integer>(v));
-  } else {
-    return 0;
-  }
-}
-
-const Bool* asBool(const ValueBase* v)
-{
-  if(v) {
-    return downcast<Bool>(v);
-  } else {
-    return 0;
-  }
-}
-
-Bool* asBool(const SharedHandle<ValueBase>& v)
-{
-  if(v.get()) {
-    return const_cast<Bool*>(downcast<Bool>(v));
-  } else {
-    return 0;
-  }
-}
-
-const Null* asNull(const ValueBase* v)
-{
-  if(v) {
-    return downcast<Null>(v);
-  } else {
-    return 0;
-  }
-}
-
-Null* asNull(const SharedHandle<ValueBase>& v)
-{
-  if(v) {
-    return const_cast<Null*>(downcast<Null>(v));
-  } else {
-    return 0;
-  }
-}
-
-const List* asList(const ValueBase* v)
-{
-  if(v) {
-    return downcast<List>(v);
-  } else {
-    return 0;
-  }
-}
-
-List* asList(ValueBase* v)
-{
-  if(v) {
-    return const_cast<List*>(downcast<List>(v));
-  } else {
-    return 0;
-  }
-}
-
-List* asList(const SharedHandle<ValueBase>& v)
-{
-  if(v.get()) {
-    return const_cast<List*>(downcast<List>(v));
-  } else {
-    return 0;
-  }
-}
-
-const Dict* asDict(const ValueBase* v)
-{
-  if(v) {
-    return downcast<Dict>(v);
-  } else {
-    return 0;
-  }
-}
-
-Dict* asDict(ValueBase* v)
-{
-  if(v) {
-    return const_cast<Dict*>(downcast<Dict>(v));
-  } else {
-    return 0;
-  }
-}
-
-Dict* asDict(const SharedHandle<ValueBase>& v)
-{
-  if(v.get()) {
-    return const_cast<Dict*>(downcast<Dict>(v));
-  } else {
-    return 0;
-  }
-}
-
 } // namespace aria2

+ 20 - 34
src/ValueBase.h

@@ -239,6 +239,8 @@ public:
 
   const SharedHandle<ValueBase>& get(const std::string& key) const;
 
+  SharedHandle<ValueBase>& get(const std::string& key);
+
   // 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
@@ -321,42 +323,26 @@ private:
 template<typename T, typename VPtr>
 const T* downcast(const VPtr& v)
 {
-  DowncastValueBaseVisitor<T> visitor;
-  v->accept(visitor);
-  return visitor.getResult();
+  if(v) {
+    DowncastValueBaseVisitor<T> visitor;
+    v->accept(visitor);
+    return visitor.getResult();
+  } else {
+    return 0;
+  }
 }
 
-const String* asString(const ValueBase* v);
-
-String* asString(ValueBase* v);
-
-String* asString(const SharedHandle<ValueBase>& v);
-
-const Integer* asInteger(const ValueBase* v);
-
-Integer* asInteger(ValueBase* v);
-
-Integer* asInteger(const SharedHandle<ValueBase>& v);
-
-const Bool* asBool(const ValueBase* v);
-
-Bool* asBool(const SharedHandle<ValueBase>& v);
-
-const Null* asNull(const ValueBase* v);
-
-Null* asNull(const SharedHandle<ValueBase>& v);
-
-const List* asList(const ValueBase* v);
-
-List* asList(ValueBase* v);
-
-List* asList(const SharedHandle<ValueBase>& v);
-
-const Dict* asDict(const ValueBase* v);
-
-Dict* asDict(ValueBase* v);
-
-Dict* asDict(const SharedHandle<ValueBase>& v);
+template<typename T, typename VPtr>
+T* downcast(VPtr& v)
+{
+  if(v) {
+    DowncastValueBaseVisitor<T> visitor;
+    v->accept(visitor);
+    return const_cast<T*>(visitor.getResult());
+  } else {
+    return 0;
+  }
+}
 
 } // namespace aria2
 

+ 1 - 1
src/Xml2XmlRpcRequestProcessor.cc

@@ -159,7 +159,7 @@ XmlRpcRequestProcessor::parseMemory(const std::string& xml)
   if(r != 0) {
     throw DL_ABORT_EX(MSG_CANNOT_PARSE_XML_RPC_REQUEST);
   }
-  if(!asList(stm_->getCurrentFrameValue())) {
+  if(!downcast<List>(stm_->getCurrentFrameValue())) {
     throw DL_ABORT_EX("Bad XML-RPC parameter list");
   }
   return RpcRequest(stm_->getMethodName(),

+ 2 - 2
src/XmlRpcRequestParserController.cc

@@ -51,7 +51,7 @@ void XmlRpcRequestParserController::popStructFrame()
   assert(!frameStack_.empty());
 
   StateFrame parentFrame = frameStack_.top();
-  Dict* dict = asDict(parentFrame.value_);
+  Dict* dict = downcast<Dict>(parentFrame.value_);
   assert(dict);
   frameStack_.pop();
   if(currentFrame_.validMember()) {
@@ -65,7 +65,7 @@ void XmlRpcRequestParserController::popArrayFrame()
   assert(!frameStack_.empty());
 
   StateFrame parentFrame = frameStack_.top();
-  List* list = asList(parentFrame.value_);
+  List* list = downcast<List>(parentFrame.value_);
   assert(list);
   frameStack_.pop();
   if(currentFrame_.value_) {

+ 31 - 31
src/bittorrent_helper.cc

@@ -156,7 +156,7 @@ void extractUrlList
     {
       for(List::ValueType::const_iterator itr = v.begin(), eoi = v.end();
           itr != eoi; ++itr) {
-        const String* uri = asString(*itr);
+        const String* uri = downcast<String>(*itr);
         if(uri) {
           std::string utf8Uri = util::encodeNonUtf8(uri->s());
           uris_.push_back(utf8Uri);
@@ -209,7 +209,7 @@ void extractFileEntries
     } else {
       nameKey = C_NAME;
     }
-    const String* nameData = asString(infoDict->get(nameKey));
+    const String* nameData = downcast<String>(infoDict->get(nameKey));
     if(nameData) {
       utf8Name = util::encodeNonUtf8(nameData->s());
       if(util::detectDirTraversal(utf8Name)) {
@@ -226,7 +226,7 @@ void extractFileEntries
   }
   torrent->name = utf8Name;
   std::vector<SharedHandle<FileEntry> > fileEntries;
-  const List* filesList = asList(infoDict->get(C_FILES));
+  const List* filesList = downcast<List>(infoDict->get(C_FILES));
   if(filesList) {
     fileEntries.reserve(filesList->size());
     uint64_t length = 0;
@@ -235,11 +235,11 @@ void extractFileEntries
     torrent->mode = MULTI;
     for(List::ValueType::const_iterator itr = filesList->begin(),
           eoi = filesList->end(); itr != eoi; ++itr) {
-      const Dict* fileDict = asDict(*itr);
+      const Dict* fileDict = downcast<Dict>(*itr);
       if(!fileDict) {
         continue;
       }
-      const Integer* fileLengthData = asInteger(fileDict->get(C_LENGTH));
+      const Integer* fileLengthData = downcast<Integer>(fileDict->get(C_LENGTH));
       if(!fileLengthData) {
         throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str()),
                            error_code::BITTORRENT_PARSE_ERROR);
@@ -252,7 +252,7 @@ void extractFileEntries
       } else {
         pathKey = C_PATH;
       }
-      const List* pathList = asList(fileDict->get(pathKey));
+      const List* pathList = downcast<List>(fileDict->get(pathKey));
       if(!pathList || pathList->empty()) {
         throw DL_ABORT_EX2("Path is empty.",
                            error_code::BITTORRENT_PARSE_ERROR);
@@ -264,7 +264,7 @@ void extractFileEntries
       ++pathelemOutItr;
       for(List::ValueType::const_iterator itr = pathList->begin(),
             eoi = pathList->end(); itr != eoi; ++itr) {
-        const String* elem = asString(*itr);
+        const String* elem = downcast<String>(*itr);
         if(elem) {
           (*pathelemOutItr++) = elem->s();
         } else {
@@ -295,7 +295,7 @@ void extractFileEntries
   } else {
     // single-file mode;
     torrent->mode = SINGLE;
-    const Integer* lengthData = asInteger(infoDict->get(C_LENGTH));
+    const Integer* lengthData = downcast<Integer>(infoDict->get(C_LENGTH));
     if(!lengthData) {
       throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_LENGTH.c_str()),
                          error_code::BITTORRENT_PARSE_ERROR);
@@ -332,18 +332,18 @@ namespace {
 void extractAnnounce
 (const SharedHandle<TorrentAttribute>& torrent, const Dict* rootDict)
 {
-  const List* announceList = asList(rootDict->get(C_ANNOUNCE_LIST));
+  const List* announceList = downcast<List>(rootDict->get(C_ANNOUNCE_LIST));
   if(announceList) {
     for(List::ValueType::const_iterator tierIter = announceList->begin(),
           eoi = announceList->end(); tierIter != eoi; ++tierIter) {
-      const List* tier = asList(*tierIter);
+      const List* tier = downcast<List>(*tierIter);
       if(!tier) {
         continue;
       }
       std::vector<std::string> ntier;
       for(List::ValueType::const_iterator uriIter = tier->begin(),
             eoi2 = tier->end(); uriIter != eoi2; ++uriIter) {
-        const String* uri = asString(*uriIter);
+        const String* uri = downcast<String>(*uriIter);
         if(uri) {
           ntier.push_back(util::encodeNonUtf8(util::strip(uri->s())));
         }
@@ -353,7 +353,7 @@ void extractAnnounce
       }
     }
   } else {
-    const String* announce = asString(rootDict->get(C_ANNOUNCE));
+    const String* announce = downcast<String>(rootDict->get(C_ANNOUNCE));
     if(announce) {
       std::vector<std::string> tier;
       tier.push_back(util::encodeNonUtf8(util::strip(announce->s())));
@@ -367,15 +367,15 @@ namespace {
 void extractNodes
 (const SharedHandle<TorrentAttribute>& torrent, const ValueBase* nodesListSrc)
 {
-  const List* nodesList = asList(nodesListSrc);
+  const List* nodesList = downcast<List>(nodesListSrc);
   if(nodesList) {
     for(List::ValueType::const_iterator i = nodesList->begin(),
           eoi = nodesList->end(); i != eoi; ++i) {
-      const List* addrPairList = asList(*i);
+      const List* addrPairList = downcast<List>(*i);
       if(!addrPairList || addrPairList->size() != 2) {
         continue;
       }
-      const String* hostname = asString(addrPairList->get(0));
+      const String* hostname = downcast<String>(addrPairList->get(0));
       if(!hostname) {
         continue;
       }
@@ -384,7 +384,7 @@ void extractNodes
       if(utf8Hostname.empty()) {
         continue;
       }
-      const Integer* port = asInteger(addrPairList->get(1));
+      const Integer* port = downcast<Integer>(addrPairList->get(1));
       if(!port || !(0 < port->i() && port->i() < 65536)) {
         continue;
       }
@@ -403,12 +403,12 @@ void processRootDictionary
  const std::string& overrideName,
  const std::vector<std::string>& uris)
 {
-  const Dict* rootDict = asDict(root);
+  const Dict* rootDict = downcast<Dict>(root);
   if(!rootDict) {
     throw DL_ABORT_EX2("torrent file does not contain a root dictionary.",
                        error_code::BITTORRENT_PARSE_ERROR);
   }
-  const Dict* infoDict = asDict(rootDict->get(C_INFO));
+  const Dict* infoDict = downcast<Dict>(rootDict->get(C_INFO));
   if(!infoDict) {
     throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_INFO.c_str()),
                        error_code::BITTORRENT_PARSE_ERROR);
@@ -427,7 +427,7 @@ void processRootDictionary
   torrent->metadataSize = encodedInfoDict.size();
 
   // calculate the number of pieces
-  const String* piecesData = asString(infoDict->get(C_PIECES));
+  const String* piecesData = downcast<String>(infoDict->get(C_PIECES));
   if(!piecesData) {
     throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_PIECES.c_str()),
                        error_code::BITTORRENT_PARSE_ERROR);
@@ -442,7 +442,7 @@ void processRootDictionary
   //     throw DL_ABORT_EX("The number of pieces is 0.");
   //   }
   // retrieve piece length
-  const Integer* pieceLengthData = asInteger(infoDict->get(C_PIECE_LENGTH));
+  const Integer* pieceLengthData = downcast<Integer>(infoDict->get(C_PIECE_LENGTH));
   if(!pieceLengthData) {
     throw DL_ABORT_EX2(fmt(MSG_MISSING_BT_INFO, C_PIECE_LENGTH.c_str()),
                        error_code::BITTORRENT_PARSE_ERROR);
@@ -452,7 +452,7 @@ void processRootDictionary
   // retrieve piece hashes
   extractPieceHash(ctx, piecesData->s(), PIECE_HASH_LENGTH, numPieces);
   // private flag
-  const Integer* privateData = asInteger(infoDict->get(C_PRIVATE));
+  const Integer* privateData = downcast<Integer>(infoDict->get(C_PRIVATE));
   int privatefg = 0;
   if(privateData) {
     if(privateData->i() == 1) {
@@ -483,20 +483,20 @@ void processRootDictionary
   // retrieve nodes
   extractNodes(torrent, rootDict->get(C_NODES).get());
 
-  const Integer* creationDate = asInteger(rootDict->get(C_CREATION_DATE));
+  const Integer* creationDate = downcast<Integer>(rootDict->get(C_CREATION_DATE));
   if(creationDate) {
     torrent->creationDate = creationDate->i();
   }
-  const String* commentUtf8 = asString(rootDict->get(C_COMMENT_UTF8));
+  const String* commentUtf8 = downcast<String>(rootDict->get(C_COMMENT_UTF8));
   if(commentUtf8) {
     torrent->comment = util::encodeNonUtf8(commentUtf8->s());
   } else {
-    const String* comment = asString(rootDict->get(C_COMMENT));
+    const String* comment = downcast<String>(rootDict->get(C_COMMENT));
     if(comment) {
       torrent->comment = util::encodeNonUtf8(comment->s());
     }
   }
-  const String* createdBy = asString(rootDict->get(C_CREATED_BY));
+  const String* createdBy = downcast<String>(rootDict->get(C_CREATED_BY));
   if(createdBy) {
     torrent->createdBy = util::encodeNonUtf8(createdBy->s());
   }
@@ -881,7 +881,7 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
     throw DL_ABORT_EX2("Bad BitTorrent Magnet URI.",
                        error_code::MAGNET_PARSE_ERROR);
   }
-  const List* xts = asList(r->get("xt"));
+  const List* xts = downcast<List>(r->get("xt"));
   if(!xts) {
     throw DL_ABORT_EX2("Missing xt parameter in Magnet URI.",
                        error_code::MAGNET_PARSE_ERROR);
@@ -890,7 +890,7 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
   std::string infoHash;
   for(List::ValueType::const_iterator xtiter = xts->begin(),
         eoi = xts->end(); xtiter != eoi && infoHash.empty(); ++xtiter) {
-    const String* xt = asString(*xtiter);
+    const String* xt = downcast<String>(*xtiter);
     if(util::startsWith(xt->s(), "urn:btih:")) {
       std::string xtarg = xt->s().substr(9);
       size_t size = xtarg.size();
@@ -912,19 +912,19 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
                        "No valid BitTorrent Info Hash found.",
                        error_code::MAGNET_PARSE_ERROR);
   }
-  const List* trs = asList(r->get("tr"));
+  const List* trs = downcast<List>(r->get("tr"));
   if(trs) {
     for(List::ValueType::const_iterator i = trs->begin(), eoi = trs->end();
         i != eoi; ++i) {
       std::vector<std::string> tier;
-      tier.push_back(util::encodeNonUtf8(asString(*i)->s()));
+      tier.push_back(util::encodeNonUtf8(downcast<String>(*i)->s()));
       attrs->announceList.push_back(tier);
     }
   }
   std::string name = "[METADATA]";
-  const List* dns = asList(r->get("dn"));
+  const List* dns = downcast<List>(r->get("dn"));
   if(dns && !dns->empty()) {
-    const String* dn = asString(dns->get(0));
+    const String* dn = downcast<String>(dns->get(0));
     name += util::encodeNonUtf8(dn->s());
   } else {
     name += util::toHex(infoHash);

+ 3 - 3
src/bittorrent_helper.h

@@ -290,14 +290,14 @@ void extractPeer(const ValueBase* peerData, int family, OutputIterator dest)
     {
       for(List::ValueType::const_iterator itr = peerData.begin(),
             eoi = peerData.end(); itr != eoi; ++itr) {
-        const Dict* peerDict = asDict(*itr);
+        const Dict* peerDict = downcast<Dict>(*itr);
         if(!peerDict) {
           continue;
         }
         static const std::string IP = "ip";
         static const std::string PORT = "port";
-        const String* ip = asString(peerDict->get(IP));
-        const Integer* port = asInteger(peerDict->get(PORT));
+        const String* ip = downcast<String>(peerDict->get(IP));
+        const Integer* port = downcast<Integer>(peerDict->get(PORT));
         if(!ip || !port || !(0 < port->i() && port->i() < 65536)) {
           continue;
         }

+ 1 - 1
src/json.cc

@@ -405,7 +405,7 @@ decodeObject
       ++first;
       std::pair<SharedHandle<ValueBase>, std::string::const_iterator>
         valueRet = decode(first, last, depth);
-      dict->put(asString(keyRet.first)->s(), valueRet.first);
+      dict->put(downcast<String>(keyRet.first)->s(), valueRet.first);
       first = valueRet.second;
       first = skipWs(first, last);
       if(first == last || (*first != ',' && *first != '}')) {

+ 1 - 1
src/magnet.cc

@@ -54,7 +54,7 @@ SharedHandle<Dict> parse(const std::string& magnet)
     std::pair<std::string, std::string> kv;
     util::divide(kv, *i, '=');
     std::string value = util::percentDecode(kv.second);
-    List* l = asList(dict->get(kv.first));
+    List* l = downcast<List>(dict->get(kv.first));
     if(l) {
       l->append(String::g(value));
     } else {

+ 10 - 10
test/AnnounceListTest.cc

@@ -50,10 +50,10 @@ std::vector<std::vector<std::string> > toVector
   for(List::ValueType::const_iterator tierIter = announceList->begin(),
         eoi = announceList->end(); tierIter != eoi; ++tierIter) {
     std::vector<std::string> ntier;
-    const List* tier = asList(*tierIter);
+    const List* tier = downcast<List>(*tierIter);
     for(List::ValueType::const_iterator uriIter = tier->begin(),
           eoi2 = tier->end(); uriIter != eoi2; ++uriIter) {
-      const String* uri = asString(*uriIter);
+      const String* uri = downcast<String>(*uriIter);
       ntier.push_back(uri->s());
     }
     dest.push_back(ntier);
@@ -68,7 +68,7 @@ void AnnounceListTest::testSingleElementList() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1 ], [ tracker2 ], [ tracker3 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
   
   CPPUNIT_ASSERT(!announceList.allTiersFailed());
   std::string url =  announceList.getAnnounce();
@@ -114,7 +114,7 @@ void AnnounceListTest::testMultiElementList() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1, tracker2, tracker3 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
   
   CPPUNIT_ASSERT(!announceList.allTiersFailed());
   std::string url = announceList.getAnnounce();
@@ -147,7 +147,7 @@ void AnnounceListTest::testSingleAndMulti() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1, tracker2 ], [ tracker3 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
 
   std::string url = announceList.getAnnounce();
   CPPUNIT_ASSERT_EQUAL(std::string("tracker1"), url);
@@ -170,7 +170,7 @@ void AnnounceListTest::testSingleAndMulti() {
 void AnnounceListTest::testNoGroup() {
   std::string peersString = "llee";
   SharedHandle<ValueBase> announcesList = bencode2::decode(peersString);
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
   CPPUNIT_ASSERT(announceList.countTier() == 0);
 }
 
@@ -180,7 +180,7 @@ void AnnounceListTest::testNextEventIfAfterStarted() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
   announceList.setEvent(AnnounceTier::STOPPED);
   announceList.announceFailure();
   announceList.resetTier();
@@ -200,7 +200,7 @@ void AnnounceListTest::testEvent() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1 ], [ tracker2 ], [ tracker3 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
 
   announceList.setEvent(AnnounceTier::STOPPED);
   announceList.announceSuccess();
@@ -224,7 +224,7 @@ void AnnounceListTest::testCountStoppedAllowedTier() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1 ], [ tracker2 ], [ tracker3 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
 
   CPPUNIT_ASSERT_EQUAL((size_t)0, announceList.countStoppedAllowedTier());
   announceList.setEvent(AnnounceTier::STARTED);
@@ -251,7 +251,7 @@ void AnnounceListTest::testCountCompletedAllowedTier() {
 
   // ANNOUNCE_LIST
   // [ [ tracker1 ], [ tracker2 ], [ tracker3 ] ]
-  AnnounceList announceList(toVector(asList(announcesList)));
+  AnnounceList announceList(toVector(downcast<List>(announcesList)));
 
   CPPUNIT_ASSERT_EQUAL((size_t)0, announceList.countCompletedAllowedTier());
   announceList.setEvent(AnnounceTier::STARTED);

+ 14 - 14
test/Bencode2Test.cc

@@ -29,30 +29,30 @@ void Bencode2Test::testDecode()
     // string, integer and list in dict
     SharedHandle<ValueBase> r =
       bencode2::decode("d4:name5:aria24:sizei12345678900e5:filesl3:bin3:docee");
-    const Dict* dict = asDict(r);
+    const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
     CPPUNIT_ASSERT_EQUAL(std::string("aria2"),
-                         asString(dict->get("name"))->s());
+                         downcast<String>(dict->get("name"))->s());
     CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(12345678900LL),
-                         asInteger(dict->get("size"))->i());
-    const List* list = asList(dict->get("files"));
+                         downcast<Integer>(dict->get("size"))->i());
+    const List* list = downcast<List>(dict->get("files"));
     CPPUNIT_ASSERT(list);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), list->size());
     CPPUNIT_ASSERT_EQUAL(std::string("bin"),
-                         asString(list->get(0))->s());
+                         downcast<String>(list->get(0))->s());
     CPPUNIT_ASSERT_EQUAL(std::string("doc"),
-                         asString(list->get(1))->s());
+                         downcast<String>(list->get(1))->s());
   }
   {
     // dict in list
     SharedHandle<ValueBase> r = bencode2::decode("ld1:ki123eee");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), list->size());
-    const Dict* dict = asDict(list->get(0));
+    const Dict* dict = downcast<Dict>(list->get(0));
     CPPUNIT_ASSERT(dict);
     CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(123),
-                         asInteger(dict->get("k"))->i());
+                         downcast<Integer>(dict->get("k"))->i());
   }
   {
     // empty key is allowed
@@ -61,17 +61,17 @@ void Bencode2Test::testDecode()
   {
     // empty string
     SharedHandle<ValueBase> s = bencode2::decode("0:");
-    CPPUNIT_ASSERT_EQUAL(std::string(""), asString(s)->s());
+    CPPUNIT_ASSERT_EQUAL(std::string(""), downcast<String>(s)->s());
   }
   {
     // empty dict
     SharedHandle<ValueBase> d = bencode2::decode("de");
-    CPPUNIT_ASSERT(asDict(d)->empty());
+    CPPUNIT_ASSERT(downcast<Dict>(d)->empty());
   }
   {
     // empty list
     SharedHandle<ValueBase> l = bencode2::decode("le");
-    CPPUNIT_ASSERT(asList(l)->empty());
+    CPPUNIT_ASSERT(downcast<List>(l)->empty());
   }
   {
     // integer, without ending 'e'
@@ -151,13 +151,13 @@ void Bencode2Test::testDecode()
   {
     // ignore trailing garbage at the end of the input.
     SharedHandle<ValueBase> s = bencode2::decode("5:aria2trail");
-    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), asString(s)->s());
+    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), downcast<String>(s)->s());
   }
   {
     // Get trailing garbage position
     size_t end;
     SharedHandle<ValueBase> s = bencode2::decode("5:aria2trail", end);
-    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), asString(s)->s());
+    CPPUNIT_ASSERT_EQUAL(std::string("aria2"), downcast<String>(s)->s());
     CPPUNIT_ASSERT_EQUAL((size_t)7, end);
   }
 }

+ 3 - 3
test/BittorrentHelperTest.cc

@@ -732,7 +732,7 @@ void BittorrentHelperTest::testMetadata() {
   load(A2_TEST_DIR"/test.torrent", dctx, option_);
   std::string torrentData = readFile(A2_TEST_DIR"/test.torrent");
   SharedHandle<ValueBase> tr = bencode2::decode(torrentData);
-  SharedHandle<ValueBase> infoDic = asDict(tr)->get("info");
+  SharedHandle<ValueBase> infoDic = downcast<Dict>(tr)->get("info");
   std::string metadata = bencode2::encode(infoDic);
   SharedHandle<TorrentAttribute> attrs = getTorrentAttrs(dctx);
   CPPUNIT_ASSERT(metadata == attrs->metadata);
@@ -848,7 +848,7 @@ void BittorrentHelperTest::testExtractPeerFromList()
   SharedHandle<ValueBase> dict = bencode2::decode(peersString);
   
   std::deque<SharedHandle<Peer> > peers;
-  extractPeer(asDict(dict)->get("peers"), AF_INET, std::back_inserter(peers));
+  extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)1, peers.size());
   SharedHandle<Peer> peer = *peers.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());
@@ -865,7 +865,7 @@ void BittorrentHelperTest::testExtract2PeersFromList()
   SharedHandle<ValueBase> dict = bencode2::decode(peersString);
 
   std::deque<SharedHandle<Peer> > peers;
-  extractPeer(asDict(dict)->get("peers"), AF_INET, std::back_inserter(peers));
+  extractPeer(downcast<Dict>(dict)->get("peers"), AF_INET, std::back_inserter(peers));
   CPPUNIT_ASSERT_EQUAL((size_t)2, peers.size());
   SharedHandle<Peer> peer = *peers.begin();
   CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress());

+ 2 - 2
test/DefaultBtAnnounceTest.cc

@@ -124,10 +124,10 @@ void setAnnounceList(const SharedHandle<DownloadContext>& dctx,
   for(List::ValueType::const_iterator tierIter = announceList->begin(),
         eoi = announceList->end(); tierIter != eoi; ++tierIter) {
     std::vector<std::string> ntier;
-    const List* tier = asList(*tierIter);
+    const List* tier = downcast<List>(*tierIter);
     for(List::ValueType::const_iterator uriIter = tier->begin(),
           eoi2 = tier->end(); uriIter != eoi2; ++uriIter) {
-      const String* uri = asString(*uriIter);
+      const String* uri = downcast<String>(*uriIter);
       ntier.push_back(uri->s());
     }
     dest.push_back(ntier);

+ 39 - 39
test/JsonTest.cc

@@ -33,150 +33,150 @@ void JsonTest::testDecode()
   {
     // empty object
     SharedHandle<ValueBase> r = json::decode("{}");
-    const Dict* dict = asDict(r);
+    const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
   }
   {
     // empty object
     SharedHandle<ValueBase> r = json::decode("{  }");
-    const Dict* dict = asDict(r);
+    const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
   }
   {
     // empty array
     SharedHandle<ValueBase> r = json::decode("[]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
   }
   {
     // empty array
     SharedHandle<ValueBase> r = json::decode("[ ]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
   }
   {
     // empty string
     SharedHandle<ValueBase> r = json::decode("[\"\"]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string(), s->s());
   }
   {
     // string
     SharedHandle<ValueBase> r = json::decode("[\"foobar\"]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foobar"), s->s());
   }
   {
     // string with escape
     SharedHandle<ValueBase> r = json::decode("[\"\\\\foo\\\"\\\"bar\"]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("\\foo\"\"bar"), s->s());
   }
   {
     // string with escape
     SharedHandle<ValueBase> r = json::decode("[\"foo\\\"\"]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foo\""), s->s());
   }
   {
     // string: utf-8 1 to 3 bytes.
     SharedHandle<ValueBase> r = json::decode("[\"\\u0024\\u00A2\\u20AC\"]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("$¢€"), s->s());
   }
   {
     // string: utf-8 4 bytes
     SharedHandle<ValueBase> r = json::decode("[\"\\uD852\\uDF62\"]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     const char arr[] = { 0xF0u, 0xA4u, 0xADu, 0xA2u };
     CPPUNIT_ASSERT_EQUAL(std::string(vbegin(arr), vend(arr)), s->s());
   }
   {
     // null
     SharedHandle<ValueBase> r = json::decode("[null]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const Null* s = asNull(list->get(0));
+    const Null* s = downcast<Null>(list->get(0));
     CPPUNIT_ASSERT(s);
   }
   {
     // true, false
     SharedHandle<ValueBase> r = json::decode("[true, false]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const Bool* trueValue = asBool(list->get(0));
+    const Bool* trueValue = downcast<Bool>(list->get(0));
     CPPUNIT_ASSERT(trueValue);
     CPPUNIT_ASSERT(trueValue->val());
-    const Bool* falseValue = asBool(list->get(1));
+    const Bool* falseValue = downcast<Bool>(list->get(1));
     CPPUNIT_ASSERT(falseValue);
     CPPUNIT_ASSERT(!falseValue->val());
   }
   {
     // object: 1 member
     SharedHandle<ValueBase> r = json::decode("{\"foo\":[\"bar\"]}");
-    const Dict* dict = asDict(r);
+    const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
-    const List* list = asList(dict->get("foo"));
+    const List* list = downcast<List>(dict->get("foo"));
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
   }
   {
     // object: 2 members
     SharedHandle<ValueBase> r = json::decode("{\"\":[\"bar\"], "
                                              "\"alpha\" : \"bravo\"}");
-    const Dict* dict = asDict(r);
+    const Dict* dict = downcast<Dict>(r);
     CPPUNIT_ASSERT(dict);
-    const List* list = asList(dict->get(""));
+    const List* list = downcast<List>(dict->get(""));
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("bar"), s->s());
-    const String* str = asString(dict->get("alpha"));
+    const String* str = downcast<String>(dict->get("alpha"));
     CPPUNIT_ASSERT_EQUAL(std::string("bravo"), str->s());
   }
   {
     // array: 2 values
     SharedHandle<ValueBase> r = json::decode("[\"foo\", {}]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const String* s = asString(list->get(0));
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("foo"), s->s());
-    const Dict* dict = asDict(list->get(1));
+    const Dict* dict = downcast<Dict>(list->get(1));
     CPPUNIT_ASSERT(dict);
   }
   {
     // Number: currently we handle floating point number as string
     SharedHandle<ValueBase> r = json::decode("[0,-1,1.2,-1.2e-10,-1e10]");
-    const List* list = asList(r);
+    const List* list = downcast<List>(r);
     CPPUNIT_ASSERT(list);
-    const Integer* i = asInteger(list->get(0));
+    const Integer* i = downcast<Integer>(list->get(0));
     CPPUNIT_ASSERT_EQUAL((Integer::ValueType)0, i->i());
-    const Integer* i1 = asInteger(list->get(1));
+    const Integer* i1 = downcast<Integer>(list->get(1));
     CPPUNIT_ASSERT_EQUAL((Integer::ValueType)-1, i1->i());
-    const String* s2 = asString(list->get(2));
+    const String* s2 = downcast<String>(list->get(2));
     CPPUNIT_ASSERT_EQUAL(std::string("1.2"), s2->s());
-    const String* s3 = asString(list->get(3));
+    const String* s3 = downcast<String>(list->get(3));
     CPPUNIT_ASSERT_EQUAL(std::string("-1.2e-10"), s3->s());
-    const String* s4 = asString(list->get(4));
+    const String* s4 = downcast<String>(list->get(4));
     CPPUNIT_ASSERT_EQUAL(std::string("-1e10"), s4->s());
   }
   {
     // escape chars: ", \, /, \b, \f, \n, \r, \t
     SharedHandle<ValueBase> r =json::decode("[\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"]");
-    const List* list = asList(r);
-    const String* s = asString(list->get(0));
+    const List* list = downcast<List>(r);
+    const String* s = downcast<String>(list->get(0));
     CPPUNIT_ASSERT_EQUAL(std::string("\"\\/\b\f\n\r\t"), s->s());
   }
 }

+ 1 - 1
test/MagnetTest.cc

@@ -23,7 +23,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION(MagnetTest);
 namespace {
 const std::string& nthStr(const SharedHandle<ValueBase>& v, size_t index)
 {
-  return asString(asList(v)->get(index))->s();
+  return downcast<String>(downcast<List>(v)->get(index))->s();
 }
 } // namespace
 

+ 1 - 1
test/MockDHTMessageFactory.h

@@ -33,7 +33,7 @@ public:
     remoteNode->setPort(port);
     SharedHandle<MockDHTResponseMessage> m
       (new MockDHTResponseMessage(localNode_, remoteNode,
-                                  asString(dict->get("t"))->s()));
+                                  downcast<String>(dict->get("t"))->s()));
     return m;
   }
 

+ 63 - 63
test/RpcMethodTest.cc

@@ -148,7 +148,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION(RpcMethodTest);
 namespace {
 std::string getString(const Dict* dict, const std::string& key)
 {
-  return asString(dict->get(key))->s();
+  return downcast<String>(dict->get(key))->s();
 }
 } // namespace
 
@@ -270,7 +270,7 @@ void RpcMethodTest::testAddTorrent()
       (File(e_->getOption()->get(PREF_DIR)+
             "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").exists());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
-    CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(res.param)->s());
+    CPPUNIT_ASSERT_EQUAL(std::string("1"), downcast<String>(res.param)->s());
 
     SharedHandle<RequestGroup> group =
       e_->getRequestGroupMan()->findReservedGroup(1);
@@ -354,10 +354,10 @@ void RpcMethodTest::testAddMetalink()
   {
     RpcResponse res = m.execute(req, e_.get());
     CPPUNIT_ASSERT_EQUAL(0, res.code);
-    const List* resParams = asList(res.param);
+    const List* resParams = downcast<List>(res.param);
     CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
-    CPPUNIT_ASSERT_EQUAL(std::string("1"), asString(resParams->get(0))->s());
-    CPPUNIT_ASSERT_EQUAL(std::string("2"), asString(resParams->get(1))->s());
+    CPPUNIT_ASSERT_EQUAL(std::string("1"), downcast<String>(resParams->get(0))->s());
+    CPPUNIT_ASSERT_EQUAL(std::string("2"), downcast<String>(resParams->get(1))->s());
 #ifdef ENABLE_MESSAGE_DIGEST
     CPPUNIT_ASSERT
       (File(e_->getOption()->get(PREF_DIR)+
@@ -577,7 +577,7 @@ void RpcMethodTest::testNoSuchMethod()
   RpcResponse res = m.execute(req, 0);
   CPPUNIT_ASSERT_EQUAL(1, res.code);
   CPPUNIT_ASSERT_EQUAL(std::string("No such method: make.hamburger"),
-                       getString(asDict(res.param), "faultString"));
+                       getString(downcast<Dict>(res.param), "faultString"));
 }
 
 void RpcMethodTest::testTellStatus_withoutGid()
@@ -630,19 +630,19 @@ void RpcMethodTest::testTellWaiting()
   req.params->append(Integer::g(2));
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  const List* resParams = asList(res.param);
+  const List* resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
   CPPUNIT_ASSERT_EQUAL(std::string("2"),
-                       getString(asDict(resParams->get(0)), "gid"));
+                       getString(downcast<Dict>(resParams->get(0)), "gid"));
   CPPUNIT_ASSERT_EQUAL(std::string("3"),
-                       getString(asDict(resParams->get(1)), "gid"));
+                       getString(downcast<Dict>(resParams->get(1)), "gid"));
   // waiting.size() == offset+num 
   req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
   req.params->append(Integer::g(1));
   req.params->append(Integer::g(3));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  resParams = asList(res.param);
+  resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
   // waiting.size() < offset+num 
   req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
@@ -650,7 +650,7 @@ void RpcMethodTest::testTellWaiting()
   req.params->append(Integer::g(4));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  resParams = asList(res.param);
+  resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
   // negative offset
   req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
@@ -658,29 +658,29 @@ void RpcMethodTest::testTellWaiting()
   req.params->append(Integer::g(2));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  resParams = asList(res.param);
+  resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
   CPPUNIT_ASSERT_EQUAL(std::string("4"),
-                       getString(asDict(resParams->get(0)), "gid"));
+                       getString(downcast<Dict>(resParams->get(0)), "gid"));
   CPPUNIT_ASSERT_EQUAL(std::string("3"),
-                       getString(asDict(resParams->get(1)), "gid"));
+                       getString(downcast<Dict>(resParams->get(1)), "gid"));
   // negative offset and size < num
   req.params->set(1, Integer::g(100));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  resParams = asList(res.param);
+  resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)4, resParams->size());
   // nagative offset and normalized offset < 0
   req.params->set(0, Integer::g(-5));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  resParams = asList(res.param);
+  resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
   // nagative offset and normalized offset == 0
   req.params->set(0, Integer::g(-4));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  resParams = asList(res.param);
+  resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)1, resParams->size());
 }
 
@@ -698,14 +698,14 @@ void RpcMethodTest::testGetVersion()
   RpcRequest req(GetVersionRpcMethod::getMethodName(), List::g());
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  const Dict* resParams = asDict(res.param);
+  const Dict* resParams = downcast<Dict>(res.param);
   CPPUNIT_ASSERT_EQUAL(std::string(PACKAGE_VERSION),
                        getString(resParams, "version"));
-  const List* featureList = asList(resParams->get("enabledFeatures"));
+  const List* featureList = downcast<List>(resParams->get("enabledFeatures"));
   std::string features;
   for(List::ValueType::const_iterator i = featureList->begin();
       i != featureList->end(); ++i) {
-    const String* s = asString(*i);
+    const String* s = downcast<String>(*i);
     features += s->s();
     features += ", ";
   }
@@ -733,11 +733,11 @@ void RpcMethodTest::testGatherStoppedDownload()
   std::vector<std::string> keys;
   gatherStoppedDownload(entry, d, keys);
 
-  const List* followedByRes = asList(entry->get("followedBy"));
-  CPPUNIT_ASSERT_EQUAL(std::string("3"), asString(followedByRes->get(0))->s());
-  CPPUNIT_ASSERT_EQUAL(std::string("4"), asString(followedByRes->get(1))->s());
+  const List* followedByRes = downcast<List>(entry->get("followedBy"));
+  CPPUNIT_ASSERT_EQUAL(std::string("3"), downcast<String>(followedByRes->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("4"), downcast<String>(followedByRes->get(1))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("2"),
-                       asString(entry->get("belongsTo"))->s());
+                       downcast<String>(entry->get("belongsTo"))->s());
 
   keys.push_back("gid");
 
@@ -766,26 +766,26 @@ void RpcMethodTest::testGatherProgressCommon()
   std::vector<std::string> keys;
   gatherProgressCommon(entry, group, keys);
   
-  const List* followedByRes = asList(entry->get("followedBy"));
+  const List* followedByRes = downcast<List>(entry->get("followedBy"));
   CPPUNIT_ASSERT_EQUAL(util::itos(followedBy[0]->getGID()),
-                       asString(followedByRes->get(0))->s());
+                       downcast<String>(followedByRes->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(util::itos(followedBy[1]->getGID()),
-                       asString(followedByRes->get(1))->s());
+                       downcast<String>(followedByRes->get(1))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("2"),
-                       asString(entry->get("belongsTo"))->s());
-  const List* files = asList(entry->get("files"));
+                       downcast<String>(entry->get("belongsTo"))->s());
+  const List* files = downcast<List>(entry->get("files"));
   CPPUNIT_ASSERT_EQUAL((size_t)1, files->size());
-  const Dict* file = asDict(files->get(0));
+  const Dict* file = downcast<Dict>(files->get(0));
   CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"),
-                       asString(file->get("path"))->s());
+                       downcast<String>(file->get("path"))->s());
   CPPUNIT_ASSERT_EQUAL(uris[0],
-                       asString
-                       (asDict
-                        (asList(file->get("uris"))->get(0))
+                       downcast<String>
+                       (downcast<Dict>
+                        (downcast<List>(file->get("uris"))->get(0))
                         ->get("uri"))
                        ->s());
   CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR),
-                       asString(entry->get("dir"))->s());
+                       downcast<String>(entry->get("dir"))->s());
 
   keys.push_back("gid");
   entry = Dict::g();
@@ -806,25 +806,25 @@ void RpcMethodTest::testGatherBitTorrentMetadata()
   SharedHandle<Dict> btDict = Dict::g();
   gatherBitTorrentMetadata(btDict, bittorrent::getTorrentAttrs(dctx));
   CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"),
-                       asString(btDict->get("comment"))->s());
+                       downcast<String>(btDict->get("comment"))->s());
   CPPUNIT_ASSERT_EQUAL((int64_t)1123456789,
-                       asInteger(btDict->get("creationDate"))->i());
+                       downcast<Integer>(btDict->get("creationDate"))->i());
   CPPUNIT_ASSERT_EQUAL(std::string("multi"),
-                       asString(btDict->get("mode"))->s());
+                       downcast<String>(btDict->get("mode"))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("aria2-test"),
-                       asString
-                       (asDict
+                       downcast<String>
+                       (downcast<Dict>
                         (btDict->get("info"))
                         ->get("name"))
                        ->s());
-  const List* announceList = asList(btDict->get("announceList"));
+  const List* announceList = downcast<List>(btDict->get("announceList"));
   CPPUNIT_ASSERT_EQUAL((size_t)3, announceList->size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"),
-                       asString(asList(announceList->get(0))->get(0))->s());
+                       downcast<String>(downcast<List>(announceList->get(0))->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"),
-                       asString(asList(announceList->get(1))->get(0))->s());
+                       downcast<String>(downcast<List>(announceList->get(1))->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("http://tracker3"),
-                       asString(asList(announceList->get(2))->get(0))->s());
+                       downcast<String>(downcast<List>(announceList->get(2))->get(0))->s());
   // Remove some keys
   SharedHandle<TorrentAttribute> modBtAttrs = bittorrent::getTorrentAttrs(dctx);
   modBtAttrs->comment.clear();
@@ -855,7 +855,7 @@ void RpcMethodTest::testChangePosition()
   req.params->append("POS_SET");
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)1, asInteger(res.param)->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1, downcast<Integer>(res.param)->i());
   CPPUNIT_ASSERT_EQUAL
     ((a2_gid_t)1, e_->getRequestGroupMan()->getReservedGroups()[1]->getGID());
 }
@@ -905,8 +905,8 @@ void RpcMethodTest::testChangeUri()
   req.params->append(adduris);
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)2, asInteger(asList(res.param)->get(0))->i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)3, asInteger(asList(res.param)->get(1))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)2, downcast<Integer>(downcast<List>(res.param)->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)3, downcast<Integer>(downcast<List>(res.param)->get(1))->i());
   CPPUNIT_ASSERT_EQUAL((size_t)0, files[0]->getRemainingUris().size());
   CPPUNIT_ASSERT_EQUAL((size_t)0, files[2]->getRemainingUris().size());
   std::deque<std::string> uris = files[1]->getRemainingUris();
@@ -925,8 +925,8 @@ void RpcMethodTest::testChangeUri()
   req.params->append(Integer::g(2));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)0, asInteger(asList(res.param)->get(0))->i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)2, asInteger(asList(res.param)->get(1))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)0, downcast<Integer>(downcast<List>(res.param)->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)2, downcast<Integer>(downcast<List>(res.param)->get(1))->i());
   uris = files[1]->getRemainingUris();
   CPPUNIT_ASSERT_EQUAL((size_t)6, uris.size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-1"), uris[2]);
@@ -938,8 +938,8 @@ void RpcMethodTest::testChangeUri()
   req.params->set(4, Integer::g(1000));
   res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  CPPUNIT_ASSERT_EQUAL((int64_t)0, asInteger(asList(res.param)->get(0))->i());
-  CPPUNIT_ASSERT_EQUAL((int64_t)2, asInteger(asList(res.param)->get(1))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)0, downcast<Integer>(downcast<List>(res.param)->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((int64_t)2, downcast<Integer>(downcast<List>(res.param)->get(1))->i());
   uris = files[0]->getRemainingUris();
   CPPUNIT_ASSERT_EQUAL((size_t)2, uris.size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-1"), uris[0]);
@@ -1005,7 +1005,7 @@ void RpcMethodTest::testGetSessionInfo()
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
   CPPUNIT_ASSERT_EQUAL(util::toHex(e_->getSessionId()),
-                       getString(asDict(res.param), "sessionId"));
+                       getString(downcast<Dict>(res.param), "sessionId"));
 }
 
 void RpcMethodTest::testPause()
@@ -1111,26 +1111,26 @@ void RpcMethodTest::testSystemMulticall()
   }
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(0, res.code);
-  const List* resParams = asList(res.param);
+  const List* resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)7, resParams->size());
   CPPUNIT_ASSERT_EQUAL(std::string("1"),
-                       asString(asList(resParams->get(0))->get(0))->s());
+                       downcast<String>(downcast<List>(resParams->get(0))->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("2"),
-                       asString(asList(resParams->get(1))->get(0))->s());
+                       downcast<String>(downcast<List>(resParams->get(1))->get(0))->s());
   CPPUNIT_ASSERT_EQUAL((int64_t)1,
-                       asInteger
-                       (asDict(resParams->get(2))->get("faultCode"))
+                       downcast<Integer>
+                       (downcast<Dict>(resParams->get(2))->get("faultCode"))
                        ->i());
   CPPUNIT_ASSERT_EQUAL((int64_t)1,
-                       asInteger
-                       (asDict(resParams->get(3))->get("faultCode"))
+                       downcast<Integer>
+                       (downcast<Dict>(resParams->get(3))->get("faultCode"))
                        ->i());
   CPPUNIT_ASSERT_EQUAL((int64_t)1,
-                       asInteger
-                       (asDict(resParams->get(4))->get("faultCode"))
+                       downcast<Integer>
+                       (downcast<Dict>(resParams->get(4))->get("faultCode"))
                        ->i());
-  CPPUNIT_ASSERT(asList(resParams->get(5)));
-  CPPUNIT_ASSERT(asList(resParams->get(6)));
+  CPPUNIT_ASSERT(downcast<List>(resParams->get(5)));
+  CPPUNIT_ASSERT(downcast<List>(resParams->get(6)));
 }
 
 void RpcMethodTest::testSystemMulticall_fail()

+ 17 - 16
test/ValueBaseTest.cc

@@ -61,23 +61,24 @@ void ValueBaseTest::testString()
 void ValueBaseTest::testDowncast()
 {
   Integer integer(100);
-  const Integer* x = asInteger(&integer);
+  const Integer* x = downcast<Integer>(&integer);
   CPPUNIT_ASSERT(x);
   CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(100), x->i());
+  CPPUNIT_ASSERT(!downcast<String>(&integer));
   SharedHandle<Integer> si(new Integer(101));
-  const Integer* x2 = asInteger(si);
+  const Integer* x2 = downcast<Integer>(si);
   CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(101), x2->i());
 
   String str("foo");
-  const String* x3 = asString(&str);
+  const String* x3 = downcast<String>(&str);
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("foo"), x3->s());
 
   List list;
-  const List* x4 = asList(&list);
+  const List* x4 = downcast<List>(&list);
   CPPUNIT_ASSERT(x4);
 
   Dict dict;
-  const Dict* x5 = asDict(&dict);
+  const Dict* x5 = downcast<Dict>(&dict);
   CPPUNIT_ASSERT(x5);
 }
 
@@ -92,10 +93,10 @@ void ValueBaseTest::testDict()
   CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), dict.size());
   CPPUNIT_ASSERT(dict.containsKey("ki"));
   CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(7),
-                       asInteger(dict["ki"])->i());
+                       downcast<Integer>(dict["ki"])->i());
   CPPUNIT_ASSERT(dict.containsKey("ks"));
   CPPUNIT_ASSERT_EQUAL(std::string("abc"),
-                       asString(dict["ks"])->s());
+                       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());
@@ -141,15 +142,15 @@ void ValueBaseTest::testList()
 
   CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), list.size());
   CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(7),
-                       asInteger(list[0])->i());
+                       downcast<Integer>(list[0])->i());
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("aria2"),
-                       asString(list[1])->s());
+                       downcast<String>(list[1])->s());
 
   const List& ref = list;
   CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(7),
-                       asInteger(ref[0])->i());
+                       downcast<Integer>(ref[0])->i());
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("aria2"),
-                       asString(ref[1])->s());
+                       downcast<String>(ref[1])->s());
 }
 
 void ValueBaseTest::testListIter()
@@ -162,19 +163,19 @@ void ValueBaseTest::testListIter()
 
   List::ValueType::iterator i = list.begin();
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("alpha2"),
-                       asString(*i++)->s());
+                       downcast<String>(*i++)->s());
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("charlie"),
-                       asString(*i++)->s());
+                       downcast<String>(*i++)->s());
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("bravo"),
-                       asString(*i++)->s());
+                       downcast<String>(*i++)->s());
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("alpha"),
-                       asString(*i++)->s());
+                       downcast<String>(*i++)->s());
   CPPUNIT_ASSERT(list.end() == i);
 
   const List& ref = list;
   List::ValueType::const_iterator ci = ref.begin();
   CPPUNIT_ASSERT_EQUAL(static_cast<String::ValueType>("alpha2"),
-                       asString(*ci++)->s());
+                       downcast<String>(*ci++)->s());
   std::advance(ci, 3);
   CPPUNIT_ASSERT(ref.end() == ci);
 }

+ 15 - 15
test/XmlRpcRequestParserControllerTest.cc

@@ -40,10 +40,10 @@ void XmlRpcRequestParserControllerTest::testPopStructFrame()
   controller.setCurrentFrameValue(String::g("Hello, aria2"));
   controller.setCurrentFrameName("greeting");
   controller.popStructFrame();
-  const Dict* structValue = asDict(controller.getCurrentFrameValue());
+  const Dict* structValue = downcast<Dict>(controller.getCurrentFrameValue());
   CPPUNIT_ASSERT_EQUAL((size_t)1, structValue->size());
   CPPUNIT_ASSERT_EQUAL(std::string("Hello, aria2"),
-                       asString(structValue->get("greeting"))->s());
+                       downcast<String>(structValue->get("greeting"))->s());
 }
 
 void XmlRpcRequestParserControllerTest::testPopStructFrame_noName()
@@ -53,7 +53,7 @@ void XmlRpcRequestParserControllerTest::testPopStructFrame_noName()
   controller.pushFrame();
   controller.setCurrentFrameValue(String::g("Hello, aria2"));
   controller.popStructFrame();
-  const Dict* structValue = asDict(controller.getCurrentFrameValue());
+  const Dict* structValue = downcast<Dict>(controller.getCurrentFrameValue());
   CPPUNIT_ASSERT(structValue->empty());
 }
 
@@ -64,7 +64,7 @@ void XmlRpcRequestParserControllerTest::testPopStructFrame_noValue()
   controller.pushFrame();
   controller.setCurrentFrameName("greeting");
   controller.popStructFrame();
-  const Dict* structValue = asDict(controller.getCurrentFrameValue());
+  const Dict* structValue = downcast<Dict>(controller.getCurrentFrameValue());
   CPPUNIT_ASSERT(structValue->empty());
 }
 
@@ -75,9 +75,9 @@ void XmlRpcRequestParserControllerTest::testPopArrayFrame()
   controller.pushFrame();
   controller.setCurrentFrameValue(Integer::g(100));
   controller.popArrayFrame();
-  const List* array = asList(controller.getCurrentFrameValue());
+  const List* array = downcast<List>(controller.getCurrentFrameValue());
   CPPUNIT_ASSERT_EQUAL((size_t)1, array->size());
-  CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100, asInteger(array->get(0))->i());
+  CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100, downcast<Integer>(array->get(0))->i());
 }
 
 void XmlRpcRequestParserControllerTest::testPopArrayFrame_noValue()
@@ -86,7 +86,7 @@ void XmlRpcRequestParserControllerTest::testPopArrayFrame_noValue()
   controller.setCurrentFrameValue(List::g());
   controller.pushFrame();
   controller.popArrayFrame();
-  const List* array = asList(controller.getCurrentFrameValue());
+  const List* array = downcast<List>(controller.getCurrentFrameValue());
   CPPUNIT_ASSERT(array->empty());
 }
 
@@ -145,16 +145,16 @@ void XmlRpcRequestParserControllerTest::testPopArrayFrame_compound()
 
   controller.popArrayFrame();
 
-  const List* result = asList(controller.getCurrentFrameValue());
-  const Dict* dict = asDict(result->get(0));
-  const List* uris = asList(dict->get("uris"));
-  const Dict* options = asDict(dict->get("options"));
-  const List* countryList = asList(result->get(1));
+  const List* result = downcast<List>(controller.getCurrentFrameValue());
+  const Dict* dict = downcast<Dict>(result->get(0));
+  const List* uris = downcast<List>(dict->get("uris"));
+  const Dict* options = downcast<Dict>(dict->get("options"));
+  const List* countryList = downcast<List>(result->get(1));
   CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sf.net/"),
-                       asString(uris->get(1))->s());
+                       downcast<String>(uris->get(1))->s());
   CPPUNIT_ASSERT_EQUAL((Integer::ValueType)120,
-                       asInteger(options->get("timeout"))->i());
-  CPPUNIT_ASSERT_EQUAL(std::string("jp"), asString(countryList->get(0))->s());
+                       downcast<Integer>(options->get("timeout"))->i());
+  CPPUNIT_ASSERT_EQUAL(std::string("jp"), downcast<String>(countryList->get(0))->s());
 }
 
 } // namespace rpc

+ 15 - 15
test/XmlRpcRequestProcessorTest.cc

@@ -70,16 +70,16 @@ void XmlRpcRequestProcessorTest::testParseMemory()
   CPPUNIT_ASSERT_EQUAL(std::string("aria2.addURI"), req.methodName);
   CPPUNIT_ASSERT_EQUAL((size_t)3, req.params->size());
   CPPUNIT_ASSERT_EQUAL((Integer::ValueType)100,
-                       asInteger(req.params->get(0))->i());
-  const Dict* dict = asDict(req.params->get(1));
+                       downcast<Integer>(req.params->get(0))->i());
+  const Dict* dict = downcast<Dict>(req.params->get(1));
   CPPUNIT_ASSERT_EQUAL((Integer::ValueType)65535,
-                       asInteger(dict->get("max-count"))->i());
+                       downcast<Integer>(dict->get("max-count"))->i());
   // Current implementation handles double as string.
   CPPUNIT_ASSERT_EQUAL(std::string("0.99"),
-                       asString(dict->get("seed-ratio"))->s());
-  const List* list = asList(req.params->get(2));
-  CPPUNIT_ASSERT_EQUAL(std::string("pudding"), asString(list->get(0))->s());
-  CPPUNIT_ASSERT_EQUAL(std::string("hello world"), asString(list->get(1))->s());
+                       downcast<String>(dict->get("seed-ratio"))->s());
+  const List* list = downcast<List>(req.params->get(2));
+  CPPUNIT_ASSERT_EQUAL(std::string("pudding"), downcast<String>(list->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("hello world"), downcast<String>(list->get(1))->s());
 }
 
 void XmlRpcRequestProcessorTest::testParseMemory_shouldFail()
@@ -156,16 +156,16 @@ void XmlRpcRequestProcessorTest::testParseMemory_withoutStringTag()
 
   CPPUNIT_ASSERT_EQUAL((size_t)4, req.params->size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net"),
-                       asString(req.params->get(0))->s());
+                       downcast<String>(req.params->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(std::string("http://aria2.sourceforge.net"),
-                       asString(req.params->get(1))->s());
-  const Dict* dict = asDict(req.params->get(2));
+                       downcast<String>(req.params->get(1))->s());
+  const Dict* dict = downcast<Dict>(req.params->get(2));
   CPPUNIT_ASSERT_EQUAL(std::string("world"),
-                       asString(dict->get("hello"))->s());
-  const List* list = asList(req.params->get(3));
-  CPPUNIT_ASSERT_EQUAL(std::string("apple"), asString(list->get(0))->s());
-  CPPUNIT_ASSERT_EQUAL(std::string("banana"), asString(list->get(1))->s());
-  CPPUNIT_ASSERT_EQUAL(std::string("lemon"), asString(list->get(2))->s());
+                       downcast<String>(dict->get("hello"))->s());
+  const List* list = downcast<List>(req.params->get(3));
+  CPPUNIT_ASSERT_EQUAL(std::string("apple"), downcast<String>(list->get(0))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("banana"), downcast<String>(list->get(1))->s());
+  CPPUNIT_ASSERT_EQUAL(std::string("lemon"), downcast<String>(list->get(2))->s());
 }
 
 } // namespace rpc