diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-05-16 23:09:19 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2013-05-16 23:09:19 +0900 |
| commit | c7c4d46672a12eec9531723037ee1fb7cd5028b4 (patch) | |
| tree | 698b38190c44204d4b0dd78e65b7c3dbfe002a25 /src | |
| parent | be4c9aa95e4ee240507d91de2925a6d6a2394ebf (diff) | |
Add changeOption and DownloadHandle::getOption API
In aria2c.rst, define section label for "Input File" section so that
it can be referenced from other document.
Diffstat (limited to 'src')
| -rw-r--r-- | src/RpcMethodImpl.cc | 156 | ||||
| -rw-r--r-- | src/RpcMethodImpl.h | 5 | ||||
| -rw-r--r-- | src/aria2api.cc | 83 | ||||
| -rw-r--r-- | src/includes/aria2/aria2.h | 52 |
4 files changed, 217 insertions, 79 deletions
diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc index c88753f7..1142c445 100644 --- a/src/RpcMethodImpl.cc +++ b/src/RpcMethodImpl.cc @@ -1082,85 +1082,6 @@ SharedHandle<ValueBase> RemoveDownloadResultRpcMethod::process return VLB_OK; } -namespace { -void changeOption -(const SharedHandle<RequestGroup>& group, - const Option& option, - DownloadEngine* e) -{ - const SharedHandle<DownloadContext>& dctx = group->getDownloadContext(); - const SharedHandle<Option>& grOption = group->getOption(); - grOption->merge(option); - if(option.defined(PREF_CHECKSUM)) { - const std::string& checksum = grOption->get(PREF_CHECKSUM); - std::pair<Scip, Scip> p; - util::divide(p, checksum.begin(), checksum.end(), '='); - std::string hashType(p.first.first, p.first.second); - util::lowercase(hashType); - dctx->setDigest(hashType, util::fromHex(p.second.first, p.second.second)); - } - if(option.defined(PREF_SELECT_FILE)) { - SegList<int> sgl; - util::parseIntSegments(sgl, grOption->get(PREF_SELECT_FILE)); - sgl.normalize(); - dctx->setFileFilter(sgl); - } - if(option.defined(PREF_SPLIT)) { - group->setNumConcurrentCommand(grOption->getAsInt(PREF_SPLIT)); - } - if(option.defined(PREF_MAX_CONNECTION_PER_SERVER)) { - int maxConn = grOption->getAsInt(PREF_MAX_CONNECTION_PER_SERVER); - const std::vector<SharedHandle<FileEntry> >& files = dctx->getFileEntries(); - for(std::vector<SharedHandle<FileEntry> >::const_iterator i = files.begin(), - eoi = files.end(); i != eoi; ++i) { - (*i)->setMaxConnectionPerServer(maxConn); - } - } - if(option.defined(PREF_DIR) || option.defined(PREF_OUT)) { - if(dctx->getFileEntries().size() == 1 -#ifdef ENABLE_BITTORRENT - && !dctx->hasAttribute(CTX_ATTR_BT) -#endif // ENABLE_BITTORRENT - ) { - dctx->getFirstFileEntry()->setPath - (grOption->blank(PREF_OUT) ? A2STR::NIL : - util::applyDir(grOption->get(PREF_DIR), grOption->get(PREF_OUT))); - } - } -#ifdef ENABLE_BITTORRENT - if(option.defined(PREF_DIR) || option.defined(PREF_INDEX_OUT)) { - if(dctx->hasAttribute(CTX_ATTR_BT)) { - std::istringstream indexOutIn(grOption->get(PREF_INDEX_OUT)); - std::vector<std::pair<size_t, std::string> > indexPaths = - util::createIndexPaths(indexOutIn); - for(std::vector<std::pair<size_t, std::string> >::const_iterator i = - indexPaths.begin(), eoi = indexPaths.end(); i != eoi; ++i) { - dctx->setFilePathWithIndex - ((*i).first, - util::applyDir(grOption->get(PREF_DIR), (*i).second)); - } - } - } -#endif // ENABLE_BITTORRENT - if(option.defined(PREF_MAX_DOWNLOAD_LIMIT)) { - group->setMaxDownloadSpeedLimit - (grOption->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)); - } - if(option.defined(PREF_MAX_UPLOAD_LIMIT)) { - group->setMaxUploadSpeedLimit(grOption->getAsInt(PREF_MAX_UPLOAD_LIMIT)); - } -#ifdef ENABLE_BITTORRENT - const SharedHandle<BtObject>& btObject = - e->getBtRegistry()->get(group->getGID()); - if(btObject) { - if(option.defined(PREF_BT_MAX_PEERS)) { - btObject->btRuntime->setMaxPeers(grOption->getAsInt(PREF_BT_MAX_PEERS)); - } - } -#endif // ENABLE_BITTORRENT -} -} // namespace - SharedHandle<ValueBase> ChangeOptionRpcMethod::process (const RpcRequest& req, DownloadEngine* e) { @@ -1544,4 +1465,81 @@ bool pauseRequestGroup } } +void changeOption +(const SharedHandle<RequestGroup>& group, + const Option& option, + DownloadEngine* e) +{ + const SharedHandle<DownloadContext>& dctx = group->getDownloadContext(); + const SharedHandle<Option>& grOption = group->getOption(); + grOption->merge(option); + if(option.defined(PREF_CHECKSUM)) { + const std::string& checksum = grOption->get(PREF_CHECKSUM); + std::pair<Scip, Scip> p; + util::divide(p, checksum.begin(), checksum.end(), '='); + std::string hashType(p.first.first, p.first.second); + util::lowercase(hashType); + dctx->setDigest(hashType, util::fromHex(p.second.first, p.second.second)); + } + if(option.defined(PREF_SELECT_FILE)) { + SegList<int> sgl; + util::parseIntSegments(sgl, grOption->get(PREF_SELECT_FILE)); + sgl.normalize(); + dctx->setFileFilter(sgl); + } + if(option.defined(PREF_SPLIT)) { + group->setNumConcurrentCommand(grOption->getAsInt(PREF_SPLIT)); + } + if(option.defined(PREF_MAX_CONNECTION_PER_SERVER)) { + int maxConn = grOption->getAsInt(PREF_MAX_CONNECTION_PER_SERVER); + const std::vector<SharedHandle<FileEntry> >& files = dctx->getFileEntries(); + for(std::vector<SharedHandle<FileEntry> >::const_iterator i = files.begin(), + eoi = files.end(); i != eoi; ++i) { + (*i)->setMaxConnectionPerServer(maxConn); + } + } + if(option.defined(PREF_DIR) || option.defined(PREF_OUT)) { + if(dctx->getFileEntries().size() == 1 +#ifdef ENABLE_BITTORRENT + && !dctx->hasAttribute(CTX_ATTR_BT) +#endif // ENABLE_BITTORRENT + ) { + dctx->getFirstFileEntry()->setPath + (grOption->blank(PREF_OUT) ? A2STR::NIL : + util::applyDir(grOption->get(PREF_DIR), grOption->get(PREF_OUT))); + } + } +#ifdef ENABLE_BITTORRENT + if(option.defined(PREF_DIR) || option.defined(PREF_INDEX_OUT)) { + if(dctx->hasAttribute(CTX_ATTR_BT)) { + std::istringstream indexOutIn(grOption->get(PREF_INDEX_OUT)); + std::vector<std::pair<size_t, std::string> > indexPaths = + util::createIndexPaths(indexOutIn); + for(std::vector<std::pair<size_t, std::string> >::const_iterator i = + indexPaths.begin(), eoi = indexPaths.end(); i != eoi; ++i) { + dctx->setFilePathWithIndex + ((*i).first, + util::applyDir(grOption->get(PREF_DIR), (*i).second)); + } + } + } +#endif // ENABLE_BITTORRENT + if(option.defined(PREF_MAX_DOWNLOAD_LIMIT)) { + group->setMaxDownloadSpeedLimit + (grOption->getAsInt(PREF_MAX_DOWNLOAD_LIMIT)); + } + if(option.defined(PREF_MAX_UPLOAD_LIMIT)) { + group->setMaxUploadSpeedLimit(grOption->getAsInt(PREF_MAX_UPLOAD_LIMIT)); + } +#ifdef ENABLE_BITTORRENT + const SharedHandle<BtObject>& btObject = + e->getBtRegistry()->get(group->getGID()); + if(btObject) { + if(option.defined(PREF_BT_MAX_PEERS)) { + btObject->btRuntime->setMaxPeers(grOption->getAsInt(PREF_BT_MAX_PEERS)); + } + } +#endif // ENABLE_BITTORRENT +} + } // namespace aria2 diff --git a/src/RpcMethodImpl.h b/src/RpcMethodImpl.h index 90e439c4..b1b254b5 100644 --- a/src/RpcMethodImpl.h +++ b/src/RpcMethodImpl.h @@ -608,6 +608,11 @@ void gatherBitTorrentMetadata bool pauseRequestGroup (const SharedHandle<RequestGroup>& group, bool reserved, bool forcePause); +void changeOption +(const SharedHandle<RequestGroup>& group, + const Option& option, + DownloadEngine* e); + } // namespace aria2 #endif // D_RPC_METHOD_IMPL_H diff --git a/src/aria2api.cc b/src/aria2api.cc index f3634224..069bb12a 100644 --- a/src/aria2api.cc +++ b/src/aria2api.cc @@ -226,6 +226,27 @@ void apiGatherRequestOption(Option* option, const KeyVals& options, } // namespace namespace { +void apiGatherChangeableOption(Option* option, const KeyVals& options, + const SharedHandle<OptionParser>& optionParser) +{ + apiGatherOption(options.begin(), options.end(), + std::mem_fun(&OptionHandler::getChangeOption), + option, optionParser); +} +} // namespace + +namespace { +void apiGatherChangeableOptionForReserved +(Option* option, const KeyVals& options, + const SharedHandle<OptionParser>& optionParser) +{ + apiGatherOption(options.begin(), options.end(), + std::mem_fun(&OptionHandler::getChangeOptionForReserved), + option, optionParser); +} +} // namespace + +namespace { void addRequestGroup(const SharedHandle<RequestGroup>& group, const SharedHandle<DownloadEngine>& e, int position) @@ -419,6 +440,32 @@ int changePosition(Session* session, const A2Gid& gid, int pos, OffsetMode how) } } +int changeOption(Session* session, const A2Gid& gid, const KeyVals& options) +{ + const SharedHandle<DownloadEngine>& e = + session->context->reqinfo->getDownloadEngine(); + SharedHandle<RequestGroup> group = e->getRequestGroupMan()->findGroup(gid); + if(group) { + Option option; + try { + if(group->getState() == RequestGroup::STATE_ACTIVE) { + apiGatherChangeableOption(&option, options, + OptionParser::getInstance()); + } else { + apiGatherChangeableOptionForReserved(&option, options, + OptionParser::getInstance()); + } + } catch(RecoverableException& err) { + A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, err); + return -1; + } + changeOption(group, option, e.get()); + return 0; + } else { + return -1; + } +} + std::vector<A2Gid> getActiveDownload(Session* session) { const SharedHandle<DownloadEngine>& e = @@ -528,6 +575,23 @@ void createFileEntry } // namespace namespace { +template<typename OutputIterator> +void pushRequestOption +(OutputIterator out, + const SharedHandle<Option>& option, + const SharedHandle<OptionParser>& oparser) +{ + for(size_t i = 1, len = option::countOption(); i < len; ++i) { + const Pref* pref = option::i2p(i); + const OptionHandler* h = oparser->find(pref); + if(h && h->getInitialOption() && option->defined(pref)) { + out++ = KeyVals::value_type(pref->k, option->get(pref)); + } + } +} +} // namespace + +namespace { struct RequestGroupDH : public DownloadHandle { RequestGroupDH(const SharedHandle<RequestGroup>& group) : group(group), @@ -660,6 +724,17 @@ struct RequestGroupDH : public DownloadHandle { #endif // ENABLE_BITTORRENT return res; } + virtual const std::string& getOption(const std::string& name) + { + return group->getOption()->get(option::k2p(name)); + } + virtual KeyVals getOption() + { + KeyVals res; + pushRequestOption(std::back_inserter(res), group->getOption(), + OptionParser::getInstance()); + return res; + } SharedHandle<RequestGroup> group; TransferStat ts; }; @@ -761,6 +836,14 @@ struct DownloadResultDH : public DownloadHandle { { return BtMetaInfoData(); } + virtual const std::string& getOption(const std::string& name) + { + return A2STR::NIL; + } + virtual KeyVals getOption() + { + return KeyVals(); + } SharedHandle<DownloadResult> dr; }; } // namespace diff --git a/src/includes/aria2/aria2.h b/src/includes/aria2/aria2.h index 8ca87e29..c1a4b637 100644 --- a/src/includes/aria2/aria2.h +++ b/src/includes/aria2/aria2.h @@ -405,6 +405,38 @@ int pauseDownload(Session* session, const A2Gid& gid, bool force = false); int unpauseDownload(Session* session, const A2Gid& gid); /** + * @function + * + * Apply options in the |options| to the download denoted by the |gid| + * dynamically. The following options can be changed for downloads in + * :c:macro:`DOWNLOAD_ACTIVE` status: + * + * * :option:`bt-max-peers <--bt-max-peers>` + * * :option:`bt-request-peer-speed-limit <--bt-request-peer-speed-limit>` + * * :option:`bt-remove-unselected-file <--bt-remove-unselected-file>` + * * :option:`force-save <--force-save>` + * * :option:`max-download-limit <--max-download-limit>` + * * :option:`max-upload-limit <-u>` + * + * For downloads in :c:macro:`DOWNLOAD_WAITING` or + * :c:macro:`DOWNLOAD_PAUSED` status, in addition to the above + * options, options listed in :ref:`input-file` subsection are available, + * except for following options: + * :option:`dry-run <--dry-run>`, + * :option:`metalink-base-uri <--metalink-base-uri>`, + * :option:`parameterized-uri <-P>`, + * :option:`pause <--pause>`, + * :option:`piece-length <--piece-length>` and + * :option:`rpc-save-upload-metadata <--rpc-save-upload-metadata>` option. + * + * The options which are not applicable or unknown, they are just + * ignored. + * + * This function returns 0 if it succeeds, or negative error code. + */ +int changeOption(Session* session, const A2Gid& gid, const KeyVals& options); + +/** * @enum * * Constants how to re-position a download. @@ -733,6 +765,26 @@ public: * stopped/completed. */ virtual BtMetaInfoData getBtMetaInfo() = 0; + /** + * Returns the option value denoted by the |name|. If the option + * denoted by the |name| is not available, returns empty string. + * + * Calling this function for the download which is not in + * :c:macro:`DOWNLOAD_ACTIVE`, :c:macro:`DOWNLOAD_PAUSED` or + * :c:macro:`DOWNLOAD_WAITING` will return empty string. + */ + virtual const std::string& getOption(const std::string& name) = 0; + /** + * Returns options for this download. Note that this function does + * not return options which have no default value and have not been + * set by :func:`sessionNew()`, configuration files or API + * functions. + * + * Calling this function for the download which is not in + * :c:macro:`DOWNLOAD_ACTIVE`, :c:macro:`DOWNLOAD_PAUSED` or + * :c:macro:`DOWNLOAD_WAITING` will return empty array. + */ + virtual KeyVals getOption() = 0; }; /** |
