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>