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