diff options
author | Frederic Peters <fpeters@entrouvert.com> | 2008-04-29 12:05:12 +0000 |
---|---|---|
committer | Frederic Peters <fpeters@entrouvert.com> | 2008-04-29 12:05:12 +0000 |
commit | 0ac403922ffc4126f21e48dddd0c38076257ca74 (patch) | |
tree | 158c308e82073bc4ce782d397f45092d331dd05b | |
parent | 62b71580574c634b7e8bac0a4b3105db1a9a2538 (diff) | |
download | lasso-0ac403922ffc4126f21e48dddd0c38076257ca74.tar.gz lasso-0ac403922ffc4126f21e48dddd0c38076257ca74.tar.xz lasso-0ac403922ffc4126f21e48dddd0c38076257ca74.zip |
[project @ fpeters@0d.be-20071113015838-961yf93m001amgi1]
merging Damien branch
Original author: Frederic Peters <fpeters@0d.be>
Date: 2007-11-13 02:58:38.825000+01:00
-rw-r--r-- | bindings/lang_php5_helpers/php_code.py | 84 | ||||
-rw-r--r-- | bindings/lang_php5_helpers/wrapper_source.py | 43 | ||||
-rw-r--r-- | bindings/lang_php5_helpers/wrapper_source_top.c | 166 | ||||
-rw-r--r-- | bindings/overrides.xml | 5 | ||||
-rwxr-xr-x | bindings/php5/tests/binding_tests.php | 39 |
5 files changed, 273 insertions, 64 deletions
diff --git a/bindings/lang_php5_helpers/php_code.py b/bindings/lang_php5_helpers/php_code.py index 92b54e25..820874de 100644 --- a/bindings/lang_php5_helpers/php_code.py +++ b/bindings/lang_php5_helpers/php_code.py @@ -30,8 +30,8 @@ class PhpCode: self.fd = fd def is_object(self, t): - return t not in ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', - 'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums + return t not in [None, 'char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', + 'xmlNode*', 'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums def generate(self): self.generate_header() @@ -167,43 +167,38 @@ function cptrToPhp ($cptr) { options = m[2] # Getters - for m2 in klass.methods: - # If method is already defined in C, don't define it twice - if m2.rename: - m2name = m2.rename - else: - m2name = m2.name - if '_get_' in m2name: - class_name = re.match(r'lasso_(.*)_get_\w+', m2name).group(1) - attr_name = re.match(r'lasso_.*_get_(\w+)', m2name).group(1) - if class_name and attr_name: - class_name = 'Lasso' + class_name.capitalize() - if class_name == klass.name and attr_name == mname: - print >> sys.stderr, 'W: Bad function name : %s function prevents \ -writing a standard accessor for attribute "%s"' % (m2name, attr_name) - break + print >> self.fd, ' protected function get_%s() {' % mname + if self.is_object(m[0]): + 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);' + print >> self.fd, ' }' + print >> self.fd, ' return $array;' else: - print >> self.fd, ' protected function get_%s() {' % mname - if self.is_object(m[0]): - print >> self.fd, ' return cptrToPhp(%s_%s_get($this->_cptr));' % ( - klass.name, mname) - else: - print >> self.fd, ' return %s_%s_get($this->_cptr);' % (klass.name, mname) - print >> self.fd, ' }' + print >> self.fd, ' return %s_%s_get($this->_cptr);' % (klass.name, mname) + print >> self.fd, ' }' # Setters - for m2 in klass.methods: - # If method is already defined in C, don't define it twice - if m2.name == 'set_%s' % mname: - break + print >> self.fd, ' protected function set_%s($value) {' % mname + if self.is_object(m[0]): + 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();' + 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;' + print >> self.fd, ' }' + print >> self.fd, ' }' + print >> self.fd, ' %s_%s_set($this->_cptr, $cptr_array);' % (klass.name, mname) else: - print >> self.fd, ' protected function set_%s($value) {' % mname - if self.is_object(m[0]): - print >> self.fd, ' %s_%s_set($this->_cptr, $value->_cptr);' % (klass.name, mname) - else: - print >> self.fd, ' %s_%s_set($this->_cptr, $value);' % (klass.name, mname) - print >> self.fd, ' }' - print >> self.fd, '' + print >> self.fd, ' %s_%s_set($this->_cptr, $value);' % (klass.name, mname) + print >> self.fd, ' }' + print >> self.fd, '' def generate_methods(self, klass): @@ -227,11 +222,21 @@ writing a standard accessor for attribute "%s"' % (m2name, attr_name) mname = re.match(r'lasso_.*_get_(\w+)', meth_name).group(1) print >> self.fd, ' protected function get_%s() {' % mname - print >> self.fd, ' return %s($this->_cptr);' % (meth_name) + if self.is_object(m.return_type): + print >> self.fd, ' $cptr = %s($this->_cptr);' % meth_name + print >> self.fd, ' if (! is_null($cptr)) {' + print >> self.fd, ' return cptrToPhp($cptr);' + print >> self.fd, ' }' + print >> self.fd, ' return null;' + else: + print >> self.fd, ' return %s($this->_cptr);' % meth_name print >> self.fd, ' }' if setter: print >> self.fd, ' protected function set_%s($value) {' % mname - print >> self.fd, ' %s($this->_cptr, $value);' % (setter.name) + if self.is_object(m.return_type): + print >> self.fd, ' %s($this->_cptr, $value->_cptr);' % setter.name + else: + print >> self.fd, ' %s($this->_cptr, $value);' % setter.name print >> self.fd, ' }' print >> self.fd, '' @@ -360,13 +365,12 @@ class LassoError extends Exception { if (! class_exists($exception)) { $exception = "LassoError"; } - throw new $exception(lasso_strerror($rc), $rc); + throw new $exception(strError($rc), $rc); } } ''' def generate_footer(self): print >> self.fd, '''\ -?> -''' +?>''' diff --git a/bindings/lang_php5_helpers/wrapper_source.py b/bindings/lang_php5_helpers/wrapper_source.py index 8df9c7c1..5096877b 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 ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', + return t not in [None, 'char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', 'xmlNode*', 'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums def generate(self): @@ -98,7 +98,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) def return_value(self, vtype, options): if vtype is None: - print >> self.fd, ' RETURN_NULL();' + return elif vtype == 'gboolean': print >> self.fd, ' RETURN_BOOL(return_c_value);' elif vtype in ['int', 'gint'] + self.binding_data.enums: @@ -134,10 +134,15 @@ PHP_MSHUTDOWN_FUNCTION(lasso) 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 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, '''\ + set_array_from_hashtable_of_objects(return_c_value, &return_value); +''' else: print >> self.fd, '''\ if (return_c_value) { @@ -225,6 +230,10 @@ PHP_MSHUTDOWN_FUNCTION(lasso) 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('elem_type') != 'char*': @@ -302,14 +311,10 @@ PHP_MSHUTDOWN_FUNCTION(lasso) parse_tuple_args.append('&%s' % arg_name) print >> self.fd, ' %s %s;' % ('long', arg_name) # Must also handle lists of Objects - elif arg_type == 'GList*' and arg_options.get('elem_type') == 'char*': + elif arg_type in ('GList*', 'GHashTable*'): parse_tuple_format += 'a' parse_tuple_args.append('&zval_%s' % arg_name) print >> self.fd, ' %s zval_%s;' % ('zval*', arg_name) - print >> self.fd, ' %s %s_data;' % ('zval**', arg_name) - print >> self.fd, ' %s %s_hashtable;' % ('HashTable*', arg_name) - print >> self.fd, ' %s %s_pointer;' % ('HashPosition', arg_name) - print >> self.fd, ' %s %s_size;' % ('int', arg_name) else: parse_tuple_format += 'r' parse_tuple_args.append('&zval_%s' % arg_name) @@ -351,7 +356,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> self.fd, ' } else {' print >> self.fd, ' this->%s = NULL;' % m_name print >> self.fd, ' }' - elif parse_tuple_format == 'a': + elif arg_type == 'GList*' and arg_options.get('elem_type') == 'char*': if m_options.get('elem_type') == 'char*': print >> self.fd, ''' if (this->%(name)s) { @@ -359,15 +364,12 @@ PHP_MSHUTDOWN_FUNCTION(lasso) g_list_foreach(this->%(name)s, (GFunc)g_free, NULL); g_list_free(this->%(name)s); } - %(name)s_hashtable = Z_ARRVAL_P(zval_%(name)s); - %(name)s_size = zend_hash_num_elements(%(name)s_hashtable); - for (zend_hash_internal_pointer_reset_ex(%(name)s_hashtable, &%(name)s_pointer); - zend_hash_get_current_data_ex(%(name)s_hashtable, (void**) &%(name)s_data, &%(name)s_pointer) == SUCCESS; - zend_hash_move_forward_ex(%(name)s_hashtable, &%(name)s_pointer)) { - if (Z_TYPE_PP(%(name)s_data) == IS_STRING) { - this->%(name)s = g_list_append(this->%(name)s, estrndup(Z_STRVAL_PP(%(name)s_data), Z_STRLEN_PP(%(name)s_data))); - } - } + this->%(name)s = get_list_from_array_of_strings(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 */ + this->%(name)s = get_hashtable_from_array_of_objects(zval_%(name)s); ''' % { '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) @@ -376,11 +378,6 @@ PHP_MSHUTDOWN_FUNCTION(lasso) 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_functions_list(self): print >> self.fd, '''\ static function_entry lasso_functions[] = {''' diff --git a/bindings/lang_php5_helpers/wrapper_source_top.c b/bindings/lang_php5_helpers/wrapper_source_top.c index 1868a754..b293cecb 100644 --- a/bindings/lang_php5_helpers/wrapper_source_top.c +++ b/bindings/lang_php5_helpers/wrapper_source_top.c @@ -57,7 +57,8 @@ get_string_from_xml_node(xmlNode *xmlnode) } static xmlNode* -get_xml_node_from_string(char *string) { +get_xml_node_from_string(char *string) +{ xmlDoc *doc; xmlNode *node; @@ -71,3 +72,166 @@ get_xml_node_from_string(char *string) { return node; } +static GList* +get_list_from_array_of_strings(zval* array) +{ + HashTable* hashtable; + HashPosition pointer; + int size; + zval** data; + zval 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)) { + temp = **data; + zval_copy_ctor(&temp); + convert_to_string(&temp); + result = g_list_append(result, estrndup(Z_STRVAL(temp), Z_STRLEN(temp))); + zval_dtor(&temp); + } + 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; + + 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); + } else { + add_assoc_null(*array, (char*)keys->data); + } + } + g_list_free(keys); +} + +static GHashTable* +get_hashtable_from_array_of_strings(zval* array) +{ + HashTable* hashtable; + HashPosition pointer; + int size; + char *key; + unsigned int key_len; + unsigned long index; + zval** data; + zval temp; + GHashTable* 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)) { + 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))); + } else { + g_hash_table_insert(result, (void*)index, estrndup(Z_STRVAL(temp), Z_STRLEN(temp))); + } + zval_dtor(&temp); + } + return result; +} + +static GHashTable* +get_hashtable_from_array_of_objects(zval *array) +{ + HashTable *hashtable; + HashPosition pointer; + int size; + char *key; + unsigned int key_len; + unsigned long index; + zval **data; + PhpGObjectPtr *cvt_temp; + 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)) { + 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); + } else { + g_hash_table_insert(result, key, NULL); + } + } else { + if (cvt_temp != NULL) { + g_hash_table_insert(result, (gpointer)index, cvt_temp->obj); + } else { + g_hash_table_insert(result, (gpointer)index, NULL); + } + } + } + return result; +} + diff --git a/bindings/overrides.xml b/bindings/overrides.xml index 36e9c4be..a9743e87 100644 --- a/bindings/overrides.xml +++ b/bindings/overrides.xml @@ -42,6 +42,11 @@ <param name="remote_providerID" optional="true"/> <param name="request_method" optional="true" default="c:LASSO_HTTP_METHOD_ANY"/> </func> + <!-- LassoDefederation --> + <func name="lasso_defederation_init_notification"> + <param name="remote_providerID" optional="true"/> + <param name="http_method" optional="true" default="c:LASSO_HTTP_METHOD_ANY"/> + </func> <!-- LassoNameIdentifier --> <func name="lasso_name_identifier_mapping_init_request"> <param name="remote_providerID" optional="true" /> diff --git a/bindings/php5/tests/binding_tests.php b/bindings/php5/tests/binding_tests.php index 1a2d999d..e9e48401 100755 --- a/bindings/php5/tests/binding_tests.php +++ b/bindings/php5/tests/binding_tests.php @@ -43,7 +43,46 @@ function test01() { echo "OK.\n"; } +function test02() { + echo "Get and set a GList of strings... "; + + $requestAuthnContext = new LassoLibRequestAuthnContext(); + $requestAuthnContext->authnContextClassRef = array(LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); + assert(! is_null($requestAuthnContext->authnContextClassRef)); + assert(sizeof($requestAuthnContext->authnContextClassRef) == 1); + assert($requestAuthnContext->authnContextClassRef[0] == LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD); + + echo "OK.\n"; +} + +function test03() { + echo "Get and set 'providers' attribute (hashtable) of a server object... "; + + $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"); + assert(!is_null($server->providers)); + assert($server->providers["https://idp1/metadata"]->providerId == "https://idp1/metadata"); + $tmp_providers = $server->providers; + $server->providers = NULL; + assert(!$server->providers); + $server->providers = $tmp_providers; + assert($server->providers["https://idp1/metadata"]->providerId == "https://idp1/metadata"); + + echo "OK.\n"; +} + + lasso_init(); test01(); +test02(); +test03(); lasso_shutdown(); |