Annotation of embedaddon/php/ext/simplexml/simplexml.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: Sterling Hughes <sterling@php.net>                          |
        !            16:   |          Marcus Boerger <helly@php.net>                              |
        !            17:   |          Rob Richards <rrichards@php.net>                            |
        !            18:   +----------------------------------------------------------------------+
        !            19: */
        !            20: 
        !            21: /* $Id: simplexml.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            22: 
        !            23: #ifdef HAVE_CONFIG_H
        !            24: #include "config.h"
        !            25: #endif
        !            26: 
        !            27: #include "php.h"
        !            28: #if HAVE_LIBXML && HAVE_SIMPLEXML
        !            29: 
        !            30: #include "php_ini.h"
        !            31: #include "ext/standard/info.h"
        !            32: #include "ext/standard/php_string.h"
        !            33: #include "php_simplexml.h"
        !            34: #include "php_simplexml_exports.h"
        !            35: #include "zend_exceptions.h"
        !            36: #include "zend_interfaces.h"
        !            37: #include "sxe.h"
        !            38: 
        !            39: #define SXE_ELEMENT_BY_NAME 0
        !            40: 
        !            41: zend_class_entry *sxe_class_entry = NULL;
        !            42: 
        !            43: PHP_SXE_API zend_class_entry *sxe_get_element_class_entry() /* {{{ */
        !            44: {
        !            45:        return sxe_class_entry;
        !            46: }
        !            47: /* }}} */
        !            48: 
        !            49: #define SXE_ME(func, arg_info, flags) PHP_ME(simplexml_element, func, arg_info, flags)
        !            50: #define SXE_MALIAS(func, alias, arg_info, flags) PHP_MALIAS(simplexml_element, func, alias, arg_info, flags)
        !            51: 
        !            52: #define SXE_METHOD(func) PHP_METHOD(simplexml_element, func)
        !            53: 
        !            54: static php_sxe_object* php_sxe_object_new(zend_class_entry *ce TSRMLS_DC);
        !            55: static zend_object_value php_sxe_register_object(php_sxe_object * TSRMLS_DC);
        !            56: static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data TSRMLS_DC);
        !            57: static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data TSRMLS_DC);
        !            58: static zval *sxe_get_value(zval *z TSRMLS_DC);
        !            59: static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
        !            60: static int php_sxe_iterator_valid(zend_object_iterator *iter TSRMLS_DC);
        !            61: static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
        !            62: static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
        !            63: static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC);
        !            64: static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC);
        !            65: 
        !            66: /* {{{ _node_as_zval()
        !            67:  */
        !            68: static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE_ITER itertype, char *name, const xmlChar *nsprefix, int isprefix TSRMLS_DC)
        !            69: {
        !            70:        php_sxe_object *subnode;
        !            71: 
        !            72:        subnode = php_sxe_object_new(sxe->zo.ce TSRMLS_CC);
        !            73:        subnode->document = sxe->document;
        !            74:        subnode->document->refcount++;
        !            75:        subnode->iter.type = itertype;
        !            76:        if (name) {
        !            77:                subnode->iter.name = xmlStrdup((xmlChar *)name);
        !            78:        }
        !            79:        if (nsprefix && *nsprefix) {
        !            80:                subnode->iter.nsprefix = xmlStrdup(nsprefix);
        !            81:                subnode->iter.isprefix = isprefix;
        !            82:        }
        !            83: 
        !            84:        php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL TSRMLS_CC);
        !            85: 
        !            86:        value->type = IS_OBJECT;
        !            87:        value->value.obj = php_sxe_register_object(subnode TSRMLS_CC);
        !            88: }
        !            89: /* }}} */
        !            90: 
        !            91: #define APPEND_PREV_ELEMENT(__c, __v) \
        !            92:        if ((__c) == 1) { \
        !            93:                array_init(return_value); \
        !            94:                add_next_index_zval(return_value, __v); \
        !            95:        }
        !            96: 
        !            97: #define APPEND_CUR_ELEMENT(__c, __v) \
        !            98:        if (++(__c) > 1) { \
        !            99:                add_next_index_zval(return_value, __v); \
        !           100:        }
        !           101: 
        !           102: #define GET_NODE(__s, __n) { \
        !           103:        if ((__s)->node && (__s)->node->node) { \
        !           104:                __n = (__s)->node->node; \
        !           105:        } else { \
        !           106:                __n = NULL; \
        !           107:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node no longer exists"); \
        !           108:        } \
        !           109: }
        !           110: 
        !           111: static xmlNodePtr php_sxe_get_first_node(php_sxe_object *sxe, xmlNodePtr node TSRMLS_DC) /* {{{ */
        !           112: {
        !           113:        php_sxe_object *intern;
        !           114:        xmlNodePtr retnode = NULL;
        !           115: 
        !           116:        if (sxe && sxe->iter.type != SXE_ITER_NONE) {
        !           117:                php_sxe_reset_iterator(sxe, 1 TSRMLS_CC);
        !           118:                if (sxe->iter.data) {
        !           119:                        intern = (php_sxe_object *)zend_object_store_get_object(sxe->iter.data TSRMLS_CC);
        !           120:                        GET_NODE(intern, retnode)
        !           121:                }
        !           122:                return retnode;
        !           123:        } else {
        !           124:                return node;
        !           125:        }
        !           126: }
        !           127: /* }}} */
        !           128: 
        !           129: static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name, int prefix) /* {{{ */
        !           130: {
        !           131:        if (name == NULL && (node->ns == NULL || node->ns->prefix == NULL)) {
        !           132:                return 1;
        !           133:        }
        !           134: 
        !           135:        if (node->ns && !xmlStrcmp(prefix ? node->ns->prefix : node->ns->href, name)) {
        !           136:                return 1;
        !           137:        }
        !           138: 
        !           139:        return 0;
        !           140: }
        !           141: /* }}} */
        !           142: 
        !           143: static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node, long *cnt) /* {{{ */
        !           144: {
        !           145:        long nodendx = 0;
        !           146: 
        !           147:        if (sxe->iter.type == SXE_ITER_NONE) {
        !           148:                if (offset == 0) {
        !           149:                        if (cnt) {
        !           150:                                *cnt = 0;
        !           151:                        }
        !           152:                        return node;
        !           153:                } else {
        !           154:                        return NULL;
        !           155:                }
        !           156:        }
        !           157:        while (node && nodendx <= offset) {
        !           158:                SKIP_TEXT(node)
        !           159:                if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           160:                        if (sxe->iter.type == SXE_ITER_CHILD || (
        !           161:                                sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name))) {
        !           162:                                if (nodendx == offset) {
        !           163:                                        break;
        !           164:                                }
        !           165:                                nodendx++;
        !           166:                        }
        !           167:                }
        !           168: next_iter:
        !           169:                node = node->next;
        !           170:        }
        !           171: 
        !           172:        if (cnt) {
        !           173:                *cnt = nodendx;
        !           174:        }
        !           175: 
        !           176:        return node;
        !           177: }
        !           178: /* }}} */
        !           179: 
        !           180: static xmlNodePtr sxe_find_element_by_name(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name TSRMLS_DC) /* {{{ */
        !           181: {
        !           182:        while (node) {
        !           183:                SKIP_TEXT(node)
        !           184:                if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           185:                        if (!xmlStrcmp(node->name, name)) {
        !           186:                                return node;
        !           187:                        }
        !           188:                }
        !           189: next_iter:
        !           190:                node = node->next;
        !           191:        }
        !           192:        return NULL;
        !           193: } /* }}} */
        !           194: 
        !           195: static xmlNodePtr sxe_get_element_by_name(php_sxe_object *sxe, xmlNodePtr node, char **name, SXE_ITER *type TSRMLS_DC) /* {{{ */
        !           196: {
        !           197:        int         orgtype;
        !           198:        xmlNodePtr  orgnode = node;
        !           199:        xmlNodePtr  retnode = NULL;
        !           200: 
        !           201:        if (sxe->iter.type != SXE_ITER_ATTRLIST)
        !           202:        {
        !           203:                orgtype = sxe->iter.type;
        !           204:                if (sxe->iter.type == SXE_ITER_NONE) {
        !           205:                        sxe->iter.type = SXE_ITER_CHILD;
        !           206:                }
        !           207:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           208:                sxe->iter.type = orgtype;
        !           209:        }
        !           210: 
        !           211:        if (sxe->iter.type == SXE_ITER_ELEMENT) {
        !           212:                orgnode = sxe_find_element_by_name(sxe, node, sxe->iter.name TSRMLS_CC);
        !           213:                if (!orgnode) {
        !           214:                        return NULL;
        !           215:                }
        !           216:                node = orgnode->children;
        !           217:        }
        !           218: 
        !           219:        while (node) {
        !           220:                SKIP_TEXT(node)
        !           221:                if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           222:                        if (!xmlStrcmp(node->name, (xmlChar *)*name)) {
        !           223:                                if (1||retnode)
        !           224:                                {
        !           225:                                        *type = SXE_ITER_ELEMENT;
        !           226:                                        return orgnode;
        !           227:                                }
        !           228:                                retnode = node;
        !           229:                        }
        !           230:                }
        !           231: next_iter:
        !           232:                node = node->next;
        !           233:        }
        !           234: 
        !           235:        if (retnode)
        !           236:        {
        !           237:                *type = SXE_ITER_NONE;
        !           238:                *name = NULL;
        !           239:                return retnode;
        !           240:        }
        !           241: 
        !           242:        return NULL;
        !           243: }
        !           244: /* }}} */
        !           245: 
        !           246: /* {{{ sxe_prop_dim_read()
        !           247:  */
        !           248: static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, int type TSRMLS_DC)
        !           249: {
        !           250:        zval           *return_value;
        !           251:        php_sxe_object *sxe;
        !           252:        char           *name;
        !           253:        xmlNodePtr      node;
        !           254:        xmlAttrPtr      attr = NULL;
        !           255:        zval            tmp_zv;
        !           256:        int             nodendx = 0;
        !           257:        int             test = 0;
        !           258: 
        !           259:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !           260: 
        !           261:        if (!member || Z_TYPE_P(member) == IS_LONG) {
        !           262:                if (sxe->iter.type != SXE_ITER_ATTRLIST) {
        !           263:                        attribs = 0;
        !           264:                        elements = 1;
        !           265:                } else if (!member) {
        !           266:                        /* This happens when the user did: $sxe[]->foo = $value */
        !           267:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute");
        !           268:                        return NULL;
        !           269:                }
        !           270:                name = NULL;
        !           271:        } else {
        !           272:                if (Z_TYPE_P(member) != IS_STRING) {
        !           273:                        tmp_zv = *member;
        !           274:                        zval_copy_ctor(&tmp_zv);
        !           275:                        member = &tmp_zv;
        !           276:                        convert_to_string(member);
        !           277:                }
        !           278:                name = Z_STRVAL_P(member);
        !           279:        }
        !           280: 
        !           281:        GET_NODE(sxe, node);
        !           282: 
        !           283:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !           284:                attribs = 1;
        !           285:                elements = 0;
        !           286:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           287:                attr = (xmlAttrPtr)node;
        !           288:                test = sxe->iter.name != NULL;
        !           289:        } else if (sxe->iter.type != SXE_ITER_CHILD) {
        !           290:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           291:                attr = node ? node->properties : NULL;
        !           292:                test = 0;
        !           293:                if (!member && node && node->parent &&
        !           294:                    node->parent->type == XML_DOCUMENT_NODE) {
        !           295:                        /* This happens when the user did: $sxe[]->foo = $value */
        !           296:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute");
        !           297:                        return NULL;
        !           298:                }
        !           299:        }
        !           300: 
        !           301:        MAKE_STD_ZVAL(return_value);
        !           302:        ZVAL_NULL(return_value);
        !           303: 
        !           304:        if (node) {
        !           305:                if (attribs) {
        !           306:                        if (Z_TYPE_P(member) != IS_LONG || sxe->iter.type == SXE_ITER_ATTRLIST) {
        !           307:                                if (Z_TYPE_P(member) == IS_LONG) {
        !           308:                                        while (attr && nodendx <= Z_LVAL_P(member)) {
        !           309:                                                if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           310:                                                        if (nodendx == Z_LVAL_P(member)) {
        !           311:                                                                _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           312:                                                                break;
        !           313:                                                        }
        !           314:                                                        nodendx++;
        !           315:                                                }
        !           316:                                                attr = attr->next;
        !           317:                                        }
        !           318:                                } else {
        !           319:                                        while (attr) {
        !           320:                                                if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           321:                                                        _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           322:                                                        break;
        !           323:                                                }
        !           324:                                                attr = attr->next;
        !           325:                                        }
        !           326:                                }
        !           327:                        }
        !           328:                }
        !           329: 
        !           330:                if (elements) {
        !           331:                        if (!sxe->node) {
        !           332:                                php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL TSRMLS_CC);
        !           333:                        }
        !           334:                        if (!member || Z_TYPE_P(member) == IS_LONG) {
        !           335:                                long cnt = 0;
        !           336:                                xmlNodePtr mynode = node;
        !           337: 
        !           338:                                if (sxe->iter.type == SXE_ITER_CHILD) {
        !           339:                                        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           340:                                }
        !           341:                                if (sxe->iter.type == SXE_ITER_NONE) {
        !           342:                                        if (member && Z_LVAL_P(member) > 0) {
        !           343:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only 0 such elements exist", mynode->name, Z_LVAL_P(member));
        !           344:                                        }
        !           345:                                } else if (member) {
        !           346:                                        node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
        !           347:                                } else {
        !           348:                                        node = NULL;
        !           349:                                }
        !           350:                                if (node) {
        !           351:                                        _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           352:                                } else if (type == BP_VAR_W || type == BP_VAR_RW) {
        !           353:                                        if (member && cnt < Z_LVAL_P(member)) {
        !           354:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only %ld such elements exist", mynode->name, Z_LVAL_P(member), cnt);
        !           355:                                        }
        !           356:                                        node = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, NULL);
        !           357:                                        _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           358:                                }
        !           359:                        } else {
        !           360: #if SXE_ELEMENT_BY_NAME
        !           361:                                int newtype;
        !           362: 
        !           363:                                GET_NODE(sxe, node);
        !           364:                                node = sxe_get_element_by_name(sxe, node, &name, &newtype TSRMLS_CC);
        !           365:                                if (node) {
        !           366:                                        _node_as_zval(sxe, node, return_value, newtype, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           367:                                }
        !           368: #else
        !           369:                                _node_as_zval(sxe, node, return_value, SXE_ITER_ELEMENT, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           370: #endif
        !           371:                        }
        !           372:                }
        !           373:        }
        !           374: 
        !           375:        Z_SET_REFCOUNT_P(return_value, 0);
        !           376:        Z_UNSET_ISREF_P(return_value);
        !           377: 
        !           378:        if (member == &tmp_zv) {
        !           379:                zval_dtor(&tmp_zv);
        !           380:        }
        !           381:        if (Z_TYPE_P(return_value) == IS_NULL) {
        !           382:                FREE_ZVAL(return_value);
        !           383:                return_value = &EG(uninitialized_zval);
        !           384:        }
        !           385: 
        !           386:        return return_value;
        !           387: }
        !           388: /* }}} */
        !           389: 
        !           390: /* {{{ sxe_property_read()
        !           391:  */
        !           392: static zval * sxe_property_read(zval *object, zval *member, int type TSRMLS_DC)
        !           393: {
        !           394:        return sxe_prop_dim_read(object, member, 1, 0, type TSRMLS_CC);
        !           395: }
        !           396: /* }}} */
        !           397: 
        !           398: /* {{{ sxe_dimension_read()
        !           399:  */
        !           400: static zval * sxe_dimension_read(zval *object, zval *offset, int type TSRMLS_DC)
        !           401: {
        !           402:        return sxe_prop_dim_read(object, offset, 0, 1, type TSRMLS_CC);
        !           403: }
        !           404: /* }}} */
        !           405: 
        !           406: /* {{{ change_node_zval()
        !           407:  */
        !           408: static void change_node_zval(xmlNodePtr node, zval *value TSRMLS_DC)
        !           409: {
        !           410:        zval value_copy;
        !           411:        xmlChar *buffer;
        !           412:        int buffer_len;
        !           413: 
        !           414:        if (!value)
        !           415:        {
        !           416:                xmlNodeSetContentLen(node, (xmlChar *)"", 0);
        !           417:                return;
        !           418:        }
        !           419:        switch (Z_TYPE_P(value)) {
        !           420:                case IS_LONG:
        !           421:                case IS_BOOL:
        !           422:                case IS_DOUBLE:
        !           423:                case IS_NULL:
        !           424:                        if (Z_REFCOUNT_P(value) > 1) {
        !           425:                                value_copy = *value;
        !           426:                                zval_copy_ctor(&value_copy);
        !           427:                                value = &value_copy;
        !           428:                        }
        !           429:                        convert_to_string(value);
        !           430:                        /* break missing intentionally */
        !           431:                case IS_STRING:
        !           432:                        buffer = xmlEncodeEntitiesReentrant(node->doc, (xmlChar *)Z_STRVAL_P(value));
        !           433:                        buffer_len = xmlStrlen(buffer);
        !           434:                        /* check for NULL buffer in case of memory error in xmlEncodeEntitiesReentrant */
        !           435:                        if (buffer) {
        !           436:                                xmlNodeSetContentLen(node, buffer, buffer_len);
        !           437:                                xmlFree(buffer);
        !           438:                        }
        !           439:                        if (value == &value_copy) {
        !           440:                                zval_dtor(value);
        !           441:                        }
        !           442:                        break;
        !           443:                default:
        !           444:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "It is not possible to assign complex types to nodes");
        !           445:                        break;
        !           446:        }
        !           447: }
        !           448: /* }}} */
        !           449: 
        !           450: /* {{{ sxe_property_write()
        !           451:  */
        !           452: static int sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool elements, zend_bool attribs, xmlNodePtr *pnewnode TSRMLS_DC)
        !           453: {
        !           454:        php_sxe_object *sxe;
        !           455:        xmlNodePtr      node;
        !           456:        xmlNodePtr      newnode = NULL;
        !           457:        xmlNodePtr      mynode;
        !           458:        xmlNodePtr              tempnode;
        !           459:        xmlAttrPtr      attr = NULL;
        !           460:        int             counter = 0;
        !           461:        int             is_attr = 0;
        !           462:        int                             nodendx = 0;
        !           463:        int             test = 0;
        !           464:        int                             new_value = 0;
        !           465:        long            cnt = 0;
        !           466:        int                             retval = SUCCESS;
        !           467:        zval            tmp_zv, trim_zv, value_copy;
        !           468: 
        !           469:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !           470: 
        !           471:        if (!member || Z_TYPE_P(member) == IS_LONG) {
        !           472:                if (sxe->iter.type != SXE_ITER_ATTRLIST) {
        !           473:                        attribs = 0;
        !           474:                        elements = 1;
        !           475:                } else if (!member) {
        !           476:                        /* This happens when the user did: $sxe[] = $value
        !           477:                         * and could also be E_PARSE, but we use this only during parsing
        !           478:                         * and this is during runtime.
        !           479:                         */
        !           480:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute");
        !           481:                        return FAILURE;
        !           482:                }
        !           483:        } else {
        !           484:                if (Z_TYPE_P(member) != IS_STRING) {
        !           485:                        trim_zv = *member;
        !           486:                        zval_copy_ctor(&trim_zv);
        !           487:                        convert_to_string(&trim_zv);
        !           488:                        php_trim(Z_STRVAL(trim_zv), Z_STRLEN(trim_zv), NULL, 0, &tmp_zv, 3 TSRMLS_CC);
        !           489:                        zval_dtor(&trim_zv);
        !           490:                        member = &tmp_zv;
        !           491:                }
        !           492: 
        !           493:                if (!Z_STRLEN_P(member)) {
        !           494:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write or create unnamed %s", attribs ? "attribute" : "element");
        !           495:                        if (member == &tmp_zv) {
        !           496:                                zval_dtor(&tmp_zv);
        !           497:                        }
        !           498:                        return FAILURE;
        !           499:                }
        !           500:        }
        !           501: 
        !           502:        GET_NODE(sxe, node);
        !           503: 
        !           504:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !           505:                attribs = 1;
        !           506:                elements = 0;
        !           507:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           508:                attr = (xmlAttrPtr)node;
        !           509:                test = sxe->iter.name != NULL;
        !           510:        } else if (sxe->iter.type != SXE_ITER_CHILD) {
        !           511:                mynode = node;
        !           512:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           513:                attr = node ? node->properties : NULL;
        !           514:                test = 0;
        !           515:                if (!member && node && node->parent &&
        !           516:                    node->parent->type == XML_DOCUMENT_NODE) {
        !           517:                        /* This happens when the user did: $sxe[] = $value
        !           518:                         * and could also be E_PARSE, but we use this only during parsing
        !           519:                         * and this is during runtime.
        !           520:                         */
        !           521:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute");
        !           522:                        return FAILURE;
        !           523:                }
        !           524:                if (attribs && !node && sxe->iter.type == SXE_ITER_ELEMENT) {
        !           525:                        node = xmlNewChild(mynode, mynode->ns, sxe->iter.name, NULL);
        !           526:                        attr = node->properties;
        !           527:                }
        !           528:        }
        !           529: 
        !           530:        mynode = node;
        !           531: 
        !           532:        if (value) {
        !           533:                switch (Z_TYPE_P(value)) {
        !           534:                        case IS_LONG:
        !           535:                        case IS_BOOL:
        !           536:                        case IS_DOUBLE:
        !           537:                        case IS_NULL:
        !           538:                                if (Z_REFCOUNT_P(value) > 1) {
        !           539:                                        value_copy = *value;
        !           540:                                        zval_copy_ctor(&value_copy);
        !           541:                                        value = &value_copy;
        !           542:                                }
        !           543:                                convert_to_string(value);
        !           544:                                break;
        !           545:                        case IS_STRING:
        !           546:                                break;
        !           547:                        case IS_OBJECT:
        !           548:                                if (Z_OBJCE_P(value) == sxe_class_entry) {
        !           549:                                        value = sxe_get_value(value TSRMLS_CC);
        !           550:                                        INIT_PZVAL(value);
        !           551:                                        new_value = 1;
        !           552:                                        break;
        !           553:                                }
        !           554:                                /* break is missing intentionally */
        !           555:                        default:
        !           556:                                if (member == &tmp_zv) {
        !           557:                                        zval_dtor(&tmp_zv);
        !           558:                                }
        !           559:                                zend_error(E_WARNING, "It is not yet possible to assign complex types to %s", attribs ? "attributes" : "properties");
        !           560:                                return FAILURE;
        !           561:                }
        !           562:        }
        !           563: 
        !           564:        if (node) {
        !           565:                if (attribs) {
        !           566:                        if (Z_TYPE_P(member) == IS_LONG) {
        !           567:                                while (attr && nodendx <= Z_LVAL_P(member)) {
        !           568:                                        if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           569:                                                if (nodendx == Z_LVAL_P(member)) {
        !           570:                                                        is_attr = 1;
        !           571:                                                        ++counter;
        !           572:                                                        break;
        !           573:                                                }
        !           574:                                                nodendx++;
        !           575:                                        }
        !           576:                                        attr = attr->next;
        !           577:                                }
        !           578:                        } else {
        !           579:                                while (attr) {
        !           580:                                        if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           581:                                                is_attr = 1;
        !           582:                                                ++counter;
        !           583:                                                break;
        !           584:                                        }
        !           585:                                        attr = attr->next;
        !           586:                                }
        !           587:                        }
        !           588: 
        !           589:                }
        !           590: 
        !           591:                if (elements) {
        !           592:                        if (!member || Z_TYPE_P(member) == IS_LONG) {
        !           593:                                if (node->type == XML_ATTRIBUTE_NODE) {
        !           594:                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create duplicate attribute");
        !           595:                                        return FAILURE;
        !           596:                                }
        !           597: 
        !           598:                                if (sxe->iter.type == SXE_ITER_NONE) {
        !           599:                                        newnode = node;
        !           600:                                        ++counter;
        !           601:                                        if (member && Z_LVAL_P(member) > 0) {
        !           602:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only 0 such elements exist", mynode->name, Z_LVAL_P(member));
        !           603:                                                retval = FAILURE;
        !           604:                                        }
        !           605:                                } else if (member) {
        !           606:                                        newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
        !           607:                                        if (newnode) {
        !           608:                                                ++counter;
        !           609:                                        }
        !           610:                                }
        !           611:                        } else {
        !           612:                                node = node->children;
        !           613:                                while (node) {
        !           614:                                        SKIP_TEXT(node);
        !           615: 
        !           616:                                        if (!xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member))) {
        !           617:                                                newnode = node;
        !           618:                                                ++counter;
        !           619:                                        }
        !           620: 
        !           621: next_iter:
        !           622:                                        node = node->next;
        !           623:                                }
        !           624:                        }
        !           625:                }
        !           626: 
        !           627:                if (counter == 1) {
        !           628:                        if (is_attr) {
        !           629:                                newnode = (xmlNodePtr) attr;
        !           630:                        }
        !           631:                        if (value) {
        !           632:                                while ((tempnode = (xmlNodePtr) newnode->children)) {
        !           633:                                        xmlUnlinkNode(tempnode);
        !           634:                                        php_libxml_node_free_resource((xmlNodePtr) tempnode TSRMLS_CC);
        !           635:                                }
        !           636:                                change_node_zval(newnode, value TSRMLS_CC);
        !           637:                        }
        !           638:                } else if (counter > 1) {
        !           639:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)");
        !           640:                        retval = FAILURE;
        !           641:                } else if (elements) {
        !           642:                        if (!node) {
        !           643:                                if (!member || Z_TYPE_P(member) == IS_LONG) {
        !           644:                                        newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
        !           645:                                } else {
        !           646:                                        newnode = xmlNewTextChild(mynode, mynode->ns, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
        !           647:                                }
        !           648:                        } else if (!member || Z_TYPE_P(member) == IS_LONG) {
        !           649:                                if (member && cnt < Z_LVAL_P(member)) {
        !           650:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only %ld such elements exist", mynode->name, Z_LVAL_P(member), cnt);
        !           651:                                        retval = FAILURE;
        !           652:                                }
        !           653:                                newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
        !           654:                        }
        !           655:                } else if (attribs) {
        !           656:                        if (Z_TYPE_P(member) == IS_LONG) {
        !           657:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot change attribute number %ld when only %d attributes exist", Z_LVAL_P(member), nodendx);
        !           658:                                retval = FAILURE;
        !           659:                        } else {
        !           660:                                newnode = (xmlNodePtr)xmlNewProp(node, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
        !           661:                        }
        !           662:                }
        !           663:        }
        !           664: 
        !           665:        if (member == &tmp_zv) {
        !           666:                zval_dtor(&tmp_zv);
        !           667:        }
        !           668:        if (pnewnode) {
        !           669:                *pnewnode = newnode;
        !           670:        }
        !           671:        if (value && value == &value_copy) {
        !           672:                zval_dtor(value);
        !           673:        }
        !           674:        if (new_value) {
        !           675:                zval_ptr_dtor(&value);
        !           676:        }
        !           677:        return retval;
        !           678: }
        !           679: /* }}} */
        !           680: 
        !           681: /* {{{ sxe_property_write()
        !           682:  */
        !           683: static void sxe_property_write(zval *object, zval *member, zval *value TSRMLS_DC)
        !           684: {
        !           685:        sxe_prop_dim_write(object, member, value, 1, 0, NULL TSRMLS_CC);
        !           686: }
        !           687: /* }}} */
        !           688: 
        !           689: /* {{{ sxe_dimension_write()
        !           690:  */
        !           691: static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_DC)
        !           692: {
        !           693:        sxe_prop_dim_write(object, offset, value, 0, 1, NULL TSRMLS_CC);
        !           694: }
        !           695: /* }}} */
        !           696: 
        !           697: static zval** sxe_property_get_adr(zval *object, zval *member TSRMLS_DC) /* {{{ */
        !           698: {
        !           699:        php_sxe_object *sxe;
        !           700:        xmlNodePtr      node;
        !           701:        zval           *return_value;
        !           702:        char           *name;
        !           703:        SXE_ITER        type;
        !           704: 
        !           705:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !           706: 
        !           707:        GET_NODE(sxe, node);
        !           708:        convert_to_string(member);
        !           709:        name = Z_STRVAL_P(member);
        !           710:        node = sxe_get_element_by_name(sxe, node, &name, &type TSRMLS_CC);
        !           711:        if (node) {
        !           712:                return NULL;
        !           713:        }
        !           714:        if (sxe_prop_dim_write(object, member, NULL, 1, 0, &node TSRMLS_CC) != SUCCESS) {
        !           715:                return NULL;
        !           716:        }
        !           717:        type = SXE_ITER_NONE;
        !           718:        name = NULL;
        !           719: 
        !           720:        MAKE_STD_ZVAL(return_value);
        !           721:        _node_as_zval(sxe, node, return_value, type, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !           722: 
        !           723:        sxe = php_sxe_fetch_object(return_value TSRMLS_CC);
        !           724:        if (sxe->tmp) {
        !           725:                zval_ptr_dtor(&sxe->tmp);
        !           726:        }
        !           727:        sxe->tmp = return_value;
        !           728:        Z_SET_ISREF_P(return_value);
        !           729: 
        !           730:        return &sxe->tmp;
        !           731: }
        !           732: /* }}} */
        !           733: 
        !           734: /* {{{ sxe_prop_dim_exists()
        !           735:  */
        !           736: static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend_bool elements, zend_bool attribs TSRMLS_DC)
        !           737: {
        !           738:        php_sxe_object *sxe;
        !           739:        xmlNodePtr      node;
        !           740:        xmlAttrPtr      attr = NULL;
        !           741:        int                             exists = 0;
        !           742:        int             test = 0;
        !           743:        zval            tmp_zv;
        !           744: 
        !           745:        if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) {
        !           746:                tmp_zv = *member;
        !           747:                zval_copy_ctor(&tmp_zv);
        !           748:                member = &tmp_zv;
        !           749:                convert_to_string(member);
        !           750:        }
        !           751: 
        !           752:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !           753: 
        !           754:        GET_NODE(sxe, node);
        !           755: 
        !           756:        if (Z_TYPE_P(member) == IS_LONG) {
        !           757:                if (sxe->iter.type != SXE_ITER_ATTRLIST) {
        !           758:                        attribs = 0;
        !           759:                        elements = 1;
        !           760:                        if (sxe->iter.type == SXE_ITER_CHILD) {
        !           761:                                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           762:                        }
        !           763:                }
        !           764:        }
        !           765: 
        !           766:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !           767:                attribs = 1;
        !           768:                elements = 0;
        !           769:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           770:                attr = (xmlAttrPtr)node;
        !           771:                test = sxe->iter.name != NULL;
        !           772:        } else if (sxe->iter.type != SXE_ITER_CHILD) {
        !           773:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           774:                attr = node ? node->properties : NULL;
        !           775:                test = 0;
        !           776:        }
        !           777: 
        !           778:        if (node) {
        !           779:                if (attribs) {
        !           780:                        if (Z_TYPE_P(member) == IS_LONG) {
        !           781:                                int     nodendx = 0;
        !           782: 
        !           783:                                while (attr && nodendx <= Z_LVAL_P(member)) {
        !           784:                                        if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           785:                                                if (nodendx == Z_LVAL_P(member)) {
        !           786:                                                        exists = 1;
        !           787:                                                        break;
        !           788:                                                }
        !           789:                                                nodendx++;
        !           790:                                        }
        !           791:                                        attr = attr->next;
        !           792:                                }
        !           793:                        } else {
        !           794:                                while (attr) {
        !           795:                                        if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           796:                                                exists = 1;
        !           797:                                                break;
        !           798:                                        }
        !           799: 
        !           800:                                        attr = attr->next;
        !           801:                                }
        !           802:                        }
        !           803:                        if (exists && check_empty == 1 &&
        !           804:                                (!attr->children || !attr->children->content || !attr->children->content[0] || !xmlStrcmp(attr->children->content, "0")) ) {
        !           805:                                /* Attribute with no content in it's text node */
        !           806:                                exists = 0;
        !           807:                        }
        !           808:                }
        !           809: 
        !           810:                if (elements) {
        !           811:                        if (Z_TYPE_P(member) == IS_LONG) {
        !           812:                                if (sxe->iter.type == SXE_ITER_CHILD) {
        !           813:                                        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           814:                                }
        !           815:                                node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
        !           816:                        }
        !           817:                        else {
        !           818:                                node = node->children;
        !           819:                                while (node) {
        !           820:                                        xmlNodePtr nnext;
        !           821:                                        nnext = node->next;
        !           822:                                        if ((node->type == XML_ELEMENT_NODE) && !xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member))) {
        !           823:                                                break;
        !           824:                                        }
        !           825:                                        node = nnext;
        !           826:                                }
        !           827:                        }
        !           828:                        if (node) {
        !           829:                                exists = 1;
        !           830:                                 if (check_empty == 1 &&
        !           831:                                        (!node->children || (node->children->type == XML_TEXT_NODE && !node->children->next &&
        !           832:                                                (!node->children->content || !node->children->content[0] || !xmlStrcmp(node->children->content, "0")))) ) {
        !           833:                                        exists = 0;
        !           834:                                }
        !           835:                        }
        !           836:                }
        !           837:        }
        !           838: 
        !           839:        if (member == &tmp_zv) {
        !           840:                zval_dtor(&tmp_zv);
        !           841:        }
        !           842: 
        !           843:        return exists;
        !           844: }
        !           845: /* }}} */
        !           846: 
        !           847: /* {{{ sxe_property_exists()
        !           848:  */
        !           849: static int sxe_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC)
        !           850: {
        !           851:        return sxe_prop_dim_exists(object, member, check_empty, 1, 0 TSRMLS_CC);
        !           852: }
        !           853: /* }}} */
        !           854: 
        !           855: /* {{{ sxe_property_exists()
        !           856:  */
        !           857: static int sxe_dimension_exists(zval *object, zval *member, int check_empty TSRMLS_DC)
        !           858: {
        !           859:        return sxe_prop_dim_exists(object, member, check_empty, 0, 1 TSRMLS_CC);
        !           860: }
        !           861: /* }}} */
        !           862: 
        !           863: /* {{{ sxe_prop_dim_delete()
        !           864:  */
        !           865: static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements, zend_bool attribs TSRMLS_DC)
        !           866: {
        !           867:        php_sxe_object *sxe;
        !           868:        xmlNodePtr      node;
        !           869:        xmlNodePtr      nnext;
        !           870:        xmlAttrPtr      attr = NULL;
        !           871:        xmlAttrPtr      anext;
        !           872:        zval            tmp_zv;
        !           873:        int             test = 0;
        !           874: 
        !           875:        if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) {
        !           876:                tmp_zv = *member;
        !           877:                zval_copy_ctor(&tmp_zv);
        !           878:                member = &tmp_zv;
        !           879:                convert_to_string(member);
        !           880:        }
        !           881: 
        !           882:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !           883: 
        !           884:        GET_NODE(sxe, node);
        !           885: 
        !           886:        if (Z_TYPE_P(member) == IS_LONG) {
        !           887:                if (sxe->iter.type != SXE_ITER_ATTRLIST) {
        !           888:                        attribs = 0;
        !           889:                        elements = 1;
        !           890:                        if (sxe->iter.type == SXE_ITER_CHILD) {
        !           891:                                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           892:                        }
        !           893:                }
        !           894:        }
        !           895: 
        !           896:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !           897:                attribs = 1;
        !           898:                elements = 0;
        !           899:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           900:                attr = (xmlAttrPtr)node;
        !           901:                test = sxe->iter.name != NULL;
        !           902:        } else if (sxe->iter.type != SXE_ITER_CHILD) {
        !           903:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           904:                attr = node ? node->properties : NULL;
        !           905:                test = 0;
        !           906:        }
        !           907: 
        !           908:        if (node) {
        !           909:                if (attribs) {
        !           910:                        if (Z_TYPE_P(member) == IS_LONG) {
        !           911:                                int     nodendx = 0;
        !           912: 
        !           913:                                while (attr && nodendx <= Z_LVAL_P(member)) {
        !           914:                                        if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           915:                                                if (nodendx == Z_LVAL_P(member)) {
        !           916:                                                        xmlUnlinkNode((xmlNodePtr) attr);
        !           917:                                                        php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC);
        !           918:                                                        break;
        !           919:                                                }
        !           920:                                                nodendx++;
        !           921:                                        }
        !           922:                                        attr = attr->next;
        !           923:                                }
        !           924:                        } else {
        !           925:                                while (attr) {
        !           926:                                        anext = attr->next;
        !           927:                                        if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, (xmlChar *)Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !           928:                                                xmlUnlinkNode((xmlNodePtr) attr);
        !           929:                                                php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC);
        !           930:                                                break;
        !           931:                                        }
        !           932:                                        attr = anext;
        !           933:                                }
        !           934:                        }
        !           935:                }
        !           936: 
        !           937:                if (elements) {
        !           938:                        if (Z_TYPE_P(member) == IS_LONG) {
        !           939:                                if (sxe->iter.type == SXE_ITER_CHILD) {
        !           940:                                        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !           941:                                }
        !           942:                                node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
        !           943:                                if (node) {
        !           944:                                        xmlUnlinkNode(node);
        !           945:                                        php_libxml_node_free_resource(node TSRMLS_CC);
        !           946:                                }
        !           947:                        } else {
        !           948:                                node = node->children;
        !           949:                                while (node) {
        !           950:                                        nnext = node->next;
        !           951: 
        !           952:                                        SKIP_TEXT(node);
        !           953: 
        !           954:                                        if (!xmlStrcmp(node->name, (xmlChar *)Z_STRVAL_P(member))) {
        !           955:                                                xmlUnlinkNode(node);
        !           956:                                                php_libxml_node_free_resource(node TSRMLS_CC);
        !           957:                                        }
        !           958: 
        !           959: next_iter:
        !           960:                                        node = nnext;
        !           961:                                }
        !           962:                        }
        !           963:                }
        !           964:        }
        !           965: 
        !           966:        if (member == &tmp_zv) {
        !           967:                zval_dtor(&tmp_zv);
        !           968:        }
        !           969: }
        !           970: /* }}} */
        !           971: 
        !           972: /* {{{ sxe_property_delete()
        !           973:  */
        !           974: static void sxe_property_delete(zval *object, zval *member TSRMLS_DC)
        !           975: {
        !           976:        sxe_prop_dim_delete(object, member, 1, 0 TSRMLS_CC);
        !           977: }
        !           978: /* }}} */
        !           979: 
        !           980: /* {{{ sxe_dimension_unset()
        !           981:  */
        !           982: static void sxe_dimension_delete(zval *object, zval *offset TSRMLS_DC)
        !           983: {
        !           984:        sxe_prop_dim_delete(object, offset, 0, 1 TSRMLS_CC);
        !           985: }
        !           986: /* }}} */
        !           987: 
        !           988: static inline char * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) /* {{{ */
        !           989: {
        !           990:        xmlChar *tmp = xmlNodeListGetString(doc, list, inLine);
        !           991:        char    *res;
        !           992:        
        !           993:        if (tmp) {
        !           994:                res = estrdup((char*)tmp);
        !           995:                xmlFree(tmp);
        !           996:        } else {
        !           997:                res = STR_EMPTY_ALLOC();
        !           998:        }
        !           999: 
        !          1000:        return res;
        !          1001: }
        !          1002: /* }}} */
        !          1003: 
        !          1004: /* {{{ _get_base_node_value()
        !          1005:  */
        !          1006: static void _get_base_node_value(php_sxe_object *sxe_ref, xmlNodePtr node, zval **value, xmlChar *nsprefix, int isprefix TSRMLS_DC)
        !          1007: {
        !          1008:        php_sxe_object *subnode;
        !          1009:        xmlChar        *contents;
        !          1010: 
        !          1011:        MAKE_STD_ZVAL(*value);
        !          1012: 
        !          1013:        if (node->children && node->children->type == XML_TEXT_NODE && !xmlIsBlankNode(node->children)) {
        !          1014:                contents = xmlNodeListGetString(node->doc, node->children, 1);
        !          1015:                if (contents) {
        !          1016:                        ZVAL_STRING(*value, (char *)contents, 1);
        !          1017:                        xmlFree(contents);
        !          1018:                }
        !          1019:        } else {
        !          1020:                subnode = php_sxe_object_new(sxe_ref->zo.ce TSRMLS_CC);
        !          1021:                subnode->document = sxe_ref->document;
        !          1022:                subnode->document->refcount++;
        !          1023:                if (nsprefix && *nsprefix) {
        !          1024:                        subnode->iter.nsprefix = xmlStrdup((xmlChar *)nsprefix);
        !          1025:                        subnode->iter.isprefix = isprefix;
        !          1026:                }
        !          1027:                php_libxml_increment_node_ptr((php_libxml_node_object *)subnode, node, NULL TSRMLS_CC);
        !          1028: 
        !          1029:                (*value)->type = IS_OBJECT;
        !          1030:                (*value)->value.obj = php_sxe_register_object(subnode TSRMLS_CC);
        !          1031:                /*zval_add_ref(value);*/
        !          1032:        }
        !          1033: }
        !          1034: /* }}} */
        !          1035: 
        !          1036: static void sxe_properties_add(HashTable *rv, char *name, int namelen, zval *value TSRMLS_DC) /* {{{ */
        !          1037: {
        !          1038:        zval  **data_ptr;
        !          1039:        zval  *newptr;
        !          1040:        ulong h = zend_hash_func(name, namelen);
        !          1041: 
        !          1042:        if (zend_hash_quick_find(rv, name, namelen, h, (void **) &data_ptr) == SUCCESS) {
        !          1043:                if (Z_TYPE_PP(data_ptr) == IS_ARRAY) {
        !          1044:                        zend_hash_next_index_insert(Z_ARRVAL_PP(data_ptr), &value, sizeof(zval *), NULL);
        !          1045:                } else {
        !          1046:                        MAKE_STD_ZVAL(newptr);
        !          1047:                        array_init(newptr);
        !          1048: 
        !          1049:                        zval_add_ref(data_ptr);
        !          1050:                        zend_hash_next_index_insert(Z_ARRVAL_P(newptr), data_ptr, sizeof(zval *), NULL);
        !          1051:                        zend_hash_next_index_insert(Z_ARRVAL_P(newptr), &value, sizeof(zval *), NULL);
        !          1052: 
        !          1053:                        zend_hash_quick_update(rv, name, namelen, h, &newptr, sizeof(zval *), NULL);
        !          1054:                }
        !          1055:        } else {
        !          1056:                zend_hash_quick_update(rv, name, namelen, h, &value, sizeof(zval *), NULL);
        !          1057:        }
        !          1058: }
        !          1059: /* }}} */
        !          1060: 
        !          1061: static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ */
        !          1062: {
        !          1063:        zval            *value;
        !          1064:        zval            *zattr;
        !          1065:        HashTable       *rv;
        !          1066:        php_sxe_object  *sxe;
        !          1067:        char            *name;
        !          1068:        xmlNodePtr       node;
        !          1069:        xmlAttrPtr       attr;
        !          1070:        int              namelen;
        !          1071:        int              test;
        !          1072: 
        !          1073:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !          1074: 
        !          1075:        if (is_debug) {
        !          1076:                ALLOC_HASHTABLE(rv);
        !          1077:                zend_hash_init(rv, 0, NULL, ZVAL_PTR_DTOR, 0);
        !          1078:        }
        !          1079:        else if (sxe->properties) {
        !          1080:                if (GC_G(gc_active)) {
        !          1081:                        return sxe->properties;
        !          1082:                }
        !          1083:                zend_hash_clean(sxe->properties);
        !          1084:                rv = sxe->properties;
        !          1085:        } else {
        !          1086:                if (GC_G(gc_active)) {
        !          1087:                        return NULL;
        !          1088:                }
        !          1089:                ALLOC_HASHTABLE(rv);
        !          1090:                zend_hash_init(rv, 0, NULL, ZVAL_PTR_DTOR, 0);
        !          1091:                sxe->properties = rv;
        !          1092:        }
        !          1093: 
        !          1094:        GET_NODE(sxe, node);
        !          1095:        if (!node) {
        !          1096:                return rv;
        !          1097:        }
        !          1098:        if (is_debug || sxe->iter.type != SXE_ITER_CHILD) {
        !          1099:                if (sxe->iter.type == SXE_ITER_ELEMENT) {
        !          1100:                        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1101:                }
        !          1102:                if (!node || node->type != XML_ENTITY_DECL) {
        !          1103:                        attr = node ? (xmlAttrPtr)node->properties : NULL;
        !          1104:                        zattr = NULL;
        !          1105:                        test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST;
        !          1106:                        while (attr) {
        !          1107:                                if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) {
        !          1108:                                        MAKE_STD_ZVAL(value);
        !          1109:                                        ZVAL_STRING(value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1), 0);
        !          1110:                                        namelen = xmlStrlen(attr->name) + 1;
        !          1111:                                        if (!zattr) {
        !          1112:                                                MAKE_STD_ZVAL(zattr);
        !          1113:                                                array_init(zattr);
        !          1114:                                                sxe_properties_add(rv, "@attributes", sizeof("@attributes"), zattr TSRMLS_CC);
        !          1115:                                        }
        !          1116:                                        add_assoc_zval_ex(zattr, (char*)attr->name, namelen, value);
        !          1117:                                }
        !          1118:                                attr = attr->next;
        !          1119:                        }
        !          1120:                }
        !          1121:        }
        !          1122: 
        !          1123:        GET_NODE(sxe, node);
        !          1124:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1125:        if (node && sxe->iter.type != SXE_ITER_ATTRLIST) {
        !          1126:                if (node->type == XML_ATTRIBUTE_NODE) {
        !          1127:                        MAKE_STD_ZVAL(value);
        !          1128:                        ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node->children, 1), 0);
        !          1129:                        zend_hash_next_index_insert(rv, &value, sizeof(zval *), NULL);
        !          1130:                        node = NULL;
        !          1131:                } else if (sxe->iter.type != SXE_ITER_CHILD) {
        !          1132:                        node = node->children;
        !          1133:                }
        !          1134: 
        !          1135:                while (node) {
        !          1136:                        if (node->children != NULL || node->prev != NULL || node->next != NULL) {
        !          1137:                                SKIP_TEXT(node);
        !          1138:                        } else {
        !          1139:                                if (node->type == XML_TEXT_NODE) {
        !          1140:                                        const xmlChar *cur = node->content;
        !          1141:                                        
        !          1142:                                        if (*cur != 0) {
        !          1143:                                                MAKE_STD_ZVAL(value);
        !          1144:                                                ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node, 1), 0);
        !          1145:                                                zend_hash_next_index_insert(rv, &value, sizeof(zval *), NULL);
        !          1146:                                        }
        !          1147:                                        goto next_iter;
        !          1148:                                }
        !          1149:                        }
        !          1150: 
        !          1151:                        if (node->type == XML_ELEMENT_NODE && (! match_ns(sxe, node, sxe->iter.nsprefix, sxe->iter.isprefix))) {
        !          1152:                                goto next_iter;
        !          1153:                        }
        !          1154: 
        !          1155:                        name = (char *) node->name;
        !          1156:                        if (!name) {
        !          1157:                                goto next_iter;
        !          1158:                        } else {
        !          1159:                                namelen = xmlStrlen(node->name) + 1;
        !          1160:                        }
        !          1161: 
        !          1162:                        _get_base_node_value(sxe, node, &value, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
        !          1163: 
        !          1164:                        sxe_properties_add(rv, name, namelen, value TSRMLS_CC);
        !          1165: next_iter:
        !          1166:                        node = node->next;
        !          1167:                }
        !          1168:        }
        !          1169: 
        !          1170:        return rv;
        !          1171: }
        !          1172: /* }}} */
        !          1173: 
        !          1174: static HashTable * sxe_get_properties(zval *object TSRMLS_DC) /* {{{ */
        !          1175: {
        !          1176:        return sxe_get_prop_hash(object, 0 TSRMLS_CC);
        !          1177: }
        !          1178: /* }}} */
        !          1179: 
        !          1180: static HashTable * sxe_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
        !          1181: {
        !          1182:        *is_temp = 1;
        !          1183:        return sxe_get_prop_hash(object, 1 TSRMLS_CC);
        !          1184: }
        !          1185: /* }}} */
        !          1186: 
        !          1187: static int sxe_objects_compare(zval *object1, zval *object2 TSRMLS_DC) /* {{{ */
        !          1188: {
        !          1189:        php_sxe_object *sxe1;
        !          1190:        php_sxe_object *sxe2;
        !          1191: 
        !          1192:        sxe1 = php_sxe_fetch_object(object1 TSRMLS_CC);
        !          1193:        sxe2 = php_sxe_fetch_object(object2 TSRMLS_CC);
        !          1194: 
        !          1195:        if (sxe1->node == NULL) {
        !          1196:                if (sxe2->node) {
        !          1197:                        return 1;
        !          1198:                } else if (sxe1->document->ptr == sxe2->document->ptr) {
        !          1199:                        return 0;
        !          1200:                }
        !          1201:        } else {
        !          1202:                return !(sxe1->node == sxe2->node);
        !          1203:        }
        !          1204:        return 1;
        !          1205: }
        !          1206: /* }}} */
        !          1207: 
        !          1208: /* {{{ proto array SimpleXMLElement::xpath(string path)
        !          1209:    Runs XPath query on the XML data */
        !          1210: SXE_METHOD(xpath)
        !          1211: {
        !          1212:        php_sxe_object    *sxe;
        !          1213:        zval              *value;
        !          1214:        char              *query;
        !          1215:        int                query_len;
        !          1216:        int                i;
        !          1217:        int                nsnbr = 0;
        !          1218:        xmlNsPtr          *ns = NULL;
        !          1219:        xmlXPathObjectPtr  retval;
        !          1220:        xmlNodeSetPtr      result;
        !          1221:        xmlNodePtr                 nodeptr;
        !          1222: 
        !          1223:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) {
        !          1224:                return;
        !          1225:        }
        !          1226: 
        !          1227:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1228: 
        !          1229:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !          1230:                return; /* attributes don't have attributes */
        !          1231:        }
        !          1232: 
        !          1233:        if (!sxe->xpath) {
        !          1234:                sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr);
        !          1235:        }
        !          1236:        if (!sxe->node) {
        !          1237:                php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL TSRMLS_CC);
        !          1238:        }
        !          1239: 
        !          1240:        nodeptr = php_sxe_get_first_node(sxe, sxe->node->node TSRMLS_CC);
        !          1241: 
        !          1242:        sxe->xpath->node = nodeptr;
        !          1243: 
        !          1244:        ns = xmlGetNsList((xmlDocPtr) sxe->document->ptr, nodeptr);
        !          1245:        if (ns != NULL) {
        !          1246:                while (ns[nsnbr] != NULL) {
        !          1247:                        nsnbr++;
        !          1248:                }
        !          1249:        }
        !          1250: 
        !          1251:        sxe->xpath->namespaces = ns;
        !          1252:        sxe->xpath->nsNr = nsnbr;
        !          1253: 
        !          1254:        retval = xmlXPathEval((xmlChar *)query, sxe->xpath);
        !          1255:        if (ns != NULL) {
        !          1256:                xmlFree(ns);
        !          1257:                sxe->xpath->namespaces = NULL;
        !          1258:                sxe->xpath->nsNr = 0;
        !          1259:        }
        !          1260: 
        !          1261:        if (!retval) {
        !          1262:                RETURN_FALSE;
        !          1263:        }
        !          1264: 
        !          1265:        result = retval->nodesetval;
        !          1266: 
        !          1267:        array_init(return_value);
        !          1268:                
        !          1269:        if (result != NULL) {
        !          1270:                for (i = 0; i < result->nodeNr; ++i) {
        !          1271:                        nodeptr = result->nodeTab[i];
        !          1272:                        if (nodeptr->type == XML_TEXT_NODE || nodeptr->type == XML_ELEMENT_NODE || nodeptr->type == XML_ATTRIBUTE_NODE) {
        !          1273:                                MAKE_STD_ZVAL(value);
        !          1274:                                /**
        !          1275:                                 * Detect the case where the last selector is text(), simplexml
        !          1276:                                 * always accesses the text() child by default, therefore we assign
        !          1277:                                 * to the parent node.
        !          1278:                                 */
        !          1279:                                if (nodeptr->type == XML_TEXT_NODE) {
        !          1280:                                        _node_as_zval(sxe, nodeptr->parent, value, SXE_ITER_NONE, NULL, NULL, 0 TSRMLS_CC);
        !          1281:                                } else if (nodeptr->type == XML_ATTRIBUTE_NODE) {
        !          1282:                                        _node_as_zval(sxe, nodeptr->parent, value, SXE_ITER_ATTRLIST, (char*)nodeptr->name, nodeptr->ns ? (xmlChar *)nodeptr->ns->href : NULL, 0 TSRMLS_CC);
        !          1283:                                } else {
        !          1284:                                        _node_as_zval(sxe, nodeptr, value, SXE_ITER_NONE, NULL, NULL, 0 TSRMLS_CC);
        !          1285:                                }
        !          1286: 
        !          1287:                                add_next_index_zval(return_value, value);
        !          1288:                        }
        !          1289:                }
        !          1290:        }
        !          1291: 
        !          1292:        xmlXPathFreeObject(retval);
        !          1293: }
        !          1294: /* }}} */
        !          1295: 
        !          1296: /* {{{ proto bool SimpleXMLElement::registerXPathNamespace(string prefix, string ns)
        !          1297:    Creates a prefix/ns context for the next XPath query */
        !          1298: SXE_METHOD(registerXPathNamespace)
        !          1299: {
        !          1300:        php_sxe_object    *sxe;
        !          1301:        int prefix_len, ns_uri_len;
        !          1302:        char *prefix, *ns_uri;
        !          1303: 
        !          1304:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) {
        !          1305:                return;
        !          1306:        }
        !          1307: 
        !          1308:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1309:        if (!sxe->xpath) {
        !          1310:                sxe->xpath = xmlXPathNewContext((xmlDocPtr) sxe->document->ptr);
        !          1311:        }
        !          1312: 
        !          1313:        if (xmlXPathRegisterNs(sxe->xpath, (xmlChar *)prefix, (xmlChar *)ns_uri) != 0) {
        !          1314:                RETURN_FALSE
        !          1315:        }
        !          1316:        RETURN_TRUE;
        !          1317: }
        !          1318: 
        !          1319: /* }}} */
        !          1320: 
        !          1321: /* {{{ proto string SimpleXMLElement::asXML([string filename])
        !          1322:    Return a well-formed XML string based on SimpleXML element */
        !          1323: SXE_METHOD(asXML)
        !          1324: {
        !          1325:        php_sxe_object     *sxe;
        !          1326:        xmlNodePtr          node;
        !          1327:        xmlOutputBufferPtr  outbuf;
        !          1328:        xmlChar            *strval;
        !          1329:        int                 strval_len;
        !          1330:        char               *filename;
        !          1331:        int                 filename_len;
        !          1332: 
        !          1333:        if (ZEND_NUM_ARGS() > 1) {
        !          1334:                RETURN_FALSE;
        !          1335:        }
        !          1336: 
        !          1337:        if (ZEND_NUM_ARGS() == 1) {
        !          1338:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
        !          1339:                        RETURN_FALSE;
        !          1340:                }
        !          1341: 
        !          1342:                sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1343:                GET_NODE(sxe, node);
        !          1344:                node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1345: 
        !          1346:                if (node) {
        !          1347:                        if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
        !          1348:                                int bytes;
        !          1349:                                bytes = xmlSaveFile(filename, (xmlDocPtr) sxe->document->ptr);
        !          1350:                                if (bytes == -1) {
        !          1351:                                        RETURN_FALSE;
        !          1352:                                } else {
        !          1353:                                        RETURN_TRUE;
        !          1354:                                }
        !          1355:                        } else {
        !          1356:                                outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0);
        !          1357: 
        !          1358:                                if (outbuf == NULL) {
        !          1359:                                        RETURN_FALSE;
        !          1360:                                }
        !          1361: 
        !          1362:                                xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, NULL);
        !          1363:                                xmlOutputBufferClose(outbuf);
        !          1364:                                RETURN_TRUE;
        !          1365:                        }
        !          1366:                } else {
        !          1367:                        RETURN_FALSE;
        !          1368:                }
        !          1369:        }
        !          1370: 
        !          1371:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1372:        GET_NODE(sxe, node);
        !          1373:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1374: 
        !          1375:        if (node) {
        !          1376:                if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
        !          1377:                        xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, ((xmlDocPtr) sxe->document->ptr)->encoding);
        !          1378:                        RETVAL_STRINGL((char *)strval, strval_len, 1);
        !          1379:                        xmlFree(strval);
        !          1380:                } else {
        !          1381:                        /* Should we be passing encoding information instead of NULL? */
        !          1382:                        outbuf = xmlAllocOutputBuffer(NULL);
        !          1383: 
        !          1384:                        if (outbuf == NULL) {
        !          1385:                                RETURN_FALSE;
        !          1386:                        }
        !          1387: 
        !          1388:                        xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding);
        !          1389:                        xmlOutputBufferFlush(outbuf);
        !          1390:                        RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1);
        !          1391:                        xmlOutputBufferClose(outbuf);
        !          1392:                }
        !          1393:        } else {
        !          1394:                RETVAL_FALSE;
        !          1395:        }
        !          1396: }
        !          1397: /* }}} */
        !          1398: 
        !          1399: #define SXE_NS_PREFIX(ns) (ns->prefix ? (char*)ns->prefix : "")
        !          1400: 
        !          1401: static inline void sxe_add_namespace_name(zval *return_value, xmlNsPtr ns) /* {{{ */
        !          1402: {
        !          1403:        char *prefix = SXE_NS_PREFIX(ns);
        !          1404:        if (zend_hash_exists(Z_ARRVAL_P(return_value), prefix, strlen(prefix) + 1) == 0) {
        !          1405:                add_assoc_string(return_value, prefix, (char*)ns->href, 1);
        !          1406:        }
        !          1407: }
        !          1408: /* }}} */
        !          1409: 
        !          1410: static void sxe_add_namespaces(php_sxe_object *sxe, xmlNodePtr node, zend_bool recursive, zval *return_value TSRMLS_DC) /* {{{ */
        !          1411: {
        !          1412:        xmlAttrPtr  attr;
        !          1413: 
        !          1414:        if (node->ns) {
        !          1415:                sxe_add_namespace_name(return_value, node->ns);
        !          1416:        }
        !          1417: 
        !          1418:        attr = node->properties;
        !          1419:        while (attr) {
        !          1420:                if (attr->ns) {
        !          1421:                        sxe_add_namespace_name(return_value, attr->ns);
        !          1422:                }
        !          1423:                attr = attr->next;
        !          1424:        }
        !          1425: 
        !          1426:        if (recursive) {
        !          1427:                node = node->children;
        !          1428:                while (node) {
        !          1429:                        if (node->type == XML_ELEMENT_NODE) {
        !          1430:                                sxe_add_namespaces(sxe, node, recursive, return_value TSRMLS_CC);
        !          1431:                        }
        !          1432:                        node = node->next;
        !          1433:                }
        !          1434:        }
        !          1435: } /* }}} */
        !          1436: 
        !          1437: /* {{{ proto string SimpleXMLElement::getNamespaces([bool recursve])
        !          1438:    Return all namespaces in use */
        !          1439: SXE_METHOD(getNamespaces)
        !          1440: {
        !          1441:        zend_bool           recursive = 0;
        !          1442:        php_sxe_object     *sxe;
        !          1443:        xmlNodePtr          node;
        !          1444: 
        !          1445:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &recursive) == FAILURE) {
        !          1446:                return;
        !          1447:        }
        !          1448: 
        !          1449:        array_init(return_value);
        !          1450: 
        !          1451:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1452:        GET_NODE(sxe, node);
        !          1453:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1454: 
        !          1455:        if (node) {
        !          1456:                if (node->type == XML_ELEMENT_NODE) {
        !          1457:                        sxe_add_namespaces(sxe, node, recursive, return_value TSRMLS_CC);
        !          1458:                } else if (node->type == XML_ATTRIBUTE_NODE && node->ns) {
        !          1459:                        sxe_add_namespace_name(return_value, node->ns);
        !          1460:                }
        !          1461:        }
        !          1462: }
        !          1463: /* }}} */
        !          1464: 
        !          1465: static void sxe_add_registered_namespaces(php_sxe_object *sxe, xmlNodePtr node, zend_bool recursive, zval *return_value TSRMLS_DC) /* {{{ */
        !          1466: {
        !          1467:        xmlNsPtr ns;
        !          1468: 
        !          1469:        if (node->type == XML_ELEMENT_NODE) {
        !          1470:                ns = node->nsDef;
        !          1471:                while (ns != NULL) {
        !          1472:                        sxe_add_namespace_name(return_value, ns);
        !          1473:                        ns = ns->next;
        !          1474:                }
        !          1475:                if (recursive) {
        !          1476:                        node = node->children;
        !          1477:                        while (node) {
        !          1478:                                sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC);
        !          1479:                                node = node->next;
        !          1480:                        }
        !          1481:                }
        !          1482:        }
        !          1483: }
        !          1484: /* }}} */
        !          1485: 
        !          1486: /* {{{ proto string SimpleXMLElement::getDocNamespaces([bool recursive])
        !          1487:    Return all namespaces registered with document */
        !          1488: SXE_METHOD(getDocNamespaces)
        !          1489: {
        !          1490:        zend_bool           recursive = 0;
        !          1491:        php_sxe_object     *sxe;
        !          1492: 
        !          1493:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &recursive) == FAILURE) {
        !          1494:                return;
        !          1495:        }
        !          1496: 
        !          1497:        array_init(return_value);
        !          1498: 
        !          1499:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1500: 
        !          1501:        sxe_add_registered_namespaces(sxe, xmlDocGetRootElement((xmlDocPtr)sxe->document->ptr), recursive, return_value TSRMLS_CC);
        !          1502: }
        !          1503: /* }}} */
        !          1504: 
        !          1505: /* {{{ proto object SimpleXMLElement::children([string ns [, bool is_prefix]])
        !          1506:    Finds children of given node */
        !          1507: SXE_METHOD(children)
        !          1508: {
        !          1509:        php_sxe_object *sxe;
        !          1510:        char           *nsprefix = NULL;
        !          1511:        int             nsprefix_len = 0;
        !          1512:        xmlNodePtr      node;
        !          1513:        zend_bool       isprefix = 0;
        !          1514: 
        !          1515:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!b", &nsprefix, &nsprefix_len, &isprefix) == FAILURE) {
        !          1516:                return;
        !          1517:        }
        !          1518: 
        !          1519:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1520: 
        !          1521:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !          1522:                return; /* attributes don't have attributes */
        !          1523:        }
        !          1524: 
        !          1525:        GET_NODE(sxe, node);
        !          1526:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1527: 
        !          1528:        _node_as_zval(sxe, node, return_value, SXE_ITER_CHILD, NULL, (xmlChar *)nsprefix, isprefix TSRMLS_CC);
        !          1529: 
        !          1530: }
        !          1531: /* }}} */
        !          1532: 
        !          1533: /* {{{ proto object SimpleXMLElement::getName()
        !          1534:    Finds children of given node */
        !          1535: SXE_METHOD(getName)
        !          1536: {
        !          1537:        php_sxe_object *sxe;
        !          1538:        xmlNodePtr      node;
        !          1539:        int             namelen;
        !          1540: 
        !          1541:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1542: 
        !          1543:        GET_NODE(sxe, node);
        !          1544:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1545:        if (node) {
        !          1546:                namelen = xmlStrlen(node->name);
        !          1547:                RETURN_STRINGL((char*)node->name, namelen, 1);
        !          1548:        } else {
        !          1549:                RETURN_EMPTY_STRING();
        !          1550:        }
        !          1551: }
        !          1552: /* }}} */
        !          1553: 
        !          1554: /* {{{ proto array SimpleXMLElement::attributes([string ns [, bool is_prefix]])
        !          1555:    Identifies an element's attributes */
        !          1556: SXE_METHOD(attributes)
        !          1557: {
        !          1558:        php_sxe_object *sxe;
        !          1559:        char           *nsprefix = NULL;
        !          1560:        int             nsprefix_len = 0;
        !          1561:        xmlNodePtr      node;
        !          1562:        zend_bool       isprefix = 0;
        !          1563: 
        !          1564:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!b", &nsprefix, &nsprefix_len, &isprefix) == FAILURE) {
        !          1565:                return;
        !          1566:        }
        !          1567: 
        !          1568:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1569:        GET_NODE(sxe, node);
        !          1570: 
        !          1571:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !          1572:                return; /* attributes don't have attributes */
        !          1573:        }
        !          1574: 
        !          1575:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1576: 
        !          1577:        _node_as_zval(sxe, node, return_value, SXE_ITER_ATTRLIST, NULL, (xmlChar *)nsprefix, isprefix TSRMLS_CC);
        !          1578: }
        !          1579: /* }}} */
        !          1580: 
        !          1581: /* {{{ proto void SimpleXMLElement::addChild(string qName [, string value [, string ns]])
        !          1582:    Add Element with optional namespace information */
        !          1583: SXE_METHOD(addChild)
        !          1584: {
        !          1585:        php_sxe_object *sxe;
        !          1586:        char           *qname, *value = NULL, *nsuri = NULL;
        !          1587:        int             qname_len, value_len = 0, nsuri_len = 0;
        !          1588:        xmlNodePtr      node, newnode;
        !          1589:        xmlNsPtr        nsptr = NULL;
        !          1590:        xmlChar        *localname, *prefix = NULL;
        !          1591: 
        !          1592:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!",
        !          1593:                &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) {
        !          1594:                return;
        !          1595:        }
        !          1596: 
        !          1597:        if (qname_len == 0) {
        !          1598:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Element name is required");
        !          1599:                return;
        !          1600:        }
        !          1601: 
        !          1602:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1603:        GET_NODE(sxe, node);
        !          1604: 
        !          1605:        if (sxe->iter.type == SXE_ITER_ATTRLIST) {
        !          1606:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to attributes");
        !          1607:                return;
        !          1608:        }
        !          1609: 
        !          1610:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1611: 
        !          1612:        if (node == NULL) {
        !          1613:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add child. Parent is not a permanent member of the XML tree");
        !          1614:                return;
        !          1615:        }
        !          1616: 
        !          1617:        localname = xmlSplitQName2((xmlChar *)qname, &prefix);
        !          1618:        if (localname == NULL) {
        !          1619:                localname = xmlStrdup((xmlChar *)qname);
        !          1620:        }
        !          1621: 
        !          1622:        newnode = xmlNewChild(node, NULL, localname, (xmlChar *)value);
        !          1623: 
        !          1624:        if (nsuri != NULL) {
        !          1625:                if (nsuri_len == 0) {
        !          1626:                        newnode->ns = NULL;
        !          1627:                        nsptr = xmlNewNs(newnode, (xmlChar *)nsuri, prefix);
        !          1628:                } else {
        !          1629:                        nsptr = xmlSearchNsByHref(node->doc, node, (xmlChar *)nsuri);
        !          1630:                        if (nsptr == NULL) {
        !          1631:                                nsptr = xmlNewNs(newnode, (xmlChar *)nsuri, prefix);
        !          1632:                        }
        !          1633:                        newnode->ns = nsptr;
        !          1634:                }
        !          1635:        }
        !          1636: 
        !          1637:        _node_as_zval(sxe, newnode, return_value, SXE_ITER_NONE, (char *)localname, prefix, 0 TSRMLS_CC);
        !          1638: 
        !          1639:        xmlFree(localname);
        !          1640:        if (prefix != NULL) {
        !          1641:                xmlFree(prefix);
        !          1642:        }
        !          1643: }
        !          1644: /* }}} */
        !          1645: 
        !          1646: /* {{{ proto void SimpleXMLElement::addAttribute(string qName, string value [,string ns])
        !          1647:    Add Attribute with optional namespace information */
        !          1648: SXE_METHOD(addAttribute)
        !          1649: {
        !          1650:        php_sxe_object *sxe;
        !          1651:        char           *qname, *value = NULL, *nsuri = NULL;
        !          1652:        int             qname_len, value_len = 0, nsuri_len = 0;
        !          1653:        xmlNodePtr      node;
        !          1654:        xmlAttrPtr      attrp = NULL;
        !          1655:        xmlNsPtr        nsptr = NULL;
        !          1656:        xmlChar        *localname, *prefix = NULL;
        !          1657: 
        !          1658:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s!",
        !          1659:                &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) {
        !          1660:                return;
        !          1661:        }
        !          1662: 
        !          1663:        if (qname_len == 0) {
        !          1664:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute name is required");
        !          1665:                return;
        !          1666:        }
        !          1667: 
        !          1668:        sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1669:        GET_NODE(sxe, node);
        !          1670: 
        !          1671:        node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          1672: 
        !          1673:        if (node && node->type != XML_ELEMENT_NODE) {
        !          1674:                node = node->parent;
        !          1675:        }
        !          1676: 
        !          1677:        if (node == NULL) {
        !          1678:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate parent Element");
        !          1679:                return;
        !          1680:        }
        !          1681: 
        !          1682:        localname = xmlSplitQName2((xmlChar *)qname, &prefix);
        !          1683:        if (localname == NULL) {
        !          1684:                if (nsuri_len > 0) {
        !          1685:                        if (prefix != NULL) {
        !          1686:                                xmlFree(prefix);
        !          1687:                        }
        !          1688:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute requires prefix for namespace");
        !          1689:                        return;
        !          1690:                }
        !          1691:                localname = xmlStrdup((xmlChar *)qname);
        !          1692:        }
        !          1693: 
        !          1694:        attrp = xmlHasNsProp(node, localname, (xmlChar *)nsuri);
        !          1695:        if (attrp != NULL && attrp->type != XML_ATTRIBUTE_DECL) {
        !          1696:                xmlFree(localname);
        !          1697:                if (prefix != NULL) {
        !          1698:                        xmlFree(prefix);
        !          1699:                }
        !          1700:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute already exists");
        !          1701:                return;
        !          1702:        }
        !          1703: 
        !          1704:        if (nsuri != NULL) {
        !          1705:                nsptr = xmlSearchNsByHref(node->doc, node, (xmlChar *)nsuri);
        !          1706:                if (nsptr == NULL) {
        !          1707:                        nsptr = xmlNewNs(node, (xmlChar *)nsuri, prefix);
        !          1708:                }
        !          1709:        }
        !          1710: 
        !          1711:        attrp = xmlNewNsProp(node, nsptr, localname, (xmlChar *)value);
        !          1712: 
        !          1713:        xmlFree(localname);
        !          1714:        if (prefix != NULL) {
        !          1715:                xmlFree(prefix);
        !          1716:        }
        !          1717: }
        !          1718: /* }}} */
        !          1719: 
        !          1720: /* {{{ cast_object()
        !          1721:  */
        !          1722: static int cast_object(zval *object, int type, char *contents TSRMLS_DC)
        !          1723: {
        !          1724:        if (contents) {
        !          1725:                ZVAL_STRINGL(object, contents, strlen(contents), 1);
        !          1726:        } else {
        !          1727:                ZVAL_NULL(object);
        !          1728:        }
        !          1729:        Z_SET_REFCOUNT_P(object, 1);
        !          1730:        Z_UNSET_ISREF_P(object);
        !          1731: 
        !          1732:        switch (type) {
        !          1733:                case IS_STRING:
        !          1734:                        convert_to_string(object);
        !          1735:                        break;
        !          1736:                case IS_BOOL:
        !          1737:                        convert_to_boolean(object);
        !          1738:                        break;
        !          1739:                case IS_LONG:
        !          1740:                        convert_to_long(object);
        !          1741:                        break;
        !          1742:                case IS_DOUBLE:
        !          1743:                        convert_to_double(object);
        !          1744:                        break;
        !          1745:                default:
        !          1746:                        return FAILURE;
        !          1747:        }
        !          1748:        return SUCCESS;
        !          1749: }
        !          1750: /* }}} */
        !          1751: 
        !          1752: /* {{{ sxe_object_cast()
        !          1753:  */
        !          1754: static int sxe_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
        !          1755: {
        !          1756:        php_sxe_object *sxe;
        !          1757:        xmlChar           *contents = NULL;
        !          1758:        xmlNodePtr          node;
        !          1759:        int rv;
        !          1760:        HashTable      *prop_hash;
        !          1761: 
        !          1762:        sxe = php_sxe_fetch_object(readobj TSRMLS_CC);
        !          1763: 
        !          1764:        if (type == IS_BOOL) {
        !          1765:                node = php_sxe_get_first_node(sxe, NULL TSRMLS_CC);
        !          1766:                prop_hash = sxe_get_prop_hash(readobj, 1 TSRMLS_CC);
        !          1767:                INIT_PZVAL(writeobj);
        !          1768:                ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(prop_hash) > 0);
        !          1769:                zend_hash_destroy(prop_hash);
        !          1770:                efree(prop_hash);
        !          1771:                return SUCCESS;
        !          1772:        }
        !          1773: 
        !          1774:        if (sxe->iter.type != SXE_ITER_NONE) {
        !          1775:                node = php_sxe_get_first_node(sxe, NULL TSRMLS_CC);
        !          1776:                if (node) {
        !          1777:                        contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, node->children, 1);
        !          1778:                }
        !          1779:        } else {
        !          1780:                if (!sxe->node) {
        !          1781:                        if (sxe->document) {
        !          1782:                                php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement((xmlDocPtr) sxe->document->ptr), NULL TSRMLS_CC);
        !          1783:                        }
        !          1784:                }
        !          1785: 
        !          1786:                if (sxe->node && sxe->node->node) {
        !          1787:                        if (sxe->node->node->children) {
        !          1788:                                contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, sxe->node->node->children, 1);
        !          1789:                        }
        !          1790:                }
        !          1791:        }
        !          1792: 
        !          1793:        if (readobj == writeobj) {
        !          1794:                INIT_PZVAL(writeobj);
        !          1795:                zval_dtor(readobj);
        !          1796:        }
        !          1797: 
        !          1798:        rv = cast_object(writeobj, type, (char *)contents TSRMLS_CC);
        !          1799: 
        !          1800:        if (contents) {
        !          1801:                xmlFree(contents);
        !          1802:        }
        !          1803:        return rv;
        !          1804: }
        !          1805: /* }}} */
        !          1806: 
        !          1807: /* {{{ proto object SimpleXMLElement::__toString() U
        !          1808:    Returns the string content */
        !          1809: SXE_METHOD(__toString)
        !          1810: {
        !          1811:        zval           *result;
        !          1812: 
        !          1813:        ALLOC_INIT_ZVAL(result);
        !          1814: 
        !          1815:        if (sxe_object_cast(getThis(), result, IS_STRING TSRMLS_CC) == SUCCESS) {
        !          1816:                RETURN_ZVAL(result, 1, 1);
        !          1817:        } else {
        !          1818:                zval_ptr_dtor(&result);
        !          1819:                RETURN_EMPTY_STRING();
        !          1820:        }
        !          1821: }
        !          1822: /* }}} */
        !          1823: 
        !          1824: static int php_sxe_count_elements_helper(php_sxe_object *sxe, long *count TSRMLS_DC) /* {{{ */
        !          1825: {
        !          1826:        xmlNodePtr       node;
        !          1827:        zval            *data;
        !          1828: 
        !          1829:        *count = 0;
        !          1830: 
        !          1831:        data = sxe->iter.data;
        !          1832:        sxe->iter.data = NULL;
        !          1833: 
        !          1834:        node = php_sxe_reset_iterator(sxe, 0 TSRMLS_CC);
        !          1835: 
        !          1836:        while (node)
        !          1837:        {
        !          1838:                (*count)++;
        !          1839:                node = php_sxe_iterator_fetch(sxe, node->next, 0 TSRMLS_CC);
        !          1840:        }
        !          1841: 
        !          1842:        if (sxe->iter.data) {
        !          1843:                zval_ptr_dtor(&sxe->iter.data);
        !          1844:        }
        !          1845:        sxe->iter.data = data;
        !          1846: 
        !          1847:        return SUCCESS;
        !          1848: }
        !          1849: /* }}} */
        !          1850: 
        !          1851: static int sxe_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
        !          1852: {
        !          1853:        php_sxe_object  *intern;
        !          1854:        intern = php_sxe_fetch_object(object TSRMLS_CC);
        !          1855:        if (intern->fptr_count) {
        !          1856:                zval *rv;
        !          1857:                zend_call_method_with_0_params(&object, intern->zo.ce, &intern->fptr_count, "count", &rv);
        !          1858:                if (rv) {
        !          1859:                        if (intern->tmp) {
        !          1860:                                zval_ptr_dtor(&intern->tmp);
        !          1861:                        }
        !          1862:                        MAKE_STD_ZVAL(intern->tmp);
        !          1863:                        ZVAL_ZVAL(intern->tmp, rv, 1, 1);
        !          1864:                        convert_to_long(intern->tmp);
        !          1865:                        *count = (long) Z_LVAL_P(intern->tmp);
        !          1866:                        return SUCCESS;
        !          1867:                }
        !          1868:                return FAILURE;
        !          1869:        }
        !          1870:        return php_sxe_count_elements_helper(intern, count TSRMLS_CC);
        !          1871: }
        !          1872: /* }}} */
        !          1873: 
        !          1874: /* {{{ proto int SimpleXMLElement::count()
        !          1875:  Get number of child elements */
        !          1876: SXE_METHOD(count)
        !          1877: {
        !          1878:        long count = 0;
        !          1879:        php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          1880: 
        !          1881:        if (zend_parse_parameters_none() == FAILURE) {
        !          1882:                return;
        !          1883:        }
        !          1884: 
        !          1885:        php_sxe_count_elements_helper(sxe, &count TSRMLS_CC);
        !          1886:        
        !          1887:        RETURN_LONG(count);
        !          1888: }
        !          1889: /* }}} */
        !          1890: 
        !          1891: static zval *sxe_get_value(zval *z TSRMLS_DC) /* {{{ */
        !          1892: {
        !          1893:        zval *retval;
        !          1894: 
        !          1895:        MAKE_STD_ZVAL(retval);
        !          1896: 
        !          1897:        if (sxe_object_cast(z, retval, IS_STRING TSRMLS_CC)==FAILURE) {
        !          1898:                zend_error(E_ERROR, "Unable to cast node to string");
        !          1899:                /* FIXME: Should not be fatal */
        !          1900:        }
        !          1901: 
        !          1902:        Z_SET_REFCOUNT_P(retval, 0);
        !          1903:        return retval;
        !          1904: }
        !          1905: /* }}} */
        !          1906: 
        !          1907: static zend_object_handlers sxe_object_handlers = { /* {{{ */
        !          1908:        ZEND_OBJECTS_STORE_HANDLERS,
        !          1909:        sxe_property_read,
        !          1910:        sxe_property_write,
        !          1911:        sxe_dimension_read,
        !          1912:        sxe_dimension_write,
        !          1913:        sxe_property_get_adr,
        !          1914:        sxe_get_value,                  /* get */
        !          1915:        NULL,
        !          1916:        sxe_property_exists,
        !          1917:        sxe_property_delete,
        !          1918:        sxe_dimension_exists,
        !          1919:        sxe_dimension_delete,
        !          1920:        sxe_get_properties,
        !          1921:        NULL, /* zend_get_std_object_handlers()->get_method,*/
        !          1922:        NULL, /* zend_get_std_object_handlers()->call_method,*/
        !          1923:        NULL, /* zend_get_std_object_handlers()->get_constructor, */
        !          1924:        NULL, /* zend_get_std_object_handlers()->get_class_entry,*/
        !          1925:        NULL, /* zend_get_std_object_handlers()->get_class_name,*/
        !          1926:        sxe_objects_compare,
        !          1927:        sxe_object_cast,
        !          1928:        sxe_count_elements,
        !          1929:        sxe_get_debug_info
        !          1930: };
        !          1931: /* }}} */
        !          1932: 
        !          1933: /* {{{ sxe_object_clone()
        !          1934:  */
        !          1935: static void
        !          1936: sxe_object_clone(void *object, void **clone_ptr TSRMLS_DC)
        !          1937: {
        !          1938:        php_sxe_object *sxe = (php_sxe_object *) object;
        !          1939:        php_sxe_object *clone;
        !          1940:        xmlNodePtr nodep = NULL;
        !          1941:        xmlDocPtr docp = NULL;
        !          1942: 
        !          1943:        clone = php_sxe_object_new(sxe->zo.ce TSRMLS_CC);
        !          1944:        clone->document = sxe->document;
        !          1945:        if (clone->document) {
        !          1946:                clone->document->refcount++;
        !          1947:                docp = clone->document->ptr;
        !          1948:        }
        !          1949: 
        !          1950:        clone->iter.isprefix = sxe->iter.isprefix;
        !          1951:        if (sxe->iter.name != NULL) {
        !          1952:                clone->iter.name = xmlStrdup((xmlChar *)sxe->iter.name);
        !          1953:        }
        !          1954:        if (sxe->iter.nsprefix != NULL) {
        !          1955:                clone->iter.nsprefix = xmlStrdup((xmlChar *)sxe->iter.nsprefix);
        !          1956:        }
        !          1957:        clone->iter.type = sxe->iter.type;
        !          1958: 
        !          1959:        if (sxe->node) {
        !          1960:                nodep = xmlDocCopyNode(sxe->node->node, docp, 1);
        !          1961:        }
        !          1962: 
        !          1963:        php_libxml_increment_node_ptr((php_libxml_node_object *)clone, nodep, NULL TSRMLS_CC);
        !          1964: 
        !          1965:        *clone_ptr = (void *) clone;
        !          1966: }
        !          1967: /* }}} */
        !          1968: 
        !          1969: /* {{{ sxe_object_dtor()
        !          1970:  */
        !          1971: static void sxe_object_dtor(void *object, zend_object_handle handle TSRMLS_DC)
        !          1972: {
        !          1973:        /* dtor required to cleanup iterator related data properly */
        !          1974: 
        !          1975:        php_sxe_object *sxe;
        !          1976: 
        !          1977:        sxe = (php_sxe_object *) object;
        !          1978: 
        !          1979:        if (sxe->iter.data) {
        !          1980:                zval_ptr_dtor(&sxe->iter.data);
        !          1981:                sxe->iter.data = NULL;
        !          1982:        }
        !          1983: 
        !          1984:        if (sxe->iter.name) {
        !          1985:                xmlFree(sxe->iter.name);
        !          1986:                sxe->iter.name = NULL;
        !          1987:        }
        !          1988:        if (sxe->iter.nsprefix) {
        !          1989:                xmlFree(sxe->iter.nsprefix);
        !          1990:                sxe->iter.nsprefix = NULL;
        !          1991:        }
        !          1992:        if (sxe->tmp) {
        !          1993:                zval_ptr_dtor(&sxe->tmp);
        !          1994:                sxe->tmp = NULL;
        !          1995:        }
        !          1996: }
        !          1997: /* }}} */
        !          1998: 
        !          1999: /* {{{ sxe_object_free_storage()
        !          2000:  */
        !          2001: static void sxe_object_free_storage(void *object TSRMLS_DC)
        !          2002: {
        !          2003:        php_sxe_object *sxe;
        !          2004: 
        !          2005:        sxe = (php_sxe_object *) object;
        !          2006: 
        !          2007: #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
        !          2008:        zend_object_std_dtor(&sxe->zo TSRMLS_CC);
        !          2009: #else
        !          2010:        if (sxe->zo.guards) {
        !          2011:                zend_hash_destroy(sxe->zo.guards);
        !          2012:                FREE_HASHTABLE(sxe->zo.guards);
        !          2013:        }
        !          2014: 
        !          2015:        if (sxe->zo.properties) {
        !          2016:                zend_hash_destroy(sxe->zo.properties);
        !          2017:                FREE_HASHTABLE(sxe->zo.properties);
        !          2018:        }
        !          2019: #endif
        !          2020: 
        !          2021:        php_libxml_node_decrement_resource((php_libxml_node_object *)sxe TSRMLS_CC);
        !          2022: 
        !          2023:        if (sxe->xpath) {
        !          2024:                xmlXPathFreeContext(sxe->xpath);
        !          2025:        }
        !          2026: 
        !          2027:        if (sxe->properties) {
        !          2028:                zend_hash_destroy(sxe->properties);
        !          2029:                FREE_HASHTABLE(sxe->properties);
        !          2030:        }
        !          2031: 
        !          2032:        efree(object);
        !          2033: }
        !          2034: /* }}} */
        !          2035: 
        !          2036: /* {{{ php_sxe_object_new()
        !          2037:  */
        !          2038: static php_sxe_object* php_sxe_object_new(zend_class_entry *ce TSRMLS_DC)
        !          2039: {
        !          2040:        php_sxe_object *intern;
        !          2041:        zend_class_entry     *parent = ce;
        !          2042:        int inherited = 0;
        !          2043: 
        !          2044:        intern = ecalloc(1, sizeof(php_sxe_object));
        !          2045: 
        !          2046:        intern->iter.type = SXE_ITER_NONE;
        !          2047:        intern->iter.nsprefix = NULL;
        !          2048:        intern->iter.name = NULL;
        !          2049:        intern->fptr_count = NULL;
        !          2050: 
        !          2051: #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
        !          2052:        zend_object_std_init(&intern->zo, ce TSRMLS_CC);
        !          2053: #else
        !          2054:        ALLOC_HASHTABLE(intern->zo.properties);
        !          2055:        zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
        !          2056: 
        !          2057:        intern->zo.ce = ce;
        !          2058:        intern->zo.guards = NULL;
        !          2059: #endif
        !          2060: 
        !          2061:        while (parent) {
        !          2062:                if (parent == sxe_class_entry) {
        !          2063:                        break;
        !          2064:                }
        !          2065: 
        !          2066:                parent = parent->parent;
        !          2067:                inherited = 1;
        !          2068:        }
        !          2069: 
        !          2070:        if (inherited) {
        !          2071:                zend_hash_find(&ce->function_table, "count", sizeof("count"),(void **) &intern->fptr_count);
        !          2072:                if (intern->fptr_count->common.scope == parent) {
        !          2073:                        intern->fptr_count = NULL;
        !          2074:                }
        !          2075:        }
        !          2076: 
        !          2077:        return intern;
        !          2078: }
        !          2079: /* }}} */
        !          2080: 
        !          2081: /* {{{ php_sxe_register_object
        !          2082:  */
        !          2083: static zend_object_value
        !          2084: php_sxe_register_object(php_sxe_object *intern TSRMLS_DC)
        !          2085: {
        !          2086:        zend_object_value rv;
        !          2087: 
        !          2088:        rv.handle = zend_objects_store_put(intern, sxe_object_dtor, (zend_objects_free_object_storage_t)sxe_object_free_storage, sxe_object_clone TSRMLS_CC);
        !          2089:        rv.handlers = (zend_object_handlers *) &sxe_object_handlers;
        !          2090: 
        !          2091:        return rv;
        !          2092: }
        !          2093: /* }}} */
        !          2094: 
        !          2095: /* {{{ sxe_object_new()
        !          2096:  */
        !          2097: PHP_SXE_API zend_object_value
        !          2098: sxe_object_new(zend_class_entry *ce TSRMLS_DC)
        !          2099: {
        !          2100:        php_sxe_object    *intern;
        !          2101: 
        !          2102:        intern = php_sxe_object_new(ce TSRMLS_CC);
        !          2103:        return php_sxe_register_object(intern TSRMLS_CC);
        !          2104: }
        !          2105: /* }}} */
        !          2106: 
        !          2107: /* {{{ proto simplemxml_element simplexml_load_file(string filename [, string class_name [, int options [, string ns [, bool is_prefix]]]])
        !          2108:    Load a filename and return a simplexml_element object to allow for processing */
        !          2109: PHP_FUNCTION(simplexml_load_file)
        !          2110: {
        !          2111:        php_sxe_object *sxe;
        !          2112:        char           *filename;
        !          2113:        int             filename_len;
        !          2114:        xmlDocPtr       docp;
        !          2115:        char           *ns = NULL;
        !          2116:        int             ns_len = 0;
        !          2117:        long            options = 0;
        !          2118:        zend_class_entry *ce= sxe_class_entry;
        !          2119:        zend_bool       isprefix = 0;
        !          2120: 
        !          2121:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C!lsb", &filename, &filename_len, &ce, &options, &ns, &ns_len, &isprefix) == FAILURE) {
        !          2122:                return;
        !          2123:        }
        !          2124: 
        !          2125:        docp = xmlReadFile(filename, NULL, options);
        !          2126: 
        !          2127:        if (! docp) {
        !          2128:                RETURN_FALSE;
        !          2129:        }
        !          2130: 
        !          2131:        if (!ce) {
        !          2132:                ce = sxe_class_entry;
        !          2133:        }
        !          2134:        sxe = php_sxe_object_new(ce TSRMLS_CC);
        !          2135:        sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL;
        !          2136:        sxe->iter.isprefix = isprefix;
        !          2137:        php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC);
        !          2138:        php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC);
        !          2139: 
        !          2140:        return_value->type = IS_OBJECT;
        !          2141:        return_value->value.obj = php_sxe_register_object(sxe TSRMLS_CC);
        !          2142: }
        !          2143: /* }}} */
        !          2144: 
        !          2145: /* {{{ proto simplemxml_element simplexml_load_string(string data [, string class_name [, int options [, string ns [, bool is_prefix]]]])
        !          2146:    Load a string and return a simplexml_element object to allow for processing */
        !          2147: PHP_FUNCTION(simplexml_load_string)
        !          2148: {
        !          2149:        php_sxe_object *sxe;
        !          2150:        char           *data;
        !          2151:        int             data_len;
        !          2152:        xmlDocPtr       docp;
        !          2153:        char           *ns = NULL;
        !          2154:        int             ns_len = 0;
        !          2155:        long            options = 0;
        !          2156:        zend_class_entry *ce= sxe_class_entry;
        !          2157:        zend_bool       isprefix = 0;
        !          2158: 
        !          2159:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|C!lsb", &data, &data_len, &ce, &options, &ns, &ns_len, &isprefix) == FAILURE) {
        !          2160:                return;
        !          2161:        }
        !          2162: 
        !          2163:        docp = xmlReadMemory(data, data_len, NULL, NULL, options);
        !          2164: 
        !          2165:        if (! docp) {
        !          2166:                RETURN_FALSE;
        !          2167:        }
        !          2168: 
        !          2169:        if (!ce) {
        !          2170:                ce = sxe_class_entry;
        !          2171:        }
        !          2172:        sxe = php_sxe_object_new(ce TSRMLS_CC);
        !          2173:        sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL;
        !          2174:        sxe->iter.isprefix = isprefix;
        !          2175:        php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC);
        !          2176:        php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC);
        !          2177: 
        !          2178:        return_value->type = IS_OBJECT;
        !          2179:        return_value->value.obj = php_sxe_register_object(sxe TSRMLS_CC);
        !          2180: }
        !          2181: /* }}} */
        !          2182: 
        !          2183: /* {{{ proto SimpleXMLElement::__construct(string data [, int options [, bool data_is_url [, string ns [, bool is_prefix]]]])
        !          2184:    SimpleXMLElement constructor */
        !          2185: SXE_METHOD(__construct)
        !          2186: {
        !          2187:        php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
        !          2188:        char           *data, *ns = NULL;
        !          2189:        int             data_len, ns_len = 0;
        !          2190:        xmlDocPtr       docp;
        !          2191:        long            options = 0;
        !          2192:        zend_bool       is_url = 0, isprefix = 0;
        !          2193:        zend_error_handling error_handling;
        !          2194: 
        !          2195:        zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
        !          2196:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbsb", &data, &data_len, &options, &is_url, &ns, &ns_len, &isprefix) == FAILURE) {
        !          2197:                zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2198:                return;
        !          2199:        }
        !          2200: 
        !          2201:        zend_restore_error_handling(&error_handling TSRMLS_CC);
        !          2202: 
        !          2203:        docp = is_url ? xmlReadFile(data, NULL, options) : xmlReadMemory(data, data_len, NULL, NULL, options);
        !          2204: 
        !          2205:        if (!docp) {
        !          2206:                ((php_libxml_node_object *)sxe)->document = NULL;
        !          2207:                zend_throw_exception(zend_exception_get_default(TSRMLS_C), "String could not be parsed as XML", 0 TSRMLS_CC);
        !          2208:                return;
        !          2209:        }
        !          2210: 
        !          2211:        sxe->iter.nsprefix = ns_len ? xmlStrdup((xmlChar *)ns) : NULL;
        !          2212:        sxe->iter.isprefix = isprefix;
        !          2213:        php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC);
        !          2214:        php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC);
        !          2215: }
        !          2216: /* }}} */
        !          2217: 
        !          2218: zend_object_iterator_funcs php_sxe_iterator_funcs = { /* {{{ */
        !          2219:        php_sxe_iterator_dtor,
        !          2220:        php_sxe_iterator_valid,
        !          2221:        php_sxe_iterator_current_data,
        !          2222:        php_sxe_iterator_current_key,
        !          2223:        php_sxe_iterator_move_forward,
        !          2224:        php_sxe_iterator_rewind,
        !          2225: };
        !          2226: /* }}} */
        !          2227: 
        !          2228: static xmlNodePtr php_sxe_iterator_fetch(php_sxe_object *sxe, xmlNodePtr node, int use_data TSRMLS_DC) /* {{{ */
        !          2229: {
        !          2230:        xmlChar *prefix  = sxe->iter.nsprefix;
        !          2231:        int isprefix  = sxe->iter.isprefix;
        !          2232:        int test_elem = sxe->iter.type == SXE_ITER_ELEMENT  && sxe->iter.name;
        !          2233:        int test_attr = sxe->iter.type == SXE_ITER_ATTRLIST && sxe->iter.name;
        !          2234: 
        !          2235:        while (node) {
        !          2236:                SKIP_TEXT(node);
        !          2237:                if (sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) {
        !          2238:                        if ((!test_elem || !xmlStrcmp(node->name, sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) {
        !          2239:                                break;
        !          2240:                        }
        !          2241:                } else if (node->type == XML_ATTRIBUTE_NODE) {
        !          2242:                        if ((!test_attr || !xmlStrcmp(node->name, sxe->iter.name)) && match_ns(sxe, node, prefix, isprefix)) {
        !          2243:                                break;
        !          2244:                        }
        !          2245:                }
        !          2246: next_iter:
        !          2247:                node = node->next;
        !          2248:        }
        !          2249: 
        !          2250:        if (node && use_data) {
        !          2251:                ALLOC_INIT_ZVAL(sxe->iter.data);
        !          2252:                _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, prefix, isprefix TSRMLS_CC);
        !          2253:        }
        !          2254: 
        !          2255:        return node;
        !          2256: }
        !          2257: /* }}} */
        !          2258: 
        !          2259: static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data TSRMLS_DC) /* {{{ */
        !          2260: {
        !          2261:        xmlNodePtr node;
        !          2262: 
        !          2263:        if (sxe->iter.data) {
        !          2264:                zval_ptr_dtor(&sxe->iter.data);
        !          2265:                sxe->iter.data = NULL;
        !          2266:        }
        !          2267: 
        !          2268:        GET_NODE(sxe, node)
        !          2269: 
        !          2270:        if (node) {
        !          2271:                switch (sxe->iter.type) {
        !          2272:                        case SXE_ITER_ELEMENT:
        !          2273:                        case SXE_ITER_CHILD:
        !          2274:                        case SXE_ITER_NONE:
        !          2275:                                node = node->children;
        !          2276:                                break;
        !          2277:                        case SXE_ITER_ATTRLIST:
        !          2278:                                node = (xmlNodePtr) node->properties;
        !          2279:                }
        !          2280:                return php_sxe_iterator_fetch(sxe, node, use_data TSRMLS_CC);
        !          2281:        }
        !          2282:        return NULL;
        !          2283: }
        !          2284: /* }}} */
        !          2285: 
        !          2286: zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
        !          2287: {
        !          2288:        php_sxe_iterator *iterator;
        !          2289: 
        !          2290:        if (by_ref) {
        !          2291:                zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
        !          2292:        }
        !          2293:        iterator = emalloc(sizeof(php_sxe_iterator));
        !          2294: 
        !          2295:        Z_ADDREF_P(object);
        !          2296:        iterator->intern.data = (void*)object;
        !          2297:        iterator->intern.funcs = &php_sxe_iterator_funcs;
        !          2298:        iterator->sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !          2299: 
        !          2300:        return (zend_object_iterator*)iterator;
        !          2301: }
        !          2302: /* }}} */
        !          2303: 
        !          2304: static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        !          2305: {
        !          2306:        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
        !          2307: 
        !          2308:        /* cleanup handled in sxe_object_dtor as we dont always have an iterator wrapper */
        !          2309:        if (iterator->intern.data) {
        !          2310:                zval_ptr_dtor((zval**)&iterator->intern.data);
        !          2311:        }
        !          2312: 
        !          2313:        efree(iterator);
        !          2314: }
        !          2315: /* }}} */
        !          2316: 
        !          2317: static int php_sxe_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        !          2318: {
        !          2319:        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
        !          2320: 
        !          2321:        return iterator->sxe->iter.data ? SUCCESS : FAILURE;
        !          2322: }
        !          2323: /* }}} */
        !          2324: 
        !          2325: static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
        !          2326: {
        !          2327:        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
        !          2328: 
        !          2329:        *data = &iterator->sxe->iter.data;
        !          2330: }
        !          2331: /* }}} */
        !          2332: 
        !          2333: static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
        !          2334: {
        !          2335:        zval *curobj;
        !          2336:        xmlNodePtr curnode = NULL;
        !          2337:        php_sxe_object *intern;
        !          2338:        int namelen;
        !          2339: 
        !          2340:        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
        !          2341:        curobj = iterator->sxe->iter.data;
        !          2342: 
        !          2343:        intern = (php_sxe_object *)zend_object_store_get_object(curobj TSRMLS_CC);
        !          2344:        if (intern != NULL && intern->node != NULL) {
        !          2345:                curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
        !          2346:        }
        !          2347:        if (!curnode) {
        !          2348:                return HASH_KEY_NON_EXISTANT;
        !          2349:        }
        !          2350: 
        !          2351:        namelen = xmlStrlen(curnode->name);
        !          2352:        *str_key = estrndup((char *)curnode->name, namelen);
        !          2353:        *str_key_len = namelen + 1;
        !          2354:        return HASH_KEY_IS_STRING;
        !          2355: 
        !          2356: }
        !          2357: /* }}} */
        !          2358: 
        !          2359: PHP_SXE_API void php_sxe_move_forward_iterator(php_sxe_object *sxe TSRMLS_DC) /* {{{ */
        !          2360: {
        !          2361:        xmlNodePtr      node = NULL;
        !          2362:        php_sxe_object  *intern;
        !          2363: 
        !          2364:        if (sxe->iter.data) {
        !          2365:                intern = (php_sxe_object *)zend_object_store_get_object(sxe->iter.data TSRMLS_CC);
        !          2366:                GET_NODE(intern, node)
        !          2367:                zval_ptr_dtor(&sxe->iter.data);
        !          2368:                sxe->iter.data = NULL;
        !          2369:        }
        !          2370: 
        !          2371:        if (node) {
        !          2372:                php_sxe_iterator_fetch(sxe, node->next, 1 TSRMLS_CC);
        !          2373:        }
        !          2374: }
        !          2375: /* }}} */
        !          2376: 
        !          2377: static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        !          2378: {
        !          2379:        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
        !          2380:        php_sxe_move_forward_iterator(iterator->sxe TSRMLS_CC);
        !          2381: }
        !          2382: /* }}} */
        !          2383: 
        !          2384: static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        !          2385: {
        !          2386:        php_sxe_object  *sxe;
        !          2387: 
        !          2388:        php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
        !          2389:        sxe = iterator->sxe;
        !          2390: 
        !          2391:        php_sxe_reset_iterator(sxe, 1 TSRMLS_CC);
        !          2392: }
        !          2393: /* }}} */
        !          2394: 
        !          2395: void *simplexml_export_node(zval *object TSRMLS_DC) /* {{{ */
        !          2396: {
        !          2397:        php_sxe_object *sxe;
        !          2398:        xmlNodePtr node;
        !          2399: 
        !          2400:        sxe = php_sxe_fetch_object(object TSRMLS_CC);
        !          2401:        GET_NODE(sxe, node);
        !          2402:        return php_sxe_get_first_node(sxe, node TSRMLS_CC);
        !          2403: }
        !          2404: /* }}} */
        !          2405: 
        !          2406: /* {{{ proto simplemxml_element simplexml_import_dom(domNode node [, string class_name])
        !          2407:    Get a simplexml_element object from dom to allow for processing */
        !          2408: PHP_FUNCTION(simplexml_import_dom)
        !          2409: {
        !          2410:        php_sxe_object *sxe;
        !          2411:        zval *node;
        !          2412:        php_libxml_node_object *object;
        !          2413:        xmlNodePtr              nodep = NULL;
        !          2414:        zend_class_entry *ce= sxe_class_entry;
        !          2415: 
        !          2416:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|C!", &node, &ce) == FAILURE) {
        !          2417:                return;
        !          2418:        }
        !          2419: 
        !          2420:        object = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC);
        !          2421: 
        !          2422:        nodep = php_libxml_import_node(node TSRMLS_CC);
        !          2423: 
        !          2424:        if (nodep) {
        !          2425:                if (nodep->doc == NULL) {
        !          2426:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Imported Node must have associated Document");
        !          2427:                        RETURN_NULL();
        !          2428:                }
        !          2429:                if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
        !          2430:                        nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
        !          2431:                }
        !          2432:        }
        !          2433: 
        !          2434:        if (nodep && nodep->type == XML_ELEMENT_NODE) {
        !          2435:                if (!ce) {
        !          2436:                        ce = sxe_class_entry;
        !          2437:                }
        !          2438:                sxe = php_sxe_object_new(ce TSRMLS_CC);
        !          2439:                sxe->document = object->document;
        !          2440:                php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, nodep->doc TSRMLS_CC);
        !          2441:                php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, nodep, NULL TSRMLS_CC);
        !          2442: 
        !          2443:                return_value->type = IS_OBJECT;
        !          2444:                return_value->value.obj = php_sxe_register_object(sxe TSRMLS_CC);
        !          2445:        } else {
        !          2446:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Nodetype to import");
        !          2447:                RETVAL_NULL();
        !          2448:        }
        !          2449: }
        !          2450: /* }}} */
        !          2451: 
        !          2452: /* {{{ arginfo */
        !          2453: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexml_load_file, 0, 0, 1)
        !          2454:        ZEND_ARG_INFO(0, filename)
        !          2455:        ZEND_ARG_INFO(0, class_name)
        !          2456:        ZEND_ARG_INFO(0, options)
        !          2457:        ZEND_ARG_INFO(0, ns)
        !          2458:        ZEND_ARG_INFO(0, is_prefix)
        !          2459: ZEND_END_ARG_INFO()
        !          2460: 
        !          2461: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexml_load_string, 0, 0, 1)
        !          2462:        ZEND_ARG_INFO(0, data)
        !          2463:        ZEND_ARG_INFO(0, class_name)
        !          2464:        ZEND_ARG_INFO(0, options)
        !          2465:        ZEND_ARG_INFO(0, ns)
        !          2466:        ZEND_ARG_INFO(0, is_prefix)
        !          2467: ZEND_END_ARG_INFO()
        !          2468: 
        !          2469: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexml_import_dom, 0, 0, 1)
        !          2470:        ZEND_ARG_INFO(0, node)
        !          2471:        ZEND_ARG_INFO(0, class_name)
        !          2472: ZEND_END_ARG_INFO()
        !          2473: 
        !          2474: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_xpath, 0, 0, 1)
        !          2475:        ZEND_ARG_INFO(0, path)
        !          2476: ZEND_END_ARG_INFO()
        !          2477: 
        !          2478: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_registerxpathnamespace, 0, 0, 2)
        !          2479:        ZEND_ARG_INFO(0, prefix)
        !          2480:        ZEND_ARG_INFO(0, ns)
        !          2481: ZEND_END_ARG_INFO()
        !          2482: 
        !          2483: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_asxml, 0, 0, 0)
        !          2484:        ZEND_ARG_INFO(0, filename)
        !          2485: ZEND_END_ARG_INFO()
        !          2486: 
        !          2487: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_getnamespaces, 0, 0, 0)
        !          2488:        ZEND_ARG_INFO(0, recursve)
        !          2489: ZEND_END_ARG_INFO()
        !          2490: 
        !          2491: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_children, 0, 0, 0)
        !          2492:        ZEND_ARG_INFO(0, ns)
        !          2493:        ZEND_ARG_INFO(0, is_prefix)
        !          2494: ZEND_END_ARG_INFO()
        !          2495: 
        !          2496: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement__construct, 0, 0, 1)
        !          2497:        ZEND_ARG_INFO(0, data)
        !          2498:        ZEND_ARG_INFO(0, options)
        !          2499:        ZEND_ARG_INFO(0, data_is_url)
        !          2500:        ZEND_ARG_INFO(0, ns)
        !          2501:        ZEND_ARG_INFO(0, is_prefix)
        !          2502: ZEND_END_ARG_INFO()
        !          2503: 
        !          2504: ZEND_BEGIN_ARG_INFO(arginfo_simplexmlelement__void, 0)
        !          2505: ZEND_END_ARG_INFO()
        !          2506: 
        !          2507: ZEND_BEGIN_ARG_INFO_EX(arginfo_simplexmlelement_addchild, 0, 0, 1)
        !          2508:        ZEND_ARG_INFO(0, name)
        !          2509:        ZEND_ARG_INFO(0, value)
        !          2510:        ZEND_ARG_INFO(0, ns)
        !          2511: ZEND_END_ARG_INFO()
        !          2512: /* }}} */
        !          2513: 
        !          2514: const zend_function_entry simplexml_functions[] = { /* {{{ */
        !          2515:        PHP_FE(simplexml_load_file,     arginfo_simplexml_load_file)
        !          2516:        PHP_FE(simplexml_load_string,   arginfo_simplexml_load_string)
        !          2517:        PHP_FE(simplexml_import_dom,    arginfo_simplexml_import_dom)
        !          2518:        PHP_FE_END
        !          2519: };
        !          2520: /* }}} */
        !          2521: 
        !          2522: static const zend_module_dep simplexml_deps[] = { /* {{{ */
        !          2523:        ZEND_MOD_REQUIRED("libxml")
        !          2524:        ZEND_MOD_REQUIRED("spl")
        !          2525:        ZEND_MOD_END
        !          2526: };
        !          2527: /* }}} */
        !          2528: 
        !          2529: zend_module_entry simplexml_module_entry = { /* {{{ */
        !          2530:        STANDARD_MODULE_HEADER_EX, NULL,
        !          2531:        simplexml_deps,
        !          2532:        "SimpleXML",
        !          2533:        simplexml_functions,
        !          2534:        PHP_MINIT(simplexml),
        !          2535:        PHP_MSHUTDOWN(simplexml),
        !          2536:        NULL,
        !          2537:        NULL,
        !          2538:        PHP_MINFO(simplexml),
        !          2539:        "0.1",
        !          2540:        STANDARD_MODULE_PROPERTIES
        !          2541: };
        !          2542: /* }}} */
        !          2543: 
        !          2544: #ifdef COMPILE_DL_SIMPLEXML
        !          2545: ZEND_GET_MODULE(simplexml)
        !          2546: #endif
        !          2547: 
        !          2548: /* the method table */
        !          2549: /* each method can have its own parameters and visibility */
        !          2550: static const zend_function_entry sxe_functions[] = { /* {{{ */
        !          2551:        SXE_ME(__construct,            arginfo_simplexmlelement__construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) /* must be called */
        !          2552:        SXE_ME(asXML,                  arginfo_simplexmlelement_asxml, ZEND_ACC_PUBLIC)
        !          2553:        SXE_MALIAS(saveXML, asXML,         arginfo_simplexmlelement_asxml, ZEND_ACC_PUBLIC)
        !          2554:        SXE_ME(xpath,                  arginfo_simplexmlelement_xpath, ZEND_ACC_PUBLIC)
        !          2555:        SXE_ME(registerXPathNamespace, arginfo_simplexmlelement_registerxpathnamespace, ZEND_ACC_PUBLIC)
        !          2556:        SXE_ME(attributes,             arginfo_simplexmlelement_children, ZEND_ACC_PUBLIC)
        !          2557:        SXE_ME(children,               arginfo_simplexmlelement_children, ZEND_ACC_PUBLIC)
        !          2558:        SXE_ME(getNamespaces,          arginfo_simplexmlelement_getnamespaces, ZEND_ACC_PUBLIC)
        !          2559:        SXE_ME(getDocNamespaces,       arginfo_simplexmlelement_getnamespaces, ZEND_ACC_PUBLIC)
        !          2560:        SXE_ME(getName,                arginfo_simplexmlelement__void, ZEND_ACC_PUBLIC)
        !          2561:        SXE_ME(addChild,               arginfo_simplexmlelement_addchild, ZEND_ACC_PUBLIC)
        !          2562:        SXE_ME(addAttribute,           arginfo_simplexmlelement_addchild, ZEND_ACC_PUBLIC)
        !          2563:        SXE_ME(__toString,             arginfo_simplexmlelement__void, ZEND_ACC_PUBLIC)
        !          2564:        SXE_ME(count,                  arginfo_simplexmlelement__void, ZEND_ACC_PUBLIC)
        !          2565:        PHP_FE_END
        !          2566: };
        !          2567: /* }}} */
        !          2568: 
        !          2569: /* {{{ PHP_MINIT_FUNCTION(simplexml)
        !          2570:  */
        !          2571: PHP_MINIT_FUNCTION(simplexml)
        !          2572: {
        !          2573:        zend_class_entry sxe;
        !          2574: 
        !          2575:        INIT_CLASS_ENTRY(sxe, "SimpleXMLElement", sxe_functions);
        !          2576:        sxe.create_object = sxe_object_new;
        !          2577:        sxe_class_entry = zend_register_internal_class(&sxe TSRMLS_CC);
        !          2578:        sxe_class_entry->get_iterator = php_sxe_get_iterator;
        !          2579:        sxe_class_entry->iterator_funcs.funcs = &php_sxe_iterator_funcs;
        !          2580:        zend_class_implements(sxe_class_entry TSRMLS_CC, 1, zend_ce_traversable);
        !          2581:        sxe_object_handlers.get_method = zend_get_std_object_handlers()->get_method;
        !          2582:        sxe_object_handlers.get_constructor = zend_get_std_object_handlers()->get_constructor;
        !          2583:        sxe_object_handlers.get_class_entry = zend_get_std_object_handlers()->get_class_entry;
        !          2584:        sxe_object_handlers.get_class_name = zend_get_std_object_handlers()->get_class_name;
        !          2585:        sxe_class_entry->serialize = zend_class_serialize_deny;
        !          2586:        sxe_class_entry->unserialize = zend_class_unserialize_deny;
        !          2587: 
        !          2588:        php_libxml_register_export(sxe_class_entry, simplexml_export_node);
        !          2589: 
        !          2590:        PHP_MINIT(sxe)(INIT_FUNC_ARGS_PASSTHRU);
        !          2591: 
        !          2592:        return SUCCESS;
        !          2593: }
        !          2594: /* }}} */
        !          2595: 
        !          2596: /* {{{ PHP_MSHUTDOWN_FUNCTION(simplexml)
        !          2597:  */
        !          2598: PHP_MSHUTDOWN_FUNCTION(simplexml)
        !          2599: {
        !          2600:        sxe_class_entry = NULL;
        !          2601:        return SUCCESS;
        !          2602: }
        !          2603: /* }}} */
        !          2604: 
        !          2605: /* {{{ PHP_MINFO_FUNCTION(simplexml)
        !          2606:  */
        !          2607: PHP_MINFO_FUNCTION(simplexml)
        !          2608: {
        !          2609:        php_info_print_table_start();
        !          2610:        php_info_print_table_header(2, "Simplexml support", "enabled");
        !          2611:        php_info_print_table_row(2, "Revision", "$Revision: 321634 $");
        !          2612:        php_info_print_table_row(2, "Schema support",
        !          2613: #ifdef LIBXML_SCHEMAS_ENABLED
        !          2614:                "enabled");
        !          2615: #else
        !          2616:                "not available");
        !          2617: #endif
        !          2618:        php_info_print_table_end();
        !          2619: }
        !          2620: /* }}} */
        !          2621: 
        !          2622: #endif
        !          2623: 
        !          2624: /**
        !          2625:  * Local Variables:
        !          2626:  * c-basic-offset: 4
        !          2627:  * tab-width: 4
        !          2628:  * indent-tabs-mode: t
        !          2629:  * End:
        !          2630:  * vim600: fdm=marker
        !          2631:  * vim: noet sw=4 ts=4
        !          2632:  */

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