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