Skip to content

Commit f11ea2a

Browse files
committed
Refactor dom_html_collection_named_item()
This factors out the specific objmap handling to virtual functions. This is the last step in preparation for GH-18550.
1 parent a2d6535 commit f11ea2a

File tree

3 files changed

+45
-27
lines changed

3 files changed

+45
-27
lines changed

ext/dom/html_collection.c

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,47 +46,35 @@ static dom_named_item dom_html_collection_named_item(zend_string *key, zend_obje
4646

4747
/* 2. Return the first element in the collection for which at least one of the following is true: */
4848
xmlNodePtr basep = dom_object_get_node(objmap->baseobj);
49-
if (basep != NULL) {
50-
zend_long cur = 0;
51-
zend_long next = cur; /* not +1, otherwise we skip the first candidate */
52-
xmlNodePtr candidate = basep->children;
53-
bool iterate_tag_name = objmap->handler == &php_dom_obj_map_by_tag_name;
54-
while (candidate != NULL) {
55-
if (iterate_tag_name) {
56-
candidate = dom_get_elements_by_tag_name_ns_raw(basep, candidate, objmap->ns, objmap->local, objmap->local_lower, &cur, next);
57-
if (candidate == NULL) {
58-
break;
59-
}
60-
next = cur + 1;
61-
} else {
62-
if (candidate->type != XML_ELEMENT_NODE) {
63-
candidate = candidate->next;
64-
continue;
65-
}
49+
if (basep != NULL && basep->children != NULL) {
50+
php_dom_obj_map_collection_iter iter = {0};
51+
iter.candidate = basep->children;
52+
iter.basep = basep;
53+
54+
while (true) {
55+
objmap->handler->collection_named_item_iter(objmap, &iter);
56+
if (iter.candidate == NULL) {
57+
break;
6658
}
6759

68-
ZEND_ASSERT(candidate->type == XML_ELEMENT_NODE);
60+
ZEND_ASSERT(iter.candidate->type == XML_ELEMENT_NODE);
6961

7062
xmlAttrPtr attr;
7163

7264
/* it has an ID which is key; */
73-
if ((attr = xmlHasNsProp(candidate, BAD_CAST "id", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
65+
if ((attr = xmlHasNsProp(iter.candidate, BAD_CAST "id", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
7466
ret.context_intern = objmap->baseobj;
75-
ret.node = candidate;
67+
ret.node = iter.candidate;
7668
return ret;
7769
}
7870
/* it is in the HTML namespace and has a name attribute whose value is key; */
79-
else if (php_dom_ns_is_fast(candidate, php_dom_ns_is_html_magic_token)) {
80-
if ((attr = xmlHasNsProp(candidate, BAD_CAST "name", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
71+
else if (php_dom_ns_is_fast(iter.candidate, php_dom_ns_is_html_magic_token)) {
72+
if ((attr = xmlHasNsProp(iter.candidate, BAD_CAST "name", NULL)) != NULL && dom_compare_value(attr, BAD_CAST ZSTR_VAL(key))) {
8173
ret.context_intern = objmap->baseobj;
82-
ret.node = candidate;
74+
ret.node = iter.candidate;
8375
return ret;
8476
}
8577
}
86-
87-
if (!iterate_tag_name) {
88-
candidate = candidate->next;
89-
}
9078
}
9179
}
9280

ext/dom/obj_map.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,16 @@ static void dom_map_get_elements_item(dom_nnodemap_object *map, zend_long index,
266266
}
267267
}
268268

269+
static void dom_map_collection_named_item_elements_iter(dom_nnodemap_object *map, php_dom_obj_map_collection_iter *iter)
270+
{
271+
if (iter->candidate != iter->basep->children) {
272+
iter->candidate = iter->candidate->next;
273+
}
274+
while (iter->candidate && iter->candidate->type != XML_ELEMENT_NODE) {
275+
iter->candidate = iter->candidate->next;
276+
}
277+
}
278+
269279
static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
270280
{
271281
xmlNodePtr nodep = dom_object_get_node(map->baseobj);
@@ -282,6 +292,12 @@ static void dom_map_get_by_tag_name_item(dom_nnodemap_object *map, zend_long ind
282292
}
283293
}
284294

295+
static void dom_map_collection_named_item_by_tag_name_iter(dom_nnodemap_object *map, php_dom_obj_map_collection_iter *iter)
296+
{
297+
iter->candidate = dom_get_elements_by_tag_name_ns_raw(iter->basep, iter->candidate, map->ns, map->local, map->local_lower, &iter->cur, iter->next);
298+
iter->next = iter->cur + 1;
299+
}
300+
285301
static void dom_map_get_null_item(dom_nnodemap_object *map, zend_long index, zval *return_value)
286302
{
287303
RETURN_NULL();
@@ -447,6 +463,7 @@ const php_dom_obj_map_handler php_dom_obj_map_attributes = {
447463
.get_item = dom_map_get_attributes_item,
448464
.get_ns_named_item = dom_map_get_ns_named_item_prop,
449465
.has_ns_named_item = dom_map_has_ns_named_item_prop,
466+
.collection_named_item_iter = NULL,
450467
.use_cache = false,
451468
.nameless = false,
452469
};
@@ -456,6 +473,7 @@ const php_dom_obj_map_handler php_dom_obj_map_by_tag_name = {
456473
.get_item = dom_map_get_by_tag_name_item,
457474
.get_ns_named_item = dom_map_get_ns_named_item_null,
458475
.has_ns_named_item = dom_map_has_ns_named_item_null,
476+
.collection_named_item_iter = dom_map_collection_named_item_by_tag_name_iter,
459477
.use_cache = true,
460478
.nameless = true,
461479
};
@@ -465,6 +483,7 @@ const php_dom_obj_map_handler php_dom_obj_map_child_nodes = {
465483
.get_item = dom_map_get_nodes_item,
466484
.get_ns_named_item = dom_map_get_ns_named_item_null,
467485
.has_ns_named_item = dom_map_has_ns_named_item_null,
486+
.collection_named_item_iter = NULL,
468487
.use_cache = true,
469488
.nameless = true,
470489
};
@@ -474,6 +493,7 @@ const php_dom_obj_map_handler php_dom_obj_map_nodeset = {
474493
.get_item = dom_map_get_nodeset_item,
475494
.get_ns_named_item = dom_map_get_ns_named_item_null,
476495
.has_ns_named_item = dom_map_has_ns_named_item_null,
496+
.collection_named_item_iter = NULL,
477497
.use_cache = false,
478498
.nameless = true,
479499
};
@@ -483,6 +503,7 @@ const php_dom_obj_map_handler php_dom_obj_map_entities = {
483503
.get_item = dom_map_get_entity_item,
484504
.get_ns_named_item = dom_map_get_ns_named_item_entity,
485505
.has_ns_named_item = dom_map_has_ns_named_item_xmlht,
506+
.collection_named_item_iter = NULL,
486507
.use_cache = false,
487508
.nameless = false,
488509
};
@@ -492,6 +513,7 @@ const php_dom_obj_map_handler php_dom_obj_map_notations = {
492513
.get_item = dom_map_get_notation_item,
493514
.get_ns_named_item = dom_map_get_ns_named_item_notation,
494515
.has_ns_named_item = dom_map_has_ns_named_item_xmlht,
516+
.collection_named_item_iter = NULL,
495517
.use_cache = false,
496518
.nameless = false,
497519
};
@@ -501,6 +523,7 @@ const php_dom_obj_map_handler php_dom_obj_map_child_elements = {
501523
.get_item = dom_map_get_elements_item,
502524
.get_ns_named_item = dom_map_get_ns_named_item_null,
503525
.has_ns_named_item = dom_map_has_ns_named_item_null,
526+
.collection_named_item_iter = dom_map_collection_named_item_elements_iter,
504527
.use_cache = true,
505528
.nameless = true,
506529
};
@@ -510,6 +533,7 @@ const php_dom_obj_map_handler php_dom_obj_map_noop = {
510533
.get_item = dom_map_get_null_item,
511534
.get_ns_named_item = dom_map_get_ns_named_item_null,
512535
.has_ns_named_item = dom_map_has_ns_named_item_null,
536+
.collection_named_item_iter = NULL,
513537
.use_cache = false,
514538
.nameless = true,
515539
};

ext/dom/obj_map.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919

2020
typedef struct dom_nnodemap_object dom_nnodemap_object;
2121

22+
typedef struct php_dom_obj_map_collection_iter {
23+
zend_long cur, next;
24+
xmlNodePtr candidate, basep;
25+
} php_dom_obj_map_collection_iter;
26+
2227
typedef struct php_dom_obj_map_handler {
2328
zend_long (*length)(dom_nnodemap_object *);
2429
void (*get_item)(dom_nnodemap_object *, zend_long, zval *);
2530
xmlNodePtr (*get_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
2631
bool (*has_ns_named_item)(dom_nnodemap_object *, const zend_string *, const char *);
32+
void (*collection_named_item_iter)(dom_nnodemap_object *, php_dom_obj_map_collection_iter *);
2733
bool use_cache;
2834
bool nameless;
2935
} php_dom_obj_map_handler;

0 commit comments

Comments
 (0)