xref: /PHP-7.2/ext/dom/nodelist.c (revision 7a7ec01a)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Christian Stocker <chregu@php.net>                          |
16    |          Rob Richards <rrichards@php.net>                            |
17    +----------------------------------------------------------------------+
18 */
19 
20 /* $Id$ */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "php.h"
27 #if HAVE_LIBXML && HAVE_DOM
28 #include "php_dom.h"
29 
30 
31 /* {{{ arginfo */
32 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1)
33 	ZEND_ARG_INFO(0, index)
34 ZEND_END_ARG_INFO();
35 /* }}} */
36 
37 /* {{{ arginfo */
38 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_count, 0, 0, 0)
39 ZEND_END_ARG_INFO();
40 /* }}} */
41 
42 /*
43 * class DOMNodeList
44 *
45 * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-536297177
46 * Since:
47 */
48 
49 const zend_function_entry php_dom_nodelist_class_functions[] = {
50 	PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item)
51 	PHP_FALIAS(count, dom_nodelist_count, arginfo_dom_nodelist_count)
52 	PHP_FE_END
53 };
54 
55 
56 /* {{{ length	int
57 readonly=yes
58 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-203510337
59 Since:
60 */
dom_nodelist_length_read(dom_object * obj,zval * retval)61 int dom_nodelist_length_read(dom_object *obj, zval *retval)
62 {
63 	dom_nnodemap_object *objmap;
64 	xmlNodePtr nodep, curnode;
65 	int count = 0;
66 	HashTable *nodeht;
67 
68 	objmap = (dom_nnodemap_object *)obj->ptr;
69 	if (objmap != NULL) {
70 		if (objmap->ht) {
71 			count = xmlHashSize(objmap->ht);
72 		} else {
73 			if (objmap->nodetype == DOM_NODESET) {
74 				nodeht = HASH_OF(&objmap->baseobj_zv);
75 				count = zend_hash_num_elements(nodeht);
76 			} else {
77 				nodep = dom_object_get_node(objmap->baseobj);
78 				if (nodep) {
79 					if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
80 						curnode = nodep->children;
81 						if (curnode) {
82 							count++;
83 							while (curnode->next != NULL) {
84 								count++;
85 								curnode = curnode->next;
86 							}
87 						}
88 					} else {
89 						if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
90 							nodep = xmlDocGetRootElement((xmlDoc *) nodep);
91 						} else {
92 							nodep = nodep->children;
93 						}
94 						curnode = dom_get_elements_by_tag_name_ns_raw(
95 							nodep, (char *) objmap->ns, (char *) objmap->local, &count, -1);
96 					}
97 				}
98 			}
99 		}
100 	}
101 
102 	ZVAL_LONG(retval, count);
103 	return SUCCESS;
104 }
105 
106 
107 /* {{{ proto int|bool dom_nodelist_count();
108 */
PHP_FUNCTION(dom_nodelist_count)109 PHP_FUNCTION(dom_nodelist_count)
110 {
111 	zval *id;
112 	dom_object *intern;
113 
114 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_nodelist_class_entry) == FAILURE) {
115 		return;
116 	}
117 
118 	intern = Z_DOMOBJ_P(id);
119 	if(dom_nodelist_length_read(intern, return_value) == FAILURE) {
120 		RETURN_FALSE;
121 	}
122 }
123 /* }}} end dom_nodelist_count */
124 
125 /* }}} */
126 
127 /* {{{ proto DOMNode dom_nodelist_item(int index);
128 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
129 Since:
130 */
PHP_FUNCTION(dom_nodelist_item)131 PHP_FUNCTION(dom_nodelist_item)
132 {
133 	zval *id;
134 	zend_long index;
135 	int ret;
136 	dom_object *intern;
137 	xmlNodePtr itemnode = NULL;
138 
139 	dom_nnodemap_object *objmap;
140 	xmlNodePtr nodep, curnode;
141 	int count = 0;
142 
143 	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &id, dom_nodelist_class_entry, &index) == FAILURE) {
144 		return;
145 	}
146 
147 	if (index >= 0) {
148 		intern = Z_DOMOBJ_P(id);
149 
150 		objmap = (dom_nnodemap_object *)intern->ptr;
151 		if (objmap != NULL) {
152 			if (objmap->ht) {
153 				if (objmap->nodetype == XML_ENTITY_NODE) {
154 					itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
155 				} else {
156 					itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
157 				}
158 			} else {
159 				if (objmap->nodetype == DOM_NODESET) {
160 					HashTable *nodeht = HASH_OF(&objmap->baseobj_zv);
161 					zval *entry = zend_hash_index_find(nodeht, index);
162 					if (entry) {
163 						ZVAL_COPY(return_value, entry);
164 						return;
165 					}
166 				} else if (objmap->baseobj) {
167 					nodep = dom_object_get_node(objmap->baseobj);
168 					if (nodep) {
169 						if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
170 							curnode = nodep->children;
171 							while (count < index && curnode != NULL) {
172 								count++;
173 								curnode = curnode->next;
174 							}
175 							itemnode = curnode;
176 						} else {
177 							if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
178 								nodep = xmlDocGetRootElement((xmlDoc *) nodep);
179 							} else {
180 								nodep = nodep->children;
181 							}
182 							itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, (char *) objmap->ns, (char *) objmap->local, &count, index);
183 						}
184 					}
185 				}
186 			}
187 		}
188 
189 		if (itemnode) {
190 			DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
191 			return;
192 		}
193 	}
194 
195 	RETVAL_NULL();
196 }
197 /* }}} end dom_nodelist_item */
198 
199 
200 #endif
201 
202 /*
203  * Local variables:
204  * tab-width: 4
205  * c-basic-offset: 4
206  * End:
207  * vim600: noet sw=4 ts=4 fdm=marker
208  * vim<600: noet sw=4 ts=4
209  */
210