/* */ #ifndef D_RPC_METHOD_IMPL_H #define D_RPC_METHOD_IMPL_H #include "RpcMethod.h" #include #include #include #include "RpcRequest.h" #include "ValueBase.h" #include "TorrentAttribute.h" #include "DlAbortEx.h" #include "fmt.h" #include "IndexedList.h" #include "GroupId.h" #include "RequestGroupMan.h" namespace aria2 { struct DownloadResult; class RequestGroup; namespace rpc { template const T* checkParam(const RpcRequest& req, size_t index, bool required = false) { const T* p = 0; if(req.params->size() > index) { if((p = downcast(req.params->get(index))) == 0) { throw DL_ABORT_EX(fmt("The parameter at %lu has wrong type.", static_cast(index))); } } else if(required) { throw DL_ABORT_EX(fmt("The parameter at %lu is required but missing.", static_cast(index))); } return p; } template const T* checkRequiredParam(const RpcRequest& req, size_t index) { return checkParam(req, index, true); } struct IntegerGE { IntegerGE(int32_t min):min(min) {} bool operator()(const Integer* param, std::string* error) const { if(min <= param->i()) { return true; } else { if(error) { *error = fmt("the value must be greater than or equal to %d.", min); } return false; } } int32_t min; }; template const Integer* checkRequiredInteger(const RpcRequest& req, size_t index, Validator validator) { const Integer* param = checkRequiredParam(req, index); std::string error; if(!validator(param, &error)) { throw DL_ABORT_EX(fmt("The integer parameter at %lu has invalid value: %s", static_cast(index), error.c_str())); } return param; } template void toStringList(OutputIterator out, const List* src) { if(!src) { return; } for(List::ValueType::const_iterator i = src->begin(), eoi = src->end(); i != eoi; ++i) { const String* s = downcast(*i); if(s) { *out++ = s->s(); } } } class AddUriRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.addUri"; } }; class RemoveRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.remove"; } }; class ForceRemoveRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.forceRemove"; } }; class PauseRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.pause"; } }; class ForcePauseRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.forcePause"; } }; class PauseAllRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.pauseAll"; } }; class ForcePauseAllRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.forcePauseAll"; } }; class UnpauseRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.unpause"; } }; class UnpauseAllRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.unpauseAll"; } }; #ifdef ENABLE_BITTORRENT class AddTorrentRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.addTorrent"; } }; #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK class AddMetalinkRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.addMetalink"; } }; #endif // ENABLE_METALINK class PurgeDownloadResultRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.purgeDownloadResult"; } }; class RemoveDownloadResultRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.removeDownloadResult"; } }; class GetUrisRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getUris"; } }; class GetFilesRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getFiles"; } }; #ifdef ENABLE_BITTORRENT class GetPeersRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getPeers"; } }; #endif // ENABLE_BITTORRENT class GetServersRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getServers"; } }; class TellStatusRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.tellStatus"; } }; class TellActiveRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.tellActive"; } }; template class AbstractPaginationRpcMethod:public RpcMethod { private: template std::pair getPaginationRange (int64_t offset, int64_t num, InputIterator first, InputIterator last) { int64_t size = std::distance(first, last); if(offset < 0) { int64_t tempoffset = offset+size; if(tempoffset < 0) { return std::make_pair(last, last); } offset = tempoffset-(num-1); if(offset < 0) { offset = 0; num = tempoffset+1; } } else if(size <= offset) { return std::make_pair(last, last); } int64_t lastDistance; if(size < offset+num) { lastDistance = size; } else { lastDistance = offset+num; } last = first; std::advance(first, offset); std::advance(last, lastDistance); return std::make_pair(first, last); } protected: typedef IndexedList > ItemListType; virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e) { const Integer* offsetParam = checkRequiredParam(req, 0); const Integer* numParam = checkRequiredInteger(req, 1, IntegerGE(0)); const List* keysParam = checkParam(req, 2); int64_t offset = offsetParam->i(); int64_t num = numParam->i(); std::vector keys; toStringList(std::back_inserter(keys), keysParam); const ItemListType& items = getItems(e); std::pair range = getPaginationRange(offset, num, items.begin(), items.end()); SharedHandle list = List::g(); for(; range.first != range.second; ++range.first) { SharedHandle entryDict = Dict::g(); createEntry(entryDict, *range.first, e, keys); list->append(entryDict); } if(offset < 0) { std::reverse(list->begin(), list->end()); } return list; } virtual const ItemListType& getItems(DownloadEngine* e) const = 0; virtual void createEntry (const SharedHandle& entryDict, const SharedHandle& item, DownloadEngine* e, const std::vector& keys) const = 0; }; class TellWaitingRpcMethod: public AbstractPaginationRpcMethod { protected: virtual const RequestGroupList& getItems(DownloadEngine* e) const; virtual void createEntry (const SharedHandle& entryDict, const SharedHandle& item, DownloadEngine* e, const std::vector& keys) const; public: static const char* getMethodName() { return "aria2.tellWaiting"; } }; class TellStoppedRpcMethod: public AbstractPaginationRpcMethod { protected: virtual const DownloadResultList& getItems(DownloadEngine* e) const; virtual void createEntry (const SharedHandle& entryDict, const SharedHandle& item, DownloadEngine* e, const std::vector& keys) const; public: static const char* getMethodName() { return "aria2.tellStopped"; } }; class ChangeOptionRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.changeOption"; } }; class ChangeGlobalOptionRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.changeGlobalOption"; } }; class GetVersionRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getVersion"; } }; class GetOptionRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getOption"; } }; class GetGlobalOptionRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getGlobalOption"; } }; class ChangePositionRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.changePosition"; } }; class ChangeUriRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.changeUri"; } }; class GetSessionInfoRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getSessionInfo"; } }; class ShutdownRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.shutdown"; } }; class GetGlobalStatRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.getGlobalStat"; } }; class ForceShutdownRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "aria2.forceShutdown"; } }; class SystemMulticallRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); public: static const char* getMethodName() { return "system.multicall"; } }; class NoSuchMethodRpcMethod:public RpcMethod { protected: virtual SharedHandle process (const RpcRequest& req, DownloadEngine* e); }; // Helper function to store data to entryDict from ds. This function // is used by tellStatus method. void gatherStoppedDownload (const SharedHandle& entryDict, const SharedHandle& ds, const std::vector& keys); // Helper function to store data to entryDict from group. This // function is used by tellStatus/tellActive/tellWaiting method void gatherProgressCommon (const SharedHandle& entryDict, const SharedHandle& group, const std::vector& keys); #ifdef ENABLE_BITTORRENT // Helper function to store BitTorrent metadata from torrentAttrs. void gatherBitTorrentMetadata (const SharedHandle& btDict, const SharedHandle& torrentAttrs); #endif // ENABLE_BITTORRENT } // namespace rpc bool pauseRequestGroup (const SharedHandle& group, bool reserved, bool forcePause); void changeOption (const SharedHandle& group, const Option& option, DownloadEngine* e); void changeGlobalOption(const Option& option, DownloadEngine* e); } // namespace aria2 #endif // D_RPC_METHOD_IMPL_H