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: 1019 1204 84.6 %
Date: 2014-09-19 Functions: 70 73 95.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 19 Sep 2014 17:11:15 +0000 (32 hours ago)

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