rendered paste body/* ======= otr.i ======= */
%module otr
// [ some includes ]
%{
void check_and_abort(const char * f, int l) {
if (PyErr_Occurred() != NULL) {
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
fprintf(stderr, "%s:%d FATAL: Exception in callback: %s\n", f, l, PyString_AsString(value));
abort();
}
}
void prepare_python_callback(void *opdata, const char * name, PyObject **cb_func, PyObject **kwargs) {
Py_ssize_t len = PySequence_Size(opdata);
check_and_abort(__FILE__,__LINE__);
PyObject *cb_obj = PySequence_GetItem(opdata, 0);
check_and_abort(__FILE__,__LINE__);
*cb_func = PyObject_GetAttrString(cb_obj, name);
check_and_abort(__FILE__,__LINE__);
PyObject *args_opdata = NULL;
if (len >= 2)
args_opdata = PySequence_GetItem(opdata, 1);
check_and_abort(__FILE__,__LINE__);
*kwargs = PyDict_New();
PyDict_SetItemString(*kwargs, "opdata", args_opdata);
check_and_abort(__FILE__,__LINE__);
Py_XDECREF(args_opdata);
Py_DECREF(cb_obj);
}
OtrlPolicy wrap_ops_policy(void *opdata, ConnContext *context) {
const char * name = "policy";
PyObject *cb, *kwargs;
prepare_python_callback(opdata, name, &cb, &kwargs);
PyDict_SetItemString(kwargs, "context", SWIG_NewPointerObj(SWIG_as_voidptr(context), SWIGTYPE_p_p_context, 0 | 0 ));
PyObject *result = PyObject_Call(cb, PyTuple_New(0), kwargs);
check_and_abort(__FILE__,__LINE__);
Py_DECREF(cb); // would crashes with Py_CLEAR here
Py_DECREF(kwargs);
unsigned int retval = (int) PyInt_AsUnsignedLongMask(result);
check_and_abort(__FILE__,__LINE__);
Py_DECREF(result);
return retval;
}
void wrap_ops_update_context_list(void *opdata) {
const char * name = "update_context_list";
PyObject *cb, *kwargs;
prepare_python_callback(opdata, name, &cb, &kwargs);
PyObject_Call(cb, PyTuple_New(0), kwargs);
check_and_abort(__FILE__,__LINE__);
Py_DECREF(cb); // crashes, but doesn't crash with Py_CLEAR here
Py_DECREF(kwargs);
}
void ops_new(OtrlMessageAppOps *ops) {
ops->policy = wrap_ops_policy;
ops->update_context_list = wrap_ops_update_context_list;
}
%}
%rename(otrl_message_sending) wrap_otrl_message_sending;
%inline %{
PyObject* wrap_otrl_message_sending(OtrlUserState us,
PyObject *ops, PyObject *opdata, const char *accountname,
const char *protocol, const char *recipient, const char *message,
OtrlTLV *tlvs, void (*add_appdata)(void *data, ConnContext *context),
void *data) {
OtrlMessageAppOps *c_ops = (OtrlMessageAppOps *) malloc(sizeof(OtrlMessageAppOps));
ops_new(c_ops);
PyObject * ops_t = PyTuple_New(2);
PyTuple_SetItem(ops_t, 0, ops);
PyTuple_SetItem(ops_t, 1, opdata);
char * encMsg = NULL;
gcry_error_t e = otrl_message_sending(us, c_ops, ops_t, accountname,
protocol, recipient, message, tlvs, &encMsg,
add_appdata, data);
free(c_ops);
Py_DECREF(ops_t);
printf("otrl_message_sending finished: %d\n", e);
if (e != 0)
PyErr_SetObject(PyExc_RuntimeError, PyInt_FromLong(e));
else
if (encMsg == NULL) {
return Py_True;
}
else {
return Py_False;
}
}
%}
/* ======= test.py ======= */
import otr;
otr.otrl_init(3,1,0);
us = otr.otrl_userstate_create();
class xyz:
def update_context_list(self,**kwargs):
print "update_context_list", kwargs
def policy(self,**kwargs):
print "policy", kwargs
return otr.OTRL_POLICY_NEVER
x = xyz()
m = otr.otrl_message_sending(us, x, ("some", "thing", 0, 3, 1/3., __builtins__), "from", "proto", "to", "message", None, None, None)
print m