From 047a574e6c930ff4c451031843687d89305ce8c4 Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Fri, 29 Aug 2003 23:27:22 +0000 Subject: [PATCH] - Add zend_merge_properties() which is designed to serve *_fetch_object(). - Explain drawbacks of object_and_properties_init and zend_merge_properties. # # I guess we can live with the purity problem of potentially calling __set() # of an object which wasn't already ctored. # --- Zend/zend_API.c | 38 ++++++++++++++++++++++++++++++++++++++ Zend/zend_API.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index ccfb51fce5..ead407f9e7 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -655,6 +655,44 @@ ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC) } +static int zend_merge_property(zval **value, int num_args, va_list args, zend_hash_key *hash_key) +{ + /* which name should a numeric property have ? */ + if (hash_key->nKeyLength) { + zval *obj = va_arg(args, zval *); + zend_object_handlers *obj_ht = va_arg(args, zend_object_handlers *); + zval member; + TSRMLS_FETCH(); + + ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0); + obj_ht->write_property(obj, &member, *value TSRMLS_CC); + } + return ZEND_HASH_APPLY_KEEP; +} + + +/* This function should be called after the constructor has been called + * because it may call __set from the uninitialized object otherwise. */ +ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC) +{ + zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj); + zend_class_entry *old_scope = EG(scope); + + EG(scope) = Z_OBJCE_P(obj); + zend_hash_apply_with_arguments(properties, (apply_func_args_t)zend_merge_property, 2, obj, obj_ht); + EG(scope) = old_scope; + + if (destroy_ht) { + zend_hash_destroy(properties); + FREE_HASHTABLE(properties); + } +} + + +/* This function requires 'properties' to contain all props declared in the + * class and all props being public. If only a subset is given or the class + * has protected members then you need to merge the properties seperately by + * calling zend_merge_properties(). */ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC) { zval *tmp; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index ad500c1532..4bbc3c2e09 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -203,6 +203,8 @@ ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC); ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC TSRMLS_DC); ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC); +ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC); + /* no longer supported */ ZEND_API int add_assoc_function(zval *arg, char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS)); -- 2.40.0