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

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      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);
1.1.1.2   misho     254:                curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC);
1.1       misho     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);
1.1.1.2   misho     333:                curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC);
1.1       misho     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>