All pastes #933973 Raw Edit

Unbenannt

public text v1 · immutable
·published 2008-03-08 15:50 UTC
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