PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/simplexml - simplexml.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 1016 1199 84.7 %
Date: 2014-12-13 Functions: 70 73 95.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:20 +0000 (7 days ago)

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