From ab15058f23708f9b17ca58f65a17f76c9687d949 Mon Sep 17 00:00:00 2001 From: Andreas Treichel Date: Sun, 9 Jul 2017 02:15:38 +0200 Subject: [PATCH 1/2] Implement Countable for DomNodeList and DOMNamedNodeMap (Request #74837) --- ext/dom/dom_fe.h | 2 ++ ext/dom/namednodemap.c | 25 ++++++++++++++++++++ ext/dom/nodelist.c | 29 ++++++++++++++++++++++++ ext/dom/php_dom.c | 2 ++ ext/dom/tests/DOMNamedNodeMap_count.phpt | 28 +++++++++++++++++++++++ ext/dom/tests/DomNodeList_count.phpt | 28 +++++++++++++++++++++++ 6 files changed, 114 insertions(+) create mode 100644 ext/dom/tests/DOMNamedNodeMap_count.phpt create mode 100644 ext/dom/tests/DomNodeList_count.phpt diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h index 231d8402d89e..6f1035a57731 100644 --- a/ext/dom/dom_fe.h +++ b/ext/dom/dom_fe.h @@ -172,6 +172,7 @@ PHP_METHOD(domnode, getLineNo); /* domnodelist methods */ PHP_FUNCTION(dom_nodelist_item); +PHP_FUNCTION(dom_nodelist_count); /* domnamednodemap methods */ PHP_FUNCTION(dom_namednodemap_get_named_item); @@ -181,6 +182,7 @@ PHP_FUNCTION(dom_namednodemap_item); PHP_FUNCTION(dom_namednodemap_get_named_item_ns); PHP_FUNCTION(dom_namednodemap_set_named_item_ns); PHP_FUNCTION(dom_namednodemap_remove_named_item_ns); +PHP_FUNCTION(dom_namednodemap_count); /* domcharacterdata methods */ PHP_FUNCTION(dom_characterdata_substring_data); diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c index 4dea7be28a91..cfae5a920ecb 100644 --- a/ext/dom/namednodemap.c +++ b/ext/dom/namednodemap.c @@ -57,6 +57,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item_ns, 0, 0, 0) ZEND_ARG_INFO(0, namespaceURI) ZEND_ARG_INFO(0, localName) ZEND_END_ARG_INFO(); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_count, 0, 0, 0) +ZEND_END_ARG_INFO(); /* }}} */ /* @@ -74,6 +77,7 @@ const zend_function_entry php_dom_namednodemap_class_functions[] = { /* {{{ */ PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, arginfo_dom_namednodemap_get_named_item_ns) PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, arginfo_dom_namednodemap_set_named_item_ns) PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, arginfo_dom_namednodemap_remove_named_item_ns) + PHP_FALIAS(count, dom_namednodemap_count, arginfo_dom_namednodemap_count) PHP_FE_END }; /* }}} */ @@ -332,6 +336,27 @@ PHP_FUNCTION(dom_namednodemap_remove_named_item_ns) } /* }}} end dom_namednodemap_remove_named_item_ns */ +/* {{{ proto int|bool dom_namednodemap_count(); +*/ +PHP_FUNCTION(dom_namednodemap_count) +{ + zval *id; + dom_object *intern; + zval *count; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_namednodemap_class_entry) == FAILURE) { + return; + } + + intern = Z_DOMOBJ_P(id); + if(dom_namednodemap_length_read(intern, &count)) { + RETURN_FALSE; + } + + RETURN_LONG(count); +} +/* }}} end dom_namednodemap_count */ + #endif /* diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index d469467f48a9..86e5d2f082d3 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -34,6 +34,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1) ZEND_END_ARG_INFO(); /* }}} */ +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_count, 0, 0, 0) +ZEND_END_ARG_INFO(); +/* }}} */ + /* * class DOMNodeList * @@ -43,9 +48,11 @@ ZEND_END_ARG_INFO(); const zend_function_entry php_dom_nodelist_class_functions[] = { PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item) + PHP_FALIAS(count, dom_nodelist_count, arginfo_dom_nodelist_count) PHP_FE_END }; + /* {{{ length int readonly=yes URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-203510337 @@ -96,6 +103,27 @@ int dom_nodelist_length_read(dom_object *obj, zval *retval) return SUCCESS; } + +/* {{{ proto int|bool dom_nodelist_count(); +*/ +PHP_FUNCTION(dom_nodelist_count) +{ + zval *id; + dom_object *intern; + zval *count; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_nodelist_class_entry) == FAILURE) { + return; + } + + intern = Z_DOMOBJ_P(id); + if(dom_nodelist_length_read(intern, &count)) { + RETURN_FALSE; + } + RETURN_LONG(count); +} +/* }}} end dom_nodelist_count */ + /* }}} */ /* {{{ proto DOMNode dom_nodelist_item(int index); @@ -170,6 +198,7 @@ PHP_FUNCTION(dom_nodelist_item) } /* }}} end dom_nodelist_item */ + #endif /* diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 6b844ab33304..0b0f48080419 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -707,6 +707,7 @@ PHP_MINIT_FUNCTION(dom) dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL); dom_nodelist_class_entry->get_iterator = php_dom_get_iterator; zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_traversable); + zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_countable); zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", sizeof("length")-1, dom_nodelist_length_read, NULL); @@ -717,6 +718,7 @@ PHP_MINIT_FUNCTION(dom) dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL); dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator; zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_traversable); + zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_countable); zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", sizeof("length")-1, dom_namednodemap_length_read, NULL); diff --git a/ext/dom/tests/DOMNamedNodeMap_count.phpt b/ext/dom/tests/DOMNamedNodeMap_count.phpt new file mode 100644 index 000000000000..656dd4859efc --- /dev/null +++ b/ext/dom/tests/DOMNamedNodeMap_count.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test count nodes in DOMNamedNodeMap +--CREDITS-- +Andreas Treichel +--SKIPIF-- + +--FILE-- +createElement('root'); +$document->appendChild($root); +for($i = 0; $i < 5; $i++) { + $root->setAttribute('attribute-' . $i, 'value-' . $i); +} +for($i = 0; $i < 7; $i++) { + $item = $document->createElement('item'); + $root->appendChild($item); +} +var_dump($root->attributes->length); +var_dump($root->attributes->count()); +var_dump(count($root->attributes)); + +?> +--EXPECTF-- +int(5) +int(5) +int(5) diff --git a/ext/dom/tests/DomNodeList_count.phpt b/ext/dom/tests/DomNodeList_count.phpt new file mode 100644 index 000000000000..3ebf4ae7d2ea --- /dev/null +++ b/ext/dom/tests/DomNodeList_count.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test count nodes in DOMNodeList +--CREDITS-- +Andreas Treichel +--SKIPIF-- + +--FILE-- +createElement('root'); +$document->appendChild($root); +for($i = 0; $i < 5; $i++) { + $root->setAttribute('attribute-' . $i, 'value-' . $i); +} +for($i = 0; $i < 7; $i++) { + $item = $document->createElement('item'); + $root->appendChild($item); +} +var_dump($root->childNodes->length); +var_dump($root->childNodes->count()); +var_dump(count($root->childNodes)); + +?> +--EXPECTF-- +int(7) +int(7) +int(7) From 46ff960f4403a8752284fa4b8c0477bbc40708fd Mon Sep 17 00:00:00 2001 From: Andreas Treichel Date: Sun, 9 Jul 2017 12:27:54 +0200 Subject: [PATCH 2/2] Implement multiple interfaces at once and remove unnecessary return --- ext/dom/namednodemap.c | 5 +---- ext/dom/nodelist.c | 4 +--- ext/dom/php_dom.c | 6 ++---- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c index cfae5a920ecb..3ed426cb8e74 100644 --- a/ext/dom/namednodemap.c +++ b/ext/dom/namednodemap.c @@ -342,18 +342,15 @@ PHP_FUNCTION(dom_namednodemap_count) { zval *id; dom_object *intern; - zval *count; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_namednodemap_class_entry) == FAILURE) { return; } intern = Z_DOMOBJ_P(id); - if(dom_namednodemap_length_read(intern, &count)) { + if(dom_namednodemap_length_read(intern, return_value) == FAILURE) { RETURN_FALSE; } - - RETURN_LONG(count); } /* }}} end dom_namednodemap_count */ diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index 86e5d2f082d3..c7fbc76fd1c8 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -110,17 +110,15 @@ PHP_FUNCTION(dom_nodelist_count) { zval *id; dom_object *intern; - zval *count; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_nodelist_class_entry) == FAILURE) { return; } intern = Z_DOMOBJ_P(id); - if(dom_nodelist_length_read(intern, &count)) { + if(dom_nodelist_length_read(intern, return_value) == FAILURE) { RETURN_FALSE; } - RETURN_LONG(count); } /* }}} end dom_nodelist_count */ diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 0b0f48080419..77f918ae9bf9 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -706,8 +706,7 @@ PHP_MINIT_FUNCTION(dom) ce.create_object = dom_nnodemap_objects_new; dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL); dom_nodelist_class_entry->get_iterator = php_dom_get_iterator; - zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_traversable); - zend_class_implements(dom_nodelist_class_entry, 1, zend_ce_countable); + zend_class_implements(dom_nodelist_class_entry, 2, zend_ce_traversable, zend_ce_countable); zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", sizeof("length")-1, dom_nodelist_length_read, NULL); @@ -717,8 +716,7 @@ PHP_MINIT_FUNCTION(dom) ce.create_object = dom_nnodemap_objects_new; dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL); dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator; - zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_traversable); - zend_class_implements(dom_namednodemap_class_entry, 1, zend_ce_countable); + zend_class_implements(dom_namednodemap_class_entry, 2, zend_ce_traversable, zend_ce_countable); zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, dom_dtor_prop_handler, 1); dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", sizeof("length")-1, dom_namednodemap_length_read, NULL);