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: Marcus Boerger <helly@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "zend_interfaces.h"
29
30 #include "php_simplexml.h"
31 #include "ext/spl/php_spl.h"
32 #include "ext/spl/spl_iterators.h"
33 #include "sxe.h"
34
35 PHP_SXE_API zend_class_entry *ce_SimpleXMLIterator = NULL;
36 PHP_SXE_API zend_class_entry *ce_SimpleXMLElement;
37
38 #include "php_simplexml_exports.h"
39
40 /* {{{ proto void SimpleXMLIterator::rewind()
41 Rewind to first element */
PHP_METHOD(ce_SimpleXMLIterator,rewind)42 PHP_METHOD(ce_SimpleXMLIterator, rewind)
43 {
44 php_sxe_iterator iter;
45
46 if (zend_parse_parameters_none() == FAILURE) {
47 return;
48 }
49
50 iter.sxe = Z_SXEOBJ_P(getThis());
51 ce_SimpleXMLElement->iterator_funcs.funcs->rewind((zend_object_iterator*)&iter);
52 }
53 /* }}} */
54
55 /* {{{ proto bool SimpleXMLIterator::valid()
56 Check whether iteration is valid */
PHP_METHOD(ce_SimpleXMLIterator,valid)57 PHP_METHOD(ce_SimpleXMLIterator, valid)
58 {
59 php_sxe_object *sxe = Z_SXEOBJ_P(getThis());
60
61 if (zend_parse_parameters_none() == FAILURE) {
62 return;
63 }
64
65 RETURN_BOOL(!Z_ISUNDEF(sxe->iter.data));
66 }
67 /* }}} */
68
69 /* {{{ proto SimpleXMLIterator SimpleXMLIterator::current()
70 Get current element */
PHP_METHOD(ce_SimpleXMLIterator,current)71 PHP_METHOD(ce_SimpleXMLIterator, current)
72 {
73 php_sxe_object *sxe = Z_SXEOBJ_P(getThis());
74 zval *data;
75
76 if (zend_parse_parameters_none() == FAILURE) {
77 return;
78 }
79
80 if (Z_ISUNDEF(sxe->iter.data)) {
81 return; /* return NULL */
82 }
83
84 data = &sxe->iter.data;
85 ZVAL_DEREF(data);
86 ZVAL_COPY(return_value, data);
87 }
88 /* }}} */
89
90 /* {{{ proto string SimpleXMLIterator::key()
91 Get name of current child element */
PHP_METHOD(ce_SimpleXMLIterator,key)92 PHP_METHOD(ce_SimpleXMLIterator, key)
93 {
94 xmlNodePtr curnode;
95 php_sxe_object *intern;
96 php_sxe_object *sxe = Z_SXEOBJ_P(getThis());
97
98 if (zend_parse_parameters_none() == FAILURE) {
99 return;
100 }
101
102 if (Z_ISUNDEF(sxe->iter.data)) {
103 RETURN_FALSE;
104 }
105
106 intern = Z_SXEOBJ_P(&sxe->iter.data);
107 if (intern != NULL && intern->node != NULL) {
108 curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
109 RETURN_STRINGL((char*)curnode->name, xmlStrlen(curnode->name));
110 }
111
112 RETURN_FALSE;
113 }
114 /* }}} */
115
116 /* {{{ proto void SimpleXMLIterator::next()
117 Move to next element */
PHP_METHOD(ce_SimpleXMLIterator,next)118 PHP_METHOD(ce_SimpleXMLIterator, next)
119 {
120 php_sxe_iterator iter;
121
122 if (zend_parse_parameters_none() == FAILURE) {
123 return;
124 }
125
126 iter.sxe = Z_SXEOBJ_P(getThis());
127 ce_SimpleXMLElement->iterator_funcs.funcs->move_forward((zend_object_iterator*)&iter);
128 }
129 /* }}} */
130
131 /* {{{ proto bool SimpleXMLIterator::hasChildren()
132 Check whether element has children (elements) */
PHP_METHOD(ce_SimpleXMLIterator,hasChildren)133 PHP_METHOD(ce_SimpleXMLIterator, hasChildren)
134 {
135 php_sxe_object *sxe = Z_SXEOBJ_P(getThis());
136 php_sxe_object *child;
137 xmlNodePtr node;
138
139 if (zend_parse_parameters_none() == FAILURE) {
140 return;
141 }
142
143 if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) {
144 RETURN_FALSE;
145 }
146 child = Z_SXEOBJ_P(&sxe->iter.data);
147
148 GET_NODE(child, node);
149 if (node) {
150 node = node->children;
151 }
152 while (node && node->type != XML_ELEMENT_NODE) {
153 node = node->next;
154 }
155 RETURN_BOOL(node ? 1 : 0);
156 }
157 /* }}} */
158
159 /* {{{ proto SimpleXMLIterator SimpleXMLIterator::getChildren()
160 Get child element iterator */
PHP_METHOD(ce_SimpleXMLIterator,getChildren)161 PHP_METHOD(ce_SimpleXMLIterator, getChildren)
162 {
163 php_sxe_object *sxe = Z_SXEOBJ_P(getThis());
164 zval *data;
165
166 if (zend_parse_parameters_none() == FAILURE) {
167 return;
168 }
169
170 if (Z_ISUNDEF(sxe->iter.data) || sxe->iter.type == SXE_ITER_ATTRLIST) {
171 return; /* return NULL */
172 }
173
174 data = &sxe->iter.data;
175 ZVAL_DEREF(data);
176 ZVAL_COPY(return_value, data);
177 }
178
179 /* {{{ arginfo */
180 ZEND_BEGIN_ARG_INFO(arginfo_simplexmliterator__void, 0)
181 ZEND_END_ARG_INFO()
182 /* }}} */
183
184 static const zend_function_entry funcs_SimpleXMLIterator[] = {
185 PHP_ME(ce_SimpleXMLIterator, rewind, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
186 PHP_ME(ce_SimpleXMLIterator, valid, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
187 PHP_ME(ce_SimpleXMLIterator, current, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
188 PHP_ME(ce_SimpleXMLIterator, key, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
189 PHP_ME(ce_SimpleXMLIterator, next, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
190 PHP_ME(ce_SimpleXMLIterator, hasChildren, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
191 PHP_ME(ce_SimpleXMLIterator, getChildren, arginfo_simplexmliterator__void, ZEND_ACC_PUBLIC)
192 PHP_FE_END
193 };
194 /* }}} */
195
PHP_MINIT_FUNCTION(sxe)196 PHP_MINIT_FUNCTION(sxe) /* {{{ */
197 {
198 zend_class_entry *pce;
199 zend_class_entry sxi;
200
201 if ((pce = zend_hash_str_find_ptr(CG(class_table), "simplexmlelement", sizeof("SimpleXMLElement") - 1)) == NULL) {
202 ce_SimpleXMLElement = NULL;
203 ce_SimpleXMLIterator = NULL;
204 return SUCCESS; /* SimpleXML must be initialized before */
205 }
206
207 ce_SimpleXMLElement = pce;
208
209 INIT_CLASS_ENTRY_EX(sxi, "SimpleXMLIterator", sizeof("SimpleXMLIterator") - 1, funcs_SimpleXMLIterator);
210 ce_SimpleXMLIterator = zend_register_internal_class_ex(&sxi, ce_SimpleXMLElement);
211 ce_SimpleXMLIterator->create_object = ce_SimpleXMLElement->create_object;
212
213 zend_class_implements(ce_SimpleXMLIterator, 1, spl_ce_RecursiveIterator);
214 zend_class_implements(ce_SimpleXMLIterator, 1, spl_ce_Countable);
215
216 return SUCCESS;
217 }
218 /* }}} */
219
220 /*
221 * Local variables:
222 * tab-width: 4
223 * c-basic-offset: 4
224 * End:
225 * vim600: fdm=marker
226 * vim: noet sw=4 ts=4
227 */
228