Annotation of embedaddon/php/ext/dom/dom_iterators.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 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: dom_iterators.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            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 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:        xmlNodePtr curnode = NULL;
        !           164:        dom_object *intern;
        !           165:        zval *object;
        !           166:        int namelen;
        !           167: 
        !           168:        php_dom_iterator *iterator = (php_dom_iterator *)iter;
        !           169: 
        !           170:        object = (zval *)iterator->intern.data;
        !           171: 
        !           172:        if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
        !           173:                *int_key = iter->index;
        !           174:                return HASH_KEY_IS_LONG;
        !           175:        } else {
        !           176:                curobj = iterator->curobj;
        !           177: 
        !           178:                intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
        !           179:                if (intern != NULL && intern->ptr != NULL) {
        !           180:                        curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
        !           181:                } else {
        !           182:                        return HASH_KEY_NON_EXISTANT;
        !           183:                }
        !           184: 
        !           185:                namelen = xmlStrlen(curnode->name);
        !           186:                *str_key = estrndup(curnode->name, namelen);
        !           187:                *str_key_len = namelen + 1;
        !           188:                return HASH_KEY_IS_STRING;
        !           189:        }
        !           190: }
        !           191: /* }}} */
        !           192: 
        !           193: static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        !           194: {
        !           195:        zval *curobj, *curattr = NULL;
        !           196:        zval *object;
        !           197:        xmlNodePtr curnode = NULL, basenode;
        !           198:        dom_object *intern;
        !           199:        dom_object *nnmap;
        !           200:        dom_nnodemap_object *objmap;
        !           201:        int ret, previndex=0;
        !           202:        HashTable *nodeht;
        !           203:        zval **entry;
        !           204: 
        !           205:        php_dom_iterator *iterator = (php_dom_iterator *)iter;
        !           206: 
        !           207:        object = (zval *)iterator->intern.data;
        !           208:        nnmap = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
        !           209:        objmap = (dom_nnodemap_object *)nnmap->ptr;
        !           210: 
        !           211:        curobj = iterator->curobj;
        !           212:        intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
        !           213:        if (intern != NULL && intern->ptr != NULL) {
        !           214:                if (objmap->nodetype != XML_ENTITY_NODE && 
        !           215:                        objmap->nodetype != XML_NOTATION_NODE) {
        !           216:                        if (objmap->nodetype == DOM_NODESET) {
        !           217:                                nodeht = HASH_OF(objmap->baseobjptr);
        !           218:                                zend_hash_move_forward(nodeht);
        !           219:                                if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
        !           220:                                        curattr = *entry;
        !           221:                                        Z_ADDREF_P(curattr);
        !           222:                                }
        !           223:                        } else {
        !           224:                                curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
        !           225:                                if (objmap->nodetype == XML_ATTRIBUTE_NODE || 
        !           226:                                        objmap->nodetype == XML_ELEMENT_NODE) {
        !           227:                                        curnode = curnode->next;
        !           228:                                } else {
        !           229:                                        /* Nav the tree evey time as this is LIVE */
        !           230:                                        basenode = dom_object_get_node(objmap->baseobj);
        !           231:                                        if (basenode && (basenode->type == XML_DOCUMENT_NODE || 
        !           232:                                                basenode->type == XML_HTML_DOCUMENT_NODE)) {
        !           233:                                                basenode = xmlDocGetRootElement((xmlDoc *) basenode);
        !           234:                                        } else if (basenode) {
        !           235:                                                basenode = basenode->children;
        !           236:                                        } else {
        !           237:                                                goto err;
        !           238:                                        }
        !           239:                                        curnode = dom_get_elements_by_tag_name_ns_raw(basenode, objmap->ns, objmap->local, &previndex, iter->index);
        !           240:                                }
        !           241:                        }
        !           242:                } else {
        !           243:                        if (objmap->nodetype == XML_ENTITY_NODE) {
        !           244:                                curnode = php_dom_libxml_hash_iter(objmap->ht, iter->index);
        !           245:                        } else {
        !           246:                                curnode = php_dom_libxml_notation_iter(objmap->ht, iter->index);
        !           247:                        }
        !           248:                }
        !           249:        }
        !           250: err:
        !           251:        zval_ptr_dtor((zval**)&curobj);
        !           252:        if (curnode) {
        !           253:                MAKE_STD_ZVAL(curattr);
        !           254:                curattr = php_dom_create_object(curnode, &ret, NULL, curattr, objmap->baseobj TSRMLS_CC);
        !           255:        }
        !           256: 
        !           257:        iterator->curobj = curattr;
        !           258: }
        !           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: 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:        xmlNodePtr nodep, curnode=NULL;
        !           275:        zval *curattr = NULL;
        !           276:        int ret, curindex = 0;
        !           277:        HashTable *nodeht;
        !           278:        zval **entry;
        !           279:        php_dom_iterator *iterator;
        !           280: 
        !           281:        if (by_ref) {
        !           282:                zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
        !           283:        }
        !           284:        iterator = emalloc(sizeof(php_dom_iterator));
        !           285: 
        !           286:        Z_ADDREF_P(object);
        !           287:        iterator->intern.data = (void*)object;
        !           288:        iterator->intern.funcs = &php_dom_iterator_funcs;
        !           289: 
        !           290:        intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
        !           291:        objmap = (dom_nnodemap_object *)intern->ptr;
        !           292:        if (objmap != NULL) {
        !           293:                if (objmap->nodetype != XML_ENTITY_NODE && 
        !           294:                        objmap->nodetype != XML_NOTATION_NODE) {
        !           295:                        if (objmap->nodetype == DOM_NODESET) {
        !           296:                                nodeht = HASH_OF(objmap->baseobjptr);
        !           297:                                zend_hash_internal_pointer_reset(nodeht);
        !           298:                                if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
        !           299:                                        curattr = *entry;
        !           300:                                        Z_ADDREF_P(curattr);
        !           301:                                }
        !           302:                        } else {
        !           303:                                nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
        !           304:                                if (!nodep) {
        !           305:                                        goto err;
        !           306:                                }
        !           307:                                if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
        !           308:                                        if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
        !           309:                                                curnode = (xmlNodePtr) nodep->properties;
        !           310:                                        } else {
        !           311:                                                curnode = (xmlNodePtr) nodep->children;
        !           312:                                        }
        !           313:                                } else {
        !           314:                                        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
        !           315:                                                nodep = xmlDocGetRootElement((xmlDoc *) nodep);
        !           316:                                        } else {
        !           317:                                                nodep = nodep->children;
        !           318:                                        }
        !           319:                                        curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
        !           320:                                }
        !           321:                        }
        !           322:                } else {
        !           323:                        if (objmap->nodetype == XML_ENTITY_NODE) {
        !           324:                                curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
        !           325:                        } else {
        !           326:                                curnode = php_dom_libxml_notation_iter(objmap->ht, 0);
        !           327:                        }
        !           328:                }
        !           329:        }
        !           330: err:
        !           331:        if (curnode) {
        !           332:                MAKE_STD_ZVAL(curattr);
        !           333:                curattr = php_dom_create_object(curnode, &ret, NULL, curattr, objmap->baseobj TSRMLS_CC);
        !           334:        }
        !           335: 
        !           336:        iterator->curobj = curattr;
        !           337: 
        !           338:        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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>