From 78728e33fa197d67ce8ddd652c5e0510db85af0f Mon Sep 17 00:00:00 2001 From: Etienne Kneuss Date: Wed, 5 Jan 2011 15:01:18 +0000 Subject: [PATCH] Implement SplObjectStorage::removeAllExcept (Patch by Matthey Turland) --- ext/spl/spl_observer.c | 31 +++++++++++++ ...plObjectStorage_removeAllExcept_basic.phpt | 27 ++++++++++++ ...age_removeAllExcept_invalid_parameter.phpt | 44 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 ext/spl/tests/SplObjectStorage_removeAllExcept_basic.phpt create mode 100644 ext/spl/tests/SplObjectStorage_removeAllExcept_invalid_parameter.phpt diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 4945ec1c63f..698ad22d76f 100755 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -580,6 +580,36 @@ SPL_METHOD(SplObjectStorage, removeAll) RETURN_LONG(zend_hash_num_elements(&intern->storage)); } /* }}} */ +/* {{{ proto bool SplObjectStorage::removeAllExcept(SplObjectStorage $os) + Remove elements not common to both this SplObjectStorage instance and $os */ +SPL_METHOD(SplObjectStorage, removeAllExcept) +{ + zval *obj; + spl_SplObjectStorage *intern = (spl_SplObjectStorage *)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_SplObjectStorage *other; + spl_SplObjectStorageElement *element; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, spl_ce_SplObjectStorage) == FAILURE) { + return; + } + + other = (spl_SplObjectStorage *)zend_object_store_get_object(obj TSRMLS_CC); + + zend_hash_internal_pointer_reset(&intern->storage); + while (zend_hash_get_current_data(&intern->storage, (void **)&element) == SUCCESS) { + if (!spl_object_storage_contains(other, getThis(), element->obj TSRMLS_CC)) { + spl_object_storage_detach(intern, getThis(), element->obj TSRMLS_CC); + } + zend_hash_move_forward(&intern->storage); + } + + zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); + intern->index = 0; + + RETURN_LONG(zend_hash_num_elements(&intern->storage)); +} +/* }}} */ + /* {{{ proto bool SplObjectStorage::contains($obj) Determine whethe an object is contained in the storage */ SPL_METHOD(SplObjectStorage, contains) @@ -940,6 +970,7 @@ static const zend_function_entry spl_funcs_SplObjectStorage[] = { SPL_ME(SplObjectStorage, contains, arginfo_Object, 0) SPL_ME(SplObjectStorage, addAll, arginfo_Object, 0) SPL_ME(SplObjectStorage, removeAll, arginfo_Object, 0) + SPL_ME(SplObjectStorage, removeAllExcept, arginfo_Object, 0) SPL_ME(SplObjectStorage, getInfo, arginfo_splobject_void,0) SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0) SPL_ME(SplObjectStorage, getHash, arginfo_getHash, 0) diff --git a/ext/spl/tests/SplObjectStorage_removeAllExcept_basic.phpt b/ext/spl/tests/SplObjectStorage_removeAllExcept_basic.phpt new file mode 100644 index 00000000000..7c8cb7574cd --- /dev/null +++ b/ext/spl/tests/SplObjectStorage_removeAllExcept_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Check that SplObjectStorage::removeUncommon functions when receiving proper input +--CREDITS-- +Matthew Turland (me@matthewturland.com) +--FILE-- +attach($a); + $foo->attach($b); + + $bar = new SplObjectStorage; + $bar->attach($b); + $bar->attach($c); + + $foo->removeAllExcept($bar); + var_dump($foo->contains($a)); + var_dump($foo->contains($b)); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/ext/spl/tests/SplObjectStorage_removeAllExcept_invalid_parameter.phpt b/ext/spl/tests/SplObjectStorage_removeAllExcept_invalid_parameter.phpt new file mode 100644 index 00000000000..62e0dde65be --- /dev/null +++ b/ext/spl/tests/SplObjectStorage_removeAllExcept_invalid_parameter.phpt @@ -0,0 +1,44 @@ +--TEST-- +Check that SplObjectStorage::removeAllExcept generate a warning and returns NULL when passed non-object param +--CREDITS-- +Matthew Turland (me@matthewturland.com) +Based on work done at PHPNW Testfest 2009 by Simon Westcott (swestcott@gmail.com) +--FILE-- +removeAllExcept($input)); +} + +?> +--EXPECTF-- +Warning: SplObjectStorage::removeAllExcept() expects parameter 1 to be SplObjectStorage, array given in %s on line %d +NULL + +Warning: SplObjectStorage::removeAllExcept() expects parameter 1 to be SplObjectStorage, boolean given in %s on line %d +NULL + +Warning: SplObjectStorage::removeAllExcept() expects parameter 1 to be SplObjectStorage, %unicode_string_optional% given in %s on line %d +NULL + +Warning: SplObjectStorage::removeAllExcept() expects parameter 1 to be SplObjectStorage, integer given in %s on line %d +NULL + +Warning: SplObjectStorage::removeAllExcept() expects parameter 1 to be SplObjectStorage, double given in %s on line %d +NULL + +Warning: SplObjectStorage::removeAllExcept() expects parameter 1 to be SplObjectStorage, null given in %s on line %d +NULL +