This source file includes following definitions.
- itemHashScanner
- create_notation
- php_dom_libxml_hash_iter
- php_dom_libxml_notation_iter
- php_dom_iterator_dtor
- php_dom_iterator_valid
- php_dom_iterator_current_data
- php_dom_iterator_current_key
- php_dom_iterator_move_forward
- php_dom_get_iterator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "php.h"
27 #if HAVE_LIBXML && HAVE_DOM
28 #include "php_dom.h"
29 #include "dom_ce.h"
30
31 typedef struct _nodeIterator nodeIterator;
32 struct _nodeIterator {
33 int cur;
34 int index;
35 xmlNode *node;
36 };
37
38 typedef struct _notationIterator notationIterator;
39 struct _notationIterator {
40 int cur;
41 int index;
42 xmlNotation *notation;
43 };
44
45 static void itemHashScanner (void *payload, void *data, xmlChar *name)
46 {
47 nodeIterator *priv = (nodeIterator *)data;
48
49 if(priv->cur < priv->index) {
50 priv->cur++;
51 } else {
52 if(priv->node == NULL) {
53 priv->node = (xmlNode *)payload;
54 }
55 }
56 }
57
58
59 xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID)
60 {
61 xmlEntityPtr ret;
62
63 ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
64 memset(ret, 0, sizeof(xmlEntity));
65 ret->type = XML_NOTATION_NODE;
66 ret->name = xmlStrdup(name);
67 ret->ExternalID = xmlStrdup(ExternalID);
68 ret->SystemID = xmlStrdup(SystemID);
69 ret->length = 0;
70 ret->content = NULL;
71 ret->URI = NULL;
72 ret->orig = NULL;
73 ret->children = NULL;
74 ret->parent = NULL;
75 ret->doc = NULL;
76 ret->_private = NULL;
77 ret->last = NULL;
78 ret->prev = NULL;
79 return((xmlNodePtr) ret);
80 }
81
82
83 xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index)
84 {
85 xmlNode *nodep = NULL;
86 nodeIterator *iter;
87 int htsize;
88
89 if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
90 iter = emalloc(sizeof(nodeIterator));
91 iter->cur = 0;
92 iter->index = index;
93 iter->node = NULL;
94 xmlHashScan(ht, itemHashScanner, iter);
95 nodep = iter->node;
96 efree(iter);
97 return nodep;
98 } else {
99 return NULL;
100 }
101 }
102
103
104 xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index)
105 {
106 notationIterator *iter;
107 xmlNotation *notep = NULL;
108 int htsize;
109
110 if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
111 iter = emalloc(sizeof(notationIterator));
112 iter->cur = 0;
113 iter->index = index;
114 iter->notation = NULL;
115 xmlHashScan(ht, itemHashScanner, iter);
116 notep = iter->notation;
117 efree(iter);
118 return create_notation(notep->name, notep->PublicID, notep->SystemID);
119 } else {
120 return NULL;
121 }
122 }
123
124
125 static void php_dom_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
126 {
127 php_dom_iterator *iterator = (php_dom_iterator *)iter;
128
129 zval_ptr_dtor((zval**)&iterator->intern.data);
130
131 if (iterator->curobj) {
132 zval_ptr_dtor((zval**)&iterator->curobj);
133 }
134
135 efree(iterator);
136 }
137
138
139 static int php_dom_iterator_valid(zend_object_iterator *iter TSRMLS_DC)
140 {
141
142 php_dom_iterator *iterator = (php_dom_iterator *)iter;
143
144 if (iterator->curobj) {
145 return SUCCESS;
146 } else {
147 return FAILURE;
148 }
149 }
150
151
152 static void php_dom_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
153 {
154 php_dom_iterator *iterator = (php_dom_iterator *)iter;
155
156 *data = &iterator->curobj;
157 }
158
159
160 static void php_dom_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
161 {
162 php_dom_iterator *iterator = (php_dom_iterator *)iter;
163 zval *object = (zval *)iterator->intern.data;
164
165 if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
166 ZVAL_LONG(key, iter->index);
167 } else {
168 dom_object *intern = (dom_object *)zend_object_store_get_object(iterator->curobj TSRMLS_CC);
169
170 if (intern != NULL && intern->ptr != NULL) {
171 xmlNodePtr curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
172 ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name), 1);
173 } else {
174 ZVAL_NULL(key);
175 }
176 }
177 }
178
179
180 static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
181 {
182 zval *curobj, *curattr = NULL;
183 zval *object;
184 xmlNodePtr curnode = NULL, basenode;
185 dom_object *intern;
186 dom_object *nnmap;
187 dom_nnodemap_object *objmap;
188 int ret, previndex=0;
189 HashTable *nodeht;
190 zval **entry;
191
192 php_dom_iterator *iterator = (php_dom_iterator *)iter;
193
194 object = (zval *)iterator->intern.data;
195 nnmap = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
196 objmap = (dom_nnodemap_object *)nnmap->ptr;
197
198 curobj = iterator->curobj;
199 intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
200 if (intern != NULL && intern->ptr != NULL) {
201 if (objmap->nodetype != XML_ENTITY_NODE &&
202 objmap->nodetype != XML_NOTATION_NODE) {
203 if (objmap->nodetype == DOM_NODESET) {
204 nodeht = HASH_OF(objmap->baseobjptr);
205 zend_hash_move_forward(nodeht);
206 if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
207 curattr = *entry;
208 Z_ADDREF_P(curattr);
209 }
210 } else {
211 curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
212 if (objmap->nodetype == XML_ATTRIBUTE_NODE ||
213 objmap->nodetype == XML_ELEMENT_NODE) {
214 curnode = curnode->next;
215 } else {
216
217 basenode = dom_object_get_node(objmap->baseobj);
218 if (basenode && (basenode->type == XML_DOCUMENT_NODE ||
219 basenode->type == XML_HTML_DOCUMENT_NODE)) {
220 basenode = xmlDocGetRootElement((xmlDoc *) basenode);
221 } else if (basenode) {
222 basenode = basenode->children;
223 } else {
224 goto err;
225 }
226 curnode = dom_get_elements_by_tag_name_ns_raw(basenode, objmap->ns, objmap->local, &previndex, iter->index);
227 }
228 }
229 } else {
230 if (objmap->nodetype == XML_ENTITY_NODE) {
231 curnode = php_dom_libxml_hash_iter(objmap->ht, iter->index);
232 } else {
233 curnode = php_dom_libxml_notation_iter(objmap->ht, iter->index);
234 }
235 }
236 }
237 err:
238 zval_ptr_dtor((zval**)&curobj);
239 if (curnode) {
240 MAKE_STD_ZVAL(curattr);
241 curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC);
242 }
243
244 iterator->curobj = curattr;
245 }
246
247
248 zend_object_iterator_funcs php_dom_iterator_funcs = {
249 php_dom_iterator_dtor,
250 php_dom_iterator_valid,
251 php_dom_iterator_current_data,
252 php_dom_iterator_current_key,
253 php_dom_iterator_move_forward,
254 NULL
255 };
256
257 zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
258 {
259 dom_object *intern;
260 dom_nnodemap_object *objmap;
261 xmlNodePtr nodep, curnode=NULL;
262 zval *curattr = NULL;
263 int ret, curindex = 0;
264 HashTable *nodeht;
265 zval **entry;
266 php_dom_iterator *iterator;
267
268 if (by_ref) {
269 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
270 }
271 iterator = emalloc(sizeof(php_dom_iterator));
272
273 Z_ADDREF_P(object);
274 iterator->intern.data = (void*)object;
275 iterator->intern.funcs = &php_dom_iterator_funcs;
276
277 intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
278 objmap = (dom_nnodemap_object *)intern->ptr;
279 if (objmap != NULL) {
280 if (objmap->nodetype != XML_ENTITY_NODE &&
281 objmap->nodetype != XML_NOTATION_NODE) {
282 if (objmap->nodetype == DOM_NODESET) {
283 nodeht = HASH_OF(objmap->baseobjptr);
284 zend_hash_internal_pointer_reset(nodeht);
285 if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
286 curattr = *entry;
287 Z_ADDREF_P(curattr);
288 }
289 } else {
290 nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
291 if (!nodep) {
292 goto err;
293 }
294 if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
295 if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
296 curnode = (xmlNodePtr) nodep->properties;
297 } else {
298 curnode = (xmlNodePtr) nodep->children;
299 }
300 } else {
301 if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
302 nodep = xmlDocGetRootElement((xmlDoc *) nodep);
303 } else {
304 nodep = nodep->children;
305 }
306 curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
307 }
308 }
309 } else {
310 if (objmap->nodetype == XML_ENTITY_NODE) {
311 curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
312 } else {
313 curnode = php_dom_libxml_notation_iter(objmap->ht, 0);
314 }
315 }
316 }
317 err:
318 if (curnode) {
319 MAKE_STD_ZVAL(curattr);
320 curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC);
321 }
322
323 iterator->curobj = curattr;
324
325 return (zend_object_iterator*)iterator;
326 }
327
328
329 #endif
330
331
332
333
334
335
336
337
338