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