xref: /PHP-5.5/ext/simplexml/sxe.c (revision 73c1be26)
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 */
PHP_METHOD(ce_SimpleXMLIterator,rewind)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 */
PHP_METHOD(ce_SimpleXMLIterator,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 */
PHP_METHOD(ce_SimpleXMLIterator,current)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 */
PHP_METHOD(ce_SimpleXMLIterator,key)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 */
PHP_METHOD(ce_SimpleXMLIterator,next)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) */
PHP_METHOD(ce_SimpleXMLIterator,hasChildren)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 */
PHP_METHOD(ce_SimpleXMLIterator,getChildren)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 
PHP_MINIT_FUNCTION(sxe)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