diff --git a/doc/manual-src/en/mkapiref.py b/doc/manual-src/en/mkapiref.py index 9f294783..719751be 100755 --- a/doc/manual-src/en/mkapiref.py +++ b/doc/manual-src/en/mkapiref.py @@ -107,6 +107,8 @@ def make_api_ref(infiles): doctype = line.split()[1] if doctype == '@function': functions.append(process_function('function', infile)) + if doctype == '@functypedef': + types.append(process_function('c:type', infile)) elif doctype == '@typedef': types.append(process_typedef(infile)) elif doctype in ['@class', '@struct', '@union']: diff --git a/examples/libaria2ex.cc b/examples/libaria2ex.cc index 9f0fe83d..f4317988 100644 --- a/examples/libaria2ex.cc +++ b/examples/libaria2ex.cc @@ -40,13 +40,43 @@ #include +int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event, + const aria2::A2Gid& gid, void* userData) +{ + std::cout << "Download Event: "; + switch(event) { + case aria2::EVENT_ON_DOWNLOAD_START: + std::cout << "START"; + break; + case aria2::EVENT_ON_DOWNLOAD_PAUSE: + std::cout << "PAUSE"; + break; + case aria2::EVENT_ON_DOWNLOAD_STOP: + std::cout << "STOP"; + break; + case aria2::EVENT_ON_DOWNLOAD_COMPLETE: + std::cout << "COMPLETE"; + break; + case aria2::EVENT_ON_DOWNLOAD_ERROR: + std::cout << "ERROR"; + break; + case aria2::EVENT_ON_BT_DOWNLOAD_COMPLETE: + std::cout << "COMPLETE"; + break; + } + std::cout << " for [" << aria2::gidToHex(gid) << "]" << std::endl; + return 0; +} + int main() { aria2::libraryInit(); // session is actually singleton: 1 session per process aria2::Session* session; - // Use default configuration + // Create default configuration aria2::SessionConfig config; + // Add event callback + config.downloadEventCallback = downloadEventCallback; session = aria2::sessionNew(aria2::KeyVals(), config); std::vector uris = { "http://localhost/" diff --git a/src/ApiCallbackDownloadEventListener.cc b/src/ApiCallbackDownloadEventListener.cc new file mode 100644 index 00000000..3a5e3742 --- /dev/null +++ b/src/ApiCallbackDownloadEventListener.cc @@ -0,0 +1,57 @@ +/* */ +#include "ApiCallbackDownloadEventListener.h" +#include "RequestGroup.h" + +namespace aria2 { + +ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener +(Session* session, + DownloadEventCallback callback, + void* userData) + : session_(session), + callback_(callback), + userData_(userData) +{} + +ApiCallbackDownloadEventListener::~ApiCallbackDownloadEventListener() {} + +void ApiCallbackDownloadEventListener::onEvent +(DownloadEvent event, const RequestGroup* group) +{ + callback_(session_, event, group->getGID(), userData_); +} + +} // namespace aria2 diff --git a/src/ApiCallbackDownloadEventListener.h b/src/ApiCallbackDownloadEventListener.h new file mode 100644 index 00000000..a681fe98 --- /dev/null +++ b/src/ApiCallbackDownloadEventListener.h @@ -0,0 +1,57 @@ +/* */ +#ifndef DOWNLOAD_EVENT_LISTENER_H +#define DOWNLOAD_EVENT_LISTENER_H + +#include "Notifier.h" + +namespace aria2 { + +class ApiCallbackDownloadEventListener : public DownloadEventListener { +public: + ApiCallbackDownloadEventListener(Session* session, + DownloadEventCallback callback, + void* userData); + virtual ~ApiCallbackDownloadEventListener(); + virtual void onEvent(DownloadEvent event, const RequestGroup* group); +private: + Session* session_; + DownloadEventCallback callback_; + void* userData_; +}; + +} // namespace aria2 + +#endif // DOWNLOAD_EVENT_LISTENER_H diff --git a/src/Makefile.am b/src/Makefile.am index 6aee0591..8920cd94 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -659,7 +659,8 @@ DISTCLEANFILES = $(pkgconfig_DATA) lib_LTLIBRARIES = libaria2.la libaria2_la_SOURCES = $(SRCS) \ aria2api.cc aria2api.h \ - KeepRunningCommand.cc KeepRunningCommand.h + KeepRunningCommand.cc KeepRunningCommand.h \ + ApiCallbackDownloadEventListener.cc ApiCallbackDownloadEventListener.h else # !ENABLE_LIBARIA2 noinst_LTLIBRARIES = libaria2.la libaria2_la_SOURCES = $(SRCS) diff --git a/src/aria2api.cc b/src/aria2api.cc index 42cabbb0..356b7515 100644 --- a/src/aria2api.cc +++ b/src/aria2api.cc @@ -59,6 +59,9 @@ #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 @@ -74,7 +77,9 @@ Session::~Session() SessionConfig::SessionConfig() : keepRunning(false), - useSignalHandler(true) + useSignalHandler(true), + downloadEventCallback(0), + userData(0) {} namespace { @@ -116,7 +121,7 @@ Session* sessionNew(const KeyVals& options, const SessionConfig& config) rv = session->context->reqinfo->prepare(); if(rv != 0) { delete session; - session = 0; + return 0; } const SharedHandle& e = session->context->reqinfo->getDownloadEngine(); @@ -125,9 +130,17 @@ Session* sessionNew(const KeyVals& options, const SessionConfig& config) // Add command to make aria2 keep event polling e->addCommand(new KeepRunningCommand(e->newCUID(), e.get())); } + if(config.downloadEventCallback) { + SharedHandle listener + (new ApiCallbackDownloadEventListener(session, + config.downloadEventCallback, + config.userData)); + SingletonHolder::instance() + ->addDownloadEventListener(listener); + } } else { delete session; - session = 0; + return 0; } return session; } diff --git a/src/includes/aria2/aria2.h b/src/includes/aria2/aria2.h index 5671c4ee..86ef420d 100644 --- a/src/includes/aria2/aria2.h +++ b/src/includes/aria2/aria2.h @@ -130,6 +130,21 @@ enum DownloadEvent { EVENT_ON_BT_DOWNLOAD_COMPLETE }; +/** + * @functypedef + * + * Callback function invoked when download event occurred. The |event| + * indicates the event. See :type:`DownloadEvent` for events. The + * |gid| refers to the download which this event was fired on. The + * |userData| is a pointer specified in + * :member:`SessionConfig::userData`. + * + * At the moment, the return value is ignored, but the implementation + * of this callback should return 0 for compatibility. + */ +typedef int (*DownloadEventCallback)(Session* session, DownloadEvent event, + const A2Gid& gid, void* userData); + /** * @struct * @@ -166,6 +181,17 @@ struct SessionConfig { * handled like shutdown(session, false) is called. */ bool useSignalHandler; + /** + * Specify the callback function which will be invoked when download + * event occurred. See :type:`DownloadEvent` about the download + * event. The default value is ``NULL``. + */ + DownloadEventCallback downloadEventCallback; + /** + * Pointer to user defined data. libaria2 treats this as opaque + * pointer and will not free it. The default value is ``NULL``. + */ + void* userData; }; /**