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
34zend_class_entry *ce_SimpleXMLIterator = NULL;
35zend_class_entry *ce_SimpleXMLElement;
36
37#include "php_simplexml_exports.h"
38
39/* {{{ proto void SimpleXMLIterator::rewind()
40 Rewind to first element */
41PHP_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 */
56PHP_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 */
70PHP_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 */
88PHP_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 */
114PHP_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) */
129PHP_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 */
157PHP_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 */
172ZEND_BEGIN_ARG_INFO(arginfo_simplexmliterator__void, 0)
173ZEND_END_ARG_INFO()
174/* }}} */
175
176static 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
188PHP_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