root/ext/dom/dom_iterators.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. itemHashScanner
  2. create_notation
  3. php_dom_libxml_hash_iter
  4. php_dom_libxml_notation_iter
  5. php_dom_iterator_dtor
  6. php_dom_iterator_valid
  7. php_dom_iterator_current_data
  8. php_dom_iterator_current_key
  9. php_dom_iterator_move_forward
  10. php_dom_get_iterator

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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: Christian Stocker <chregu@php.net>                          |
  16    |          Rob Richards <rrichards@php.net>                            |
  17    +----------------------------------------------------------------------+
  18 */
  19 
  20 /* $Id$ */
  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                                         /* Nav the tree evey time as this is LIVE */
 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  * Local variables:
 333  * tab-width: 4
 334  * c-basic-offset: 4
 335  * End:
 336  * vim600: noet sw=4 ts=4 fdm=marker
 337  * vim<600: noet sw=4 ts=4
 338  */

/* [<][>][^][v][top][bottom][index][help] */