Annotation of embedaddon/php/ext/dom/node.c, revision 1.1.1.4

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.4 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Christian Stocker <chregu@php.net>                          |
                     16:    |          Rob Richards <rrichards@php.net>                            |
                     17:    +----------------------------------------------------------------------+
                     18: */
                     19: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: #include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: #if HAVE_LIBXML && HAVE_DOM
                     28: #include "php_dom.h"
                     29: 
                     30: /* {{{ arginfo */
                     31: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1)
                     32:        ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
                     33:        ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1)
                     34: ZEND_END_ARG_INFO();
                     35: 
                     36: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2)
                     37:        ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
                     38:        ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
                     39: ZEND_END_ARG_INFO();
                     40: 
                     41: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1)
                     42:        ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
                     43: ZEND_END_ARG_INFO();
                     44: 
                     45: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1)
                     46:        ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
                     47: ZEND_END_ARG_INFO();
                     48: 
                     49: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0)
                     50: ZEND_END_ARG_INFO();
                     51: 
                     52: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1)
                     53:        ZEND_ARG_INFO(0, deep)
                     54: ZEND_END_ARG_INFO();
                     55: 
                     56: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0)
                     57: ZEND_END_ARG_INFO();
                     58: 
                     59: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2)
                     60:        ZEND_ARG_INFO(0, feature)
                     61:        ZEND_ARG_INFO(0, version)
                     62: ZEND_END_ARG_INFO();
                     63: 
                     64: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0)
                     65: ZEND_END_ARG_INFO();
                     66: 
                     67: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1)
                     68:        ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
                     69: ZEND_END_ARG_INFO();
                     70: 
                     71: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1)
                     72:        ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
                     73: ZEND_END_ARG_INFO();
                     74: 
                     75: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1)
                     76:        ZEND_ARG_INFO(0, namespaceURI)
                     77: ZEND_END_ARG_INFO();
                     78: 
                     79: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1)
                     80:        ZEND_ARG_INFO(0, namespaceURI)
                     81: ZEND_END_ARG_INFO();
                     82: 
                     83: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1)
                     84:        ZEND_ARG_INFO(0, prefix)
                     85: ZEND_END_ARG_INFO();
                     86: 
                     87: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1)
                     88:        ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
                     89: ZEND_END_ARG_INFO();
                     90: 
                     91: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2)
                     92:        ZEND_ARG_INFO(0, feature)
                     93:        ZEND_ARG_INFO(0, version)
                     94: ZEND_END_ARG_INFO();
                     95: 
                     96: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3)
                     97:        ZEND_ARG_INFO(0, key)
                     98:        ZEND_ARG_INFO(0, data)
                     99:        ZEND_ARG_INFO(0, handler)
                    100: ZEND_END_ARG_INFO();
                    101: 
                    102: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1)
                    103:        ZEND_ARG_INFO(0, key)
                    104: ZEND_END_ARG_INFO();
                    105: 
                    106: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0)
                    107: ZEND_END_ARG_INFO();
                    108: 
                    109: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getLineNo, 0, 0, 0)
                    110: ZEND_END_ARG_INFO();
                    111: 
                    112: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0)
                    113:        ZEND_ARG_INFO(0, exclusive)
                    114:        ZEND_ARG_INFO(0, with_comments)
                    115:        ZEND_ARG_ARRAY_INFO(0, xpath, 1)
                    116:        ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
                    117: ZEND_END_ARG_INFO();
                    118: 
                    119: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1)
                    120:        ZEND_ARG_INFO(0, uri)
                    121:        ZEND_ARG_INFO(0, exclusive)
                    122:        ZEND_ARG_INFO(0, with_comments)
                    123:        ZEND_ARG_ARRAY_INFO(0, xpath, 1)
                    124:        ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
                    125: ZEND_END_ARG_INFO();
                    126: /* }}} */
                    127: 
                    128: /*
                    129: * class DOMNode 
                    130: *
                    131: * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247
                    132: * Since: 
                    133: */
                    134: 
                    135: const zend_function_entry php_dom_node_class_functions[] = { /* {{{ */
                    136:        PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before)
                    137:        PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child)
                    138:        PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child)
                    139:        PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child)
                    140:        PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes)
                    141:        PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node)
                    142:        PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize)
                    143:        PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported)
                    144:        PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes)
                    145:        PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position)
                    146:        PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node)
                    147:        PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix)
                    148:        PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace)
                    149:        PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri)
                    150:        PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node)
                    151:        PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature)
                    152:        PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data)
                    153:        PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data)
                    154:        PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC)
                    155:        PHP_ME(domnode, getLineNo, arginfo_dom_node_getLineNo, ZEND_ACC_PUBLIC)
                    156:        PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC)
                    157:        PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC)
                    158:        PHP_FE_END
                    159: };
                    160: /* }}} */
                    161: 
                    162: static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
                    163: {
                    164:        xmlNsPtr nsptr, nsdftptr, curns, prevns = NULL;
                    165: 
                    166:        if (nodep->type == XML_ELEMENT_NODE) {
                    167:                /* Following if block primarily used for inserting nodes created via createElementNS */
                    168:                if (nodep->nsDef != NULL) {
                    169:                        curns = nodep->nsDef;
                    170:                        while (curns) {
                    171:                                nsdftptr = curns->next;
                    172:                                if (curns->href != NULL) {
                    173:                                        if((nsptr = xmlSearchNsByHref(doc, nodep->parent, curns->href)) && 
                    174:                                                (curns->prefix == NULL || xmlStrEqual(nsptr->prefix, curns->prefix))) {
                    175:                                                curns->next = NULL;
                    176:                                                if (prevns == NULL) {
                    177:                                                        nodep->nsDef = nsdftptr;
                    178:                                                } else {
                    179:                                                        prevns->next = nsdftptr;
                    180:                                                }
                    181:                                                dom_set_old_ns(doc, curns);
                    182:                                                curns = prevns;
                    183:                                        }
                    184:                                }
                    185:                                prevns = curns;
                    186:                                curns = nsdftptr;
                    187:                        }
                    188:                }
                    189:                xmlReconciliateNs(doc, nodep);
                    190:        }
                    191: }
                    192: /* }}} */
                    193: 
                    194: /* {{{ nodeName        string  
                    195: readonly=yes 
                    196: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
                    197: Since: 
                    198: */
                    199: int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
                    200: {
                    201:        xmlNode *nodep;
                    202:        xmlNsPtr ns;
                    203:        char *str = NULL;
                    204:        xmlChar *qname = NULL;
                    205: 
                    206:        nodep = dom_object_get_node(obj);
                    207: 
                    208:        if (nodep == NULL) {
                    209:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    210:                return FAILURE;
                    211:        }
                    212: 
                    213:        switch (nodep->type) {
                    214:                case XML_ATTRIBUTE_NODE:
                    215:                case XML_ELEMENT_NODE:
                    216:                        ns = nodep->ns;
                    217:                        if (ns != NULL && ns->prefix) {
                    218:                                qname = xmlStrdup(ns->prefix);
                    219:                                qname = xmlStrcat(qname, ":");
                    220:                                qname = xmlStrcat(qname, nodep->name);
                    221:                                str = qname;
                    222:                        } else {
                    223:                                str = (char *) nodep->name;
                    224:                        }
                    225:                        break;
                    226:                case XML_NAMESPACE_DECL:
                    227:                        ns = nodep->ns;
                    228:                        if (ns != NULL && ns->prefix) {
                    229:                                qname = xmlStrdup("xmlns");
                    230:                                qname = xmlStrcat(qname, ":");
                    231:                                qname = xmlStrcat(qname, nodep->name);
                    232:                                str = qname;
                    233:                        } else {
                    234:                                str = (char *) nodep->name;
                    235:                        }
                    236:                        break;
                    237:                case XML_DOCUMENT_TYPE_NODE:
                    238:                case XML_DTD_NODE:
                    239:                case XML_PI_NODE:
                    240:                case XML_ENTITY_DECL:
                    241:                case XML_ENTITY_REF_NODE:
                    242:                case XML_NOTATION_NODE:
                    243:                        str = (char *) nodep->name;
                    244:                        break;
                    245:                case XML_CDATA_SECTION_NODE:
                    246:                        str = "#cdata-section";
                    247:                        break;
                    248:                case XML_COMMENT_NODE:
                    249:                        str = "#comment";
                    250:                        break;
                    251:                case XML_HTML_DOCUMENT_NODE:
                    252:                case XML_DOCUMENT_NODE:
                    253:                        str = "#document";
                    254:                        break;
                    255:                case XML_DOCUMENT_FRAG_NODE:
                    256:                        str = "#document-fragment";
                    257:                        break;
                    258:                case XML_TEXT_NODE:
                    259:                        str = "#text";
                    260:                        break;
                    261:                default:
                    262:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type");
                    263:        }
                    264: 
                    265:        ALLOC_ZVAL(*retval);
                    266: 
                    267:        if(str != NULL) {
                    268:                ZVAL_STRING(*retval, str, 1);
                    269:        } else {
                    270:                ZVAL_EMPTY_STRING(*retval);
                    271:        }
                    272:        
                    273:        if (qname != NULL) {
                    274:                xmlFree(qname);
                    275:        }
                    276: 
                    277:        return SUCCESS;
                    278: 
                    279: }
                    280: 
                    281: /* }}} */
                    282: 
                    283: /* {{{ nodeValue       string  
                    284: readonly=no 
                    285: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
                    286: Since: 
                    287: */
                    288: int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC)
                    289: {
                    290:        xmlNode *nodep;
                    291:        char *str = NULL;
                    292: 
                    293:        nodep = dom_object_get_node(obj);
                    294: 
                    295:        if (nodep == NULL) {
                    296:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    297:                return FAILURE;
                    298:        }
                    299: 
                    300:        /* Access to Element node is implemented as a convience method */
                    301:        switch (nodep->type) {
                    302:                case XML_ATTRIBUTE_NODE:
                    303:                case XML_TEXT_NODE:
                    304:                case XML_ELEMENT_NODE:
                    305:                case XML_COMMENT_NODE:
                    306:                case XML_CDATA_SECTION_NODE:
                    307:                case XML_PI_NODE:
                    308:                        str = xmlNodeGetContent(nodep);
                    309:                        break;
                    310:                case XML_NAMESPACE_DECL:
                    311:                        str = xmlNodeGetContent(nodep->children);
                    312:                        break;
                    313:                default:
                    314:                        str = NULL;
                    315:                        break;
                    316:        }
                    317: 
                    318:        ALLOC_ZVAL(*retval);
                    319: 
                    320:        if(str != NULL) {
                    321:                ZVAL_STRING(*retval, str, 1);
                    322:                xmlFree(str);
                    323:        } else {
                    324:                ZVAL_NULL(*retval);
                    325:        }
                    326: 
                    327: 
                    328:        return SUCCESS;
                    329: 
                    330: }
                    331: 
                    332: int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
                    333: {
                    334:        xmlNode *nodep;
                    335:        zval value_copy;
                    336: 
                    337:        nodep = dom_object_get_node(obj);
                    338: 
                    339:        if (nodep == NULL) {
                    340:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    341:                return FAILURE;
                    342:        }
                    343: 
                    344:        /* Access to Element node is implemented as a convience method */
                    345:        switch (nodep->type) {
                    346:                case XML_ELEMENT_NODE:
                    347:                case XML_ATTRIBUTE_NODE:
                    348:                        if (nodep->children) {
                    349:                                node_list_unlink(nodep->children TSRMLS_CC);
                    350:                        }
                    351:                case XML_TEXT_NODE:
                    352:                case XML_COMMENT_NODE:
                    353:                case XML_CDATA_SECTION_NODE:
                    354:                case XML_PI_NODE:
                    355:                        if (newval->type != IS_STRING) {
                    356:                                if(Z_REFCOUNT_P(newval) > 1) {
                    357:                                        value_copy = *newval;
                    358:                                        zval_copy_ctor(&value_copy);
                    359:                                        newval = &value_copy;
                    360:                                }
                    361:                                convert_to_string(newval);
                    362:                        }
                    363:                        xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
                    364:                        if (newval == &value_copy) {
                    365:                                zval_dtor(newval);
                    366:                        }
                    367:                        break;
                    368:                default:
                    369:                        break;
                    370:        }
                    371: 
                    372:        return SUCCESS;
                    373: }
                    374: 
                    375: /* }}} */
                    376: 
                    377: /* {{{ nodeType        int
                    378: readonly=yes 
                    379: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558
                    380: Since:
                    381: */
                    382: int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC)
                    383: {
                    384:        xmlNode *nodep;
                    385: 
                    386:        nodep = dom_object_get_node(obj);
                    387: 
                    388:        if (nodep == NULL) {
                    389:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    390:                return FAILURE;
                    391:        }
                    392: 
                    393:        ALLOC_ZVAL(*retval);
                    394: 
                    395:        /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */
                    396:        if (nodep->type == XML_DTD_NODE) {
                    397:                ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE);
                    398:        } else {
                    399:                ZVAL_LONG(*retval, nodep->type);
                    400:        }
                    401: 
                    402:        return SUCCESS;
                    403: }
                    404: 
                    405: /* }}} */
                    406: 
                    407: /* {{{ parentNode      DomNode 
                    408: readonly=yes 
                    409: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317
                    410: Since: 
                    411: */
                    412: int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
                    413: {
                    414:        xmlNode *nodep, *nodeparent;
                    415:        int ret;
                    416: 
                    417:        nodep = dom_object_get_node(obj);
                    418: 
                    419:        if (nodep == NULL) {
                    420:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    421:                return FAILURE;
                    422:        }
                    423: 
                    424:        ALLOC_ZVAL(*retval);
                    425: 
                    426:        nodeparent = nodep->parent;
                    427:        if (!nodeparent) {
                    428:                ZVAL_NULL(*retval);
                    429:                return SUCCESS;
                    430:        }
                    431: 
1.1.1.2   misho     432:        if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) {
1.1       misho     433:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    434:                return FAILURE;
                    435:        }
                    436:        return SUCCESS;
                    437: }
                    438: 
                    439: /* }}} */
                    440: 
                    441: /* {{{ childNodes      DomNodeList     
                    442: readonly=yes 
                    443: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987
                    444: Since: 
                    445: */
                    446: int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
                    447: {
                    448:        xmlNode *nodep;
                    449:        dom_object *intern;
                    450: 
                    451:        nodep = dom_object_get_node(obj);
                    452: 
                    453:        if (nodep == NULL) {
                    454:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    455:                return FAILURE;
                    456:        }
                    457: 
                    458:        ALLOC_ZVAL(*retval);
                    459:        
                    460:        if (dom_node_children_valid(nodep) == FAILURE) {
                    461:                ZVAL_NULL(*retval);
                    462:        } else {
                    463:                php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
                    464:                intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
                    465:                dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
                    466:        }
                    467: 
                    468:        return SUCCESS;
                    469: }
                    470: 
                    471: /* }}} */
                    472: 
                    473: /* {{{ firstChild DomNode      
                    474: readonly=yes 
                    475: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388
                    476: Since: 
                    477: */
                    478: int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
                    479: {
                    480:        xmlNode *nodep, *first = NULL;
                    481:        int ret;
                    482: 
                    483:        nodep = dom_object_get_node(obj);
                    484: 
                    485:        if (nodep == NULL) {
                    486:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    487:                return FAILURE;
                    488:        }
                    489: 
                    490:        if (dom_node_children_valid(nodep) == SUCCESS) {
                    491:                first = nodep->children;
                    492:        }
                    493: 
                    494:        ALLOC_ZVAL(*retval);
                    495: 
                    496:        if (!first) {
                    497:                ZVAL_NULL(*retval);
                    498:                return SUCCESS;
                    499:        }
                    500: 
1.1.1.2   misho     501:        if (NULL == (*retval = php_dom_create_object(first, &ret, *retval, obj TSRMLS_CC))) {
1.1       misho     502:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    503:                return FAILURE;
                    504:        }
                    505:        return SUCCESS;
                    506: }
                    507: 
                    508: /* }}} */
                    509: 
                    510: /* {{{ lastChild       DomNode 
                    511: readonly=yes 
                    512: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB
                    513: Since: 
                    514: */
                    515: int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
                    516: {
                    517:        xmlNode *nodep, *last = NULL;
                    518:        int ret;
                    519: 
                    520:        nodep = dom_object_get_node(obj);
                    521: 
                    522:        if (nodep == NULL) {
                    523:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    524:                return FAILURE;
                    525:        }
                    526: 
                    527:        if (dom_node_children_valid(nodep) == SUCCESS) {
                    528:                last = nodep->last;
                    529:        }
                    530: 
                    531:        ALLOC_ZVAL(*retval);
                    532: 
                    533:        if (!last) {
                    534:                ZVAL_NULL(*retval);
                    535:                return SUCCESS;
                    536:        }
                    537: 
1.1.1.2   misho     538:        if (NULL == (*retval = php_dom_create_object(last, &ret, *retval, obj TSRMLS_CC))) {
1.1       misho     539:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    540:                return FAILURE;
                    541:        }
                    542:        return SUCCESS;
                    543: }
                    544: 
                    545: /* }}} */
                    546: 
                    547: /* {{{ previousSibling DomNode 
                    548: readonly=yes 
                    549: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8
                    550: Since: 
                    551: */
                    552: int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
                    553: {
                    554:        xmlNode *nodep, *prevsib;
                    555:        int ret;
                    556: 
                    557:        nodep = dom_object_get_node(obj);
                    558: 
                    559:        if (nodep == NULL) {
                    560:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    561:                return FAILURE;
                    562:        }
                    563: 
                    564:        ALLOC_ZVAL(*retval);
                    565: 
                    566:        prevsib = nodep->prev;
                    567:        if (!prevsib) {
                    568:                ZVAL_NULL(*retval);
                    569:                return SUCCESS;
                    570:        }
                    571: 
1.1.1.2   misho     572:        if (NULL == (*retval = php_dom_create_object(prevsib, &ret, *retval, obj TSRMLS_CC))) {
1.1       misho     573:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    574:                return FAILURE;
                    575:        }
                    576:        return SUCCESS;
                    577: }
                    578: 
                    579: /* }}} */
                    580: 
                    581: /* {{{ nextSibling     DomNode
                    582: readonly=yes 
                    583: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F
                    584: Since:
                    585: */
                    586: int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
                    587: {
                    588:        xmlNode *nodep, *nextsib;
                    589:        int ret;
                    590: 
                    591:        nodep = dom_object_get_node(obj);
                    592: 
                    593:        if (nodep == NULL) {
                    594:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    595:                return FAILURE;
                    596:        }
                    597: 
                    598:        nextsib = nodep->next;
                    599:        if (!nextsib) {
                    600:                return FAILURE;
                    601:        }
                    602: 
                    603:        ALLOC_ZVAL(*retval);
                    604: 
1.1.1.2   misho     605:        if (NULL == (*retval = php_dom_create_object(nextsib, &ret, *retval, obj TSRMLS_CC))) {
1.1       misho     606:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    607:                return FAILURE;
                    608:        }
                    609:        return SUCCESS;
                    610: }
                    611: 
                    612: /* }}} */
                    613: 
                    614: /* {{{ attributes      DomNamedNodeMap 
                    615: readonly=yes 
                    616: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096
                    617: Since: 
                    618: */
                    619: int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
                    620: {
                    621:        xmlNode *nodep;
                    622:        dom_object *intern;
                    623: 
                    624:        nodep = dom_object_get_node(obj);
                    625: 
                    626:        if (nodep == NULL) {
                    627:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    628:                return FAILURE;
                    629:        }
                    630: 
                    631:        ALLOC_ZVAL(*retval);
                    632: 
                    633:        if (nodep->type == XML_ELEMENT_NODE) {
                    634:                php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
                    635:                intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
                    636:                dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
                    637:        } else {
                    638:                ZVAL_NULL(*retval);
                    639:        }
                    640: 
                    641:        return SUCCESS;
                    642: }
                    643: 
                    644: /* }}} */
                    645: 
                    646: /* {{{ ownerDocument   DomDocument     
                    647: readonly=yes 
                    648: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc
                    649: Since: 
                    650: */
                    651: int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC)
                    652: {
                    653:        xmlNode *nodep;
                    654:        xmlDocPtr docp;
                    655:        int ret;
                    656: 
                    657:        nodep = dom_object_get_node(obj);
                    658: 
                    659:        if (nodep == NULL) {
                    660:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    661:                return FAILURE;
                    662:        }
                    663: 
                    664:        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
                    665:                ALLOC_ZVAL(*retval);
                    666:                ZVAL_NULL(*retval);
                    667:                return SUCCESS;
                    668:        }
                    669: 
                    670:        docp = nodep->doc;
                    671:        if (!docp) {
                    672:                return FAILURE;
                    673:        }
                    674: 
                    675:        ALLOC_ZVAL(*retval);
                    676: 
1.1.1.2   misho     677:        if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) {
1.1       misho     678:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
                    679:                return FAILURE;
                    680:        }
                    681:        return SUCCESS;
                    682: }
                    683: 
                    684: /* }}} */
                    685: 
                    686: /* {{{ namespaceUri    string  
                    687: readonly=yes 
                    688: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname
                    689: Since: DOM Level 2
                    690: */
                    691: int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
                    692: {
                    693:        xmlNode *nodep;
                    694:        char *str = NULL;
                    695: 
                    696:        nodep = dom_object_get_node(obj);
                    697: 
                    698:        if (nodep == NULL) {
                    699:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    700:                return FAILURE;
                    701:        }
                    702: 
                    703:        switch (nodep->type) {
                    704:                case XML_ELEMENT_NODE:
                    705:                case XML_ATTRIBUTE_NODE:
                    706:                case XML_NAMESPACE_DECL:
                    707:                        if (nodep->ns != NULL) {
                    708:                                str = (char *) nodep->ns->href;
                    709:                        }
                    710:                        break;
                    711:                default:
                    712:                        str = NULL;
                    713:                        break;
                    714:        }
                    715: 
                    716:        ALLOC_ZVAL(*retval);
                    717: 
                    718:        if(str != NULL) {
                    719:                ZVAL_STRING(*retval, str, 1);
                    720:        } else {
                    721:                ZVAL_NULL(*retval);
                    722:        }
                    723: 
                    724:        return SUCCESS;
                    725: }
                    726: 
                    727: /* }}} */
                    728: 
                    729: /* {{{ prefix  string  
                    730: readonly=no 
                    731: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
                    732: Since: DOM Level 2
                    733: */
                    734: int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC)
                    735: {
                    736:        xmlNode *nodep;
                    737:        xmlNsPtr ns;
                    738:        char *str = NULL;
                    739: 
                    740:        nodep = dom_object_get_node(obj);
                    741: 
                    742:        if (nodep == NULL) {
                    743:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    744:                return FAILURE;
                    745:        }
                    746: 
                    747:        switch (nodep->type) {
                    748:                case XML_ELEMENT_NODE:
                    749:                case XML_ATTRIBUTE_NODE:
                    750:                case XML_NAMESPACE_DECL:
                    751:                        ns = nodep->ns;
                    752:                        if (ns != NULL && ns->prefix) {
                    753:                                str = (char *) ns->prefix;
                    754:                        }
                    755:                        break;
                    756:                default:
                    757:                        str = NULL;
                    758:                        break;
                    759:        }
                    760: 
                    761:        ALLOC_ZVAL(*retval);
                    762: 
                    763:        if (str == NULL) {
                    764:                ZVAL_EMPTY_STRING(*retval);
                    765:        } else {
                    766:                ZVAL_STRING(*retval, str, 1);
                    767:        }
                    768:        return SUCCESS;
                    769: 
                    770: }
                    771: 
                    772: int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
                    773: {
                    774:        zval value_copy;
                    775:        xmlNode *nodep, *nsnode = NULL;
                    776:        xmlNsPtr ns = NULL, curns;
                    777:        char *strURI;
                    778:        char *prefix;
                    779: 
                    780:        nodep = dom_object_get_node(obj);
                    781: 
                    782:        if (nodep == NULL) {
                    783:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    784:                return FAILURE;
                    785:        }
                    786: 
                    787:        switch (nodep->type) {
                    788:                case XML_ELEMENT_NODE:
                    789:                        nsnode = nodep;
                    790:                case XML_ATTRIBUTE_NODE:
                    791:                        if (nsnode == NULL) {
                    792:                                nsnode = nodep->parent;
                    793:                                if (nsnode == NULL) {
                    794:                                        nsnode = xmlDocGetRootElement(nodep->doc);
                    795:                                }
                    796:                        }
                    797:                        if (newval->type != IS_STRING) {
                    798:                                if(Z_REFCOUNT_P(newval) > 1) {
                    799:                                        value_copy = *newval;
                    800:                                        zval_copy_ctor(&value_copy);
                    801:                                        newval = &value_copy;
                    802:                                }
                    803:                                convert_to_string(newval);
                    804:                        }
                    805:                        prefix = Z_STRVAL_P(newval);
                    806:                        if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
                    807:                                strURI = (char *) nodep->ns->href;
                    808:                                if (strURI == NULL || 
                    809:                                        (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
                    810:                                        (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
                    811:                                         strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
                    812:                                        (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
                    813:                                        ns = NULL;
                    814:                                } else {
                    815:                                        curns = nsnode->nsDef;
                    816:                                        while (curns != NULL) {
                    817:                                                if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) {
                    818:                                                        ns = curns;
                    819:                                                        break;
                    820:                                                }
                    821:                                                curns = curns->next;
                    822:                                        }
                    823:                                        if (ns == NULL) {
                    824:                                                ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix);
                    825:                                        }
                    826:                                }
                    827: 
                    828:                                if (ns == NULL) {
                    829:                                        if (newval == &value_copy) {
                    830:                                                zval_dtor(newval);
                    831:                                        }
                    832:                                        php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC);
                    833:                                        return FAILURE;
                    834:                                }
                    835: 
                    836:                                xmlSetNs(nodep, ns);
                    837:                        }
                    838:                        if (newval == &value_copy) {
                    839:                                zval_dtor(newval);
                    840:                        }
                    841:                        break;
                    842:                default:
                    843:                        break;
                    844:        }
                    845: 
                    846:        return SUCCESS;
                    847: }
                    848: 
                    849: /* }}} */
                    850: 
                    851: /* {{{ localName       string  
                    852: readonly=yes 
                    853: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN
                    854: Since: DOM Level 2
                    855: */
                    856: int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC)
                    857: {
                    858:        xmlNode *nodep;
                    859: 
                    860:        nodep = dom_object_get_node(obj);
                    861: 
                    862:        if (nodep == NULL) {
                    863:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    864:                return FAILURE;
                    865:        }
                    866: 
                    867:        ALLOC_ZVAL(*retval);
                    868: 
                    869:        if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) {
                    870:                ZVAL_STRING(*retval, (char *) (nodep->name), 1);
                    871:        } else {
                    872:                ZVAL_NULL(*retval);
                    873:        }
                    874: 
                    875:        return SUCCESS;
                    876: }
                    877: 
                    878: /* }}} */
                    879: 
                    880: /* {{{ baseURI string
                    881: readonly=yes
                    882: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI
                    883: Since: DOM Level 3
                    884: */
                    885: int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
                    886: {
                    887:        xmlNode *nodep;
                    888:        xmlChar *baseuri;
                    889: 
                    890:        nodep = dom_object_get_node(obj);
                    891: 
                    892:        if (nodep == NULL) {
                    893:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    894:                return FAILURE;
                    895:        }
                    896: 
                    897:        ALLOC_ZVAL(*retval);
                    898: 
                    899:        baseuri = xmlNodeGetBase(nodep->doc, nodep);
                    900:        if (baseuri) {
                    901:                ZVAL_STRING(*retval, (char *) (baseuri), 1);
                    902:                xmlFree(baseuri);
                    903:        } else {
                    904:                ZVAL_NULL(*retval);
                    905:        }
                    906: 
                    907:        return SUCCESS;
                    908: }
                    909: 
                    910: /* }}} */
                    911: 
                    912: /* {{{ textContent     string  
                    913: readonly=no 
                    914: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
                    915: Since: DOM Level 3
                    916: */
                    917: int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
                    918: {
                    919:        xmlNode *nodep;
                    920:        char *str = NULL;
                    921: 
                    922:        nodep = dom_object_get_node(obj);
                    923: 
                    924:        if (nodep == NULL) {
                    925:                php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
                    926:                return FAILURE;
                    927:        }
                    928: 
                    929:        str = xmlNodeGetContent(nodep);
                    930: 
                    931:        ALLOC_ZVAL(*retval);
                    932: 
                    933:        if(str != NULL) {
                    934:                ZVAL_STRING(*retval, str, 1);
                    935:                xmlFree(str);
                    936:        } else {
                    937:                ZVAL_EMPTY_STRING(*retval);
                    938:        }
                    939: 
                    940:        return SUCCESS;
                    941: }
                    942: 
                    943: int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
                    944: {
                    945:        return SUCCESS;
                    946: }
                    947: 
                    948: /* }}} */
                    949: 
                    950: static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlNodePtr nextsib, xmlNodePtr fragment, dom_object *intern, dom_object *childobj TSRMLS_DC) /* {{{ */
                    951: {
                    952:        xmlNodePtr newchild, node;
                    953: 
                    954:        newchild = fragment->children;
                    955: 
                    956:        if (newchild) {
                    957:                if (prevsib == NULL) {
                    958:                        nodep->children = newchild;
                    959:                } else {
                    960:                        prevsib->next = newchild;
                    961:                }
                    962:                newchild->prev = prevsib;
                    963:                if (nextsib == NULL) {
                    964:                        nodep->last = fragment->last;
                    965:                } else {
                    966:                        fragment->last->next = nextsib;
                    967:                        nextsib->prev = fragment->last;
                    968:                }
                    969: 
                    970:                node = newchild;
                    971:                while (node != NULL) {
                    972:                        node->parent = nodep;
                    973:                        if (node->doc != nodep->doc) {
                    974:                                xmlSetTreeDoc(node, nodep->doc);
                    975:                                if (node->_private != NULL) {
                    976:                                        childobj = node->_private;
                    977:                                        childobj->document = intern->document;
                    978:                                        php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
                    979:                                }
                    980:                        }
                    981:                        if (node == fragment->last) {
                    982:                                break;
                    983:                        }
                    984:                        node = node->next;
                    985:                }
                    986: 
                    987:                fragment->children = NULL;
                    988:                fragment->last = NULL;
                    989:        }
                    990: 
                    991:        return newchild;
                    992: }
                    993: /* }}} */
                    994: 
                    995: /* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild);
                    996: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
                    997: Since:
                    998: */
                    999: PHP_FUNCTION(dom_node_insert_before)
                   1000: {
                   1001:        zval *id, *node, *ref = NULL;
                   1002:        xmlNodePtr child, new_child, parentp, refp;
                   1003:        dom_object *intern, *childobj, *refpobj;
                   1004:        int ret, stricterror;
                   1005: 
                   1006:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|O!", &id, dom_node_class_entry, &node, dom_node_class_entry, &ref, dom_node_class_entry) == FAILURE) {
                   1007:                return;
                   1008:        }
                   1009: 
                   1010:        DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
                   1011: 
                   1012:        if (dom_node_children_valid(parentp) == FAILURE) {
                   1013:                RETURN_FALSE;
                   1014:        }
                   1015: 
                   1016:        DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
                   1017: 
                   1018:        new_child = NULL;
                   1019: 
                   1020:        stricterror = dom_get_strict_error(intern->document);
                   1021: 
                   1022:        if (dom_node_is_read_only(parentp) == SUCCESS ||
                   1023:                (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
                   1024:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
                   1025:                RETURN_FALSE;
                   1026:        }
                   1027: 
                   1028:        if (dom_hierarchy(parentp, child) == FAILURE) {
                   1029:                php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
                   1030:                RETURN_FALSE;
                   1031:        }
                   1032: 
                   1033:        if (child->doc != parentp->doc && child->doc != NULL) {
                   1034:                php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
                   1035:                RETURN_FALSE;
                   1036:        }
                   1037: 
                   1038:        if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
                   1039:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
                   1040:                RETURN_FALSE;
                   1041:        }
                   1042: 
                   1043:        if (child->doc == NULL && parentp->doc != NULL) {
                   1044:                childobj->document = intern->document;
                   1045:                php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
                   1046:        }
                   1047: 
                   1048:        if (ref != NULL) {
                   1049:                DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
                   1050:                if (refp->parent != parentp) {
                   1051:                        php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
                   1052:                        RETURN_FALSE;
                   1053:                }
                   1054: 
                   1055:                if (child->parent != NULL) {
                   1056:                        xmlUnlinkNode(child);
                   1057:                }
                   1058: 
                   1059:                if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE || 
                   1060:                        (refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) {
                   1061:                        if (child->doc == NULL) {
                   1062:                                xmlSetTreeDoc(child, parentp->doc);
                   1063:                        }
                   1064:                        new_child = child;
                   1065:                        new_child->parent = refp->parent;
                   1066:                        new_child->next = refp;
                   1067:                        new_child->prev = refp->prev;
                   1068:                        refp->prev = new_child;
                   1069:                        if (new_child->prev != NULL) {
                   1070:                                new_child->prev->next = new_child;
                   1071:                        }
                   1072:                        if (new_child->parent != NULL) {
                   1073:                                if (new_child->parent->children == refp) {
                   1074:                                        new_child->parent->children = new_child;
                   1075:                                }
                   1076:                        }
                   1077: 
                   1078:                } else if (child->type == XML_ATTRIBUTE_NODE) {
                   1079:                        xmlAttrPtr lastattr;
                   1080: 
                   1081:                        if (child->ns == NULL)
                   1082:                                lastattr = xmlHasProp(refp->parent, child->name);
                   1083:                        else
                   1084:                                lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
                   1085:                        if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
                   1086:                                if (lastattr != (xmlAttrPtr) child) {
                   1087:                                        xmlUnlinkNode((xmlNodePtr) lastattr);
                   1088:                                        php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
                   1089:                                } else {
1.1.1.2   misho    1090:                                        DOM_RET_OBJ(child, &ret, intern);
1.1       misho    1091:                                        return;
                   1092:                                }
                   1093:                        }
                   1094:                } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
                   1095:                        new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC);
                   1096:                }
                   1097: 
                   1098:                if (new_child == NULL) {
                   1099:                        new_child = xmlAddPrevSibling(refp, child);
                   1100:                }
                   1101:        } else {
                   1102:                if (child->parent != NULL){
                   1103:                        xmlUnlinkNode(child);
                   1104:                }
                   1105:                if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) {
                   1106:                        child->parent = parentp;
                   1107:                        if (child->doc == NULL) {
                   1108:                                xmlSetTreeDoc(child, parentp->doc);
                   1109:                        }
                   1110:                        new_child = child;
                   1111:                        if (parentp->children == NULL) {
                   1112:                                parentp->children = child;
                   1113:                                parentp->last = child;
                   1114:                        } else {
                   1115:                                child = parentp->last;
                   1116:                                child->next = new_child;
                   1117:                                new_child->prev = child;
                   1118:                                parentp->last = new_child;
                   1119:                        }
                   1120:                } else  if (child->type == XML_ATTRIBUTE_NODE) {
                   1121:                        xmlAttrPtr lastattr;
                   1122: 
                   1123:                        if (child->ns == NULL)
                   1124:                                lastattr = xmlHasProp(parentp, child->name);
                   1125:                        else
                   1126:                                lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
                   1127:                        if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
                   1128:                                if (lastattr != (xmlAttrPtr) child) {
                   1129:                                        xmlUnlinkNode((xmlNodePtr) lastattr);
                   1130:                                        php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
                   1131:                                } else {
1.1.1.2   misho    1132:                                        DOM_RET_OBJ(child, &ret, intern);
1.1       misho    1133:                                        return;
                   1134:                                }
                   1135:                        }
                   1136:                } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
                   1137:                        new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC);
                   1138:                }
                   1139:                if (new_child == NULL) {
                   1140:                        new_child = xmlAddChild(parentp, child);
                   1141:                }
                   1142:        }
                   1143: 
                   1144:        if (NULL == new_child) {
                   1145:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode");
                   1146:                RETURN_FALSE;
                   1147:        }
                   1148: 
                   1149:        dom_reconcile_ns(parentp->doc, new_child);
                   1150: 
1.1.1.2   misho    1151:        DOM_RET_OBJ(new_child, &ret, intern);
1.1       misho    1152: 
                   1153: }
                   1154: /* }}} end dom_node_insert_before */
                   1155: 
                   1156: /* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);
                   1157: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
                   1158: Since: 
                   1159: */
                   1160: PHP_FUNCTION(dom_node_replace_child)
                   1161: {
                   1162:        zval *id, *newnode, *oldnode;
                   1163:        xmlNodePtr children, newchild, oldchild, nodep;
                   1164:        dom_object *intern, *newchildobj, *oldchildobj;
                   1165:        int foundoldchild = 0, stricterror;
                   1166: 
                   1167:        int ret;
                   1168: 
                   1169:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOO", &id, dom_node_class_entry, &newnode, dom_node_class_entry, &oldnode, dom_node_class_entry) == FAILURE) {
                   1170:                return;
                   1171:        }
                   1172: 
                   1173:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1174: 
                   1175:        if (dom_node_children_valid(nodep) == FAILURE) {
                   1176:                RETURN_FALSE;
                   1177:        }
                   1178: 
                   1179:        DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
                   1180:        DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
                   1181: 
                   1182:        children = nodep->children;
                   1183:        if (!children) {
                   1184:                RETURN_FALSE;
                   1185:        }
                   1186: 
                   1187:        stricterror = dom_get_strict_error(intern->document);
                   1188: 
                   1189:        if (dom_node_is_read_only(nodep) == SUCCESS || 
                   1190:                (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
                   1191:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
                   1192:                RETURN_FALSE;
                   1193:        }
                   1194: 
                   1195:        if (newchild->doc != nodep->doc && newchild->doc != NULL) {
                   1196:                php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
                   1197:                RETURN_FALSE;
                   1198:        }
                   1199: 
                   1200:        if (dom_hierarchy(nodep, newchild) == FAILURE) {
                   1201:                php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
                   1202:                RETURN_FALSE;
                   1203:        }
                   1204: 
                   1205:        /* check for the old child and whether the new child is already a child */
                   1206:        while (children) {
                   1207:                if (children == oldchild) {
                   1208:                        foundoldchild = 1;
                   1209:                        break;
                   1210:                }
                   1211:                children = children->next;
                   1212:        }
                   1213: 
                   1214:        if (foundoldchild) {
                   1215:                if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
                   1216:                        xmlNodePtr prevsib, nextsib;
                   1217:                        prevsib = oldchild->prev;
                   1218:                        nextsib = oldchild->next;
                   1219: 
                   1220:                        xmlUnlinkNode(oldchild);
                   1221: 
                   1222:                        newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC);
                   1223:                        if (newchild) {
                   1224:                                dom_reconcile_ns(nodep->doc, newchild);
                   1225:                        }
                   1226:                } else if (oldchild != newchild) {
                   1227:                        if (newchild->doc == NULL && nodep->doc != NULL) {
                   1228:                                xmlSetTreeDoc(newchild, nodep->doc);
                   1229:                                newchildobj->document = intern->document;
                   1230:                                php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
                   1231:                        }
                   1232:                        xmlReplaceNode(oldchild, newchild);
                   1233:                        dom_reconcile_ns(nodep->doc, newchild);
                   1234:                }
1.1.1.2   misho    1235:                DOM_RET_OBJ(oldchild, &ret, intern);
1.1       misho    1236:                return;
                   1237:        } else {
                   1238:                php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
                   1239:                RETURN_FALSE;
                   1240:        }
                   1241: }
                   1242: /* }}} end dom_node_replace_child */
                   1243: 
                   1244: /* {{{ proto DomNode dom_node_remove_child(DomNode oldChild);
                   1245: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
                   1246: Since: 
                   1247: */
                   1248: PHP_FUNCTION(dom_node_remove_child)
                   1249: {
                   1250:        zval *id, *node;
                   1251:        xmlNodePtr children, child, nodep;
                   1252:        dom_object *intern, *childobj;
                   1253:        int ret, stricterror;
                   1254: 
                   1255:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
                   1256:                return;
                   1257:        }
                   1258: 
                   1259:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1260: 
                   1261:        if (dom_node_children_valid(nodep) == FAILURE) {
                   1262:                RETURN_FALSE;
                   1263:        }
                   1264: 
                   1265:        DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
                   1266: 
                   1267:        stricterror = dom_get_strict_error(intern->document);
                   1268: 
                   1269:        if (dom_node_is_read_only(nodep) == SUCCESS || 
                   1270:                (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
                   1271:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
                   1272:                RETURN_FALSE;
                   1273:        }
                   1274: 
                   1275:        children = nodep->children;
                   1276:        if (!children) {
                   1277:                php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
                   1278:                RETURN_FALSE;
                   1279:        }
                   1280: 
                   1281:        while (children) {
                   1282:                if (children == child) {
                   1283:                        xmlUnlinkNode(child);
1.1.1.2   misho    1284:                        DOM_RET_OBJ(child, &ret, intern);
1.1       misho    1285:                        return;
                   1286:                }
                   1287:                children = children->next;
                   1288:        }
                   1289: 
                   1290:        php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
                   1291:        RETURN_FALSE
                   1292: }
                   1293: /* }}} end dom_node_remove_child */
                   1294: 
                   1295: /* {{{ proto DomNode dom_node_append_child(DomNode newChild);
                   1296: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
                   1297: Since: 
                   1298: */
                   1299: PHP_FUNCTION(dom_node_append_child)
                   1300: {
                   1301:        zval *id, *node;
                   1302:        xmlNodePtr child, nodep, new_child = NULL;
                   1303:        dom_object *intern, *childobj;
                   1304:        int ret, stricterror;
                   1305: 
                   1306:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
                   1307:                return;
                   1308:        }
                   1309: 
                   1310:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1311: 
                   1312:        if (dom_node_children_valid(nodep) == FAILURE) {
                   1313:                RETURN_FALSE;
                   1314:        }
                   1315: 
                   1316:        DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
                   1317: 
                   1318:        stricterror = dom_get_strict_error(intern->document);
                   1319: 
                   1320:        if (dom_node_is_read_only(nodep) == SUCCESS ||
                   1321:                (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
                   1322:                php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
                   1323:                RETURN_FALSE;
                   1324:        }
                   1325: 
                   1326:        if (dom_hierarchy(nodep, child) == FAILURE) {
                   1327:                php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
                   1328:                RETURN_FALSE;
                   1329:        }
                   1330: 
                   1331:        if (!(child->doc == NULL || child->doc == nodep->doc)) {
                   1332:                php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
                   1333:                RETURN_FALSE;
                   1334:        }
                   1335: 
                   1336:        if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
                   1337:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
                   1338:                RETURN_FALSE;
                   1339:        }
                   1340: 
                   1341:        if (child->doc == NULL && nodep->doc != NULL) {
                   1342:                childobj->document = intern->document;
                   1343:                php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
                   1344:        }
                   1345: 
                   1346:        if (child->parent != NULL){
                   1347:                xmlUnlinkNode(child);
                   1348:        }
                   1349: 
                   1350:        if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) {
                   1351:                child->parent = nodep;
                   1352:                if (child->doc == NULL) {
                   1353:                        xmlSetTreeDoc(child, nodep->doc);
                   1354:                }
                   1355:                new_child = child;
                   1356:                if (nodep->children == NULL) {
                   1357:                        nodep->children = child;
                   1358:                        nodep->last = child;
                   1359:                } else {
                   1360:                        child = nodep->last;
                   1361:                        child->next = new_child;
                   1362:                        new_child->prev = child;
                   1363:                        nodep->last = new_child;
                   1364:                }
                   1365:        } else  if (child->type == XML_ATTRIBUTE_NODE) {
                   1366:                xmlAttrPtr lastattr;
                   1367: 
                   1368:                if (child->ns == NULL)
                   1369:                        lastattr = xmlHasProp(nodep, child->name);
                   1370:                else
                   1371:                        lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
                   1372:                if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
                   1373:                        if (lastattr != (xmlAttrPtr) child) {
                   1374:                                xmlUnlinkNode((xmlNodePtr) lastattr);
                   1375:                                php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
                   1376:                        }
                   1377:                }
                   1378:        } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
                   1379:                new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC);
                   1380:        }
                   1381: 
                   1382:        if (new_child == NULL) {
                   1383:                new_child = xmlAddChild(nodep, child);
                   1384:                if (new_child == NULL) {
                   1385:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node");
                   1386:                        RETURN_FALSE;
                   1387:                }
                   1388:        }
                   1389: 
                   1390:        dom_reconcile_ns(nodep->doc, new_child);
                   1391: 
1.1.1.2   misho    1392:        DOM_RET_OBJ(new_child, &ret, intern);
1.1       misho    1393: }
                   1394: /* }}} end dom_node_append_child */
                   1395: 
                   1396: /* {{{ proto boolean dom_node_has_child_nodes();
                   1397: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
                   1398: Since: 
                   1399: */
                   1400: PHP_FUNCTION(dom_node_has_child_nodes)
                   1401: {
                   1402:        zval *id;
                   1403:        xmlNode *nodep;
                   1404:        dom_object *intern;
                   1405: 
                   1406:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
                   1407:                return;
                   1408:        }
                   1409: 
                   1410:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1411: 
                   1412:        if (dom_node_children_valid(nodep) == FAILURE) {
                   1413:                RETURN_FALSE;
                   1414:        }
                   1415: 
                   1416:        if (nodep->children) {
                   1417:                RETURN_TRUE;
                   1418:        } else {
                   1419:                RETURN_FALSE;
                   1420:        }
                   1421: }
                   1422: /* }}} end dom_node_has_child_nodes */
                   1423: 
                   1424: /* {{{ proto DomNode dom_node_clone_node(boolean deep);
                   1425: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4
                   1426: Since: 
                   1427: */
                   1428: PHP_FUNCTION(dom_node_clone_node)
                   1429: {
                   1430:        zval *id;
                   1431:        xmlNode *n, *node;
                   1432:        int ret;
                   1433:        dom_object *intern;
                   1434:        long recursive = 0;
                   1435: 
                   1436:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
                   1437:                return;
                   1438:        }
                   1439: 
                   1440:        DOM_GET_OBJ(n, id, xmlNodePtr, intern);
                   1441: 
                   1442:        node = xmlDocCopyNode(n, n->doc, recursive);
                   1443: 
                   1444:        if (!node) {
                   1445:                RETURN_FALSE;
                   1446:        }
                   1447: 
                   1448:        /* When deep is false Element nodes still require the attributes 
                   1449:        Following taken from libxml as xmlDocCopyNode doesnt do this */
                   1450:        if (n->type == XML_ELEMENT_NODE && recursive == 0) {
                   1451:                if (n->nsDef != NULL) {
                   1452:                        node->nsDef = xmlCopyNamespaceList(n->nsDef);
                   1453:                }
                   1454:                if (n->ns != NULL) {
                   1455:                        xmlNsPtr ns;
                   1456:                        ns = xmlSearchNs(n->doc, node, n->ns->prefix);
                   1457:                        if (ns == NULL) {
                   1458:                                ns = xmlSearchNs(n->doc, n, n->ns->prefix);
                   1459:                                if (ns != NULL) {
                   1460:                                        xmlNodePtr root = node;
                   1461: 
                   1462:                                        while (root->parent != NULL) {
                   1463:                                                root = root->parent;
                   1464:                                        }
                   1465:                                        node->ns = xmlNewNs(root, ns->href, ns->prefix);
                   1466:                                }
                   1467:                        } else {
                   1468:                                node->ns = ns;
                   1469:                        }
                   1470:                }
                   1471:                if (n->properties != NULL) {
                   1472:                        node->properties = xmlCopyPropList(node, n->properties);
                   1473:                }
                   1474:        }
                   1475: 
                   1476:        /* If document cloned we want a new document proxy */
                   1477:        if (node->doc != n->doc) {
                   1478:                intern = NULL;
                   1479:        }
                   1480: 
1.1.1.2   misho    1481:        DOM_RET_OBJ(node, &ret, intern);
1.1       misho    1482: }
                   1483: /* }}} end dom_node_clone_node */
                   1484: 
                   1485: /* {{{ proto void dom_node_normalize();
                   1486: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize
                   1487: Since: 
                   1488: */
                   1489: PHP_FUNCTION(dom_node_normalize)
                   1490: {
                   1491:        zval *id;
                   1492:        xmlNode *nodep;
                   1493:        dom_object *intern;
                   1494: 
                   1495:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
                   1496:                return;
                   1497:        }
                   1498: 
                   1499:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1500: 
                   1501:        dom_normalize(nodep TSRMLS_CC);
                   1502: 
                   1503: }
                   1504: /* }}} end dom_node_normalize */
                   1505: 
                   1506: /* {{{ proto boolean dom_node_is_supported(string feature, string version);
                   1507: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports
                   1508: Since: DOM Level 2
                   1509: */
                   1510: PHP_FUNCTION(dom_node_is_supported)
                   1511: {
                   1512:        zval *id;
                   1513:        int feature_len, version_len;
                   1514:        char *feature, *version;
                   1515: 
                   1516:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) {
                   1517:                return;
                   1518:        }
                   1519: 
                   1520:        if (dom_has_feature(feature, version)) {
                   1521:                RETURN_TRUE;
                   1522:        } else {
                   1523:                RETURN_FALSE;
                   1524:        }
                   1525: }
                   1526: /* }}} end dom_node_is_supported */
                   1527: 
                   1528: /* {{{ proto boolean dom_node_has_attributes();
                   1529: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs
                   1530: Since: DOM Level 2
                   1531: */
                   1532: PHP_FUNCTION(dom_node_has_attributes)
                   1533: {
                   1534:        zval *id;
                   1535:        xmlNode *nodep;
                   1536:        dom_object *intern;
                   1537: 
                   1538:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
                   1539:                return;
                   1540:        }
                   1541: 
                   1542:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1543: 
                   1544:        if (nodep->type != XML_ELEMENT_NODE)
                   1545:                RETURN_FALSE;
                   1546: 
                   1547:        if (nodep->properties) {
                   1548:                RETURN_TRUE;
                   1549:        } else {
                   1550:                RETURN_FALSE;
                   1551:        }
                   1552: }
                   1553: /* }}} end dom_node_has_attributes */
                   1554: 
                   1555: /* {{{ proto short dom_node_compare_document_position(DomNode other);
                   1556: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition
                   1557: Since: DOM Level 3
                   1558: */
                   1559: PHP_FUNCTION(dom_node_compare_document_position)
                   1560: {
                   1561:  DOM_NOT_IMPLEMENTED();
                   1562: }
                   1563: /* }}} end dom_node_compare_document_position */
                   1564: 
                   1565: /* {{{ proto boolean dom_node_is_same_node(DomNode other);
                   1566: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
                   1567: Since: DOM Level 3
                   1568: */
                   1569: PHP_FUNCTION(dom_node_is_same_node)
                   1570: {
                   1571:        zval *id, *node;
                   1572:        xmlNodePtr nodeotherp, nodep;
                   1573:        dom_object *intern, *nodeotherobj;
                   1574: 
                   1575:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
                   1576:                return;
                   1577:        }
                   1578: 
                   1579:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1580: 
                   1581:        DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
                   1582: 
                   1583:        if (nodep == nodeotherp) {
                   1584:                RETURN_TRUE;
                   1585:        } else {
                   1586:                RETURN_FALSE;
                   1587:        }
                   1588: }
                   1589: /* }}} end dom_node_is_same_node */
                   1590: 
                   1591: /* {{{ proto string dom_node_lookup_prefix(string namespaceURI);
                   1592: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
                   1593: Since: DOM Level 3
                   1594: */
                   1595: PHP_FUNCTION(dom_node_lookup_prefix)
                   1596: {
                   1597:        zval *id;
                   1598:        xmlNodePtr nodep, lookupp = NULL;
                   1599:        dom_object *intern;
                   1600:        xmlNsPtr nsptr;
                   1601:        int uri_len = 0;
                   1602:        char *uri;
                   1603: 
                   1604:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
                   1605:                return;
                   1606:        }
                   1607: 
                   1608:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1609: 
                   1610:        if (uri_len > 0) {
                   1611:                switch (nodep->type) { 
                   1612:                        case XML_ELEMENT_NODE:
                   1613:                                lookupp = nodep;
                   1614:                                break; 
                   1615:                        case XML_DOCUMENT_NODE:
                   1616:                        case XML_HTML_DOCUMENT_NODE:
                   1617:                                lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
                   1618:                                break;
                   1619:                        case XML_ENTITY_NODE : 
                   1620:                        case XML_NOTATION_NODE: 
                   1621:                        case XML_DOCUMENT_FRAG_NODE: 
                   1622:                        case XML_DOCUMENT_TYPE_NODE:
                   1623:                        case XML_DTD_NODE:
                   1624:                                RETURN_NULL();
                   1625:                                break;
                   1626:                        default:
                   1627:                                lookupp =  nodep->parent;
                   1628:                } 
                   1629: 
                   1630:                if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
                   1631:                        if (nsptr->prefix != NULL) {
                   1632:                                RETURN_STRING((char *) nsptr->prefix, 1);
                   1633:                        }
                   1634:                }
                   1635:        }
                   1636:                
                   1637:        RETURN_NULL();
                   1638: }
                   1639: /* }}} end dom_node_lookup_prefix */
                   1640: 
                   1641: /* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI);
                   1642: URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
                   1643: Since: DOM Level 3
                   1644: */
                   1645: PHP_FUNCTION(dom_node_is_default_namespace)
                   1646: {
                   1647:        zval *id;
                   1648:        xmlNodePtr nodep;
                   1649:        dom_object *intern;
                   1650:        xmlNsPtr nsptr;
                   1651:        int uri_len = 0;
                   1652:        char *uri;
                   1653: 
                   1654:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
                   1655:                return;
                   1656:        }
                   1657: 
                   1658:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1659:        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
                   1660:                nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
                   1661:        }
                   1662: 
                   1663:        if (nodep && uri_len > 0) {
                   1664:                nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
                   1665:                if (nsptr && xmlStrEqual(nsptr->href, uri)) {
                   1666:                        RETURN_TRUE;
                   1667:                }
                   1668:        }
                   1669: 
                   1670:        RETURN_FALSE;
                   1671: }
                   1672: /* }}} end dom_node_is_default_namespace */
                   1673: 
                   1674: /* {{{ proto string dom_node_lookup_namespace_uri(string prefix);
                   1675: URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
                   1676: Since: DOM Level 3
                   1677: */
                   1678: PHP_FUNCTION(dom_node_lookup_namespace_uri)
                   1679: {
                   1680:        zval *id;
                   1681:        xmlNodePtr nodep;
                   1682:        dom_object *intern;
                   1683:        xmlNsPtr nsptr;
                   1684:        int prefix_len = 0;
                   1685:        char *prefix=NULL;
                   1686: 
                   1687:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) {
                   1688:                return;
                   1689:        }
                   1690: 
                   1691:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1692:        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
                   1693:                nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
                   1694:                if (nodep == NULL) {
                   1695:                        RETURN_NULL();
                   1696:                }
                   1697:        }
                   1698: 
                   1699:        nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
                   1700:        if (nsptr && nsptr->href != NULL) {
                   1701:                RETURN_STRING((char *) nsptr->href, 1);
                   1702:        }
                   1703: 
                   1704:        RETURN_NULL();
                   1705: }
                   1706: /* }}} end dom_node_lookup_namespace_uri */
                   1707: 
                   1708: /* {{{ proto boolean dom_node_is_equal_node(DomNode arg);
                   1709: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode
                   1710: Since: DOM Level 3
                   1711: */
                   1712: PHP_FUNCTION(dom_node_is_equal_node)
                   1713: {
                   1714:  DOM_NOT_IMPLEMENTED();
                   1715: }
                   1716: /* }}} end dom_node_is_equal_node */
                   1717: 
                   1718: /* {{{ proto DomNode dom_node_get_feature(string feature, string version);
                   1719: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature
                   1720: Since: DOM Level 3
                   1721: */
                   1722: PHP_FUNCTION(dom_node_get_feature)
                   1723: {
                   1724:  DOM_NOT_IMPLEMENTED();
                   1725: }
                   1726: /* }}} end dom_node_get_feature */
                   1727: 
                   1728: /* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);
                   1729: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData
                   1730: Since: DOM Level 3
                   1731: */
                   1732: PHP_FUNCTION(dom_node_set_user_data)
                   1733: {
                   1734:  DOM_NOT_IMPLEMENTED();
                   1735: }
                   1736: /* }}} end dom_node_set_user_data */
                   1737: 
                   1738: /* {{{ proto mixed dom_node_get_user_data(string key);
                   1739: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData
                   1740: Since: DOM Level 3
                   1741: */
                   1742: PHP_FUNCTION(dom_node_get_user_data)
                   1743: {
                   1744:  DOM_NOT_IMPLEMENTED();
                   1745: }
                   1746: /* }}} end dom_node_get_user_data */
                   1747: 
                   1748: static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
                   1749: {
                   1750:        zval *id;
                   1751:        zval *xpath_array=NULL, *ns_prefixes=NULL;
                   1752:        xmlNodePtr nodep;
                   1753:        xmlDocPtr docp;
                   1754:        xmlNodeSetPtr nodeset = NULL;
                   1755:        dom_object *intern;
                   1756:        zend_bool exclusive=0, with_comments=0;
                   1757:        xmlChar **inclusive_ns_prefixes = NULL;
                   1758:        char *file = NULL;
                   1759:        int ret = -1, file_len = 0;
                   1760:        xmlOutputBufferPtr buf;
                   1761:        xmlXPathContextPtr ctxp=NULL;
                   1762:        xmlXPathObjectPtr xpathobjp=NULL;
                   1763: 
                   1764:        if (mode == 0) {
                   1765:                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
                   1766:                        "O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments, 
                   1767:                        &xpath_array, &ns_prefixes) == FAILURE) {
                   1768:                        return;
                   1769:                }
                   1770:        } else {
                   1771:                if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
                   1772:                        "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive, 
                   1773:                        &with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
                   1774:                        return;
                   1775:                }
                   1776:        }
                   1777: 
                   1778:        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
                   1779: 
                   1780:        docp = nodep->doc;
                   1781: 
                   1782:        if (! docp) {
                   1783:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document");
                   1784:                RETURN_FALSE;
                   1785:        }
                   1786: 
                   1787:        if (xpath_array == NULL) {
                   1788:                if (nodep->type != XML_DOCUMENT_NODE) {
                   1789:                        ctxp = xmlXPathNewContext(docp);
                   1790:                        ctxp->node = nodep;
                   1791:                        xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp);
                   1792:                        ctxp->node = NULL;
                   1793:                        if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
                   1794:                                nodeset = xpathobjp->nodesetval;
                   1795:                        } else {
                   1796:                                if (xpathobjp) {
                   1797:                                        xmlXPathFreeObject(xpathobjp);
                   1798:                                }
                   1799:                                xmlXPathFreeContext(ctxp);
                   1800:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
                   1801:                                RETURN_FALSE;
                   1802:                        }
                   1803:                }
                   1804:        } else {
                   1805:                /*xpath query from xpath_array */
                   1806:                HashTable *ht = Z_ARRVAL_P(xpath_array);
                   1807:                zval **tmp;
                   1808:                char *xquery;
                   1809: 
                   1810:                if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS &&
                   1811:                    Z_TYPE_PP(tmp) == IS_STRING) {
                   1812:                        xquery = Z_STRVAL_PP(tmp);
                   1813:                } else {
                   1814:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string");
                   1815:                        RETURN_FALSE;
                   1816:                }
                   1817: 
                   1818:                ctxp = xmlXPathNewContext(docp);
                   1819:                ctxp->node = nodep;
                   1820: 
                   1821:                if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS &&
                   1822:                    Z_TYPE_PP(tmp) == IS_ARRAY) {
                   1823:                        zval **tmpns;
                   1824:                        while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) {
                   1825:                                if (Z_TYPE_PP(tmpns) == IS_STRING) {
                   1826:                                        char *prefix;
                   1827:                                        ulong idx;
1.1.1.2   misho    1828:                                        uint prefix_key_len;
1.1       misho    1829: 
                   1830:                                        if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp), 
                   1831:                                                &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
                   1832:                                                xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns));
                   1833:                                        }
                   1834:                                }
                   1835:                                zend_hash_move_forward(Z_ARRVAL_PP(tmp));
                   1836:                        }
                   1837:                }
                   1838: 
                   1839:                xpathobjp = xmlXPathEvalExpression(xquery, ctxp);
                   1840:                ctxp->node = NULL;
                   1841:                if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
                   1842:                        nodeset = xpathobjp->nodesetval;
                   1843:                } else {
                   1844:                        if (xpathobjp) {
                   1845:                                xmlXPathFreeObject(xpathobjp);
                   1846:                        }
                   1847:                        xmlXPathFreeContext(ctxp);
                   1848:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
                   1849:                        RETURN_FALSE;
                   1850:                }
                   1851:        }
                   1852: 
                   1853:        if (ns_prefixes != NULL) {
                   1854:                if (exclusive) {
                   1855:                        zval **tmpns;
                   1856:                        int nscount = 0;
                   1857: 
                   1858:                        inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1,
                   1859:                                sizeof(xmlChar *), 0);
                   1860:                        while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) {
                   1861:                                if (Z_TYPE_PP(tmpns) == IS_STRING) {
                   1862:                                        inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns);
                   1863:                                }
                   1864:                                zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes));
                   1865:                        }
                   1866:                        inclusive_ns_prefixes[nscount] = NULL;
                   1867:                } else {
                   1868:                        php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
                   1869:                                "Inclusive namespace prefixes only allowed in exclusive mode.");
                   1870:                }
                   1871:        }
                   1872: 
                   1873:        if (mode == 1) {
                   1874:                buf = xmlOutputBufferCreateFilename(file, NULL, 0);
                   1875:        } else {
                   1876:                buf = xmlAllocOutputBuffer(NULL);
                   1877:        }
                   1878: 
                   1879:     if (buf != NULL) {
                   1880:                ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
                   1881:                        with_comments, buf);
                   1882:        }
                   1883: 
                   1884:        if (inclusive_ns_prefixes != NULL) {
                   1885:                efree(inclusive_ns_prefixes);
                   1886:        }
                   1887:        if (xpathobjp != NULL) {
                   1888:                xmlXPathFreeObject(xpathobjp);
                   1889:        }
                   1890:        if (ctxp != NULL) {
                   1891:                xmlXPathFreeContext(ctxp);
                   1892:        }
                   1893: 
                   1894:     if (buf == NULL || ret < 0) {
                   1895:         RETVAL_FALSE;
                   1896:     } else {
                   1897:                if (mode == 0) {
1.1.1.3   misho    1898: #ifdef LIBXML2_NEW_BUFFER
                   1899:                        ret = xmlOutputBufferGetSize(buf);
                   1900: #else
1.1       misho    1901:                        ret = buf->buffer->use;
1.1.1.3   misho    1902: #endif
1.1       misho    1903:                        if (ret > 0) {
1.1.1.3   misho    1904: #ifdef LIBXML2_NEW_BUFFER
                   1905:                                RETVAL_STRINGL((char *) xmlOutputBufferGetContent(buf), ret, 1);
                   1906: #else
1.1       misho    1907:                                RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
1.1.1.3   misho    1908: #endif
1.1       misho    1909:                        } else {
                   1910:                                RETVAL_EMPTY_STRING();
                   1911:                        }
                   1912:                }
                   1913:     }
                   1914: 
                   1915:        if (buf) {
                   1916:                int bytes;
                   1917: 
                   1918:                bytes = xmlOutputBufferClose(buf);
                   1919:                if (mode == 1 && (ret >= 0)) {
                   1920:                        RETURN_LONG(bytes);
                   1921:                }
                   1922:        }
                   1923: }
                   1924: /* }}} */
                   1925: 
                   1926: /* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
                   1927:    Canonicalize nodes to a string */
                   1928: PHP_METHOD(domnode, C14N)
                   1929: {
                   1930:        dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   1931: }
                   1932: /* }}} */
                   1933: 
                   1934: /* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
                   1935:    Canonicalize nodes to a file */
                   1936: PHP_METHOD(domnode, C14NFile)
                   1937: {
                   1938:        dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                   1939: }
                   1940: /* }}} */
                   1941: 
                   1942: /* {{{ proto int DOMNode::getNodePath()
                   1943:    Gets an xpath for a node */
                   1944: PHP_METHOD(domnode, getNodePath)
                   1945: {
                   1946:        zval *id;
                   1947:        xmlNode *nodep;
                   1948:        dom_object *intern;
                   1949:        char *value;
                   1950:        
                   1951:        DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
                   1952: 
                   1953:        value = xmlGetNodePath(nodep);
                   1954:        if (value == NULL) {
                   1955:                RETURN_NULL();
                   1956:        } else {
                   1957:                RETVAL_STRING(value, 1);
                   1958:                xmlFree(value);
                   1959:        }
                   1960: }
                   1961: /* }}} */
                   1962: 
                   1963: /* {{{ proto int DOMNode::getLineNo()
                   1964:    Gets line number for a node */
                   1965: PHP_METHOD(domnode, getLineNo)
                   1966: {
                   1967:        zval *id;
                   1968:        xmlNode *nodep;
                   1969:        dom_object *intern;
                   1970:        
                   1971:        if (zend_parse_parameters_none() == FAILURE) {
                   1972:                return;
                   1973:        }
                   1974: 
                   1975:        DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
                   1976: 
                   1977:        RETURN_LONG(xmlGetLineNo(nodep));
                   1978: }
                   1979: /* }}} */
                   1980: 
                   1981: #endif
                   1982: 
                   1983: /*
                   1984:  * Local variables:
                   1985:  * tab-width: 4
                   1986:  * c-basic-offset: 4
                   1987:  * End:
                   1988:  * vim600: noet sw=4 ts=4 fdm=marker
                   1989:  * vim<600: noet sw=4 ts=4
                   1990:  */

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