浏览代码

Add download event callback API and its example

Tatsuhiro Tsujikawa 12 年之前
父节点
当前提交
e350df2d75

+ 2 - 0
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']:

+ 31 - 1
examples/libaria2ex.cc

@@ -40,13 +40,43 @@
 
 #include <aria2/aria2.h>
 
+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<std::string> uris = {
     "http://localhost/"

+ 57 - 0
src/ApiCallbackDownloadEventListener.cc

@@ -0,0 +1,57 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2013 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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

+ 57 - 0
src/ApiCallbackDownloadEventListener.h

@@ -0,0 +1,57 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2013 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#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

+ 2 - 1
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)

+ 16 - 3
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<DownloadEngine>& 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<DownloadEventListener> listener
+        (new ApiCallbackDownloadEventListener(session,
+                                              config.downloadEventCallback,
+                                              config.userData));
+      SingletonHolder<Notifier>::instance()
+        ->addDownloadEventListener(listener);
+    }
   } else {
     delete session;
-    session = 0;
+    return 0;
   }
   return session;
 }

+ 26 - 0
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;
 };
 
 /**