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: 153 158 96.8 %
Date: 2014-07-23 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 23 Jul 2014 19:58:30 +0000 (46 hours ago)

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