xref: /PHP-8.2/ext/dom/namednodemap.c (revision 9f7d8880)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | https://www.php.net/license/3_01.txt                                 |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors: Christian Stocker <chregu@php.net>                          |
14    |          Rob Richards <rrichards@php.net>                            |
15    +----------------------------------------------------------------------+
16 */
17 
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "php.h"
23 #if defined(HAVE_LIBXML) && defined(HAVE_DOM)
24 #include "php_dom.h"
25 #include "zend_interfaces.h"
26 
27 /*
28 * class DOMNamedNodeMap
29 *
30 * URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1780488922
31 * Since:
32 */
33 
php_dom_get_namednodemap_length(dom_object * obj)34 int php_dom_get_namednodemap_length(dom_object *obj)
35 {
36 	dom_nnodemap_object *objmap = (dom_nnodemap_object *) obj->ptr;
37 	if (!objmap) {
38 		return 0;
39 	}
40 
41 	if (objmap->nodetype == XML_NOTATION_NODE || objmap->nodetype == XML_ENTITY_NODE) {
42 		return objmap->ht ? xmlHashSize(objmap->ht) : 0;
43 	}
44 
45 	int count = 0;
46 	xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
47 	if (nodep) {
48 		xmlAttrPtr curnode = nodep->properties;
49 		if (curnode) {
50 			count++;
51 			while (curnode->next != NULL) {
52 				count++;
53 				curnode = curnode->next;
54 			}
55 		}
56 	}
57 
58 	return count;
59 }
60 
61 /* {{{ length	int
62 readonly=yes
63 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D0FB19E
64 Since:
65 */
dom_namednodemap_length_read(dom_object * obj,zval * retval)66 int dom_namednodemap_length_read(dom_object *obj, zval *retval)
67 {
68 	ZVAL_LONG(retval, php_dom_get_namednodemap_length(obj));
69 	return SUCCESS;
70 }
71 
72 /* }}} */
73 
php_dom_named_node_map_get_named_item(dom_nnodemap_object * objmap,const char * named,bool may_transform)74 xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const char *named, bool may_transform)
75 {
76 	xmlNodePtr itemnode = NULL;
77 	if (objmap != NULL) {
78 		if ((objmap->nodetype == XML_NOTATION_NODE) ||
79 			objmap->nodetype == XML_ENTITY_NODE) {
80 			if (objmap->ht) {
81 				if (objmap->nodetype == XML_ENTITY_NODE) {
82 					itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, (const xmlChar *) named);
83 				} else {
84 					xmlNotationPtr notep = xmlHashLookup(objmap->ht, (const xmlChar *) named);
85 					if (notep) {
86 						if (may_transform) {
87 							itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
88 						} else {
89 							itemnode = (xmlNodePtr) notep;
90 						}
91 					}
92 				}
93 			}
94 		} else {
95 			xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
96 			if (nodep) {
97 				itemnode = (xmlNodePtr)xmlHasProp(nodep, (const xmlChar *) named);
98 			}
99 		}
100 	}
101 	return itemnode;
102 }
103 
php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object * objmap,const char * named,zval * return_value)104 void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const char *named, zval *return_value)
105 {
106 	int ret;
107 	xmlNodePtr itemnode = php_dom_named_node_map_get_named_item(objmap, named, true);
108 	if (itemnode) {
109 		DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
110 	} else {
111 		RETURN_NULL();
112 	}
113 }
114 
115 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549
116 Since:
117 */
PHP_METHOD(DOMNamedNodeMap,getNamedItem)118 PHP_METHOD(DOMNamedNodeMap, getNamedItem)
119 {
120 	size_t namedlen;
121 	char *named;
122 
123 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &named, &namedlen) == FAILURE) {
124 		RETURN_THROWS();
125 	}
126 
127 	zval *id = ZEND_THIS;
128 	dom_nnodemap_object *objmap = Z_DOMOBJ_P(id)->ptr;
129 	php_dom_named_node_map_get_named_item_into_zval(objmap, named, return_value);
130 }
131 /* }}} end dom_namednodemap_get_named_item */
132 
php_dom_named_node_map_get_item(dom_nnodemap_object * objmap,zend_long index)133 xmlNodePtr php_dom_named_node_map_get_item(dom_nnodemap_object *objmap, zend_long index)
134 {
135 	xmlNodePtr itemnode = NULL;
136 	if (objmap != NULL) {
137 		if ((objmap->nodetype == XML_NOTATION_NODE) ||
138 			objmap->nodetype == XML_ENTITY_NODE) {
139 			if (objmap->ht) {
140 				if (objmap->nodetype == XML_ENTITY_NODE) {
141 					itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
142 				} else {
143 					itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
144 				}
145 			}
146 		} else {
147 			xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
148 			if (nodep) {
149 				xmlNodePtr curnode = (xmlNodePtr)nodep->properties;
150 				zend_long count = 0;
151 				while (count < index && curnode != NULL) {
152 					count++;
153 					curnode = (xmlNodePtr)curnode->next;
154 				}
155 				itemnode = curnode;
156 			}
157 		}
158 	}
159 	return itemnode;
160 }
161 
php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object * objmap,zend_long index,zval * return_value)162 void php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value)
163 {
164 	int ret;
165 	xmlNodePtr itemnode = php_dom_named_node_map_get_item(objmap, index);
166 	if (itemnode) {
167 		DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
168 	} else {
169 		RETURN_NULL();
170 	}
171 }
172 
173 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9
174 Since:
175 */
PHP_METHOD(DOMNamedNodeMap,item)176 PHP_METHOD(DOMNamedNodeMap, item)
177 {
178 	zend_long index;
179 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) {
180 		RETURN_THROWS();
181 	}
182 	if (index < 0 || ZEND_LONG_INT_OVFL(index)) {
183 		zend_argument_value_error(1, "must be between 0 and %d", INT_MAX);
184 		RETURN_THROWS();
185 	}
186 
187 	zval *id = ZEND_THIS;
188 	dom_object *intern = Z_DOMOBJ_P(id);
189 	dom_nnodemap_object *objmap = intern->ptr;
190 	php_dom_named_node_map_get_item_into_zval(objmap, index, return_value);
191 }
192 /* }}} end dom_namednodemap_item */
193 
194 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS
195 Since: DOM Level 2
196 */
PHP_METHOD(DOMNamedNodeMap,getNamedItemNS)197 PHP_METHOD(DOMNamedNodeMap, getNamedItemNS)
198 {
199 	zval *id;
200 	int ret;
201 	size_t namedlen=0, urilen=0;
202 	dom_object *intern;
203 	xmlNodePtr itemnode = NULL;
204 	char *uri, *named;
205 
206 	dom_nnodemap_object *objmap;
207 	xmlNodePtr nodep;
208 	xmlNotation *notep = NULL;
209 
210 	id = ZEND_THIS;
211 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &urilen, &named, &namedlen) == FAILURE) {
212 		RETURN_THROWS();
213 	}
214 
215 	intern = Z_DOMOBJ_P(id);
216 
217 	objmap = (dom_nnodemap_object *)intern->ptr;
218 
219 	if (objmap != NULL) {
220 		if ((objmap->nodetype == XML_NOTATION_NODE) ||
221 			objmap->nodetype == XML_ENTITY_NODE) {
222 			if (objmap->ht) {
223 				if (objmap->nodetype == XML_ENTITY_NODE) {
224 					itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, (xmlChar *) named);
225 				} else {
226 					notep = (xmlNotation *)xmlHashLookup(objmap->ht, (xmlChar *) named);
227 					if (notep) {
228 						itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
229 					}
230 				}
231 			}
232 		} else {
233 			nodep = dom_object_get_node(objmap->baseobj);
234 			if (nodep) {
235 				itemnode = (xmlNodePtr)xmlHasNsProp(nodep, (xmlChar *) named, (xmlChar *) uri);
236 			}
237 		}
238 	}
239 
240 	if (itemnode) {
241 		DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
242 		return;
243 	} else {
244 		RETVAL_NULL();
245 	}
246 }
247 /* }}} end dom_namednodemap_get_named_item_ns */
248 
249 /* {{{ */
PHP_METHOD(DOMNamedNodeMap,count)250 PHP_METHOD(DOMNamedNodeMap, count)
251 {
252 	zval *id;
253 	dom_object *intern;
254 
255 	id = ZEND_THIS;
256 	if (zend_parse_parameters_none() == FAILURE) {
257 		RETURN_THROWS();
258 	}
259 
260 	intern = Z_DOMOBJ_P(id);
261 	RETURN_LONG(php_dom_get_namednodemap_length(intern));
262 }
263 /* }}} end dom_namednodemap_count */
264 
PHP_METHOD(DOMNamedNodeMap,getIterator)265 PHP_METHOD(DOMNamedNodeMap, getIterator)
266 {
267 	if (zend_parse_parameters_none() == FAILURE) {
268 		return;
269 	}
270 
271 	zend_create_internal_iterator_zval(return_value, ZEND_THIS);
272 }
273 
274 #endif
275