aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Schink <swo-dev@marcschink.de>2016-08-06 11:04:56 +0200
committerMarc Schink <swo-dev@marcschink.de>2016-08-06 18:05:09 +0200
commit1206312d533a71f8425cc85e85f887440dc9f297 (patch)
treea0ed8c283f5318719bf99228efa1db13fa382b31
parentd633db4a9017827a19317d2e2f6ea333dcb8718d (diff)
bindings: Add log callback functionality
-rw-r--r--bindings/cxx/Context.cpp62
-rw-r--r--bindings/cxx/libswocxx.h11
-rw-r--r--bindings/python/Context.h2
-rw-r--r--bindings/python/swopy.i60
4 files changed, 135 insertions, 0 deletions
diff --git a/bindings/cxx/Context.cpp b/bindings/cxx/Context.cpp
index eb2def2..e85d5b3 100644
--- a/bindings/cxx/Context.cpp
+++ b/bindings/cxx/Context.cpp
@@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdio.h>
+
#include "libswocxx.h"
namespace libswo
@@ -93,6 +95,66 @@ void Context::set_log_domain(const string &domain)
throw Error(ret);
}
+static int log_callback(struct libswo_context *ctx,
+ enum libswo_log_level level, const char *format, va_list args,
+ void *user_data)
+{
+ int ret;
+ LogCallbackHelper *helper;
+ int length;
+ va_list args_copy;
+ char *tmp;
+ std::string message;
+
+ (void)ctx;
+
+ helper = (LogCallbackHelper *)user_data;
+
+ va_copy(args_copy, args);
+ length = vsnprintf(NULL, 0, format, args_copy);
+ va_end(args_copy);
+
+ if (length < 0)
+ return LIBSWO_ERR;
+
+ tmp = (char *)malloc(length + 1);
+
+ if (!tmp)
+ return LIBSWO_ERR_MALLOC;
+
+ length = vsnprintf(tmp, length + 1, format, args);
+
+ if (length < 0) {
+ free(tmp);
+ return LIBSWO_ERR;
+ }
+
+ message.assign(tmp, length);
+ free(tmp);
+
+ ret = helper->callback(static_cast<enum LogLevel>(level), message,
+ helper->user_data);
+
+ return ret;
+}
+
+void Context::set_log_callback(LogCallback callback, void *user_data)
+{
+ int ret;
+
+ if (callback) {
+ _log_callback.callback = callback;
+ _log_callback.user_data = user_data;
+ ret = libswo_log_set_callback(_context, &log_callback,
+ &_log_callback);
+ } else {
+ ret = libswo_set_callback(_context, NULL, NULL);
+ }
+
+ if (ret != LIBSWO_OK)
+ throw Error(ret);
+}
+
void Context::feed(const uint8_t *buffer, size_t length)
{
int ret;
diff --git a/bindings/cxx/libswocxx.h b/bindings/cxx/libswocxx.h
index d70f869..01325a8 100644
--- a/bindings/cxx/libswocxx.h
+++ b/bindings/cxx/libswocxx.h
@@ -98,6 +98,8 @@ public:
};
typedef int (*DecoderCallback)(const Packet &packet, void *user_data);
+typedef int (*LogCallback)(enum LogLevel level, const std::string &message,
+ void *user_data);
class LIBSWO_API Synchronization : public Packet
{
@@ -189,6 +191,13 @@ public:
void *user_data;
};
+class LIBSWO_PRIV LogCallbackHelper
+{
+public:
+ LogCallback callback;
+ void *user_data;
+};
+
class LIBSWO_API Context
{
public:
@@ -201,6 +210,7 @@ public:
string get_log_domain(void) const;
void set_log_domain(const string &domain);
+ void set_log_callback(LogCallback callback, void *user_data = NULL);
void set_callback(DecoderCallback callback, void *user_data = NULL);
@@ -209,6 +219,7 @@ public:
private:
struct libswo_context *_context;
DecoderCallbackHelper _decoder_callback;
+ LogCallbackHelper _log_callback;
};
class LIBSWO_API Version {
diff --git a/bindings/python/Context.h b/bindings/python/Context.h
index 3c81998..3aed9ed 100644
--- a/bindings/python/Context.h
+++ b/bindings/python/Context.h
@@ -31,8 +31,10 @@ public:
~Context(void);
void set_callback(PyObject *callback);
+ void set_log_callback(PyObject *callback);
private:
PyObject *_py_callback;
+ PyObject *_py_log_callback;
};
#endif /* LIBSWO_BINDINGS_PYTHON_CONTEXT_H */
diff --git a/bindings/python/swopy.i b/bindings/python/swopy.i
index e10754b..fbb664b 100644
--- a/bindings/python/swopy.i
+++ b/bindings/python/swopy.i
@@ -86,11 +86,71 @@ Context::Context(size_t buffer_size) :
libswo::Context(buffer_size)
{
_py_callback = NULL;
+ _py_log_callback = NULL;
}
Context::~Context(void)
{
Py_XDECREF(_py_callback);
+ Py_XDECREF(_py_log_callback);
+}
+
+static int log_callback(libswo::LogLevel level, const std::string &message,
+ void *user_data)
+{
+ int ret;
+ PyObject *level_obj;
+ PyObject *message_obj;
+ PyObject *res;
+
+ level_obj = PyLong_FromUnsignedLong(level);
+
+ if (!level_obj)
+ return LIBSWO_ERR;
+
+ message_obj = PyUnicode_FromString(message.c_str());
+
+ if (!message_obj)
+ return LIBSWO_ERR;
+
+ res = PyObject_CallFunctionObjArgs((PyObject *)user_data, level_obj,
+ message_obj, NULL);
+ Py_DECREF(level_obj);
+ Py_DECREF(message_obj);
+
+ if (!res) {
+ PyErr_Print();
+ return LIBSWO_ERR;
+ }
+
+ if (res == Py_None || res == Py_True) {
+ ret = 1;
+ } else if (res == Py_False) {
+ ret = 0;
+ } else {
+ PyErr_SetString(PyExc_TypeError, "log callback function "
+ "neither returned a boolean value nor None");
+ PyErr_Print();
+ ret = LIBSWO_ERR;
+ }
+
+ Py_DECREF(res);
+
+ return ret;
+}
+
+void Context::set_log_callback(PyObject *callback)
+{
+ if (!PyCallable_Check(callback))
+ throw libswo::Error(LIBSWO_ERR_ARG);
+
+ Py_XDECREF(_py_log_callback);
+
+ _py_log_callback = callback;
+ Py_INCREF(_py_log_callback);
+
+ libswo::Context::set_log_callback(&log_callback,
+ (void *)_py_log_callback);
}
static PyObject *packet_object(const libswo::Packet &packet)