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