diff options
author | Frederic Peters <fpeters@entrouvert.com> | 2008-04-29 12:05:55 +0000 |
---|---|---|
committer | Frederic Peters <fpeters@entrouvert.com> | 2008-04-29 12:05:55 +0000 |
commit | 5511b8b29d461e53008fd4f1b1ae548ff8d425cb (patch) | |
tree | 081244d085f1770b4f96e19aa5d849d1a75c48f4 | |
parent | 8e660b7eb334db6ac26b472d858198ad12b9e695 (diff) | |
download | lasso-5511b8b29d461e53008fd4f1b1ae548ff8d425cb.tar.gz lasso-5511b8b29d461e53008fd4f1b1ae548ff8d425cb.tar.xz lasso-5511b8b29d461e53008fd4f1b1ae548ff8d425cb.zip |
[project @ fpeters@0d.be-20071115162508-ydcoj2rr8zkfxyvy]
merged Damien branch
Original author: Frederic Peters <fpeters@0d.be>
Date: 2007-11-15 17:25:08.524000+01:00
-rw-r--r-- | bindings/lang_php5_helpers/php_code.py | 134 | ||||
-rw-r--r-- | bindings/lang_php5_helpers/wrapper_source.py | 63 | ||||
-rw-r--r-- | bindings/lang_php5_helpers/wrapper_source_top.c | 248 | ||||
-rw-r--r-- | bindings/lang_python_wrapper_top.c | 2 | ||||
-rw-r--r-- | bindings/php5/Makefile.am | 3 | ||||
-rwxr-xr-x | bindings/php5/tests/binding_tests.php | 68 | ||||
-rwxr-xr-x | bindings/php5/tests/profile_tests.php | 39 |
7 files changed, 404 insertions, 153 deletions
diff --git a/bindings/lang_php5_helpers/php_code.py b/bindings/lang_php5_helpers/php_code.py index 820874de..09608236 100644 --- a/bindings/lang_php5_helpers/php_code.py +++ b/bindings/lang_php5_helpers/php_code.py @@ -30,7 +30,7 @@ class PhpCode: self.fd = fd def is_object(self, t): - return t not in [None, 'char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', + return t not in ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', 'xmlNode*', 'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums def generate(self): @@ -46,6 +46,10 @@ class PhpCode: /* this file has been generated automatically; do not edit */ +/** + * @package Lasso + */ + // Try to load Lasso extension if it's not already loaded. if (!extension_loaded('lasso')) { if (strtolower(substr(PHP_OS, 0, 3)) === 'win') { @@ -64,6 +68,9 @@ if (!extension_loaded('lasso')) { } } +/* + * Convert a C object to a PHP object + */ function cptrToPhp ($cptr) { if (is_null($cptr)) return null; $typename = lasso_get_object_typename($cptr); @@ -85,6 +92,9 @@ function cptrToPhp ($cptr) { else: inheritence = '' + print >> self.fd, '/**' + print >> self.fd, ' * @package Lasso' + print >> self.fd, ' */' print >> self.fd, 'class %(class_name)s%(inheritence)s {' % locals() if klass.members or klass.methods: @@ -96,6 +106,9 @@ function cptrToPhp ($cptr) { print >> self.fd, '' # Add a special class to get an object instance without initialising + print >> self.fd, '/**' + print >> self.fd, ' * @package Lasso' + print >> self.fd, ' */' print >> self.fd, 'class %(class_name)sNoInit extends %(class_name)s {' % locals() print >> self.fd, ' public function __construct() {}' print >> self.fd, '}' @@ -144,6 +157,9 @@ function cptrToPhp ($cptr) { # FIXME: handle objects and GLists # Generic getter + print >> self.fd, ' /**' + print >> self.fd, ' * @return mixed' + print >> self.fd, ' */' print >> self.fd, ' public function __get($attr) {' print >> self.fd, ' $func = "get_" . $attr;' print >> self.fd, ' if (method_exists($this, $func)) {' @@ -163,21 +179,30 @@ function cptrToPhp ($cptr) { print >> self.fd, '' for m in klass.members: + mtype = m[0] mname = utils.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(m[0]): + if self.is_object(mtype): print >> self.fd, ' return cptrToPhp(%s_%s_get($this->_cptr));' % ( klass.name, mname) - elif m[0] == 'GHashTable*': - print >> self.fd, ' $cptr_array = %s_%s_get($this->_cptr);' % (klass.name, mname) - if options.get('elem_type') != 'char*': - print >> self.fd, ' $array = array();' - print >> self.fd, ' foreach ($cptr_array as $key => $value) {' - print >> self.fd, ' $array[$key] = cptrToPhp($value);' + elif mtype in ('GList*', 'GHashTable*'): + print >> self.fd, ' $array = %s_%s_get($this->_cptr);' % (klass.name, mname) + if self.is_object(options.get('elem_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) @@ -185,16 +210,21 @@ function cptrToPhp ($cptr) { # Setters print >> self.fd, ' protected function set_%s($value) {' % mname - if self.is_object(m[0]): + if self.is_object(mtype): print >> self.fd, ' %s_%s_set($this->_cptr, $value->_cptr);' % (klass.name, mname) - elif m[0] == 'GHashTable*' and options.get('elem_type') != 'char*': - print >> self.fd, ' $cptr_array = array();' + elif mtype in ('GList*', 'GHashTable*') and self.is_object(options.get('elem_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)) {' - print >> self.fd, ' foreach ($value as $key => $item_value) {' - print >> self.fd, ' $cptr_array[$key] = $item_value->_cptr;' + 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, ' }' print >> self.fd, ' }' - print >> self.fd, ' %s_%s_set($this->_cptr, $cptr_array);' % (klass.name, mname) + 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, ' }' @@ -220,7 +250,11 @@ function cptrToPhp ($cptr) { except IndexError: setter = None mname = re.match(r'lasso_.*_get_(\w+)', meth_name).group(1) + mname =utils.format_as_camelcase(mname) + print >> self.fd, ' /**' + print >> self.fd, ' * @return %s' % self.get_docstring_return_type(m.return_type) + print >> self.fd, ' */' print >> self.fd, ' protected function get_%s() {' % mname if self.is_object(m.return_type): print >> self.fd, ' $cptr = %s($this->_cptr);' % meth_name @@ -284,13 +318,10 @@ function cptrToPhp ($cptr) { else: c_args = '' + if m.docstring: + print >> self.fd, self.generate_docstring(m, mname, 4) print >> self.fd, ' public function %s(%s) {' % ( utils.format_underscore_as_camelcase(mname), php_args) - # FIXME: add php api documentation -# if m.docstring: -# print >> fd, " '''" -# print >> fd, self.format_docstring(m, mname, 8) -# print >> fd, " '''" if m.return_type == 'void': print >> self.fd, ' %s($this->_cptr%s);' % (m.name, c_args) elif m.return_type in ('gint', 'int'): @@ -309,6 +340,57 @@ function cptrToPhp ($cptr) { print >> self.fd, '' + def generate_docstring(self, func, method_name, indent): + docstring = func.docstring + if func.args: + first_arg_name = func.args[0][1] + else: + first_arg_name = None + + def rep(s): + type = s.group(1)[0] + var = s.group(1)[1:] + if type == '#': # struct + return var + elif type == '%': # %TRUE, %FALSE + if var in ('TRUE', 'FALSE'): + return var + print >> sys.stderr, 'W: unknown docstring thingie: %s' % s.group(1) + elif type == '@': + if var == first_arg_name: + return '$this' + else: + return '$' + var + return s.group(1) + + lines = [] + for l in docstring.splitlines(): + if l.strip() and not lines: + continue + lines.append(l) + s = indent * ' ' + '/**\n' + s += '\n'.join([indent * ' ' + ' * ' + x for x in lines[1:]]) + s += '\n' + indent * ' ' + ' */' + regex = re.compile(r'([\#%@]\w+)', re.DOTALL) + s = regex.sub(rep, s) + s = s.replace('Return value: ', '@return %s ' % self.get_docstring_return_type(func.return_type)) + return s + + def get_docstring_return_type(self, return_type): + if return_type == None: + return '' + elif return_type == 'gboolean': + return 'boolean' + elif return_type in ['int', 'gint'] + self.binding_data.enums: + return 'int' + elif return_type in ('char*', 'gchar*', 'const char*', 'const gchar*', 'xmlNode*'): + return 'string' + elif return_type in ('GList*', 'GHashTable*'): + return 'array' + else: + # Objects + return return_type.replace('*', '') + def generate_exceptions(self): done_cats = [] @@ -317,6 +399,9 @@ function cptrToPhp ($cptr) { done_cats.append(cat) parent_cat = exc_cat.attrib.get('parent', '') print >> self.fd, '''\ +/** + * @package Lasso + */ class Lasso%sError extends Lasso%sError {} ''' % (cat, parent_cat) @@ -339,11 +424,17 @@ class Lasso%sError extends Lasso%sError {} parent_cat = '' print >> self.fd, '''\ +/** + * @package Lasso + */ class Lasso%sError extends Lasso%sError {} ''' % (cat, parent_cat) if detail not in exceptions_dict: print >> self.fd, '''\ +/** + * @package Lasso + */ class Lasso%sError extends Lasso%sError { protected $code = %s; } @@ -351,8 +442,11 @@ class Lasso%sError extends Lasso%sError { exceptions_dict[detail] = c[1] print >> self.fd, '''\ +/** + * @package Lasso + */ class LassoError extends Exception { - protected static $exceptions_dict = array(''' + private static $exceptions_dict = array(''' for k, v in exceptions_dict.items(): print >> self.fd, ' %s => "Lasso%sError",' % (v, k) diff --git a/bindings/lang_php5_helpers/wrapper_source.py b/bindings/lang_php5_helpers/wrapper_source.py index 5096877b..1dfef51a 100644 --- a/bindings/lang_php5_helpers/wrapper_source.py +++ b/bindings/lang_php5_helpers/wrapper_source.py @@ -31,7 +31,7 @@ class WrapperSource: self.functions_list = [] def is_object(self, t): - return t not in [None, 'char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', + return t not in ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', 'xmlNode*', 'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums def generate(self): @@ -128,19 +128,22 @@ PHP_MSHUTDOWN_FUNCTION(lasso) } } ''' - elif vtype in ('GList*',) and options.get('elem_type') == 'char*': - print >> self.fd, '''\ - array_init(return_value); - for (item = g_list_first(return_c_value); item != NULL; item = g_list_next(item)) { - add_next_index_string(return_value, item->data, 1); - } + elif vtype == 'GList*': + if options.get('elem_type') == 'char*': + print >> self.fd, '''\ + set_array_from_list_of_strings(return_c_value, &return_value); ''' - elif vtype in ('GList*',) and options.get('elem_type') != 'char*': - print >> self.fd, ' RETURN_NULL();' - elif vtype in ('GHashTable*',) and options.get('elem_type') == 'char*': - print >> self.fd, ' RETURN_NULL();' - elif vtype in ('GHashTable*',) and options.get('elem_type') != 'char*': - print >> self.fd, '''\ + elif options.get('elem_type') == 'xmlNode*': + print >> self.fd, '''\ + set_array_from_list_of_xmlnodes(return_c_value, &return_value); +''' + else: + print >> self.fd, '''\ + set_array_from_list_of_objects(return_c_value, &return_value); +''' + elif vtype == 'GHashTable*': + if options.get('elem_type') not in ('char*', 'xmlNode*'): + print >> self.fd, '''\ set_array_from_hashtable_of_objects(return_c_value, &return_value); ''' else: @@ -168,12 +171,6 @@ PHP_MSHUTDOWN_FUNCTION(lasso) arg_type, arg_name, arg_options = arg if arg_type in ('char*', 'const char*', 'gchar*', 'const gchar*'): arg_type = arg_type.replace('const ', '') - #if arg_options.get('optional'): - # if not '|' in parse_tuple_format: - # parse_tuple_format.append('|') - # parse_tuple_format.append('z') - #else: - # parse_tuple_format.append('s') parse_tuple_format += 's' parse_tuple_args.append('&%s_str, &%s_len' % (arg_name, arg_name)) print >> self.fd, ' %s %s = NULL;' % ('char*', arg_name) @@ -195,7 +192,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) if m.return_type: print >> self.fd, ' %s return_c_value;' % m.return_type - if self.is_object(m.return_type): + if m.return_type is not None and self.is_object(m.return_type): print >> self.fd, ' PhpGObjectPtr *self;' print >> self.fd, '' @@ -236,7 +233,8 @@ PHP_MSHUTDOWN_FUNCTION(lasso) 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('elem_type') != 'char*': + if m_type == 'GList*' and m_options.get('elem_type') not in ('char*', 'xmlNode*') \ + and not self.is_object(m_options.get('elem_type')): print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('elem_type')) return @@ -255,8 +253,6 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> self.fd, ' PhpGObjectPtr *cvt_this;' if self.is_object(m_type): print >> self.fd, ' PhpGObjectPtr *self;' - elif m_type == 'GList*' and m_options.get('elem_type') == 'char*': - print >> self.fd, ' GList* item = NULL;' print >> self.fd, '' print >> self.fd, '''\ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zval_this) == FAILURE) { @@ -281,7 +277,8 @@ PHP_MSHUTDOWN_FUNCTION(lasso) def generate_setter(self, klassname, m_type, m_name, m_options): - if m_type == 'GList*' and m_options.get('elem_type') != 'char*': + if m_type == 'GList*' and m_options.get('elem_type') not in ('char*', 'xmlNode*') \ + and not self.is_object(m_options.get('elem_type')): print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('elem_type')) return @@ -350,13 +347,13 @@ PHP_MSHUTDOWN_FUNCTION(lasso) 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) + print >> self.fd, ' this->%s = get_xml_node_from_string(%s_str);' % (m_name, m_name) else: print >> self.fd, ' this->%s = estrndup(%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*' and arg_options.get('elem_type') == 'char*': + elif arg_type == 'GList*': if m_options.get('elem_type') == 'char*': print >> self.fd, ''' if (this->%(name)s) { @@ -366,6 +363,20 @@ PHP_MSHUTDOWN_FUNCTION(lasso) } this->%(name)s = get_list_from_array_of_strings(zval_%(name)s); ''' % { 'name': m_name } + elif m_options.get('elem_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, ''' + /* FIXME: Free the existing list */ + this->%(name)s = get_list_from_array_of_objects(zval_%(name)s); +''' % { 'name': m_name } elif arg_type == 'GHashTable*' and arg_options.get('elem_type') != 'char*': print >> self.fd, '''\ /* FIXME: Free the existing hashtable */ diff --git a/bindings/lang_php5_helpers/wrapper_source_top.c b/bindings/lang_php5_helpers/wrapper_source_top.c index b293cecb..9181f3c0 100644 --- a/bindings/lang_php5_helpers/wrapper_source_top.c +++ b/bindings/lang_php5_helpers/wrapper_source_top.c @@ -7,15 +7,82 @@ #include <lasso/lasso.h> #include "php_lasso.h" +/* utility functions */ + +#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) */ + +typedef struct _GHashNode GHashNode; + +struct _GHashNode +{ + gpointer key; + gpointer value; + GHashNode *next; + guint key_hash; +}; + +struct _GHashTable +{ + gint size; + gint nnodes; + GHashNode **nodes; + GHashFunc hash_func; + GEqualFunc key_equal_func; + volatile gint ref_count; + GDestroyNotify key_destroy_func; + GDestroyNotify value_destroy_func; +}; + +static GList * +g_hash_table_get_keys (GHashTable *hash_table) +{ + GHashNode *node; + gint i; + GList *retval; + + g_return_val_if_fail (hash_table != NULL, NULL); + + retval = NULL; + for (i = 0; i < hash_table->size; i++) + for (node = hash_table->nodes[i]; node; node = node->next) + retval = g_list_prepend (retval, node->key); + + return retval; +} + +#endif + +/* Define the Lasso PHP module */ + int le_lasso_server; ZEND_GET_MODULE(lasso) +/* Wrapper around GObject to get the dynamic typename */ + typedef struct { GObject *obj; char *typename; } PhpGObjectPtr; +static PhpGObjectPtr* +PhpGObjectPtr_New(GObject *obj) +{ + PhpGObjectPtr *self; + + if (obj == NULL) { + return NULL; + } + + self = (PhpGObjectPtr *)emalloc(sizeof(PhpGObjectPtr)); + self->obj = obj; + self->typename = estrdup(G_OBJECT_TYPE_NAME(obj)); + + return self; +} + PHP_FUNCTION(lasso_get_object_typename) { PhpGObjectPtr *self; @@ -29,6 +96,8 @@ PHP_FUNCTION(lasso_get_object_typename) RETURN_STRING(self->typename, 1); } +/* Conversion functions */ + static char* get_string_from_xml_node(xmlNode *xmlnode) { @@ -96,89 +165,30 @@ get_list_from_array_of_strings(zval* array) return result; } -/* utility functions */ - -#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) */ - -typedef struct _GHashNode GHashNode; - -struct _GHashNode -{ - gpointer key; - gpointer value; - GHashNode *next; - guint key_hash; -}; - -struct _GHashTable -{ - gint size; - gint nnodes; - GHashNode **nodes; - GHashFunc hash_func; - GEqualFunc key_equal_func; - volatile gint ref_count; - GDestroyNotify key_destroy_func; - GDestroyNotify value_destroy_func; -}; - -GList * -g_hash_table_get_keys (GHashTable *hash_table) -{ - GHashNode *node; - gint i; - GList *retval; - - g_return_val_if_fail (hash_table != NULL, NULL); - - retval = NULL; - for (i = 0; i < hash_table->size; i++) - for (node = hash_table->nodes[i]; node; node = node->next) - retval = g_list_prepend (retval, node->key); - - return retval; -} - -#endif - static void -set_array_from_hashtable_of_objects(GHashTable *value, zval **array) -{ - GList *keys; - GObject *item_value; - PhpGObjectPtr *tmp_item; - zval *item; +set_array_from_list_of_strings(GList* list, zval **array) { + GList* item; array_init(*array); - for (keys = g_hash_table_get_keys(value); keys; keys = g_list_next(keys)) { - item_value = g_hash_table_lookup(value, keys->data); - if (item_value) { - tmp_item = (PhpGObjectPtr *)emalloc(sizeof(PhpGObjectPtr)); - tmp_item->obj = G_OBJECT(item_value); - tmp_item->typename = estrdup(G_OBJECT_TYPE_NAME(G_OBJECT(item_value))); - ZEND_REGISTER_RESOURCE(item, tmp_item, le_lasso_server); - add_assoc_zval(*array, (char*)keys->data, item); + for (item = g_list_first(list); item != NULL; item = g_list_next(item)) { + if (item->data != NULL) { + add_next_index_string(*array, item->data, 1); } else { - add_assoc_null(*array, (char*)keys->data); + add_next_index_null(*array); } } - g_list_free(keys); } -static GHashTable* -get_hashtable_from_array_of_strings(zval* array) +static GList* +get_list_from_array_of_xmlnodes(zval* array) { HashTable* hashtable; HashPosition pointer; int size; - char *key; - unsigned int key_len; - unsigned long index; zval** data; zval temp; - GHashTable* result = NULL; + char *temp_str; + GList* result = NULL; hashtable = Z_ARRVAL_P(array); size = zend_hash_num_elements(hashtable); @@ -188,27 +198,82 @@ get_hashtable_from_array_of_strings(zval* array) temp = **data; zval_copy_ctor(&temp); convert_to_string(&temp); - if (zend_hash_get_current_key_ex(hashtable, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) { - g_hash_table_insert(result, key, estrndup(Z_STRVAL(temp), Z_STRLEN(temp))); + temp_str = estrndup(Z_STRVAL(temp), Z_STRLEN(temp)); + result = g_list_append(result, get_xml_node_from_string(temp_str)); + zval_dtor(&temp); + } + return result; +} + +static void +set_array_from_list_of_xmlnodes(GList* list, zval **array) { + GList* item; + + array_init(*array); + for (item = g_list_first(list); item != NULL; item = g_list_next(item)) { + if (item->data != NULL) { + add_next_index_string(*array, get_string_from_xml_node(item->data), 1); } else { - g_hash_table_insert(result, (void*)index, estrndup(Z_STRVAL(temp), Z_STRLEN(temp))); + add_next_index_null(*array); + } + } +} + +static GList* +get_list_from_array_of_objects(zval *array) +{ + HashTable *hashtable; + HashPosition pointer; + int size; + zval **data; + PhpGObjectPtr *cvt_temp; + GList *result = NULL; + + 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)) { + cvt_temp = (PhpGObjectPtr*) zend_fetch_resource(data TSRMLS_CC, -1, PHP_LASSO_SERVER_RES_NAME, NULL, 1, le_lasso_server); + if (cvt_temp != NULL) { + result = g_list_append(result, cvt_temp->obj); + } else { + result = g_list_append(result, NULL); } - zval_dtor(&temp); } return result; } +static void +set_array_from_list_of_objects(GList *list, zval **array) +{ + GList *item = NULL; + zval *zval_item = NULL; + + array_init(*array); + for (item = g_list_first(list); item != NULL; item = g_list_next(item)) { + if (item->data != NULL) { + zval_item = emalloc(sizeof(PhpGObjectPtr)); + ZEND_REGISTER_RESOURCE(zval_item, PhpGObjectPtr_New(item->data), le_lasso_server); + add_next_index_zval(*array, zval_item); + } else { + add_next_index_null(*array); + } + } +} + +/* FIXME: This function doesn't work yet */ static GHashTable* get_hashtable_from_array_of_objects(zval *array) { - HashTable *hashtable; + HashTable *hashtable = NULL; HashPosition pointer; int size; - char *key; + char *key = NULL; unsigned int key_len; unsigned long index; - zval **data; - PhpGObjectPtr *cvt_temp; + zval **data = NULL; + PhpGObjectPtr *cvt_temp = NULL; GHashTable *result = NULL; result = g_hash_table_new(g_str_hash, g_str_equal); @@ -220,18 +285,39 @@ get_hashtable_from_array_of_objects(zval *array) 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, cvt_temp->obj); + g_hash_table_insert(result, key, g_object_ref(cvt_temp->obj)); } else { g_hash_table_insert(result, key, NULL); - } + } } else { if (cvt_temp != NULL) { - g_hash_table_insert(result, (gpointer)index, cvt_temp->obj); + g_hash_table_insert(result, (gpointer)index, g_object_ref(cvt_temp->obj)); } else { g_hash_table_insert(result, (gpointer)index, NULL); - } + } } } return result; } +static void +set_array_from_hashtable_of_objects(GHashTable *hashtable, zval **array) +{ + GList *keys = NULL; + GObject *item = NULL; + zval *zval_item = NULL; + + array_init(*array); + for (keys = g_hash_table_get_keys(hashtable); keys; keys = g_list_next(keys)) { + item = g_hash_table_lookup(hashtable, keys->data); + if (item) { + zval_item = emalloc(sizeof(PhpGObjectPtr)); + ZEND_REGISTER_RESOURCE(zval_item, PhpGObjectPtr_New(item), le_lasso_server); + 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/lang_python_wrapper_top.c b/bindings/lang_python_wrapper_top.c index 74cc1c74..d8ae5967 100644 --- a/bindings/lang_python_wrapper_top.c +++ b/bindings/lang_python_wrapper_top.c @@ -40,7 +40,7 @@ struct _GHashTable GDestroyNotify value_destroy_func; }; -GList * +static GList * g_hash_table_get_keys (GHashTable *hash_table) { GHashNode *node; diff --git a/bindings/php5/Makefile.am b/bindings/php5/Makefile.am index 16de1232..0313a5d5 100644 --- a/bindings/php5/Makefile.am +++ b/bindings/php5/Makefile.am @@ -14,4 +14,7 @@ lasso_la_SOURCES = _lasso.c _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 + endif diff --git a/bindings/php5/tests/binding_tests.php b/bindings/php5/tests/binding_tests.php index e9e48401..d22440ff 100755 --- a/bindings/php5/tests/binding_tests.php +++ b/bindings/php5/tests/binding_tests.php @@ -26,7 +26,7 @@ require("../lasso.php"); define("DATA_DIR", "../../../tests/data/"); function test01() { - echo "Testing lasso_provider_get_organization binding which must return an xmlNode*... "; + echo "Get an xmlNode* from a Lasso function... "; $organisation_string = '<Organization xmlns="urn:liberty:metadata:2003-08"> <OrganizationName>Name of the organization</OrganizationName> @@ -44,7 +44,7 @@ function test01() { } function test02() { - echo "Get and set a GList of strings... "; + echo "Get and set a list of strings... "; $requestAuthnContext = new LassoLibRequestAuthnContext(); $requestAuthnContext->authnContextClassRef = array(LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); @@ -56,7 +56,65 @@ function test02() { } function test03() { - echo "Get and set 'providers' attribute (hashtable) of a server object... "; + echo "Get and set a list of xmlNode*..."; + + $server = new LassoServer( + DATA_DIR . "sp1-la/metadata.xml", + DATA_DIR . "sp1-la/private-key-raw.pem", + NULL, + DATA_DIR . "sp1-la/certificate.pem"); + $server->addProvider( + LASSO_PROVIDER_ROLE_IDP, + DATA_DIR . "idp1-la/metadata.xml", + DATA_DIR . "idp1-la/public-key.pem", + DATA_DIR . "idp1-la/certificate.pem"); + $login = new LassoLogin($server); + $login->initAuthnRequest(); + $requestAuthnContext = new LassoLibRequestAuthnContext(); + $extension1 = '<lib:Extension xmlns:lib="urn:liberty:iff:2003-08"> + <action>do</action> +</lib:Extension>'; + $extension2 = '<lib:Extension xmlns:lib="urn:liberty:iff:2003-08"> + <action2>do action 2</action2><action3>do action 3</action3> +</lib:Extension>'; + $extensionList = array($extension1, $extension2); + $login->request->extension = $extensionList; + assert($login->request->extension == $extensionList); + assert($login->request->extension[0] == $extension1); + assert($login->request->extension[1] == $extension2); + + echo "OK.\n"; +} + +function test04() { + echo "Get and set a list of Lasso objects..."; + + $response = new LassoSamlpResponse(); + assert(!$response->assertion); + + $assertions = array(); + $assertion1 = new LassoSamlAssertion(); + $assertion1->assertionId = "assertion 1"; + $assertions[] = $assertion1; + assert($assertions[0]->assertionId == "assertion 1"); + $assertion2 = new LassoSamlAssertion(); + $assertion2->assertionId = "assertion 2"; + $assertions[] = $assertion2; + $response->assertion = $assertions; + assert($response->assertion[0]->assertionId == "assertion 1"); + assert($response->assertion[1]->assertionId == "assertion 2"); + unset($assertions); + assert($response->assertion[0]->assertionId == "assertion 1"); + assert($response->assertion[1]->assertionId == "assertion 2"); + $assertions = $response->assertion; + assert($assertions[0]->assertionId == "assertion 1"); + assert($assertions[1]->assertionId == "assertion 2"); + + echo "OK.\n"; +} + +function test05() { + echo "Get and set a hashtable of objects... "; $server = new LassoServer( DATA_DIR . "sp1-la/metadata.xml", @@ -70,10 +128,12 @@ function test03() { DATA_DIR . "idp1-la/certificate.pem"); assert(!is_null($server->providers)); assert($server->providers["https://idp1/metadata"]->providerId == "https://idp1/metadata"); + assert($server->providers["https://idp1/metadata"]->providerId == "https://idp1/metadata"); $tmp_providers = $server->providers; $server->providers = NULL; assert(!$server->providers); $server->providers = $tmp_providers; + $provider = $server->providers["https://idp1/metadata"]; assert($server->providers["https://idp1/metadata"]->providerId == "https://idp1/metadata"); echo "OK.\n"; @@ -84,5 +144,7 @@ lasso_init(); test01(); test02(); test03(); +test04(); +//test05(); lasso_shutdown(); diff --git a/bindings/php5/tests/profile_tests.php b/bindings/php5/tests/profile_tests.php index 04e32848..cb8f4ade 100755 --- a/bindings/php5/tests/profile_tests.php +++ b/bindings/php5/tests/profile_tests.php @@ -84,12 +84,11 @@ function test03() { $login = new LassoLogin($server); $result = $login->initAuthnRequest(); assert(! is_null($login->request)); - $request = $login->request; - assert(get_class($request) == "LassoLibAuthnRequestNoInit"); - $dump = $request->dump(); - $request->protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART; - $dump2 = $request->dump(); - assert($request->protocolProfile == LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART); + assert(get_class($login->request) == "LassoLibAuthnRequestNoInit"); + $dump = $login->request->dump(); + $login->request->protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART; + assert($login->request->protocolProfile == LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART); + $dump2 = $login->request->dump(); assert($dump != $dump2); echo "OK.\n"; @@ -139,16 +138,13 @@ function test05() { $spLogin = new LassoLogin($spServer); $spLogin->initAuthnRequest(); $requestAuthnContext = new LassoLibRequestAuthnContext(); - $authnContextClassRefsList = array(LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); - $requestAuthnContext->authnContextClassRef = $authnContextClassRefsList; - assert(! is_null($requestAuthnContext->authnContextClassRef)); - assert(sizeof($requestAuthnContext->authnContextClassRef) == 1); - $request = $spLogin->request; - $request->requestAuthnContext = $requestAuthnContext; - assert(! is_null($request->requestAuthnContext)); - $request->protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART; + $requestAuthnContext->authnContextClassRef = array(LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); + assert($requestAuthnContext->authnContextClassRef[0] == LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); + $spLogin->request->requestAuthnContext = $requestAuthnContext; + assert(! is_null($spLogin->request->requestAuthnContext)); + $spLogin->request->protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART; + assert($spLogin->request->protocolProfile == LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART); $spLogin->buildAuthnRequestMsg(); - $authnRequestUrl = $spLogin->msgUrl; assert(! is_null($spLogin->msgUrl)); assert($spLogin->msgUrl != ""); @@ -167,13 +163,12 @@ function test05() { list($urlBase, $authnRequestQuery) = split("\?", $spLogin->msgUrl, 2); assert($authnRequestQuery != ""); $idpLogin->processAuthnRequestMsg($authnRequestQuery); - $request = $idpLogin->request; - assert(! is_null($request)); - assert(! is_null($request->requestAuthnContext)); - assert($request->requestAuthnContext != ""); - $requestAuthnContext = $request->requestAuthnContext; - assert(sizeof($requestAuthnContext->authnContextClassRef) == 1); - assert($requestAuthnContext->authnContextClassRef[0] == LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); + assert(! is_null($idpLogin->request)); + assert(! is_null($idpLogin->request->requestAuthnContext)); + assert($idpLogin->request->requestAuthnContext != ""); + assert(sizeof($idpLogin->request->requestAuthnContext->authnContextClassRef) == 1); + assert($idpLogin->request->requestAuthnContext->authnContextClassRef[0] == + LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); echo "OK.\n"; } |