/* */ #include "aria2api.h" #include #include "Platform.h" #include "Context.h" #include "DownloadEngine.h" #include "OptionParser.h" #include "Option.h" #include "DlAbortEx.h" #include "fmt.h" #include "OptionHandler.h" #include "RequestGroupMan.h" #include "RequestGroup.h" #include "MultiUrlRequestInfo.h" #include "prefs.h" #include "download_helper.h" #include "LogFactory.h" #include "PieceStorage.h" #include "DownloadContext.h" #include "FileEntry.h" #include "BitfieldMan.h" #include "DownloadContext.h" #include "RpcMethodImpl.h" #include "console.h" #include "KeepRunningCommand.h" #include "A2STR.h" #include "SingletonHolder.h" #include "Notifier.h" #include "ApiCallbackDownloadEventListener.h" #ifdef ENABLE_BITTORRENT #include "bittorrent_helper.h" #endif // ENABLE_BITTORRENT namespace aria2 { Session::Session(const KeyVals& options) : context(std::make_shared(false, 0, nullptr, options)) { } Session::~Session() = default; SessionConfig::SessionConfig() : keepRunning(false), useSignalHandler(true), downloadEventCallback(nullptr), userData(nullptr) { } namespace { Platform* platform = nullptr; } // namespace int libraryInit() { global::initConsole(true); try { platform = new Platform(); } catch (RecoverableException& e) { A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e); return -1; } LogFactory::setConsoleOutput(false); return 0; } int libraryDeinit() { delete platform; return 0; } Session* sessionNew(const KeyVals& options, const SessionConfig& config) { int rv; std::unique_ptr session; try { session = make_unique(options); } catch (RecoverableException& e) { return nullptr; } if (session->context->reqinfo) { if (!config.useSignalHandler) { session->context->reqinfo->setUseSignalHandler(false); } rv = session->context->reqinfo->prepare(); if (rv != 0) { return nullptr; } auto& e = session->context->reqinfo->getDownloadEngine(); if (config.keepRunning) { e->getRequestGroupMan()->setKeepRunning(true); // Add command to make aria2 keep event polling e->addCommand(make_unique(e->newCUID(), e.get())); } if (config.downloadEventCallback) { session->listener = make_unique( session.get(), config.downloadEventCallback, config.userData); SingletonHolder::instance()->addDownloadEventListener( session->listener.get()); } } else { return nullptr; } return session.release(); } int sessionFinal(Session* session) { error_code::Value rv = session->context->reqinfo->getResult(); delete session; return rv; } int run(Session* session, RUN_MODE mode) { auto& e = session->context->reqinfo->getDownloadEngine(); return e->run(mode == RUN_ONCE); } int shutdown(Session* session, bool force) { auto& e = session->context->reqinfo->getDownloadEngine(); if (force) { e->requestForceHalt(); } else { e->requestHalt(); } // Skip next polling timeout. This avoids 1 second delay when there // is no Command other than KeepRunningCommand in the queue. e->setNoWait(true); return 0; } std::string gidToHex(A2Gid gid) { return GroupId::toHex(gid); } A2Gid hexToGid(const std::string& hex) { A2Gid gid; if (GroupId::toNumericId(gid, hex.c_str()) == 0) { return gid; } else { return 0; } } bool isNull(A2Gid gid) { return gid == 0; } namespace { template void apiGatherOption(InputIterator first, InputIterator last, Pred pred, Option* option, const std::shared_ptr& optionParser) { for (; first != last; ++first) { const std::string& optionName = (*first).first; PrefPtr pref = option::k2p(optionName); const OptionHandler* handler = optionParser->find(pref); if (!handler || !pred(handler)) { // Just ignore the unacceptable options in this context. continue; } handler->parse(*option, (*first).second); } } } // namespace namespace { void apiGatherRequestOption(Option* option, const KeyVals& options, const std::shared_ptr& optionParser) { apiGatherOption(options.begin(), options.end(), std::mem_fn(&OptionHandler::getInitialOption), option, optionParser); } } // namespace namespace { void apiGatherChangeableOption( Option* option, const KeyVals& options, const std::shared_ptr& optionParser) { apiGatherOption(options.begin(), options.end(), std::mem_fn(&OptionHandler::getChangeOption), option, optionParser); } } // namespace namespace { void apiGatherChangeableOptionForReserved( Option* option, const KeyVals& options, const std::shared_ptr& optionParser) { apiGatherOption(options.begin(), options.end(), std::mem_fn(&OptionHandler::getChangeOptionForReserved), option, optionParser); } } // namespace namespace { void apiGatherChangeableGlobalOption( Option* option, const KeyVals& options, const std::shared_ptr& optionParser) { apiGatherOption(options.begin(), options.end(), std::mem_fn(&OptionHandler::getChangeGlobalOption), option, optionParser); } } // namespace namespace { void addRequestGroup(const std::shared_ptr& group, DownloadEngine* e, int position) { if (position >= 0) { e->getRequestGroupMan()->insertReservedGroup(position, group); } else { e->getRequestGroupMan()->addReservedGroup(group); } } } // namespace int addUri(Session* session, A2Gid* gid, const std::vector& uris, const KeyVals& options, int position) { auto& e = session->context->reqinfo->getDownloadEngine(); auto requestOption = std::make_shared