PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/dom - dom_iterators.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 151 156 96.8 %
Date: 2019-05-06 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 06 May 2019 17:58:13 +0000 (998 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.