]> granicus.if.org Git - php/commitdiff
guess this file should be added too :)
authorRob Richards <rrichards@php.net>
Sat, 29 Nov 2003 20:41:41 +0000 (20:41 +0000)
committerRob Richards <rrichards@php.net>
Sat, 29 Nov 2003 20:41:41 +0000 (20:41 +0000)
ext/dom/dom_iterators.c [new file with mode: 0644]

diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c
new file mode 100644 (file)
index 0000000..5f1e005
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2003 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.0 of the PHP license,       |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_0.txt.                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Christian Stocker <chregu@php.net>                          |
+   |          Rob Richards <rrichards@php.net>                            |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+#include "dom_ce.h"
+
+typedef struct _nodeIterator nodeIterator;
+struct _nodeIterator {
+       int cur;
+       int index;
+       xmlNode *node;
+};
+
+typedef struct _notationIterator notationIterator;
+struct _notationIterator {
+       int cur;
+       int index;
+       xmlNotation *notation;
+};
+
+static void itemHashScanner (void *payload, void *data, xmlChar *name) {
+       nodeIterator *priv = (nodeIterator *)data;
+
+       if(priv->cur < priv->index) {
+               priv->cur++;
+       } else {
+               if(priv->node == NULL) {
+                       priv->node = (xmlNode *)payload;
+               }
+       }
+}
+
+xmlNodePtr create_notation(const xmlChar *name, 
+                                                                       const xmlChar *ExternalID, const xmlChar *SystemID) {
+       xmlEntityPtr ret;
+
+       ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
+    memset(ret, 0, sizeof(xmlEntity));
+    ret->type = XML_NOTATION_NODE;
+    ret->name = xmlStrdup(name);
+       ret->ExternalID = xmlStrdup(ExternalID);
+       ret->SystemID = xmlStrdup(SystemID);
+       ret->length = 0;
+       ret->content = NULL;
+       ret->URI = NULL;
+       ret->orig = NULL;
+       ret->children = NULL;
+       ret->parent = NULL;
+       ret->doc = NULL;
+       ret->_private = NULL;
+       ret->last = NULL;
+       ret->prev = NULL;
+       return((xmlNodePtr) ret);
+}
+
+xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index)
+{
+       xmlNode *nodep = NULL;
+       nodeIterator *iter;
+       int htsize;
+
+       if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
+               iter = emalloc(sizeof(nodeIterator));
+               iter->cur = 0;
+               iter->index = index;
+               iter->node = NULL;
+               xmlHashScan(ht, itemHashScanner, iter);
+               nodep = iter->node;
+               efree(iter);
+               return nodep;
+       } else {
+               return NULL;
+       }
+}
+
+xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index)
+{
+       notationIterator *iter;
+       xmlNotation *notep = NULL;
+       int htsize;
+
+       if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
+               iter = emalloc(sizeof(notationIterator));
+               iter->cur = 0;
+               iter->index = index;
+               iter->notation = NULL;
+               xmlHashScan(ht, itemHashScanner, iter);
+               notep = iter->notation;
+               efree(iter);
+               return create_notation(notep->name, notep->PublicID, notep->SystemID);
+       } else {
+               return NULL;
+       }
+}
+
+static void php_dom_iterator_dtor(zend_object_iterator *iter TSRMLS_DC)
+{
+       php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+       zval_ptr_dtor((zval**)&iterator->intern.data);
+
+       if (iterator->curobj) {
+               zval_ptr_dtor((zval**)&iterator->curobj);
+       }
+
+       efree(iterator);
+}
+
+static int php_dom_iterator_has_more(zend_object_iterator *iter TSRMLS_DC)
+{
+
+       php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+       if (iterator->curobj) {
+               return SUCCESS;
+       } else {
+               return FAILURE;
+       }
+}
+
+static void php_dom_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
+{
+       php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+       *data = &iterator->curobj;
+}
+
+static int php_dom_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+{
+       zval *curobj;
+       xmlNodePtr curnode = NULL;
+       dom_object *intern;
+       zval *object;
+       int namelen;
+
+       php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+       object = (zval *)iterator->intern.data;
+
+       if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
+               *int_key = iter->index - 1;
+               return HASH_KEY_IS_LONG;
+       } else {
+               curobj = iterator->curobj;
+
+               intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
+               if (intern != NULL && intern->ptr != NULL) {
+                       curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
+               }
+
+               namelen = xmlStrlen(curnode->name);
+               *str_key = estrndup(curnode->name, namelen);
+               *str_key_len = namelen + 1;
+               return HASH_KEY_IS_STRING;
+       }
+}
+
+static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
+{
+       zval *curobj, *curattr = NULL;
+       zval *object;
+       xmlNodePtr curnode = NULL;
+       dom_object *intern;
+       dom_object *nnmap;
+       dom_nnodemap_object *objmap;
+       int ret, previndex=0;
+
+       php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+       object = (zval *)iterator->intern.data;
+       nnmap = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
+       objmap = (dom_nnodemap_object *)nnmap->ptr;
+
+       curobj = iterator->curobj;
+       intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
+       if (intern != NULL && intern->ptr != NULL) {
+               if (objmap->ht == NULL) {
+                       curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
+                       if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                               curnode = curnode->next;
+                       } else {
+                               previndex = iter->index - 1;
+                               curnode = dom_get_elements_by_tag_name_ns_raw(curnode, objmap->ns, objmap->local, &previndex, iter->index);
+                       }
+               } else {
+                       if (objmap->nodetype == XML_ENTITY_NODE) {
+                               curnode = php_dom_libxml_hash_iter(objmap->ht, iter->index);
+                       } else {
+                               curnode = php_dom_libxml_notation_iter(objmap->ht, iter->index);
+                       }
+               }
+       }
+
+       zval_ptr_dtor((zval**)&curobj);
+       if (curnode) {
+               MAKE_STD_ZVAL(curattr);
+               curattr = php_dom_create_object(curnode, &ret, NULL, curattr, objmap->baseobj TSRMLS_CC);
+       }
+
+       iterator->curobj = curattr;
+}
+
+zend_object_iterator_funcs php_dom_iterator_funcs = {
+       php_dom_iterator_dtor,
+       php_dom_iterator_has_more,
+       php_dom_iterator_current_data,
+       php_dom_iterator_current_key,
+       php_dom_iterator_move_forward,
+       NULL
+};
+
+zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC)
+{
+       dom_object *intern;
+       dom_nnodemap_object *objmap;
+       xmlNodePtr nodep, curnode;
+       zval *curattr = NULL;
+       int ret, curindex = 0;
+
+       php_dom_iterator *iterator = emalloc(sizeof(php_dom_iterator));
+
+       object->refcount++;
+       iterator->intern.data = (void*)object;
+       iterator->intern.funcs = &php_dom_iterator_funcs;
+
+       intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
+       objmap = (dom_nnodemap_object *)intern->ptr;
+       if (objmap->ht == NULL) {
+               nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
+               if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                       if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
+                               curnode = (xmlNodePtr) nodep->properties;
+                       } else {
+                               curnode = (xmlNodePtr) nodep->children;
+                       }
+               } else {
+                       if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+                               nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                       }
+                       curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
+               }
+       } else {
+               curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
+       }
+
+       if (curnode) {
+               MAKE_STD_ZVAL(curattr);
+               curattr = php_dom_create_object(curnode, &ret, NULL, curattr, objmap->baseobj TSRMLS_CC);
+       }
+
+       iterator->curobj = curattr;
+
+       return (zend_object_iterator*)iterator;
+}
+
+#endif