diff options
-rw-r--r-- | bindings/java/LassoException_top.java | 6 | ||||
-rw-r--r-- | bindings/java/Makefile.am | 21 | ||||
-rw-r--r-- | bindings/java/tests/LoginTest.java | 24 | ||||
-rw-r--r-- | bindings/lang_java.py | 21 | ||||
-rw-r--r-- | bindings/lang_php5_helpers/php_code.py | 8 | ||||
-rw-r--r-- | bindings/lang_php5_helpers/wrapper_source.py | 4 | ||||
-rw-r--r-- | bindings/lang_python.py | 203 | ||||
-rw-r--r-- | bindings/lang_python_wrapper_top.c | 351 | ||||
-rw-r--r-- | bindings/php5/Makefile.am | 4 | ||||
-rw-r--r-- | bindings/python/Makefile.am | 2 |
10 files changed, 409 insertions, 235 deletions
diff --git a/bindings/java/LassoException_top.java b/bindings/java/LassoException_top.java index 8e08f43c..012b91f8 100644 --- a/bindings/java/LassoException_top.java +++ b/bindings/java/LassoException_top.java @@ -1,6 +1,7 @@ package com.entrouvert.lasso; public class LassoException extends RuntimeException { + private static final long serialVersionUID = 6170037639785281128L; public int errorCode; private static boolean throws_for_recoverable_errors = true; /** If set to true, enables throwing of exception for @@ -18,13 +19,12 @@ public class LassoException extends RuntimeException { protected LassoException(int errorCode) { super(LassoJNI.strError(errorCode)); - errorCode = errorCode; + this.errorCode = errorCode; } protected LassoException(int errorCode, String message) { super(message); - errorCode = errorCode; + this.errorCode = errorCode; } - private static final Class[] paramst = { Integer.class }; protected static int throwError(int errorCode) throws LassoException { if (errorCode == 0 || (! throws_for_recoverable_errors && errorCode > 0)) return errorCode; diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am index be5990a4..d3a91e38 100644 --- a/bindings/java/Makefile.am +++ b/bindings/java/Makefile.am @@ -3,9 +3,8 @@ INCLUDES = -I$(top_srcdir) \ -I$(top_builddir) \ $(SASL_CFLAGS) -AM_JAVACFLAGS=-C -CLASSPATH_ENV= CLASSPATH=.:lasso.jar:/usr/share/java/junit.jar -JAVAROOT=. +# CLASSPATH_ENV= CLASSPATH=.:lasso.jar:/usr/share/java/junit.jar +CLASSPATH=.:tests java_extension_LTLIBRARIES = libjnilasso.la java_extensiondir = ${libdir}/java @@ -16,10 +15,8 @@ lasso_jardir=$(prefix)/share/java lasso_jar_DATA=lasso.jar lasso_jar_class_files = $(java_lasso_source_files:.java=.class) -JAVAH=gcjh - -$(lasso_jar_class_files): %.class: %.java - $(JAVAC) -ftarget=1.4 -C -classpath . -d . $< +%.class: %.java + $(JAVAC) $(CLASSPATH_OPT) $(CLASSPATH) $(JAVAC_FLAGS) $< all_jar_class_files = $(shell find com/entrouvert/lasso -name '*.class' | sed 's%\$$%\\$$%g') @@ -35,8 +32,8 @@ doc: mv .doc doc -com_entrouvert_lasso_LassoJNI.h: $(lasso_jar_class_files) - $(JAVAH) -jni -d . --classpath=. com.entrouvert.lasso.LassoJNI +com_entrouvert_lasso_LassoJNI.h: com/entrouvert/lasso/LassoJNI.class + $(JAVAH) $(JAVAH_FLAGS) -classpath . `echo $< | sed 'su/u.ug;su.classuu'` libjnilasso_la_CFLAGS = -fno-strict-aliasing $(LASSO_CORE_CFLAGS) -I$(top_srcdir) -I$(top_builddir) libjnilasso_la_LDFLAGS = -export-dynamic -prefer-pic -module -avoid-version @@ -61,8 +58,12 @@ clean-local: -rm -rf doc -rm tests/*.class +check tests/BindingTests.class tests/LoginTest.class : CLASSPATH :=$(CLASSPATH):/usr/share/java/junit.jar + +check: tests/BindingTests.class tests/LoginTest.class + LD_LIBRARY_PATH=.libs $(JAVA) -cp $(CLASSPATH):/usr/share/java/junit.jar BindingTests + LD_LIBRARY_PATH=.libs $(JAVA) -cp $(CLASSPATH):/usr/share/java/junit.jar LoginTest -check_JAVA = tests/BindingTests.java tests/LoginTest.java endif diff --git a/bindings/java/tests/LoginTest.java b/bindings/java/tests/LoginTest.java index 5f9286a4..293ad133 100644 --- a/bindings/java/tests/LoginTest.java +++ b/bindings/java/tests/LoginTest.java @@ -42,30 +42,30 @@ import com.entrouvert.lasso.*; public class LoginTest extends TestCase { public String generateIdentityProviderDump() { Server server = new Server( - "../../../tests/data/idp1-la/metadata.xml", - "../../../tests/data/idp1-la/private-key-raw.pem", + "../../tests/data/idp1-la/metadata.xml", + "../../tests/data/idp1-la/private-key-raw.pem", null, - "../../../tests/data/idp1-la/certificate.pem"); + "../../tests/data/idp1-la/certificate.pem"); server.addProvider( LassoConstants.PROVIDER_ROLE_SP, - "../../../tests/data/sp1-la/metadata.xml", - "../../../tests/data/sp1-la/public-key.pem", - "../../../tests/data/ca1-la/certificate.pem"); + "../../tests/data/sp1-la/metadata.xml", + "../../tests/data/sp1-la/public-key.pem", + "../../tests/data/ca1-la/certificate.pem"); String serverDump = server.dump(); return serverDump; } public String generateServiceProviderDump() { Server server = new Server( - "../../../tests/data/sp1-la/metadata.xml", - "../../../tests/data/sp1-la/private-key-raw.pem", + "../../tests/data/sp1-la/metadata.xml", + "../../tests/data/sp1-la/private-key-raw.pem", null, - "../../../tests/data/sp1-la/certificate.pem"); + "../../tests/data/sp1-la/certificate.pem"); server.addProvider( LassoConstants.PROVIDER_ROLE_IDP, - "../../../tests/data/idp1-la/metadata.xml", - "../../../tests/data/idp1-la/public-key.pem", - "../../../tests/data/ca1-la/certificate.pem"); + "../../tests/data/idp1-la/metadata.xml", + "../../tests/data/idp1-la/public-key.pem", + "../../tests/data/ca1-la/certificate.pem"); String serverDump = server.dump(); return serverDump; } diff --git a/bindings/lang_java.py b/bindings/lang_java.py index 4686eb35..7e8cf4c7 100644 --- a/bindings/lang_java.py +++ b/bindings/lang_java.py @@ -100,6 +100,9 @@ def is_collection(type): def is_string_type(type): return type in ['char*', 'const char*', 'gchar*', 'const gchar*'] +def is_const_type(type): + return type in ['const char*', 'const gchar*'] + class JavaBinding: def __init__(self, binding_data): self.binding_data = binding_data @@ -508,7 +511,10 @@ protected static native void destroy(long cptr); # Call function print >> fd, ' ', if m.return_type: - print >> fd, 'return_value = (%s)' % m.return_type, + print >> fd, 'return_value = ', + if 'new' in m.name: + print >>fd, '(%s)' % m.return_type, + print >> fd, '%s(%s);' % (m.name, ', '.join([x[1] for x in m.args])) # Free const char * args idx=0 @@ -531,7 +537,7 @@ protected static native void destroy(long cptr); if m.return_owner: if m.return_type == 'GList*': print >> fd, ' free_glist(&return_value, NULL);' - elif is_string_type(m.return_type): + elif is_string_type(m.return_type) and not is_const_type(m.return_type): print >> fd, ' if (return_value)' print >> fd, ' g_free(return_value);' print >> fd, ' return ret;' @@ -696,6 +702,7 @@ protected static native void destroy(long cptr); if abstract: print >> fd, 'abstract ', print >> fd, 'public class %s extends %s {' % (name,super) + print >> fd, ' private static final long serialVersionUID = 6170037639785281128L;' if not abstract: print >> fd, ' public %s() {' % name print >> fd, ' super(LassoConstants.%s);' % orig[6:] @@ -724,7 +731,15 @@ protected static native void destroy(long cptr); path = lasso_java_path + '%s.java' % class_name fd = open(path,'w') print >> fd, 'package %s;' % lasso_package_name - print >> fd, 'import java.util.*;' + do_import_util = 0 + for m in c.members: + if m[0] in ('GList*','GHashTable*'): + do_import_util = 1 + for m in c.methods: + if m.return_type in ('GList*','GHashTable*'): + do_import_util = 1 + if do_import_util: + print >> fd, 'import java.util.*;' print >> fd, '' #print 'class %s extends %s {' % (class_name,parent_name) print >> fd, 'public class %s extends %s {' % (class_name,parent_name) diff --git a/bindings/lang_php5_helpers/php_code.py b/bindings/lang_php5_helpers/php_code.py index 583172d1..d24b3305 100644 --- a/bindings/lang_php5_helpers/php_code.py +++ b/bindings/lang_php5_helpers/php_code.py @@ -82,6 +82,10 @@ function cptrToPhp ($cptr) { } return null; } + +function getRequestTypeFromSoapMsg($mesg) { + return lasso_get_request_type_from_soap_msg($mesg); +} ''' def generate_class(self, klass): @@ -330,7 +334,7 @@ function cptrToPhp ($cptr) { if m.return_type == 'void': print >> self.fd, ' %s($this->_cptr%s);' % (cname, c_args) elif m.return_type in ('gint', 'int'): - print >> self.fd, ' $rc = %s($this->_cptr%s);' % (m.name, c_args) + print >> self.fd, ' $rc = %s($this->_cptr%s);' % (cname, c_args) print >> self.fd, ' if ($rc == 0) {' print >> self.fd, ' return 0;' print >> self.fd, ' } else if ($rc > 0) {' # recoverable error @@ -339,7 +343,7 @@ function cptrToPhp ($cptr) { print >> self.fd, ' LassoError::throw_on_rc($rc);' print >> self.fd, ' }' else: - print >> self.fd, ' return %s($this->_cptr%s);' % (m.name, c_args) + print >> self.fd, ' return %s($this->_cptr%s);' % (cname, c_args) print >> self.fd, ' }' print >> self.fd, '' diff --git a/bindings/lang_php5_helpers/wrapper_source.py b/bindings/lang_php5_helpers/wrapper_source.py index c6a348a9..e08c089c 100644 --- a/bindings/lang_php5_helpers/wrapper_source.py +++ b/bindings/lang_php5_helpers/wrapper_source.py @@ -217,7 +217,9 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> self.fd, ' %s = (%s)cvt_%s->obj;' % (arg[1], arg[0], arg[1]) if m.return_type is not None: - print >> self.fd, ' return_c_value =', + print >> self.fd, ' return_c_value = ', + if 'new' in m.name: + print >> self.fd, '(%s)' % m.return_type, else: print >> self.fd, ' ', print >> self.fd, '%s(%s);' % (m.name, ', '.join([x[1] for x in m.args])) diff --git a/bindings/lang_python.py b/bindings/lang_python.py index 5464cc52..43aad175 100644 --- a/bindings/lang_python.py +++ b/bindings/lang_python.py @@ -141,7 +141,7 @@ class %sError(%sError): continue cat, detail = m.groups() cat = cat.title().replace('_', '') - detail = detail.title().replace('_', '') + detail = (cat + '_' + detail).title().replace('_', '') if not cat in done_cats: done_cats.append(cat) for exc_cat in self.binding_data.overrides.findall('exception/category'): @@ -611,28 +611,27 @@ register_constants(PyObject *d) {''' % (klassname[5:], mname) self.wrapper_list.append('%s_%s_get' % (klassname[5:], mname)) - print >> fd, ' %s return_value;' % m[0] - if m[0] != 'gboolean': - print >> fd, ' PyObject* return_pyvalue;' + ftype = m[0] + if ftype in ('char*', 'const char*', 'gchar*', 'const gchar*'): + ftype = 'char*' + print >> fd, ' %s return_value;' % ftype + print >> fd, ' PyObject* return_pyvalue;' print >> fd, ' PyGObjectPtr* cvt_this;' print >> fd, ' %s* this;' % klassname print >> fd, '' print >> fd, ' if (! PyArg_ParseTuple(args, "O", &cvt_this)) return NULL;' print >> fd, ' this = (%s*)cvt_this->obj;' % klassname - if self.is_pygobject(m[0]): - print >> fd, ' if (this->%s) {' % m[1] - print >> fd, ' return_value = g_object_ref(this->%s);' % m[1]; - print >> fd, ' } else {' - print >> fd, ' return_value = NULL;' - print >> fd, ' }' - elif m[0] in ('char*', 'const char*', 'gchar*', 'const gchar*'): + if self.is_pygobject(ftype): + print >> fd, ' return_value = this->%s;' % m[1]; + elif ftype in ('char*',): print >> fd, ' return_value = g_strdup(this->%s);' % m[1] else: print >> fd, ' return_value = this->%s;' % m[1]; - self.return_value(fd, m[0], m[2]) + self.return_value(fd, ftype, m[2]) + print >> fd, ' return return_pyvalue;' print >> fd, '}' print >> fd, '' @@ -645,6 +644,7 @@ register_constants(PyObject *d) print >> fd, ' PyGObjectPtr* cvt_this;' print >> fd, ' %s* this;' % klassname arg_type = m[0] + # Determine type class if m[0] in ('char*', 'const char*', 'gchar*', 'const gchar*'): arg_type = arg_type.replace('const ', '') parse_format = 'z' @@ -654,20 +654,19 @@ register_constants(PyObject *d) parse_format = 'i' parse_arg = '&value' print >> fd, ' %s value;' % arg_type - elif arg_type == 'GList*': + elif arg_type in ('GList*','GHashTable*'): parse_format = 'O' print >> fd, ' PyObject *cvt_value;' - print >> fd, ' int i, l;' parse_arg = '&cvt_value' else: parse_format = 'O' print >> fd, ' PyGObjectPtr *cvt_value;' parse_arg = '&cvt_value' - + # Get GObject print >> fd, ' if (! PyArg_ParseTuple(args, "O%s", &cvt_this, %s)) return NULL;' % ( parse_format, parse_arg) print >> fd, ' this = (%s*)cvt_this->obj;' % klassname - + # Change value if parse_format == 'i': print >> fd, ' this->%s = value;' % m[1] elif parse_format in ('s', 'z'): @@ -675,83 +674,17 @@ register_constants(PyObject *d) print >> fd, ' this->%s = g_strdup(value);' % m[1] elif parse_format == 'O' and arg_type == 'GList*': elem_type = m[2].get('elem_type') - print >> fd, '''\ - if (cvt_value != Py_None && !PyTuple_Check(cvt_value)) { - PyErr_SetString(PyExc_TypeError, "value should be tuple"); - return NULL; - } -''' if elem_type == 'char*': - print >> fd, '''\ - if (this->%(v)s) { - /* free existing list */ - g_list_foreach(this->%(v)s, (GFunc)g_free, NULL); - g_list_free(this->%(v)s); - } - this->%(v)s = NULL; - /* create new list */ - if (cvt_value == Py_None) { - l = 0; - } else { - l = PyTuple_Size(cvt_value); - } - for (i=0; i<l; i++) { - PyObject *pystr = PyTuple_GET_ITEM(cvt_value, i); - this->%(v)s = g_list_append(this->%(v)s, g_strdup(PyString_AsString(pystr))); - }''' % {'v': m[1]} + print >> fd, ' set_list_of_strings(&this->%s, cvt_value);' % m[1] elif elem_type == 'xmlNode*': - # each item is a xmlNode* - print >> fd, '''\ - if (this->%(v)s) { - /* free existing list */ - g_list_foreach(this->%(v)s, (GFunc)xmlFreeNode, NULL); - g_list_free(this->%(v)s); - } - this->%(v)s = NULL; - /* create new list */ - if (cvt_value == Py_None) { - l = 0; - } else { - l = PyTuple_Size(cvt_value); - } - for (i=0; i<l; i++) { - xmlNode *item_node = get_xml_node_from_pystring(PyTuple_GET_ITEM(cvt_value, i)); - this->%(v)s = g_list_append(this->%(v)s, item_node); - }''' % {'v': m[1]} - pass + print >> fd, ' set_list_of_xml_nodes(&this->%s, cvt_value);' % m[1] else: - # assumes type is GObject - print >> fd, '''\ - if (this->%(v)s) { - /* free existing list */ - g_list_foreach(this->%(v)s, (GFunc)g_object_unref, NULL); - g_list_free(this->%(v)s); - } - this->%(v)s = NULL; - /* create new list */ - if (cvt_value == Py_None) { - l = 0; - } else { - l = PyTuple_Size(cvt_value); - } - for (i=0; i<l; i++) { - /* XXX: should check it is really a PyGObjectPtr */ - PyGObjectPtr *pyobj = (PyGObjectPtr*)PyTuple_GET_ITEM(cvt_value, i); - this->%(v)s = g_list_append(this->%(v)s, g_object_ref(pyobj->obj)); - }''' % {'v': m[1]} - + print >> fd, ' set_list_of_pygobject(&this->%s, cvt_value);' % m[1] + elif parse_format == 'O' and arg_type == 'GHashTable*': + print >> fd, ' set_hashtable_of_pygobject(this->%s, cvt_value);' % m[1] elif parse_format == 'O': - print >> fd, ' if (this->%s) {' % m[1] - print >> fd, ' g_object_unref(this->%s);' % m[1] - print >> fd, ' }' - print >> fd, ' if ((PyObject*)cvt_value == Py_None) {' - print >> fd, ' this->%s = NULL;' % m[1] - print >> fd, ' } else {' - print >> fd, ' this->%s = (%s)g_object_ref(cvt_value->obj);' % (m[1], m[0]) - print >> fd, ' }' - - print >> fd, ' Py_INCREF(Py_None);' - print >> fd, ' return Py_None;' + print >> fd, ' set_object_field((GObject**)&this->%s, cvt_value);' % m[1] + print >> fd, ' return noneRef();' print >> fd, '}' print >> fd, '' @@ -760,106 +693,54 @@ register_constants(PyObject *d) if vtype == 'gboolean': print >> fd, ' if (return_value) {' print >> fd, ' Py_INCREF(Py_True);' - print >> fd, ' return Py_True;' + print >> fd, ' return_pyvalue = Py_True;' print >> fd, ' } else {' print >> fd, ' Py_INCREF(Py_False);' - print >> fd, ' return Py_False;' + print >> fd, ' return_pyvalue = Py_False;' print >> fd, ' }' elif vtype in ['int', 'gint'] + self.binding_data.enums: print >> fd, ' return_pyvalue = PyInt_FromLong(return_value);' - print >> fd, ' Py_INCREF(return_pyvalue);' - print >> fd, ' return return_pyvalue;' elif vtype in ('char*', 'gchar*'): print >> fd, ' if (return_value) {' print >> fd, ' return_pyvalue = PyString_FromString(return_value);' print >> fd, ' g_free(return_value);' - print >> fd, ' Py_INCREF(return_pyvalue);' - print >> fd, ' return return_pyvalue;' print >> fd, ' } else {' - print >> fd, ' Py_INCREF(Py_None);' - print >> fd, ' return Py_None;' + print >> fd, ' return_pyvalue = noneRef();' print >> fd, ' }' elif vtype in ('const char*', 'const gchar*'): print >> fd, ' if (return_value) {' print >> fd, ' return_pyvalue = PyString_FromString(return_value);' - print >> fd, ' Py_INCREF(return_pyvalue);' - print >> fd, ' return return_pyvalue;' print >> fd, ' } else {' - print >> fd, ' Py_INCREF(Py_None);' - print >> fd, ' return Py_None;' + print >> fd, ' return_pyvalue = noneRef();' print >> fd, ' }' elif vtype in ('GList*',): - print >> fd, '''\ - if (return_value == NULL) { - Py_INCREF(Py_None); - return Py_None; - } else { - GList *item; - int i; - - item = return_value; - return_pyvalue = PyTuple_New(g_list_length(return_value));''' elem_type = options.get('elem_type') if elem_type == 'char*': - print >> fd, '''\ - for (i = 0; item; i++) { - PyTuple_SetItem(return_pyvalue, i, PyString_FromString(item->data)); - item = g_list_next(item); - }''' + print >> fd, ' return_pyvalue = get_list_of_strings(return_value);' elif elem_type == 'xmlNode*': - print >> fd, '''\ - for (i = 0; item; i++) { - PyTuple_SetItem(return_pyvalue, i, get_pystring_from_xml_node(item->data)); - item = g_list_next(item); - }''' + print >> fd, ' return_pyvalue = get_list_of_xml_nodes(return_value);' else: - # assume GObject* - print >> fd, '''\ - for (i = 0; item; i++) { - PyTuple_SetItem(return_pyvalue, i, PyGObjectPtr_New(g_object_ref(item->data))); - item = g_list_next(item); - }''' - print >> fd, '''\ - return return_pyvalue; - }''' + print >> fd, ' return_pyvalue = get_list_of_pygobject(return_value);' elif vtype in ('GHashTable*',): - print >> fd, '''\ - if (return_value == NULL) { - Py_INCREF(Py_None); - return Py_None; - } else {''' elem_type = options.get('elem_type') if elem_type == 'char*': - print >> fd, '''\ - return_pyvalue = get_dict_from_hashtable_of_strings(return_value);''' + print >> fd, ' return_pyvalue = get_dict_from_hashtable_of_strings(return_value);' else: - print >> fd, '''\ - return_pyvalue = get_dict_from_hashtable_of_objects(return_value);''' - print >> fd, '''\ - return return_pyvalue; - }''' + print >> fd, ' return_pyvalue = get_dict_from_hashtable_of_objects(return_value);' elif vtype == 'xmlNode*': # convert xmlNode* to strings print >> fd, ' if (return_value) {' print >> fd, ' return_pyvalue = get_pystring_from_xml_node(return_value);' - print >> fd, ' Py_INCREF(return_pyvalue);' - print >> fd, ' return return_pyvalue;' print >> fd, ' } else {' - print >> fd, ' Py_INCREF(Py_None);' - print >> fd, ' return Py_None;' + print >> fd, ' return_pyvalue = noneRef();' print >> fd, ' }' - elif vtype in ('GList*',): - - pass else: # return a PyGObjectPtr (wrapper around GObject) print >> fd, '''\ if (return_value) { return_pyvalue = PyGObjectPtr_New(G_OBJECT(return_value)); - return return_pyvalue; } else { - Py_INCREF(Py_None); - return Py_None; + return_pyvalue = noneRef(); } ''' @@ -904,8 +785,7 @@ register_constants(PyObject *d) if m.return_type: print >> fd, ' %s return_value;' % m.return_type - if m.return_type != 'gboolean': - print >> fd, ' PyObject* return_pyvalue;' + print >> fd, ' PyObject* return_pyvalue;' print >> fd, '' parse_tuple_args = ', '.join(parse_tuple_args) @@ -920,17 +800,20 @@ register_constants(PyObject *d) print >> fd, ' %s = (%s)cvt_%s->obj;' % (arg[1], arg[0], arg[1]) if m.return_type: - print >> fd, ' return_value =', + print >> fd, ' return_value = ', + if 'new' in m.name: + print >> fd, '(%s)' % m.return_type, print >> fd, '%s(%s);' % (m.name, ', '.join([x[1] for x in m.args])) - if not m.return_owner: - print >> fd, ' if (return_value) return_value = g_object_ref(return_value);' - if not m.return_type: - print >> fd, ' Py_INCREF(Py_None);' - print >> fd, ' return Py_None;' + print >> fd, ' return noneRef();' else: + # Constructor so decrease refcount (it was incremented by PyGObjectPtr_New called + # in self.return_value self.return_value(fd, m.return_type, {}) + if m.return_owner and self.is_pygobject(m.return_type): + print >> fd, ' if (return_value) g_object_unref(return_value);' + print >> fd, ' return return_pyvalue;' print >> fd, '}' print >> fd, '' diff --git a/bindings/lang_python_wrapper_top.c b/bindings/lang_python_wrapper_top.c index d8ae5967..33ce2801 100644 --- a/bindings/lang_python_wrapper_top.c +++ b/bindings/lang_python_wrapper_top.c @@ -8,12 +8,43 @@ GQuark lasso_wrapper_key; PyMODINIT_FUNC init_lasso(void); static PyObject* get_pystring_from_xml_node(xmlNode *xmlnode); static xmlNode* get_xml_node_from_pystring(PyObject *string); -static PyObject* get_dict_from_hashtable_of_strings(GHashTable *value); static PyObject* get_dict_from_hashtable_of_objects(GHashTable *value); static PyObject* PyGObjectPtr_New(GObject *obj); +static void set_hashtable_of_pygobject(GHashTable *a_hash, PyObject *dict); +static void set_list_of_strings(GList **a_list, PyObject *seq); +static void set_list_of_xml_nodes(GList **a_list, PyObject *seq); +static void set_list_of_pygobject(GList **a_list, PyObject *seq); +static PyObject *get_list_of_strings(GList *a_list); +static PyObject *get_list_of_xml_nodes(GList *a_list); +static PyObject *get_list_of_pygobject(GList *a_list); +typedef struct { + PyObject_HEAD + GObject *obj; + PyObject *typename; +} PyGObjectPtr; +static PyTypeObject PyGObjectPtrType; /* utility functions */ +static PyObject * +noneRef() { + Py_INCREF(Py_None); + return Py_None; +} +#if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 12) +void +g_hash_table_remove_all (GHashTable *hash_table) +{ + g_return_if_fail (hash_table != NULL); + +#ifndef G_DISABLE_ASSERT + if (hash_table->nnodes != 0) + hash_table->version++; +#endif + g_hash_table_remove_all_nodes (hash_table, TRUE); + g_hash_table_maybe_resize (hash_table); +} +#endif #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14) /* copy of private struct and g_hash_table_get_keys from GLib internals * (as this function is useful but new in 2.14) */ @@ -56,40 +87,13 @@ g_hash_table_get_keys (GHashTable *hash_table) return retval; } - #endif static PyObject* -get_dict_from_hashtable_of_strings(GHashTable *value) -{ - GList *keys; - PyObject *dict; - char *item_value; - PyObject *item; - - dict = PyDict_New(); - - keys = g_hash_table_get_keys(value); - for (; keys; keys = g_list_next(keys)) { - item_value = g_hash_table_lookup(value, keys->data); - if (item_value) { - item = PyString_FromString(item_value); - PyDict_SetItemString(dict, (char*)keys->data, item); - Py_DECREF(item); - } else { - PyDict_SetItemString(dict, (char*)keys->data, Py_None); - } - } - g_list_free(keys); - - return PyDictProxy_New(dict); -} - -static PyObject* get_dict_from_hashtable_of_objects(GHashTable *value) { GList *keys; - PyObject *dict; + PyObject *dict,*proxy; GObject *item_value; PyObject *item; @@ -103,12 +107,14 @@ get_dict_from_hashtable_of_objects(GHashTable *value) PyDict_SetItemString(dict, (char*)keys->data, item); Py_DECREF(item); } else { - PyDict_SetItemString(dict, (char*)keys->data, Py_None); + PyErr_Warn(PyExc_RuntimeWarning, "hashtable contains a null value"); } } g_list_free(keys); - return PyDictProxy_New(dict); + proxy = PyDictProxy_New(dict); + Py_DECREF(dict); + return proxy; } static PyObject* @@ -138,6 +144,158 @@ get_pystring_from_xml_node(xmlNode *xmlnode) return pystring; } +gboolean +valid_seq(PyObject *seq) { + if (! seq || ( seq != Py_None && ! PyTuple_Check(seq))) { + PyErr_SetString(PyExc_TypeError, "value should be tuple"); + return 0; + } + return 1; +} + +void free_list(GList **a_list, GFunc free_help) { + if (*a_list) { + g_list_foreach(*a_list, free_help, NULL); + g_list_free(*a_list); + } +} + +/** Remove all elements from a_hash and replace them with + * the key-values pairs from the python dict. + * Increase reference of new values before removeing + * values from the hash, so if there are somme common + * values with RefCoun = 1 they won't be deallocated. + * */ +static void +set_hashtable_of_pygobject(GHashTable *a_hash, PyObject *dict) { + PyObject *key, *value; + int i; + + if (! a_hash) { + PyErr_SetString(PyExc_TypeError, "hashtable does not exist"); + return; + } + if (dict != Py_None && ! PyDict_Check(dict)) { + PyErr_SetString(PyExc_TypeError, "value should be a frozen dict"); + return; + } + i = 0; + // Increase ref count of common object between old and new + // value of the hashtable + while (PyDict_Next(dict, &i, &key, &value)) { + if (! PyString_Check(key) || ! PyObject_TypeCheck(value, &PyGObjectPtrType)) + { + PyErr_SetString(PyExc_TypeError, + "value should be a dict," + "with string keys" + "and GObjectPtr values"); + goto failure; + } + g_object_ref(((PyGObjectPtr*)value)->obj); + } + g_hash_table_remove_all (a_hash); + while (PyDict_Next(dict, &i, &key, &value)) { + char *ckey = g_strdup(PyString_AsString(key)); + g_hash_table_replace (a_hash, ckey, ((PyGObjectPtr*)value)->obj); + } + return; +failure: + i = 0; + while (PyDict_Next(dict, &i, &key, &value)) { + if (! PyString_Check(key) || ! PyObject_TypeCheck(value, &PyGObjectPtrType)) + break; + g_object_unref((PyGObjectPtr*)value); + } +} + +/** Set the GList* pointer, pointed by a_list, to a pointer on a new GList + * created by converting the python seq into a GList of char*. + */ +static void +set_list_of_strings(GList **a_list, PyObject *seq) { + GList *list = NULL; + int l = 0,i; + + g_return_if_fail(valid_seq(seq)); + if (seq != Py_None) { + l = PySequence_Length(seq); + } + for (i=0; i<l; i++) { + PyObject *pystr = PySequence_Fast_GET_ITEM(seq, i); + if (! PyString_Check(pystr)) { + PyErr_SetString(PyExc_TypeError, + "value should be a tuple of strings"); + goto failure; + } + list = g_list_append(list, g_strdup(PyString_AsString(pystr))); + } + free_list(a_list, (GFunc)g_free); + *a_list = list; + return; +failure: + free_list(&list, (GFunc)g_free); +} + +/** Set the GList* pointer, pointed by a_list, to a pointer on a new GList + * created by converting the python seq into a GList of xmlNode*. + */ +static void +set_list_of_xml_nodes(GList **a_list, PyObject *seq) { + GList *list = NULL; + int l = 0,i; + + g_return_if_fail(valid_seq(seq)); + if (seq != Py_None) { + l = PySequence_Length(seq); + } + for (i=0; i<l; i++) { + PyObject *item = PySequence_Fast_GET_ITEM(seq, i); + xmlNode *item_node; + if (! PyString_Check(item)) { + PyErr_SetString(PyExc_TypeError, + "value should be a tuple of strings"); + goto failure; + } + item_node = get_xml_node_from_pystring(item); + list = g_list_append(list, item_node); + } + free_list(a_list, (GFunc)xmlFreeNode); + *a_list = list; + return; +failure: + free_list(&list, (GFunc)xmlFreeNode); +} + +/** Set the GList* pointer, pointed by a_list, to a pointer on a new GList + * created by converting the python seq into a GList of GObject*. + */ +static void +set_list_of_pygobject(GList **a_list, PyObject *seq) { + GList *list = NULL; + int l = 0,i; + + g_return_if_fail(valid_seq(seq)); + if (seq != Py_None) { + l = PySequence_Length(seq); + } + for (i=0; i<l; i++) { + PyObject *item = PySequence_Fast_GET_ITEM(seq, i); + GObject *gobject; + if (! PyObject_TypeCheck(item, &PyGObjectPtrType)) { + PyErr_SetString(PyExc_TypeError, + "value should be a tuple of PyGobject"); + goto failure; + } + gobject = g_object_ref(((PyGObjectPtr*)item)->obj); + list = g_list_append(list, gobject); + } + free_list(a_list, (GFunc)g_object_unref); + *a_list = list; + return; +failure: + free_list(&list, (GFunc)g_object_unref); +} + static xmlNode* get_xml_node_from_pystring(PyObject *string) { xmlDoc *doc; @@ -152,17 +310,117 @@ get_xml_node_from_pystring(PyObject *string) { return node; } +/** Return a tuple containing the string contained in a_list */ +static PyObject * +get_list_of_strings(GList *a_list) { + PyObject *a_tuple = NULL; + int i = 0; + if (! a_list) { + return noneRef(); + } + a_tuple = PyTuple_New(g_list_length(a_list)); + if (! a_tuple) + goto failure; + while (a_list) { + if (a_list->data) { + PyObject *str = PyString_FromString((const char*)a_list->data); + if (!str) { + goto failure; + } + PyTuple_SetItem(a_tuple, i, str); + i++; + } else { + PyErr_Warn(PyExc_RuntimeWarning, + "list contains a NULL value"); + } + a_list = a_list->next; + } + if (_PyTuple_Resize(&a_tuple, i)) + goto failure; + return a_tuple; +failure: + PyErr_SetString(PyExc_TypeError, "Allocation problem in get_list_of_strings"); + Py_XDECREF(a_tuple); + return noneRef(); +} + +static PyObject * +get_list_of_xml_nodes(GList *a_list) { + PyObject *a_tuple = NULL; + int i = 0; + + if (! a_list) { + return noneRef(); + } + a_tuple = PyTuple_New(g_list_length(a_list)); + if (! a_tuple) + goto failure; + while (a_list) { + if (a_list->data) { + PyObject *str = get_pystring_from_xml_node((xmlNode*)a_list->data); + if (str) { + PyTuple_SetItem(a_tuple, i, str); + i++; + } else { + PyErr_Warn(PyExc_RuntimeWarning, + "could not convert an xmlNode to a string"); + } + } else { + PyErr_Warn(PyExc_RuntimeWarning, + "list contains a NULL value"); + } + a_list = a_list->next; + } + if (_PyTuple_Resize(&a_tuple, i)) + goto failure; + return a_tuple; +failure: + PyErr_SetString(PyExc_TypeError, "Allocation problem in get_list_of_strings"); + Py_XDECREF(a_tuple); + return noneRef(); +} + +static PyObject * +get_list_of_pygobject(GList *a_list) { + PyObject *a_tuple = NULL; + int i = 0; + + if (! a_list) { + return noneRef(); + } + a_tuple = PyTuple_New(g_list_length(a_list)); + if (! a_tuple) + goto failure; + while (a_list) { + if (a_list->data) { + PyObject *pygobject; + pygobject = PyGObjectPtr_New((GObject*)a_list->data); + if (pygobject) { + PyTuple_SetItem(a_tuple, i, pygobject); + i++; + } else { + PyErr_Warn(PyExc_RuntimeWarning, + "could not convert a GObject to a PyGobject"); + } + } else { + PyErr_Warn(PyExc_RuntimeWarning, + "list contains a NULL value"); + } + a_list = a_list->next; + } + if (_PyTuple_Resize(&a_tuple, i)) + goto failure; + return a_tuple; +failure: + PyErr_SetString(PyExc_TypeError, "Allocation problem in get_list_of_strings"); + Py_XDECREF(a_tuple); + return noneRef(); +} /* wrapper around GObject */ -typedef struct { - PyObject_HEAD - GObject *obj; - PyObject *typename; -} PyGObjectPtr; -static PyTypeObject PyGObjectPtrType; static void PyGObjectPtr_dealloc(PyGObjectPtr *self) @@ -185,8 +443,7 @@ PyGObjectPtr_New(GObject *obj) PyGObjectPtr *self; if (obj == NULL) { - Py_INCREF(Py_None); - return Py_None; + return noneRef(); } self = (PyGObjectPtr*)g_object_get_qdata(obj, lasso_wrapper_key); @@ -195,7 +452,7 @@ PyGObjectPtr_New(GObject *obj) } else { self = (PyGObjectPtr*)PyObject_NEW(PyGObjectPtr, &PyGObjectPtrType); g_object_set_qdata_full(obj, lasso_wrapper_key, self, NULL); - self->obj = obj; + self->obj = g_object_ref(obj); self->typename = PyString_FromString(G_OBJECT_TYPE_NAME(obj)+5); } return (PyObject*)self; @@ -215,7 +472,8 @@ static PyMemberDef PyGObjectPtr_members[] = { {NULL} }; -static PyObject* PyGObjectPtr_get_refcount(PyGObjectPtr *self, void *closure) +static PyObject* +PyGObjectPtr_get_refcount(PyGObjectPtr *self, void *closure) { PyObject *refcount; @@ -265,3 +523,14 @@ static PyTypeObject PyGObjectPtrType = { PyGObjectPtr_getseters, /* tp_getset */ }; +static void +set_object_field(GObject **a_gobject_ptr, PyGObjectPtr *a_pygobject) { + if (*a_gobject_ptr) { + g_object_unref(*a_gobject_ptr); + } + if ((PyObject*)a_pygobject == Py_None) { + *a_gobject_ptr = NULL; + } else { + *a_gobject_ptr = g_object_ref(a_pygobject->obj); + } +} diff --git a/bindings/php5/Makefile.am b/bindings/php5/Makefile.am index c9e399b8..17c5278c 100644 --- a/bindings/php5/Makefile.am +++ b/bindings/php5/Makefile.am @@ -15,14 +15,14 @@ nodist_lasso_la_SOURCES = _lasso.c BUILT_SOURCES = _lasso.c -_lasso.c: +lasso.php _lasso.c: $(PYTHON) $(top_srcdir)/bindings/bindings.py -l php5 --src-dir=$(top_srcdir)/lasso/ doc: phpdoc -o HTML:frames:earthli -f lasso.php -t docs clean-local: - -rm lasso.php php_lasso.h _lasso.c + -rm -f lasso.php php_lasso.h _lasso.c .PHONY: doc diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am index 65b4be55..62facaff 100644 --- a/bindings/python/Makefile.am +++ b/bindings/python/Makefile.am @@ -28,6 +28,6 @@ _lasso.c: $(PYTHON) $(top_srcdir)/bindings/bindings.py -l python --src-dir=$(top_srcdir)/lasso/ clean-local: - -rm lasso.py lasso.pyc _lasso.c + -rm -f lasso.py lasso.pyc _lasso.c endif |