xref: /php-src/ext/dom/namednodemap.c (revision fc9b58f6)
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 zend_result 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 zend_string * named,bool may_transform)74 xmlNodePtr php_dom_named_node_map_get_named_item(dom_nnodemap_object *objmap, const zend_string *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, BAD_CAST ZSTR_VAL(named));
83 				} else {
84 					xmlNotationPtr notep = xmlHashLookup(objmap->ht, BAD_CAST ZSTR_VAL(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 				if (php_dom_follow_spec_intern(objmap->baseobj)) {
98 					itemnode = (xmlNodePtr) php_dom_get_attribute_node(nodep, BAD_CAST ZSTR_VAL(named), ZSTR_LEN(named));
99 				} else {
100 					itemnode = (xmlNodePtr) xmlHasProp(nodep, BAD_CAST ZSTR_VAL(named));
101 				}
102 			}
103 		}
104 	}
105 	return itemnode;
106 }
107 
php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object * objmap,const zend_string * named,zval * return_value)108 void php_dom_named_node_map_get_named_item_into_zval(dom_nnodemap_object *objmap, const zend_string *named, zval *return_value)
109 {
110 	xmlNodePtr itemnode = php_dom_named_node_map_get_named_item(objmap, named, true);
111 	if (itemnode) {
112 		DOM_RET_OBJ(itemnode, objmap->baseobj);
113 	} else {
114 		RETURN_NULL();
115 	}
116 }
117 
118 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549
119 Since:
120 */
PHP_METHOD(DOMNamedNodeMap,getNamedItem)121 PHP_METHOD(DOMNamedNodeMap, getNamedItem)
122 {
123 	zend_string *named;
124 
125 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &named) == FAILURE) {
126 		RETURN_THROWS();
127 	}
128 
129 	zval *id = ZEND_THIS;
130 	dom_nnodemap_object *objmap = Z_DOMOBJ_P(id)->ptr;
131 	php_dom_named_node_map_get_named_item_into_zval(objmap, named, return_value);
132 }
133 /* }}} end dom_namednodemap_get_named_item */
134 
php_dom_named_node_map_get_item(dom_nnodemap_object * objmap,zend_long index)135 xmlNodePtr php_dom_named_node_map_get_item(dom_nnodemap_object *objmap, zend_long index)
136 {
137 	xmlNodePtr itemnode = NULL;
138 	if (objmap != NULL) {
139 		if ((objmap->nodetype == XML_NOTATION_NODE) ||
140 			objmap->nodetype == XML_ENTITY_NODE) {
141 			if (objmap->ht) {
142 				itemnode = php_dom_libxml_hash_iter(objmap, index);
143 			}
144 		} else {
145 			xmlNodePtr nodep = dom_object_get_node(objmap->baseobj);
146 			if (nodep) {
147 				xmlNodePtr curnode = (xmlNodePtr)nodep->properties;
148 				zend_long count = 0;
149 				while (count < index && curnode != NULL) {
150 					count++;
151 					curnode = (xmlNodePtr)curnode->next;
152 				}
153 				itemnode = curnode;
154 			}
155 		}
156 	}
157 	return itemnode;
158 }
159 
php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object * objmap,zend_long index,zval * return_value)160 void php_dom_named_node_map_get_item_into_zval(dom_nnodemap_object *objmap, zend_long index, zval *return_value)
161 {
162 	xmlNodePtr itemnode = php_dom_named_node_map_get_item(objmap, index);
163 	if (itemnode) {
164 		DOM_RET_OBJ(itemnode, objmap->baseobj);
165 	} else {
166 		RETURN_NULL();
167 	}
168 }
169 
170 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9
171 Since:
172 */
PHP_METHOD(DOMNamedNodeMap,item)173 PHP_METHOD(DOMNamedNodeMap, item)
174 {
175 	zend_long index;
176 	ZEND_PARSE_PARAMETERS_START(1, 1)
177 		Z_PARAM_LONG(index)
178 	ZEND_PARSE_PARAMETERS_END();
179 	if (index < 0 || ZEND_LONG_INT_OVFL(index)) {
180 		zend_argument_value_error(1, "must be between 0 and %d", INT_MAX);
181 		RETURN_THROWS();
182 	}
183 
184 	zval *id = ZEND_THIS;
185 	dom_object *intern = Z_DOMOBJ_P(id);
186 	dom_nnodemap_object *objmap = intern->ptr;
187 	php_dom_named_node_map_get_item_into_zval(objmap, index, return_value);
188 }
189 /* }}} end dom_namednodemap_item */
190 
191 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS
192 Since: DOM Level 2
193 */
PHP_METHOD(DOMNamedNodeMap,getNamedItemNS)194 PHP_METHOD(DOMNamedNodeMap, getNamedItemNS)
195 {
196 	zval *id;
197 	size_t namedlen=0, urilen=0;
198 	dom_object *intern;
199 	xmlNodePtr itemnode = NULL;
200 	char *uri, *named;
201 
202 	dom_nnodemap_object *objmap;
203 	xmlNodePtr nodep;
204 	xmlNotation *notep = NULL;
205 
206 	id = ZEND_THIS;
207 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!s", &uri, &urilen, &named, &namedlen) == FAILURE) {
208 		RETURN_THROWS();
209 	}
210 
211 	intern = Z_DOMOBJ_P(id);
212 
213 	objmap = (dom_nnodemap_object *)intern->ptr;
214 
215 	if (objmap != NULL) {
216 		if ((objmap->nodetype == XML_NOTATION_NODE) ||
217 			objmap->nodetype == XML_ENTITY_NODE) {
218 			if (objmap->ht) {
219 				if (objmap->nodetype == XML_ENTITY_NODE) {
220 					itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, BAD_CAST named);
221 				} else {
222 					notep = (xmlNotation *)xmlHashLookup(objmap->ht, BAD_CAST named);
223 					if (notep) {
224 						itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
225 					}
226 				}
227 			}
228 		} else {
229 			nodep = dom_object_get_node(objmap->baseobj);
230 			if (nodep) {
231 				itemnode = (xmlNodePtr)xmlHasNsProp(nodep, BAD_CAST named, BAD_CAST uri);
232 			}
233 		}
234 	}
235 
236 	if (itemnode) {
237 		DOM_RET_OBJ(itemnode, objmap->baseobj);
238 	} else {
239 		RETVAL_NULL();
240 	}
241 }
242 /* }}} end dom_namednodemap_get_named_item_ns */
243 
244 /* {{{ */
PHP_METHOD(DOMNamedNodeMap,count)245 PHP_METHOD(DOMNamedNodeMap, count)
246 {
247 	zval *id;
248 	dom_object *intern;
249 
250 	id = ZEND_THIS;
251 	if (zend_parse_parameters_none() == FAILURE) {
252 		RETURN_THROWS();
253 	}
254 
255 	intern = Z_DOMOBJ_P(id);
256 	RETURN_LONG(php_dom_get_namednodemap_length(intern));
257 }
258 /* }}} end dom_namednodemap_count */
259 
PHP_METHOD(DOMNamedNodeMap,getIterator)260 PHP_METHOD(DOMNamedNodeMap, getIterator)
261 {
262 	if (zend_parse_parameters_none() == FAILURE) {
263 		return;
264 	}
265 
266 	zend_create_internal_iterator_zval(return_value, ZEND_THIS);
267 }
268 
269 #endif
270