diff --git a/bindings/bindings.py b/bindings/bindings.py
index 0654be35..b46357d7 100644
--- a/bindings/bindings.py
+++ b/bindings/bindings.py
@@ -374,7 +374,7 @@ class DocString:
raise Exception('should not happen: could not found type for default: ' + annotation)
arg[2]['default'] = prefix + m.group(1)
arg[2]['optional'] = True
- m = re.search(r'\(\s*element-type\s+(\w+)(?:\s+(\w+))?', annotation)
+ m = re.search(r'\(\s*element-type\s+([\w*]+)(?:\s+([\w*]+))?', annotation)
if m:
if len(m.groups()) > 2:
arg[2]['key-type'] = \
diff --git a/bindings/overrides.xml b/bindings/overrides.xml
index 451199c6..88cedcaa 100644
--- a/bindings/overrides.xml
+++ b/bindings/overrides.xml
@@ -198,6 +198,10 @@
+
+
+
+
diff --git a/bindings/python/lang.py b/bindings/python/lang.py
index 3b8ec92a..4ef79ead 100644
--- a/bindings/python/lang.py
+++ b/bindings/python/lang.py
@@ -87,7 +87,13 @@ class Binding:
else:
raise Exception('Unsupported caller owned return type %s' % ((repr(type), name),))
elif is_hashtable(type):
- raise Exception('Unsupported caller owned return type %s' % ((repr(type), name),))
+ el_type = element_type(type)
+ k_type = key_type(type)
+ v_type = value_type(type)
+ if is_cstring(el_type) or (is_cstring(k_type) and is_cstring(v_type)):
+ print_(' g_hash_table_destroy(%s);' % name, file=fd)
+ else:
+ raise Exception('Unsupported free value of type GHashTable: %s' % type)
elif is_object(type):
print_(' if (return_value) g_object_unref(%s);' % name, file=fd)
else:
@@ -528,7 +534,9 @@ if WSF_SUPPORT:
print_(' rc = _lasso.%s(self._cptr%s)' % (
function_name, c_args), file=fd)
print_(' Error.raise_on_rc(rc)', file=fd)
- elif is_int(m.return_arg, self.binding_data) or is_xml_node(m.return_arg) or is_cstring(m.return_arg) or is_boolean(m.return_arg):
+ elif (is_int(m.return_arg, self.binding_data) or is_xml_node(m.return_arg) or
+ is_cstring(m.return_arg) or is_boolean(m.return_arg) or
+ is_hashtable(m.return_arg)):
print_(' return _lasso.%s(self._cptr%s)' % (
function_name, c_args), file=fd)
elif is_glist(m.return_arg):
@@ -539,13 +547,11 @@ if WSF_SUPPORT:
print_(' if value is not None:', file=fd)
print_(' value = tuple([cptrToPy(x) for x in value])', file=fd)
print_(' return value', file=fd)
- elif is_cstring(el_type):
+ elif is_cstring(el_type) or is_xml_node(el_type):
print_(' return _lasso.%s(self._cptr%s)' % (
function_name, c_args), file=fd)
else:
raise Exception('Return Type GList<%s> is not supported' % el_type)
- elif is_hashtable(m.return_arg):
- raise Exception('Return type GHashTable unsupported')
elif is_object(m.return_arg):
print_(' return cptrToPy(_lasso.%s(self._cptr%s))' % (
function_name, c_args), file=fd)
@@ -929,7 +935,7 @@ register_constants(PyObject *d)
arg_def = ' %s %s = %s;' % (arg[0], arg[1], defval)
else:
arg_def = ' %s %s;' % (arg[0], arg[1])
- elif is_xml_node(arg) or is_list(arg) or is_time_t_pointer(arg):
+ elif is_hashtable(arg) or is_xml_node(arg) or is_list(arg) or is_time_t_pointer(arg):
parse_tuple_format.append('O')
parse_tuple_args.append('&cvt_%s' % aname)
arg_def = ' %s %s = NULL;' % (arg[0], arg[1])
@@ -970,7 +976,7 @@ register_constants(PyObject *d)
qualifier = element_type(arg)
if is_cstring(qualifier):
print_(' set_list_of_strings(&%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
- elif qualifier == 'xmlNode*':
+ elif is_xml_node(qualifier):
print_(' set_list_of_xml_nodes(&%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
elif isinstance(qualifier, str) and qualifier.startswith('Lasso'):
print_(' set_list_of_pygobject(&%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
@@ -980,6 +986,14 @@ register_constants(PyObject *d)
print_(' %s = get_xml_node_from_pystring(cvt_%s);' % (arg[1], arg[1]), file=fd)
elif is_time_t_pointer(arg):
print_(' %s = get_time_t(cvt_%s);' % (arg[1], arg[1]), file=fd)
+ elif is_hashtable(arg):
+ el_type = element_type(arg)
+ k_type = key_type(arg)
+ v_type = value_type(arg)
+ if is_cstring(el_type) or (is_cstring(k_type) and is_cstring(v_type)):
+
+ print_(' %s = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);' % arg[1], file=fd)
+ print_(' set_hashtable_of_strings(%s, cvt_%s);' % (arg[1], arg[1]), file=fd)
elif f == 'O':
if is_optional(arg):
print_(' if (PyObject_TypeCheck((PyObject*)cvt_%s, &PyGObjectPtrType)) {' % arg[1], file=fd)
@@ -1021,14 +1035,16 @@ register_constants(PyObject *d)
print_(' PyList_SetItem(cvt_%s_out, 0, out_pyvalue);' % arg[1], file=fd)
elif arg[0] == 'GList*':
qualifier = arg[2].get('element-type')
- if qualifier == 'char*':
+ if is_cstring(qualifier):
print_(' free_list(&%s, (GFunc)g_free);' % arg[1], file=fd)
- elif qualifier == 'xmlNode*':
+ elif is_xml_node(qualifier):
print_(' free_list(&%s, (GFunc)xmlFreeNode);' % arg[1], file=fd)
- elif qualifier == 'LassoNode':
+ elif is_object(qualifier):
print_(' free_list(&%s, (GFunc)g_object_unref);' % arg[1], file=fd)
elif is_time_t_pointer(arg):
print_(' if (%s) free(%s);' % (arg[1], arg[1]), file=fd)
+ elif not is_transfer_full(arg) and is_hashtable(arg):
+ self.free_value(fd, arg)
elif not is_transfer_full(arg) and is_xml_node(arg):
self.free_value(fd, arg)
diff --git a/bindings/python/tests/binding_tests.py b/bindings/python/tests/binding_tests.py
index 3e395122..6d8e0dfa 100755
--- a/bindings/python/tests/binding_tests.py
+++ b/bindings/python/tests/binding_tests.py
@@ -301,6 +301,28 @@ class BindingTestCase(unittest.TestCase):
server = lasso.Server.newFromDump(server_dump)
assert isinstance(server, lasso.Server)
+ def test12(self):
+ node = lasso.Samlp2Extensions()
+ assert not node.any
+ content = '''
+ %s
+ '''
+ node = lasso.Node.newFromXmlNode(content)
+ assert 'next_url' in node.any[1]
+ assert 'huhu' in node.attributes.keys()[0]
+ assert node.attributes.values()[0] == 'xxx'
+ node.any = ('coin',)
+ node.attributes = {'michou': 'zozo'}
+ assert 'coin' in node.dump()
+ assert 'michou="zozo"' in node.dump()
+ node = lasso.Node.newFromDump(node.dump())
+ assert node.any == ('coin',)
+ # on reparse non namespaces attributes are ignore, they should not exist
+ assert node.attributes == {}
+
+
bindingSuite = unittest.makeSuite(BindingTestCase, 'test')
allTests = unittest.TestSuite((bindingSuite, ))
diff --git a/bindings/python/wrapper_top.c b/bindings/python/wrapper_top.c
index 09e999f3..ac930f9e 100644
--- a/bindings/python/wrapper_top.c
+++ b/bindings/python/wrapper_top.c
@@ -148,18 +148,20 @@ get_dict_from_hashtable_of_strings(GHashTable *value)
dict = PyDict_New();
- begin = 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 {
- PyErr_Warn(PyExc_RuntimeWarning, "hashtable contains a null value");
+ if (value) {
+ begin = 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 {
+ PyErr_Warn(PyExc_RuntimeWarning, "hashtable contains a null value");
+ }
}
+ g_list_free(begin);
}
- g_list_free(begin);
proxy = PyDictProxy_New(dict);
Py_DECREF(dict);
@@ -303,7 +305,7 @@ set_hashtable_of_strings(GHashTable *a_hash, PyObject *dict)
while (PyDict_Next(dict, &i, &key, &value)) {
char *ckey = PyString_AsString(key);
char *cvalue = PyString_AsString(value);
- g_hash_table_insert (a_hash, ckey, cvalue);
+ g_hash_table_insert (a_hash, g_strdup(ckey), g_strdup(cvalue));
}
failure:
return;
diff --git a/lasso/utils.h b/lasso/utils.h
index 6128c9a3..cb1491de 100644
--- a/lasso/utils.h
+++ b/lasso/utils.h
@@ -325,6 +325,17 @@
} \
}
+#define lasso_assign_list_of_xml_node(dest, src) \
+ { \
+ GList *__tmp = src; \
+ GList *__iter_dest; \
+ lasso_release_list_of_xml_node(dest); \
+ dest = g_list_copy(__tmp); \
+ for (__iter_dest = dest ; __iter_dest != NULL ; __iter_dest = g_list_next(__iter_dest)) { \
+ __iter_dest->data = xmlCopyNode(__iter_dest->data, 1); \
+ } \
+ }
+
#define lasso_assign_new_sec_key(dest, src) \
{ \
xmlSecKey *__tmp = (src); \
@@ -344,6 +355,21 @@
dest = __tmp; \
}
+G_GNUC_UNUSED static void
+_lasso_copy_helper_assign_table_of_attributes(gpointer key, gpointer val, gpointer dest){
+ g_hash_table_insert((GHashTable*) dest, g_strdup(key), g_strdup(val));
+}
+
+#define lasso_assign_table_of_attributes(dest, src) \
+ {\
+ if (!dest) {\
+ (dest) = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);\
+ }\
+ g_hash_table_remove_all(dest);\
+ g_hash_table_foreach(src, _lasso_copy_helper_assign_table_of_attributes, dest);\
+ }
+
+
/* List appending */
/* lasso_list_add_xxx macros, simplify code around list manipulation (g_list_append needs to be
diff --git a/lasso/xml/saml-2.0/samlp2_extensions.c b/lasso/xml/saml-2.0/samlp2_extensions.c
index 6dc342b3..65875d78 100644
--- a/lasso/xml/saml-2.0/samlp2_extensions.c
+++ b/lasso/xml/saml-2.0/samlp2_extensions.c
@@ -45,33 +45,35 @@
*
*/
+typedef struct _LassoSamlp2ExtensionsPrivate LassoSamlp2ExtensionsPrivate;
+
+struct _LassoSamlp2ExtensionsPrivate {
+ GList *any;
+ GHashTable *attributes;
+};
+
/*****************************************************************************/
/* private methods */
/*****************************************************************************/
static struct XmlSnippet schema_snippets[] = {
+ {"", SNIPPET_LIST_XMLNODES | SNIPPET_ANY | SNIPPET_PRIVATE,
+ G_STRUCT_OFFSET(LassoSamlp2ExtensionsPrivate, any), NULL, NULL, NULL},
+ {"", SNIPPET_ATTRIBUTE | SNIPPET_ANY | SNIPPET_PRIVATE,
+ G_STRUCT_OFFSET(LassoSamlp2ExtensionsPrivate, attributes), NULL, NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
static LassoNodeClass *parent_class = NULL;
+#define GET_PRIVATE(x) G_TYPE_INSTANCE_GET_PRIVATE(x, \
+ LASSO_TYPE_SAMLP2_EXTENSIONS, LassoSamlp2ExtensionsPrivate)
+
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
-{
- LassoNodeClass *parent_class = NULL;
- xmlNode *cur;
-
- parent_class = g_type_class_peek_parent(LASSO_NODE_GET_CLASS(node));
- cur = parent_class->get_xmlNode(node, lasso_dump);
-
- return lasso_node_get_xmlnode_for_any_type(node, cur);
-}
-
static void
class_init(LassoSamlp2ExtensionsClass *klass)
{
@@ -80,10 +82,10 @@ class_init(LassoSamlp2ExtensionsClass *klass)
parent_class = g_type_class_peek_parent(klass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
nclass->node_data->keep_xmlnode = TRUE;
- nclass->get_xmlNode = get_xmlNode;
lasso_node_class_set_nodename(nclass, "Extensions");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ g_type_class_add_private(G_OBJECT_CLASS(klass), sizeof(LassoSamlp2ExtensionsPrivate));
}
GType
@@ -123,3 +125,70 @@ lasso_samlp2_extensions_new()
{
return g_object_new(LASSO_TYPE_SAMLP2_EXTENSIONS, NULL);
}
+
+/**
+ * lasso_samlp2_extensions_get_any:
+ *
+ * Return the list of contained XML nodes.
+ *
+ * Return value:(element-type xmlNode)(transfer none): a #GList of xmlNode.
+ */
+GList*
+lasso_samlp2_extensions_get_any(LassoSamlp2Extensions *extensions)
+{
+ LassoSamlp2ExtensionsPrivate *pv = NULL;
+
+ pv = GET_PRIVATE(extensions);
+
+ return pv->any;
+}
+
+/**
+ * lasso_samlp2_extensions_set_any:
+ * @any:(allow-none)(element-type xmlNode)(transfer none): a list of xmlNode.
+ *
+ * Set the list of contained XML nodes.
+ *
+ */
+void
+lasso_samlp2_extensions_set_any(LassoSamlp2Extensions *extensions, GList *any)
+{
+ LassoSamlp2ExtensionsPrivate *pv = NULL;
+
+ pv = GET_PRIVATE(extensions);
+
+ lasso_assign_list_of_xml_node(pv->any, any);
+}
+
+/**
+ * lasso_samlp2_extensions_get_attributes:
+ *
+ * Return the list of contained XML nodes.
+ *
+ * Return value:(element-type xmlNode)(transfer none): a #GList of xmlNode.
+ */
+GHashTable*
+lasso_samlp2_extensions_get_attributes(LassoSamlp2Extensions *extensions)
+{
+ LassoSamlp2ExtensionsPrivate *pv = NULL;
+
+ pv = GET_PRIVATE(extensions);
+
+ return pv->attributes;
+}
+
+/**
+ * lasso_samlp2_extensions_set_attributes:
+ * @attributes:(element-type char* char*): table of attributes.
+ *
+ * Set the table of XML attributes.
+ */
+void
+lasso_samlp2_extensions_set_attributes(LassoSamlp2Extensions *extensions, GHashTable *attributes)
+{
+ LassoSamlp2ExtensionsPrivate *pv = NULL;
+
+ pv = GET_PRIVATE(extensions);
+
+ lasso_assign_table_of_attributes(pv->attributes, attributes);
+}
diff --git a/lasso/xml/saml-2.0/samlp2_extensions.h b/lasso/xml/saml-2.0/samlp2_extensions.h
index 37c33fcc..91e795b7 100644
--- a/lasso/xml/saml-2.0/samlp2_extensions.h
+++ b/lasso/xml/saml-2.0/samlp2_extensions.h
@@ -62,7 +62,10 @@ struct _LassoSamlp2ExtensionsClass {
LASSO_EXPORT GType lasso_samlp2_extensions_get_type(void);
LASSO_EXPORT LassoNode* lasso_samlp2_extensions_new(void);
-
+LASSO_EXPORT GList* lasso_samlp2_extensions_get_any(LassoSamlp2Extensions *extensions);
+LASSO_EXPORT void lasso_samlp2_extensions_set_any(LassoSamlp2Extensions *extensions, GList *any);
+LASSO_EXPORT GHashTable* lasso_samlp2_extensions_get_attributes(LassoSamlp2Extensions *extensions);
+LASSO_EXPORT void lasso_samlp2_extensions_set_attributes(LassoSamlp2Extensions *extensions, GHashTable *attributes);
#ifdef __cplusplus