diff options
| author | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-01-28 15:31:49 +0000 |
|---|---|---|
| committer | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-01-28 15:31:49 +0000 |
| commit | 1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce (patch) | |
| tree | 014771b1f67344ee8ad19807f541f73eb357f7ea | |
| parent | a1ae48d2ef48492faafd26464e64e2dccd0d8565 (diff) | |
| download | lasso-1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce.tar.gz lasso-1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce.tar.xz lasso-1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce.zip | |
Bindings: java, php5, python simplify logic in binding generator
* use utils.h macros to manipulate fields.
* use utils.py function to filter variables, argument and return types.
* finish support of hashtables of strings for php5 and python.
| -rw-r--r-- | bindings/java/lang.py | 18 | ||||
| -rw-r--r-- | bindings/php5/php_code.py | 103 | ||||
| -rw-r--r-- | bindings/php5/wrapper_source.py | 268 | ||||
| -rw-r--r-- | bindings/php5/wrapper_source_top.c | 64 | ||||
| -rw-r--r-- | bindings/python/lang.py | 205 | ||||
| -rwxr-xr-x | bindings/python/tests/idwsf2_tests.py | 80 | ||||
| -rw-r--r-- | bindings/python/wrapper_top.c | 68 |
7 files changed, 439 insertions, 367 deletions
diff --git a/bindings/java/lang.py b/bindings/java/lang.py index 8c60e7bc..fc0fdd5b 100644 --- a/bindings/java/lang.py +++ b/bindings/java/lang.py @@ -416,12 +416,12 @@ protected static native void destroy(long cptr); return 'get_list_of_xml_nodes(env, %s, &%s)' % (right, left) else: return 'get_list_of_objects(env, %s, &%s)' % (right, left) - elif type in ('GHashTable*',): + elif is_hashtable(type): element_type = options.get('element-type') - if element_type == 'char*': - return 'get_hash_of_strings(env, %s, &%s)' % (right, left) - else: + if is_object(element_type): return 'get_hash_of_objects(env, %s, &%s)' % (right, left) + else: + return 'get_hash_of_strings(env, %s, &%s)' % (right, left) elif type == 'xmlNode*': return 'xml_node_to_jstring(env, %s, &%s)' % (right, left) else: @@ -627,16 +627,20 @@ protected static native void destroy(long cptr); print >> fd, ' add_to_list_of_objects(env, &gobj->%s,value);' % m[1] print >> fd, '}' # remove - if element_type not in ('xmlNode*',): + if is_xml_node(element_type): + print >>sys.stderr, 'W: remove for list of xml node not supported: %s' % (m,) + else: print >> fd,'/* Remover for %s %s.%s */' % (mtype,klassname,m[1]) wrapper_decl("%s_remove" % prefix, 'void', fd) print >> fd, ', jobject jobj, %s value)\n {' % jni_elem_type(element_type) print >> fd, ' %s *gobj;' % klassname print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);' - if element_type in ('char*','gchar*'): + if is_cstring(element_type): print >> fd, ' remove_from_list_of_strings(env, &gobj->%s,value);' % m[1] - else: + elif is_object(element_type): print >> fd, ' remove_from_list_of_objects(env, &gobj->%s,value);' % m[1] + else: + raise Exception('remove_from_list unsupported for %s' % (m,)) print >> fd, '}' # add/remove/get_by_name if mtype in ('GHashTable*',): diff --git a/bindings/php5/php_code.py b/bindings/php5/php_code.py index 3530acf8..1e3fdcad 100644 --- a/bindings/php5/php_code.py +++ b/bindings/php5/php_code.py @@ -177,62 +177,59 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { elif m.name == method_prefix + 'new_full': pass - def generate_getters_and_setters(self, klass): - - # FIXME: handle objects and GLists - - for m in klass.members: - mtype = m[0] - mname = format_as_camelcase(m[1]) - options = m[2] - - # Getters - print >> self.fd, ' /**' - print >> self.fd, ' * @return %s' % self.get_docstring_return_type(mtype) - print >> self.fd, ' */' - print >> self.fd, ' protected function get_%s() {' % mname - if self.is_object(mtype): - print >> self.fd, ' return cptrToPhp(%s_%s_get($this->_cptr));' % ( - klass.name, mname) - elif mtype in ('GList*', 'GHashTable*'): - print >> self.fd, ' $array = %s_%s_get($this->_cptr);' % (klass.name, mname) - if self.is_object(options.get('element-type')): - print >> self.fd, ' $obj_array = array();' - if mtype == 'GList*': - print >> self.fd, ' foreach ($array as $item) {' - print >> self.fd, ' $obj_array[] = cptrToPhp($item);' - else: - print >> self.fd, ' foreach ($array as $key => $item) {' - print >> self.fd, ' $obj_array[$key] = cptrToPhp($item);' - print >> self.fd, ' }' - print >> self.fd, ' $array = $obj_array;' - print >> self.fd, ' return $array;' - else: - print >> self.fd, ' return %s_%s_get($this->_cptr);' % (klass.name, mname) - print >> self.fd, ' }' - # Setters - print >> self.fd, ' protected function set_%s($value) {' % mname - if self.is_object(mtype): - print >> self.fd, ' %s_%s_set($this->_cptr, $value->_cptr);' % (klass.name, mname) - elif mtype in ('GList*', 'GHashTable*') and self.is_object(options.get('element-type')): - print >> self.fd, ' $array = array();' - # FIXME: setting an array to NULL should really set it to NULL and not to an empty array - print >> self.fd, ' if (!is_null($value)) {' - if mtype == 'GList*': - print >> self.fd, ' foreach ($value as $item) {' - print >> self.fd, ' $array[] = $item->_cptr;' - else: - print >> self.fd, ' foreach ($value as $key => $item) {' - print >> self.fd, ' $array[$key] = $item->_cptr;' - print >> self.fd, ' }' + def generate_getter(self, c, m): + d = { 'type': arg_type(m), 'name': format_as_camelcase(arg_name(m)), + 'docstring': self.get_docstring_return_type(arg_type(m)), 'class': c.name } + + print >> self.fd, ''' /**' + * @return %(docstring)s + */ + protected function get_%(name)s() {''' % d + print >> self.fd, ' $t = %(class)s_%(name)s_get($this->_cptr);' % d + if is_object(m): + print >> self.fd, ' $t = cptrToPhp($t);' + elif (is_glist(m) or is_hashtable(m)) and is_object(element_type(m)): + print >> self.fd, ' foreach ($t as $key => $item) {' + print >> self.fd, ' $t[$key] = cptrToPhp($item);' print >> self.fd, ' }' - print >> self.fd, ' %s_%s_set($this->_cptr, $array);' % (klass.name, mname) - else: - print >> self.fd, ' %s_%s_set($this->_cptr, $value);' % (klass.name, mname) - print >> self.fd, ' }' - print >> self.fd, '' + elif is_hashtable(m) or (is_glist(m) and (is_cstring(element_type(m)) \ + or is_xml_node(element_type(m)))) or is_int(m, self.binding_data) \ + or is_boolean(m) or is_cstring(m) or is_xml_node(m): + pass + else: + raise Exception('Cannot generate a Php getter %s.%s' % (c,m)) + print >> self.fd, ' return $t;' + print >>self.fd, ' }' + + def generate_setter(self, c, m): + d = { 'type': arg_type(m), 'name': format_as_camelcase(arg_name(m)), + 'docstring': self.get_docstring_return_type(arg_type(m)), 'class': c.name } + print >> self.fd, ' protected function set_%(name)s($value) {' % d + if is_object(m): + print >> self.fd, ' $value = $value->_cptr;' + elif (is_glist(m) or is_hashtable(m)) and is_object(element_type(m)): + print >> self.fd, ' $array = array();' + print >> self.fd, ' if (!is_null($value)) {' + print >> self.fd, ' foreach ($value as $key => $item) {' + print >> self.fd, ' $array[$key] = $item->_cptr;' + print >> self.fd, ' }' + print >> self.fd, ' }' + print >> self.fd, ' $value = $array;' + elif is_hashtable(m) or (is_glist(m) and (is_cstring(element_type(m)) \ + or is_xml_node(element_type(m)))) or is_int(m, self.binding_data) \ + or is_boolean(m) or is_cstring(m) or is_xml_node(m): + pass + else: + raise Exception('Cannot generate a Php setter %s.%s' % (c,m)) + print >> self.fd, ' %(class)s_%(name)s_set($this->_cptr, $value);' % d + print >> self.fd, ' }' + print >> self.fd, '' + def generate_getters_and_setters(self, klass): + for m in klass.members: + self.generate_getter(klass, m) + self.generate_setter(klass, m) def generate_methods(self, klass): methods = klass.methods[:] diff --git a/bindings/php5/wrapper_source.py b/bindings/php5/wrapper_source.py index 21030dde..b9ccc48f 100644 --- a/bindings/php5/wrapper_source.py +++ b/bindings/php5/wrapper_source.py @@ -117,7 +117,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) elif is_boolean(type): print >> self.fd, ' ZVAL_BOOL(%s, %s);' % p elif is_cstring(type): - print >> self.fd, ' ZVAL_STRING(%s, %s, 1);' % p + print >> self.fd, ' ZVAL_STRING(%s, (char*)%s, 1);' % p if free and not is_const(type): print >> self.fd, 'g_free(%s)' % c_variable elif arg_type(type) == 'xmlNode*': @@ -131,7 +131,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) } } ''' % q - elif arg_type(type) == 'GList*': + elif is_glist(type): elem_type = make_arg(element_type(type)) if not arg_type(elem_type): raise Exception('unknown element-type: ' + repr(type)) @@ -146,7 +146,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) free_function = 'g_list_free(%(c_variable)s);' else: raise Exception('unknown element-type: ' + repr(type)) - print >> self.fd, ' %s(%s, &%s);' % (function, c_variable, zval_name) + print >> self.fd, ' %s((GList*)%s, &%s);' % (function, c_variable, zval_name) if free: print >> self.fd, ' ', free_function % q elif is_object(type): @@ -170,30 +170,24 @@ PHP_MSHUTDOWN_FUNCTION(lasso) - def return_value(self, vtype, options, free = False): - if vtype is None: + def return_value(self, arg, free = False): + if arg is None: return - elif vtype == 'gboolean': + + if is_boolean(arg): print >> self.fd, ' RETVAL_BOOL(return_c_value);' - elif vtype in ['int', 'gint', 'GType', ] + self.binding_data.enums: + elif is_int(arg, self.binding_data): print >> self.fd, ' RETVAL_LONG(return_c_value);' - elif vtype in ('char*', 'gchar*'): - print >> self.fd, '''\ - if (return_c_value) { - RETVAL_STRING(return_c_value, 1); - } else { - RETVAL_NULL(); - }''' - if free: - print >> self.fd, ' free(return_c_value);' - elif vtype in ('const char*', 'const gchar*'): + elif is_cstring(arg): print >> self.fd, '''\ if (return_c_value) { RETVAL_STRING((char*)return_c_value, 1); } else { RETVAL_NULL(); }''' - elif vtype == 'xmlNode*': + if free or is_transfer_full(arg): + print >> self.fd, ' free(return_c_value);' + elif is_xml_node(arg): print >> self.fd, '''\ { char* xmlString = get_string_from_xml_node(return_c_value); @@ -204,42 +198,53 @@ PHP_MSHUTDOWN_FUNCTION(lasso) } } ''' - elif vtype == 'GList*': - if options.get('element-type') == 'char*': + elif is_glist(arg): + el_type = element_type(arg) + if is_cstring(el_type): print >> self.fd, '''\ - set_array_from_list_of_strings(return_c_value, &return_value); + set_array_from_list_of_strings((GList*)return_c_value, &return_value); ''' - if free: - print >> self.fd, ' free_glist(&return_c_value, (GFunc)free);' - elif options.get('element-type') == 'xmlNode*': + if free or is_transfer_full(arg): + print >> self.fd, ' lasso_release_list_of_strings(return_c_value);' + elif is_xml_node(el_type): print >> self.fd, '''\ - set_array_from_list_of_xmlnodes(return_c_value, &return_value); + set_array_from_list_of_xmlnodes((GList*)return_c_value, &return_value); ''' - if free: - print >> self.fd, ' free_glist(&return_c_value, (GFunc)efree);' - else: + if free or is_transfer_full(arg): + print >> self.fd, ' lasso_release_list_of_xml_node(return_c_value);' + elif is_object(el_type): print >> self.fd, '''\ - set_array_from_list_of_objects(return_c_value, &return_value); + set_array_from_list_of_objects((GList*)return_c_value, &return_value); ''' - if free: - print >> self.fd, ' free_glist(&return_c_value, NULL);' - elif vtype == 'GHashTable*': - if options.get('element-type') not in ('char*', 'xmlNode*'): + if free or is_transfer_full(arg): + print >> self.fd, ' lasso_release_list_of_gobjects(return_c_value);' + else: + raise Exception('cannot return value for %s' % (arg,)) + elif is_hashtable(arg): + el_type = element_type(arg) + if is_object(el_type): print >> self.fd, '''\ set_array_from_hashtable_of_objects(return_c_value, &return_value); ''' - else: + else: + if not is_cstring(arg): + print >>sys.stderr, 'W: %s has no explicit string annotation' % (arg,) + print >> self.fd, '''\ + set_array_from_hashtable_of_strings(return_c_value, &return_value); +''' + elif is_object(arg): print >> self.fd, '''\ if (return_c_value) { + PhpGObjectPtr *self; self = PhpGObjectPtr_New(G_OBJECT(return_c_value)); ZEND_REGISTER_RESOURCE(return_value, self, le_lasso_server); } else { RETVAL_NULL(); }''' if free: - print >> self.fd, ' if (return_c_value) {' - print >> self.fd, ' g_object_unref(return_c_value); // If constructor ref is off by one' - print >> self.fd, ' }' + print >> self.fd, ' lasso_release_gobject(return_c_value);' + else: + raise Exception('cannot return value for %s' % (arg,)) def generate_function(self, m): if m.name in ('lasso_init','lasso_shutdown'): @@ -291,8 +296,8 @@ PHP_MSHUTDOWN_FUNCTION(lasso) if m.return_type: print >> self.fd, ' %s return_c_value;' % m.return_type - if m.return_type is not None and self.is_object(m.return_type): - print >> self.fd, ' PhpGObjectPtr *self;' + if m.return_type is not None and self.is_object(m.return_arg): + print >> self.fd, ' G_GNUC_UNUSED PhpGObjectPtr *self;' print >> self.fd, '' parse_tuple_args = ', '.join(parse_tuple_args) @@ -318,11 +323,13 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> self.fd, ' ZEND_FETCH_RESOURCE(cvt_%s, PhpGObjectPtr *, &zval_%s, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);' % (arg[1], arg[1]) print >> self.fd, ' %s = (%s)cvt_%s->obj;' % (arg[1], arg[0], arg[1]) elif f.startswith('a'): - element_type = arg[2].get('element-type') - if is_cstring(element_type): + el_type = element_type(arg) + if is_cstring(el_type): print >> self.fd, ' %(name)s = get_list_from_array_of_strings(zval_%(name)s);' % {'name': arg[1]} + elif is_object(el_type): + print >> self.fd, ' %(name)s = get_list_from_array_of_objects(zval_%(name)s);' % {'name': arg[1]} else: - print >> sys.stderr, 'E: In %(function)s arg %(name)s is of type GList<%(elem)s>' % { 'function': m.name, 'name': arg[1], 'elem': element_type } + print >> sys.stderr, 'E: In %(function)s arg %(name)s is of type GList<%(elem)s>' % { 'function': m.name, 'name': arg[1], 'elem': el_type } elif f == 'l': pass else: @@ -348,43 +355,39 @@ PHP_MSHUTDOWN_FUNCTION(lasso) elif argtype == 'xmlNode*': print >> self.fd, ' xmlFree(%s);' % argname elif f.startswith('a'): - element_type = arg[2].get('element-type') - if element_type == 'char*': + el_type = element_type(arg) + if is_cstring(el_type): print >> self.fd, ' if (%(name)s) {' % { 'name': arg[1] } print >> self.fd, ' free_glist(&%(name)s,(GFunc)free);' % { 'name': arg[1] } print >> self.fd, ' }' - self.return_value(m.return_type, {}, m.return_owner) + try: + self.return_value(m.return_arg, is_transfer_full(m.return_arg)) + except: + raise Exception('Cannot return value for function %s' % m) print >> self.fd, '}' print >> self.fd, '' def generate_members(self, c): - for m_type, m_name, m_options in c.members: - self.generate_getter(c.name, m_type, m_name, m_options) - self.generate_setter(c.name, m_type, m_name, m_options) - - def generate_getter(self, klassname, m_type, m_name, m_options): - if m_type == 'GList*' and m_options.get('element-type') not in ('char*', 'xmlNode*') \ - and not self.is_object(m_options.get('element-type')): - print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('element-type')) - return + for m in c.members: + self.generate_getter(c, m) + self.generate_setter(c, m) + + def generate_getter(self, c, m): + klassname = c.name + name = arg_name(m) + type = arg_type(m) - function_name = '%s_%s_get' % (klassname, format_as_camelcase(m_name)) + function_name = '%s_%s_get' % (klassname, format_as_camelcase(name)) print >> self.fd, '''PHP_FUNCTION(%s) {''' % function_name self.functions_list.append(function_name) - - if self.is_object(m_type): - print >> self.fd, ' %s return_c_value = NULL;' % m_type - else: - print >> self.fd, ' %s return_c_value;' % m_type + print >> self.fd, ' %s return_c_value;' % type print >> self.fd, ' %s* this;' % klassname print >> self.fd, ' zval* zval_this;' print >> self.fd, ' PhpGObjectPtr *cvt_this;' - if self.is_object(m_type): - print >> self.fd, ' PhpGObjectPtr *self;' print >> self.fd, '' print >> self.fd, '''\ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zval_this) == FAILURE) { @@ -394,27 +397,16 @@ PHP_MSHUTDOWN_FUNCTION(lasso) ZEND_FETCH_RESOURCE(cvt_this, PhpGObjectPtr *, &zval_this, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server); this = (%s*)cvt_this->obj; ''' % (klassname) - - if self.is_object(m_type): - print >> self.fd, ' if (this->%s != NULL) {' % m_name - print >> self.fd, ' return_c_value = this->%s;' % m_name - print >> self.fd, ' }' - else: - print >> self.fd, ' return_c_value = this->%s;' % m_name - - self.return_value(m_type, m_options) - + print >> self.fd, ' return_c_value = (%s)this->%s;' % (type, name) + self.return_value(m) print >> self.fd, '}' print >> self.fd, '' - - def generate_setter(self, klassname, m_type, m_name, m_options): - if m_type == 'GList*' and m_options.get('element-type') not in ('char*', 'xmlNode*') \ - and not self.is_object(m_options.get('element-type')): - print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('element-type')) - return - - function_name = '%s_%s_set' % (klassname, format_as_camelcase(m_name)) + def generate_setter(self, c, m): + klassname = c.name + name = arg_name(m) + type = arg_type(m) + function_name = '%s_%s_set' % (klassname, format_as_camelcase(name)) print >> self.fd, '''PHP_FUNCTION(%s) {''' % function_name self.functions_list.append(function_name) @@ -426,29 +418,28 @@ PHP_MSHUTDOWN_FUNCTION(lasso) # FIXME: This bloc should be factorised parse_tuple_format = '' parse_tuple_args = [] - arg_type = m_type - arg_name = m_name - arg_options = m_options - if arg_type in ('char*', 'const char*', 'gchar*', 'const gchar*', 'xmlNode*'): - arg_type = arg_type.replace('const ', '') + if is_cstring(m) or is_xml_node(m): + # arg_type = arg_type.replace('const ', '') parse_tuple_format += 's' - parse_tuple_args.append('&%s_str, &%s_len' % (arg_name, arg_name)) - print >> self.fd, ' %s %s_str = NULL;' % ('char*', arg_name) - print >> self.fd, ' %s %s_len = 0;' % ('int', arg_name) - elif arg_type in ['int', 'gint', 'GType', 'gboolean', 'const gboolean'] + self.binding_data.enums: + parse_tuple_args.append('&%s_str, &%s_len' % (name, name)) + print >> self.fd, ' %s %s_str = NULL;' % ('char*', name) + print >> self.fd, ' %s %s_len = 0;' % ('int', name) + elif is_int(m, self.binding_data) or is_boolean(m): parse_tuple_format += 'l' - parse_tuple_args.append('&%s' % arg_name) - print >> self.fd, ' %s %s;' % ('long', arg_name) + parse_tuple_args.append('&%s' % name) + print >> self.fd, ' %s %s;' % ('long', name) # Must also handle lists of Objects - elif arg_type in ('GList*', 'GHashTable*'): + elif is_glist(m) or is_hashtable(m): parse_tuple_format += 'a' - parse_tuple_args.append('&zval_%s' % arg_name) - print >> self.fd, ' %s zval_%s;' % ('zval*', arg_name) - else: + parse_tuple_args.append('&zval_%s' % name) + print >> self.fd, ' %s zval_%s;' % ('zval*', name) + elif is_object(m): parse_tuple_format += 'r' - parse_tuple_args.append('&zval_%s' % arg_name) - print >> self.fd, ' %s zval_%s = NULL;' % ('zval*', arg_name) - print >> self.fd, ' %s cvt_%s = NULL;' % ('PhpGObjectPtr*', arg_name) + parse_tuple_args.append('&zval_%s' % name) + print >> self.fd, ' %s zval_%s = NULL;' % ('zval*', name) + print >> self.fd, ' %s cvt_%s = NULL;' % ('PhpGObjectPtr*', name) + else: + raise Exception('Cannot make a setter for %s.%s' % (c,m)) if parse_tuple_args: parse_tuple_arg = parse_tuple_args[0] @@ -471,60 +462,37 @@ PHP_MSHUTDOWN_FUNCTION(lasso) ''' % klassname # Set new value - if parse_tuple_format == 'l': - print >> self.fd, ' this->%s = %s;' % (m_name, m_name) - elif parse_tuple_format == 's': - print >> self.fd, ' if (this->%s) {' % m_name - print >> self.fd, ' g_free(this->%s);' % m_name - print >> self.fd, ' }' - print >> self.fd, ' if (%s_str && strcmp(%s_str, "") != 0) {' % (m_name, m_name) - if arg_type == 'xmlNode*': - print >> self.fd, ' this->%s = get_xml_node_from_string(%s_str);' % (m_name, m_name) + d = { 'name': name, 'type': type } + if is_int(m, self.binding_data) or is_boolean(m): + print >> self.fd, ' this->%s = %s;' % (name, name) + elif is_cstring(m): + print >> self.fd, ' lasso_assign_string(this->%(name)s, %(name)s_str);' % d + elif is_xml_node(m): + print >> self.fd, ' lasso_assign_new_xml_node(this->%(name)s, get_xml_node_from_string(%(name)s_str));' % d + elif is_glist(m): + el_type = element_type(m) + if is_cstring(el_type): + print >> self.fd, ' lasso_assign_new_list_of_strings(this->%(name)s, get_list_from_array_of_strings(zval_%(name)s));' % d + elif is_xml_node(el_type): + print >> self.fd, ' lasso_assign_new_list_of_xml_node(this->%(name)s, get_list_from_array_of_xmlnodes(zval_%(name)s))' % d + elif is_object(el_type): + print >> self.fd, ' lasso_assign_new_list_of_gobjects(this->%(name)s, get_list_from_array_of_objects(zval_%(name)s));' % d else: - print >> self.fd, ' this->%s = g_strndup(%s_str, %s_len);' % (m_name, m_name, m_name) - print >> self.fd, ' } else {' - print >> self.fd, ' this->%s = NULL;' % m_name - print >> self.fd, ' }' - elif arg_type == 'GList*': - if m_options.get('element-type') == 'char*': - print >> self.fd, ''' - if (this->%(name)s) { - /* free existing list */ - g_list_foreach(this->%(name)s, (GFunc)g_free, NULL); - g_list_free(this->%(name)s); - } - this->%(name)s = get_list_from_array_of_strings(zval_%(name)s); -''' % { 'name': m_name } - elif m_options.get('element-type') == 'xmlNode*': - print >> self.fd, ''' - if (this->%(name)s) { - /* free existing list */ - g_list_foreach(this->%(name)s, (GFunc)xmlFreeNode, NULL); - g_list_free(this->%(name)s); - } - this->%(name)s = get_list_from_array_of_xmlnodes(zval_%(name)s); -''' % { 'name': m_name } - else: - print >> self.fd, ''' - free_glist(&this->%(name)s, (GFunc)g_object_unref); - this->%(name)s = get_list_from_array_of_objects(zval_%(name)s); -''' % { 'name': m_name } - elif arg_type == 'GHashTable*' and arg_options.get('element-type') != 'char*': + raise Exception('Cannot create C setter for %s.%s' % (c,m)) + elif is_hashtable(m): + el_type = element_type(m) print >> self.fd, '''\ - { - GHashTable *oldhash = this->%(name)s; - this->%(name)s = get_hashtable_from_array_of_objects(zval_%(name)s); - g_hash_table_destroy(oldhash); - } -''' % { 'name': m_name } - elif parse_tuple_format == 'r': - print >> self.fd, ' ZEND_FETCH_RESOURCE(cvt_%s, PhpGObjectPtr*, &zval_%s, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);' % (m_name, m_name) - print >> self.fd, ''' - g_object_ref(cvt_%(name)s->obj); - if (this->%(name)s) - g_object_unref(this->%(name)s); - this->%(name)s = (%(type)s)cvt_%(name)s->obj; -''' % { 'name': m_name, 'type': m_type } + { + GHashTable *oldhash = this->%(name)s;''' % d + if is_object(el_type): + print >>self.fd, ' this->%(name)s = get_hashtable_from_array_of_objects(zval_%(name)s);' % d + else: + print >>self.fd, ' this->%(name)s = get_hashtable_from_array_of_strings(zval_%(name)s);' % d + print >> self.fd, ' g_hash_table_destroy(oldhash);' + print >> self.fd, ' }' + elif is_object(m): + print >> self.fd, ' ZEND_FETCH_RESOURCE(cvt_%(name)s, PhpGObjectPtr*, &zval_%(name)s, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);' % d + print >> self.fd, ' lasso_assign_gobject(this->%(name)s, cvt_%(name)s->obj);' % d print >> self.fd, '}' print >> self.fd, '' diff --git a/bindings/php5/wrapper_source_top.c b/bindings/php5/wrapper_source_top.c index 8969408b..5567f499 100644 --- a/bindings/php5/wrapper_source_top.c +++ b/bindings/php5/wrapper_source_top.c @@ -192,10 +192,15 @@ get_list_from_array_of_xmlnodes(zval* array) for (zend_hash_internal_pointer_reset_ex(hashtable, &pointer); zend_hash_get_current_data_ex(hashtable, (void**) &data, &pointer) == SUCCESS; zend_hash_move_forward_ex(hashtable, &pointer)) { + xmlNode *value; + temp = **data; zval_copy_ctor(&temp); convert_to_string(&temp); - result = g_list_append(result, get_xml_node_from_string(Z_STRVAL(temp))); + value = get_xml_node_from_string(Z_STRVAL(temp)); + if (value) { + lasso_list_add_new_xml_node(result, value); + } zval_dtor(&temp); } return result; @@ -281,16 +286,37 @@ get_hashtable_from_array_of_objects(zval *array) zend_hash_move_forward_ex(hashtable, &pointer)) { cvt_temp = (PhpGObjectPtr*) zend_fetch_resource(data TSRMLS_CC, -1, PHP_LASSO_SERVER_RES_NAME, NULL, 1, le_lasso_server); if (zend_hash_get_current_key_ex(hashtable, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) { - if (cvt_temp != NULL) { - g_hash_table_insert(result, key, g_object_ref(cvt_temp->obj)); - } else { - g_hash_table_insert(result, key, NULL); - } + g_hash_table_insert(result, key, lasso_ref(cvt_temp->obj)); } else { - if (cvt_temp != NULL) { - g_hash_table_insert(result, (gpointer)index, g_object_ref(cvt_temp->obj)); + /* FIXME: throw an exception */ + } + } + return result; +} + +static GHashTable* +get_hashtable_from_array_of_strings(zval *array) +{ + HashTable *hashtable = NULL; + HashPosition pointer; + int size; + char *key = NULL; + unsigned int key_len; + unsigned long index; + zval **data = NULL; + GHashTable *result = NULL; + + result = g_hash_table_new(g_str_hash, g_str_equal); + hashtable = Z_ARRVAL_P(array); + size = zend_hash_num_elements(hashtable); + for (zend_hash_internal_pointer_reset_ex(hashtable, &pointer); + zend_hash_get_current_data_ex(hashtable, (void**) &data, &pointer) == SUCCESS; + zend_hash_move_forward_ex(hashtable, &pointer)) { + if (Z_TYPE_PP(data) == IS_STRING) { + if (zend_hash_get_current_key_ex(hashtable, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) { + g_hash_table_insert(result, g_strdup(key), g_strdup(Z_STRVAL_PP(data))); } else { - g_hash_table_insert(result, (gpointer)index, NULL); + /* FIXME: throw an exception */ } } } @@ -318,3 +344,23 @@ set_array_from_hashtable_of_objects(GHashTable *hashtable, zval **array) g_list_free(keys); } +static void +set_array_from_hashtable_of_strings(GHashTable *hashtable, zval **array) +{ + GList *keys = NULL; + zval *zval_item = NULL; + + array_init(*array); + for (keys = g_hash_table_get_keys(hashtable); keys; keys = g_list_next(keys)) { + char *item = g_hash_table_lookup(hashtable, keys->data); + if (item) { + MAKE_STD_ZVAL(zval_item); + ZVAL_STRING(zval_item, item, 1); + add_assoc_zval(*array, (char*)keys->data, zval_item); + } else { + add_assoc_null(*array, (char*)keys->data); + } + } + g_list_free(keys); +} + diff --git a/bindings/python/lang.py b/bindings/python/lang.py index 3c3e688f..b967e926 100644 --- a/bindings/python/lang.py +++ b/bindings/python/lang.py @@ -272,10 +272,10 @@ if WSF_SUPPORT: c_args = [] py_args = [] for o in m.args: - arg_type, arg_name, arg_options = o + type, arg_name, arg_options = o py_args.append(get_python_arg_decl(o)) - if self.is_pygobject(arg_type): + if self.is_pygobject(type): c_args.append('%s and %s._cptr' % (arg_name, arg_name)) else: c_args.append(arg_name) @@ -297,10 +297,10 @@ if WSF_SUPPORT: c_args = [] py_args = [] for o in m.args: - arg_type, arg_name, arg_options = o + type, arg_name, arg_options = o py_args.append(get_python_arg_decl(o)) - if self.is_pygobject(arg_type): + if self.is_pygobject(type): c_args.append('%s and %s._cptr' % (arg_name, arg_name)) else: c_args.append(arg_name) @@ -319,37 +319,52 @@ if WSF_SUPPORT: for m in clss.members: mname = format_as_camelcase(m[1]) options = m[2] + # getter print >> fd, ' def get_%s(self):' % mname - if self.is_pygobject(m[0]): - print >> fd, ' t = _lasso.%s_%s_get(self._cptr)' % ( - klassname, mname) + print >> fd, ' t = _lasso.%s_%s_get(self._cptr)' % ( + klassname, mname) + if is_object(m): print >> fd, ' return cptrToPy(t)' - elif m[0] == 'GList*' and options.get('element-type') not in ('char*', 'xmlNode*'): - print >> fd, ' l = _lasso.%s_%s_get(self._cptr)' % ( - klassname, mname) - print >> fd, ' if not l: return l' - print >> fd, ' return tuple([cptrToPy(x) for x in l])' - elif m[0] == 'GHashTable*': - print >> fd, ' d = _lasso.%s_%s_get(self._cptr)' % ( - klassname, mname) - print >> fd, ' if not d: return d' - if options.get('element-type') != 'char*': + elif is_glist(m): + el_type = element_type(m) + if is_cstring(el_type): + pass + elif is_xml_node(el_type): + pass + elif is_object(element_type(m)): + print >> fd, ' if not t: return t' + print >> fd, ' t = tuple([cptrToPy(x) for x in t])' + else: + raise Exception('Unsupported python getter %s.%s' % (clss, m)) + elif is_hashtable(m): + el_type = element_type(m) + print >> fd, ' if not t: return t' + if is_object(el_type): print >> fd, ' d2 = {}' - print >> fd, ' for k, v in d.items():' + print >> fd, ' for k, v in t.items():' print >> fd, ' d2[k] = cptrToPy(v)' - print >> fd, ' return frozendict(d2)' + print >> fd, ' t = frozendict(d2)' else: - print >> fd, ' return frozendict(d)' + print >> fd, ' t = frozendict(t)' + elif is_boolean(m) or is_int(m, self.binding_data) or is_xml_node(m) or is_cstring(m): + pass else: - print >> fd, ' return _lasso.%s_%s_get(self._cptr)' % ( - klassname, mname) + raise Exception('Unsupported python getter %s.%s' % (clss, m)) + print >> fd, ' return t;' + # setter print >> fd, ' def set_%s(self, value):' % mname - if self.is_pygobject(m[0]): + if is_object(m): print >> fd, ' if value is not None:' print >> fd, ' value = value and value._cptr' - elif m[0] == 'GList*' and options.get('element-type') not in ('char*', 'xmlNode*'): - print >> fd, ' if value is not None:' - print >> fd, ' value = tuple([x._cptr for x in value])' + elif is_glist(m): + el_type = element_type(m) + if is_cstring(el_type) or is_xml_node(el_type): + pass + elif is_object(el_type): + print >> fd, ' if value is not None:' + print >> fd, ' value = tuple([x._cptr for x in value])' + else: + raise Exception('Unsupported python setter %s.%s' % (clss, m)) print >> fd, ' _lasso.%s_%s_set(self._cptr, value)' % ( klassname, mname) print >> fd, ' %s = property(get_%s, set_%s)' % (mname, mname, mname) @@ -424,7 +439,7 @@ if WSF_SUPPORT: c_args = [] outarg = None for o in m.args[1:]: - arg_type, arg_name, arg_options = o + type, arg_name, arg_options = o if is_out(o): assert not outarg outarg = o @@ -434,7 +449,7 @@ if WSF_SUPPORT: if is_out(o): c_args.append(outvar) - elif not self.is_pygobject(arg_type): + elif not self.is_pygobject(type): c_args.append(arg_name) else: c_args.append('%s and %s._cptr' % (arg_name, arg_name)) @@ -444,7 +459,7 @@ if WSF_SUPPORT: if '=' in x: opt = True elif opt: - print 'W: non-optional follow optional,', m + print >>sys.stderr, 'W: non-optional follow optional,', m if py_args: py_args = ', ' + ', '.join(py_args) @@ -645,15 +660,16 @@ register_constants(PyObject *d) def generate_member_wrapper(self, c, fd): klassname = c.name for m in c.members: - mname = format_as_camelcase(m[1]) + name = arg_name(m) + mname = format_as_camelcase(arg_name(m)) # getter print >> fd, '''static PyObject* %s_%s_get(G_GNUC_UNUSED PyObject *self, PyObject *args) {''' % (klassname[5:], mname) self.wrapper_list.append('%s_%s_get' % (klassname[5:], mname)) - ftype = m[0] - if ftype in ('char*', 'const char*', 'guchar*', 'const guchar*', 'gchar*', 'const gchar*'): + ftype = arg_type(m) + if is_cstring(m): ftype = 'char*' print >> fd, ' %s return_value;' % ftype print >> fd, ' PyObject* return_pyvalue;' @@ -663,14 +679,17 @@ register_constants(PyObject *d) print >> fd, ' if (! PyArg_ParseTuple(args, "O", &cvt_this)) return NULL;' print >> fd, ' this = (%s*)cvt_this->obj;' % klassname - if self.is_pygobject(ftype): + if is_cstring(m): + print >> fd, ' return_value = g_strdup(this->%s);' % arg_name(m) + elif is_object(m): 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, ftype, m[2]) + try: + self.return_value(fd, m) + except: + print >>sys.stderr, 'W: cannot make an assignment for', c, m + raise print >> fd, ' return return_pyvalue;' print >> fd, '}' @@ -684,57 +703,68 @@ register_constants(PyObject *d) print >> fd, ' PyGObjectPtr* cvt_this;' print >> fd, ' %s* this;' % klassname - arg_type = m[0] + type = m[0] # Determine type class - if m[0] in ('char*', 'const char*', 'guchar*', 'const guchar*', 'gchar*', 'const gchar*'): - arg_type = arg_type.replace('const ', '') + if is_cstring(m): + type = type.replace('const ', '') parse_format = 'z' parse_arg = '&value' - print >> fd, ' %s value;' % arg_type - elif arg_type in ['int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums: + print >> fd, ' %s value;' % type + elif is_int(m, self.binding_data): parse_format = 'i' parse_arg = '&value' - print >> fd, ' %s value;' % arg_type - elif arg_type in ('GList*','GHashTable*', 'xmlNode*'): + print >> fd, ' %s value;' % type + elif is_glist(m) or is_hashtable(m) or is_xml_node(m) or is_boolean(m): parse_format = 'O' print >> fd, ' PyObject *cvt_value;' parse_arg = '&cvt_value' - else: + elif is_object(m): parse_format = 'O' print >> fd, ' PyGObjectPtr *cvt_value;' parse_arg = '&cvt_value' + else: + raise Exception('Unsupported field: %s' % (m,)) # 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'): - print >> fd, ' if (this->%s) g_free(this->%s);' % (m[1], m[1]) - print >> fd, ' this->%s = g_strdup(value);' % m[1] - elif parse_format == 'O' and arg_type == 'GList*': - element_type = m[2].get('element-type') - if element_type == 'char*': - print >> fd, ' set_list_of_strings(&this->%s, cvt_value);' % m[1] - elif element_type == 'xmlNode*': - print >> fd, ' set_list_of_xml_nodes(&this->%s, cvt_value);' % m[1] + if is_int(m, self.binding_data): + print >> fd, ' this->%s = value;' % name + elif is_boolean(m): + print >> fd, ' this->%s = PyInt_AS_LONG(cvt_value) ? TRUE : FALSE;' % name + elif is_cstring(m): + print >> fd, ' lasso_assign_string(this->%s, value);' % name + elif is_xml_node(m): + print >> fd, ' if (this->%s) xmlFreeNode(this->%s);' % (name, name) + print >> fd, ' this->%s = get_xml_node_from_pystring(cvt_value);' % name + elif is_glist(m): + el_type = element_type(m) + if is_cstring(el_type): + print >> fd, ' set_list_of_strings(&this->%s, cvt_value);' % name + elif is_xml_node(el_type): + print >> fd, ' set_list_of_xml_nodes(&this->%s, cvt_value);' % name + elif is_object(el_type): + print >> fd, ' set_list_of_pygobject(&this->%s, cvt_value);' % name + else: + raise Exception('Unsupported setter for %s' % (m,)) + elif is_hashtable(m): + el_type = element_type(m) + if is_object(el_type): + print >> fd, ' set_hashtable_of_pygobject(this->%s, cvt_value);' % name else: - 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' and arg_type == 'xmlNode*': - print >> fd, ' if (this->%s) xmlFreeNode(this->%s);' % (m[1], m[1]) - print >> fd, ' this->%s = get_xml_node_from_pystring(cvt_value);' % m[1] - elif parse_format == 'O': - print >> fd, ' set_object_field((GObject**)&this->%s, cvt_value);' % m[1] + print >> fd, ' set_hashtable_of_strings(this->%s, cvt_value);' % name + elif is_object(m): + print >> fd, ' set_object_field((GObject**)&this->%s, cvt_value);' % name + else: + raise Exception('Unsupported member %s.%s' % (klassname, m)) print >> fd, ' return noneRef();' print >> fd, '}' print >> fd, '' - def return_value(self, fd, vtype, options, return_var_name = 'return_value', return_pyvar_name = 'return_pyvalue'): - if vtype == 'gboolean': + def return_value(self, fd, arg, return_var_name = 'return_value', return_pyvar_name = 'return_pyvalue'): + if is_boolean(arg): print >> fd, ' if (%s) {' % return_var_name print >> fd, ' Py_INCREF(Py_True);' print >> fd, ' %s = Py_True;' % return_pyvar_name @@ -742,45 +772,45 @@ register_constants(PyObject *d) print >> fd, ' Py_INCREF(Py_False);' print >> fd, ' %s = Py_False;' % return_pyvar_name print >> fd, ' }' - elif vtype in ['int', 'gint'] + self.binding_data.enums: + elif is_int(arg, self.binding_data): print >> fd, ' %s = PyInt_FromLong(%s);' % (return_pyvar_name, return_var_name) - elif vtype in ('char*', 'guchar*', 'const guchar*', 'gchar*'): + elif is_cstring(arg) and is_transfer_full(arg): print >> fd, ' if (%s) {' % return_var_name print >> fd, ' %s = PyString_FromString(%s);' % (return_pyvar_name, return_var_name) print >> fd, ' g_free(%s);' % return_var_name print >> fd, ' } else {' print >> fd, ' %s = noneRef();' % return_pyvar_name print >> fd, ' }' - elif vtype in ('const char*', 'const gchar*'): + elif is_cstring(arg): print >> fd, ' if (%s) {' % return_var_name print >> fd, ' %s = PyString_FromString(%s);' % (return_pyvar_name, return_var_name) print >> fd, ' } else {' print >> fd, ' %s = noneRef();' % return_pyvar_name print >> fd, ' }' - elif vtype in ('const GList*', 'GList*',): - element_type = options.get('element-type') - if not element_type or self.is_pygobject(element_type): + elif is_glist(arg): + el_type = element_type(arg) + if is_object(el_type): print >> fd, ' %s = get_list_of_pygobject(%s);' % (return_pyvar_name, return_var_name) - elif element_type == 'char*': + elif is_cstring(el_type): print >> fd, ' %s = get_list_of_strings(%s);' % (return_pyvar_name, return_var_name) - elif element_type.startswith('xmlNode'): + elif is_xml_node(el_type): print >> fd, ' %s = get_list_of_xml_nodes(%s);' % (return_pyvar_name, return_var_name) else: - raise Exception('Should not happen: %s %s ' % (repr(options), vtype)) - elif vtype in ('GHashTable*',): - element_type = options.get('element-type') - if element_type == 'char*': - print >> fd, ' %s = get_dict_from_hashtable_of_strings(%s);' % (return_pyvar_name, return_var_name) - else: + raise Exception('failed to make an assignment for %s' % (arg,)) + elif is_hashtable(arg): + el_type = element_type(arg) + if is_object(el_type): print >> fd, ' %s = get_dict_from_hashtable_of_objects(%s);' % (return_pyvar_name, return_var_name) - elif vtype == 'xmlNode*': + else: + print >> fd, ' %s = get_dict_from_hashtable_of_strings(%s);' % (return_pyvar_name, return_var_name) + elif is_xml_node(arg): # convert xmlNode* to strings print >> fd, ' if (%s) {' % return_var_name print >> fd, ' %s = get_pystring_from_xml_node(%s);' % (return_pyvar_name, return_var_name) print >> fd, ' } else {' print >> fd, ' %s = noneRef();' % return_pyvar_name print >> fd, ' }' - else: + elif is_object(arg): # return a PyGObjectPtr (wrapper around GObject) print >> fd, '''\ if (%s) { @@ -789,6 +819,8 @@ register_constants(PyObject *d) %s = noneRef(); } ''' % (return_var_name, return_pyvar_name, return_var_name, return_pyvar_name) + else: + raise Exception('failed to make an assignment for %s' % (arg,)) def generate_function_wrapper(self, m, fd): if m.rename: @@ -908,7 +940,7 @@ register_constants(PyObject *d) for f, arg in zip(parse_tuple_format, m.args): if is_out(arg): - self.return_value(fd, var_type(arg), {'element-type': element_type(arg)}, return_var_name = arg[1], return_pyvar_name = 'out_pyvalue') + self.return_value(fd, arg, return_var_name = arg[1], return_pyvar_name = 'out_pyvalue') print >> fd, ' PyList_SetItem(cvt_%s_out, 0, out_pyvalue);' % arg[1] elif arg[0] == 'GList*': qualifier = arg[2].get('element-type') @@ -926,7 +958,12 @@ register_constants(PyObject *d) else: # Constructor so decrease refcount (it was incremented by PyGObjectPtr_New called # in self.return_value - self.return_value(fd, m.return_type, {'element-type': m.return_type_qualifier}) + try: + self.return_value(fd, m.return_arg) + except: + print >>sys.stderr, 'W: cannot assign return value of', m + raise + 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;' diff --git a/bindings/python/tests/idwsf2_tests.py b/bindings/python/tests/idwsf2_tests.py index fd98ef5e..39ce9fde 100755 --- a/bindings/python/tests/idwsf2_tests.py +++ b/bindings/python/tests/idwsf2_tests.py @@ -42,6 +42,7 @@ try: except NameError: dataDir = os.path.join(os.environ['TOP_SRCDIR'], 'tests', 'data') +disco_soap_url = 'http://idp1/soapEndpoint' class IdWsf2TestCase(unittest.TestCase): def getWspServer(self): @@ -82,29 +83,28 @@ class IdWsf2TestCase(unittest.TestCase): return server - def idpRegisterSelf(self, idp_server): - disco = lasso.IdWsf2Discovery(idp_server) - service_type = lasso.IDWSF2_DISCO_HREF - abstract = 'Disco service' - soapEndpoint = 'http://idp1/soapEndpoint' - disco.metadataRegisterSelf(service_type, abstract, soapEndpoint) - - return idp_server def metadataRegister(self, wsp, idp): wsp_disco = lasso.IdWsf2Discovery(wsp) abstract = 'Personal Profile service' soapEndpoint = 'http://idp1/soapEndpoint' - wsp_disco.initMetadataRegister( - 'urn:liberty:id-sis-pp:2005-05', abstract, wsp.providerIds[0], soapEndpoint) + wsp_disco.initMetadataRegister() + wsp_disco.addSimpleServiceMetadata( + service_types = ['urn:liberty:id-sis-pp:2005-05'], + abstract = abstract, provider_id = wsp.providerIds[0], + address = soapEndpoint) wsp_disco.buildRequestMsg() idp_disco = lasso.IdWsf2Discovery(idp) - idp_disco.processMetadataRegisterMsg(wsp_disco.msgBody) + idp_disco.processRequestMsg(wsp_disco.msgBody) + idp_disco.validateRequestMsg() + assert(len(idp_disco.metadatas) = 1) + assert(idp_disco.metadatas[0].svcMDID == idp_disco.response.SvcMDID[0]) idp_disco.buildResponseMsg() - wsp_disco.processMetadataRegisterResponseMsg(idp_disco.msgBody) - return idp, wsp_disco.svcMDIDs[0] + assert(len(wsp_disco.metadatas) = 1) + assert(wsp_disco.metadatas[0].svcMDID == wsp_disco.response.SvcMDID[0]) + return idp, wsp_disco.metadatas[0].svcMDID def login(self, sp, idp, sp_identity_dump=None, sp_session_dump=None, idp_identity_dump=None, idp_session_dump=None): @@ -124,6 +124,7 @@ class IdWsf2TestCase(unittest.TestCase): idp_login.processAuthnRequestMsg(query) idp_login.validateRequestMsg(True, True) idp_login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, None, None, None, None) + idp_login.idwsf2AddDiscoveryBootstrapEpr(url = disco_soap_url, abstract = 'Discovery Service', security_mech_id = lasso.SECURITY_MECH_NULL) idp_login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET) artifact_message = idp_login.artifactMessage @@ -150,55 +151,7 @@ class IdWsf2TestCase(unittest.TestCase): if sp_login.isSessionDirty: sp_session_dump = sp_login.session.dump() - return sp_identity_dump, sp_session_dump, idp_identity_dump, idp_session_dump - - -class IdpSelfRegistrationTestCase(IdWsf2TestCase): - def test01(self): - """Register IdP as Dicovery Service and get a random svcMDID""" - - disco = lasso.IdWsf2Discovery(self.getIdpServer()) - - service_type = lasso.IDWSF2_DISCO_HREF - abstract = 'Disco service' - soapEndpoint = 'http://idp1/soapEndpoint' - - svcMDID = disco.metadataRegisterSelf(service_type, abstract, soapEndpoint) - # In real use, store the server dump here - - self.failUnless(svcMDID, 'missing svcMDID') - - def test02(self): - """Register IdP as Dicovery Service with a given svcMDID""" - - disco = lasso.IdWsf2Discovery(self.getIdpServer()) - - service_type = lasso.IDWSF2_DISCO_HREF - abstract = 'Disco service' - soapEndpoint = 'http://idp1/soapEndpoint' - mySvcMDID = 'RaNdOm StRiNg' - - svcMDID = disco.metadataRegisterSelf(service_type, abstract, soapEndpoint, mySvcMDID) - # In real use, store the server dump here - - self.failUnless(svcMDID, 'missing svcMDID') - self.failUnlessEqual(svcMDID, mySvcMDID, 'wrong svcMDID') - - def test03(self): - """Register IdP as Dicovery Service with wrong parameters""" - - disco = lasso.IdWsf2Discovery(self.getIdpServer()) - - service_type = '' - abstract = '' - soapEndpoint = '' - - try: - svcMDID = disco.metadataRegisterSelf(service_type, abstract, soapEndpoint) - except lasso.ParamBadTypeOrNullObjError: - pass - else: - self.fail('metadataRegisterSelf should fail with a ParamBadTypeOrNullObjError') + return sp_identity_dump, sp_session_dump, idp_identity_dump, idp_session_dump, sp_login.idwsf2GetDiscoveryBootstrapEpr() class MetadataRegisterTestCase(IdWsf2TestCase): @@ -1786,13 +1739,12 @@ class DataServiceQueryTestCase(IdWsf2TestCase): self.failUnless(email_strings[1] == email2) -idpSelfRegistrationSuite = unittest.makeSuite(IdpSelfRegistrationTestCase, 'test') metadataRegisterSuite = unittest.makeSuite(MetadataRegisterTestCase, 'test') metadataAssociationAddSuite = unittest.makeSuite(MetadataAssociationAddTestCase, 'test') discoveryQuerySuite = unittest.makeSuite(DiscoveryQueryTestCase, 'test') dataServiceQuerySuite = unittest.makeSuite(DataServiceQueryTestCase, 'test') -allTests = unittest.TestSuite((idpSelfRegistrationSuite, metadataRegisterSuite, +allTests = unittest.TestSuite((metadataRegisterSuite, metadataAssociationAddSuite, discoveryQuerySuite, dataServiceQuerySuite)) if __name__ == '__main__': diff --git a/bindings/python/wrapper_top.c b/bindings/python/wrapper_top.c index a24a2dba..24eb93ac 100644 --- a/bindings/python/wrapper_top.c +++ b/bindings/python/wrapper_top.c @@ -18,8 +18,10 @@ PyMODINIT_FUNC init_lasso(void); G_GNUC_UNUSED static PyObject* get_pystring_from_xml_node(xmlNode *xmlnode); G_GNUC_UNUSED static xmlNode* get_xml_node_from_pystring(PyObject *string); G_GNUC_UNUSED static PyObject* get_dict_from_hashtable_of_objects(GHashTable *value); +G_GNUC_UNUSED static PyObject* get_dict_from_hashtable_of_strings(GHashTable *value); G_GNUC_UNUSED static PyObject* PyGObjectPtr_New(GObject *obj); G_GNUC_UNUSED static void set_hashtable_of_pygobject(GHashTable *a_hash, PyObject *dict); +G_GNUC_UNUSED static void set_hashtable_of_strings(GHashTable *a_hash, PyObject *dict); G_GNUC_UNUSED static void set_list_of_strings(GList **a_list, PyObject *seq); G_GNUC_UNUSED static void set_list_of_xml_nodes(GList **a_list, PyObject *seq); G_GNUC_UNUSED static void set_list_of_pygobject(GList **a_list, PyObject *seq); @@ -73,6 +75,34 @@ get_dict_from_hashtable_of_objects(GHashTable *value) } static PyObject* +get_dict_from_hashtable_of_strings(GHashTable *value) +{ + GList *keys, *begin; + PyObject *dict,*proxy; + char *item_value; + PyObject *item; + + 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"); + } + } + g_list_free(begin); + + proxy = PyDictProxy_New(dict); + Py_DECREF(dict); + return proxy; +} + +static PyObject* get_pystring_from_xml_node(xmlNode *xmlnode) { xmlOutputBufferPtr buf; @@ -165,6 +195,44 @@ failure: } } +static void +set_hashtable_of_strings(GHashTable *a_hash, PyObject *dict) +{ + PyObject *key, *value; + Py_ssize_t 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) || ! PyString_Check(value)) + { + PyErr_SetString(PyExc_TypeError, + "value should be a dict, " + "with string keys " + "and string values"); + goto failure; + } + } + g_hash_table_remove_all (a_hash); + i = 0; + while (PyDict_Next(dict, &i, &key, &value)) { + char *ckey = PyString_AsString(key); + char *cvalue = PyString_AsString(value); + g_hash_table_insert (a_hash, g_strdup(ckey), g_strdup(cvalue)); + } +failure: + return; +} + /** 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*. */ |
