]> granicus.if.org Git - php/commitdiff
- Consistency of apply funcs, #39320
authorMarcus Boerger <helly@php.net>
Tue, 31 Oct 2006 22:05:56 +0000 (22:05 +0000)
committerMarcus Boerger <helly@php.net>
Tue, 31 Oct 2006 22:05:56 +0000 (22:05 +0000)
Zend/zend_hash.c

index 07fbd4393cf935588bdde533631abac9e14e5d63..67a13cc5efee527133c9c4b4bee5cdaac97fffee 100644 (file)
@@ -872,12 +872,15 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
        SET_INCONSISTENT(HT_DESTROYED);
 }
 
-/* This is used to selectively delete certain entries from a hashtable.
- * destruct() receives the data and decides if the entry should be deleted
- * or not
+/* This is used to recurse elements and selectively delete certain entries 
+ * from a hashtable. apply_func() receives the data and decides if the entry 
+ * should be deleted or recursion should be stopped. The following three 
+ * return codes are possible:
+ * ZEND_HASH_APPLY_KEEP   - continue
+ * ZEND_HASH_APPLY_STOP   - stop iteration
+ * ZEND_HASH_APPLY_REMOVE - delete the element, combineable with the former
  */
 
-
 ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
 {
        Bucket *p;
@@ -887,11 +890,16 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC)
        HASH_PROTECT_RECURSION(ht);
        p = ht->pListHead;
        while (p != NULL) {
-               if (apply_func(p->pData TSRMLS_CC)) {
+               int result = apply_func(p->pData TSRMLS_CC);
+               
+               if (result & ZEND_HASH_APPLY_REMOVE) {
                        p = zend_hash_apply_deleter(ht, p);
                } else {
                        p = p->pListNext;
                }
+               if (result & ZEND_HASH_APPLY_STOP) {
+                       break;
+               }
        }
        HASH_UNPROTECT_RECURSION(ht);
 }
@@ -906,17 +914,22 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
        HASH_PROTECT_RECURSION(ht);
        p = ht->pListHead;
        while (p != NULL) {
-               if (apply_func(p->pData, argument TSRMLS_CC)) {
+               int result = apply_func(p->pData, argument TSRMLS_CC);
+               
+               if (result & ZEND_HASH_APPLY_REMOVE) {
                        p = zend_hash_apply_deleter(ht, p);
                } else {
                        p = p->pListNext;
                }
+               if (result & ZEND_HASH_APPLY_STOP) {
+                       break;
+               }
        }
        HASH_UNPROTECT_RECURSION(ht);
 }
 
 
-ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t destruct, int num_args, ...)
+ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int num_args, ...)
 {
        Bucket *p;
        va_list args;
@@ -928,16 +941,20 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t de
 
        p = ht->pListHead;
        while (p != NULL) {
+               int result;
                va_start(args, num_args);
                hash_key.nKeyLength = p->nKeyLength;
                hash_key.h = p->h;
-               hash_key.type = p->key.type;
-               hash_key.arKey.s = p->key.arKey.s;
-               if (destruct(p->pData, num_args, args, &hash_key)) {
+               result = apply_func(p->pData, num_args, args, &hash_key);
+
+               if (result & ZEND_HASH_APPLY_REMOVE) {
                        p = zend_hash_apply_deleter(ht, p);
                } else {
                        p = p->pListNext;
                }
+               if (result & ZEND_HASH_APPLY_STOP) {
+                       break;
+               }
                va_end(args);
        }