Annotation of embedaddon/php/ext/xmlreader/php_xmlreader.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   +----------------------------------------------------------------------+
        !             3:   | PHP Version 5                                                        |
        !             4:   +----------------------------------------------------------------------+
        !             5:   | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:   +----------------------------------------------------------------------+
        !             7:   | This source file is subject to version 3.01 of the PHP license,      |
        !             8:   | that is bundled with this package in the file LICENSE, and is        |
        !             9:   | available through the world-wide-web at the following url:           |
        !            10:   | http://www.php.net/license/3_01.txt                                  |
        !            11:   | If you did not receive a copy of the PHP license and are unable to   |
        !            12:   | obtain it through the world-wide-web, please send a note to          |
        !            13:   | license@php.net so we can mail you a copy immediately.               |
        !            14:   +----------------------------------------------------------------------+
        !            15:   | Author: Rob Richards <rrichards@php.net>                             |
        !            16:   +----------------------------------------------------------------------+
        !            17: */
        !            18: 
        !            19: /* $Id: php_xmlreader.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            20: 
        !            21: #ifdef HAVE_CONFIG_H
        !            22: #include "config.h"
        !            23: #endif
        !            24: 
        !            25: 
        !            26: #include "php.h"
        !            27: #include "php_ini.h"
        !            28: #include "ext/standard/info.h"
        !            29: #include "php_xmlreader.h"
        !            30: #ifdef HAVE_DOM
        !            31: #include "ext/dom/xml_common.h"
        !            32: #endif
        !            33: #include <libxml/uri.h>
        !            34: 
        !            35: zend_class_entry *xmlreader_class_entry;
        !            36: 
        !            37: static zend_object_handlers xmlreader_object_handlers;
        !            38: 
        !            39: static HashTable xmlreader_prop_handlers;
        !            40: 
        !            41: typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
        !            42: typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
        !            43: typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr reader);
        !            44: typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval TSRMLS_DC);
        !            45: 
        !            46: typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, const unsigned char *);
        !            47: 
        !            48: typedef struct _xmlreader_prop_handler {
        !            49:        xmlreader_read_int_t read_int_func;
        !            50:        xmlreader_read_const_char_t read_char_func;
        !            51:        xmlreader_write_t write_func;
        !            52:        int type;
        !            53: } xmlreader_prop_handler;
        !            54: 
        !            55: #define XMLREADER_LOAD_STRING 0
        !            56: #define XMLREADER_LOAD_FILE 1
        !            57: 
        !            58: /* {{{ xmlreader_register_prop_handler */
        !            59: static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name, xmlreader_read_int_t read_int_func, xmlreader_read_const_char_t read_char_func, int rettype TSRMLS_DC)
        !            60: {
        !            61:        xmlreader_prop_handler hnd;
        !            62:        
        !            63:        hnd.read_char_func = read_char_func;
        !            64:        hnd.read_int_func = read_int_func;
        !            65:        hnd.type = rettype;
        !            66:        zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(xmlreader_prop_handler), NULL);
        !            67: }
        !            68: /* }}} */
        !            69: 
        !            70: /* {{{ xmlreader_property_reader */
        !            71: static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC)
        !            72: {
        !            73:        const xmlChar *retchar = NULL;
        !            74:        int retint = 0;
        !            75: 
        !            76:        if (obj->ptr != NULL) {
        !            77:                if (hnd->read_char_func) {
        !            78:                        retchar = hnd->read_char_func(obj->ptr);
        !            79:                } else {
        !            80:                        if (hnd->read_int_func) {
        !            81:                                retint = hnd->read_int_func(obj->ptr);
        !            82:                                if (retint == -1) {
        !            83:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal libxml error returned");
        !            84:                                        return FAILURE;
        !            85:                                }
        !            86:                        }
        !            87:                }
        !            88:        }
        !            89: 
        !            90:        ALLOC_ZVAL(*retval);
        !            91: 
        !            92:        switch (hnd->type) {
        !            93:                case IS_STRING:
        !            94:                        if (retchar) {
        !            95:                                ZVAL_STRING(*retval, (char *) retchar, 1);
        !            96:                        } else {
        !            97:                                ZVAL_EMPTY_STRING(*retval);
        !            98:                        }
        !            99:                        break;
        !           100:                case IS_BOOL:
        !           101:                        ZVAL_BOOL(*retval, retint);
        !           102:                        break;
        !           103:                case IS_LONG:
        !           104:                        ZVAL_LONG(*retval, retint);
        !           105:                        break;
        !           106:                default:
        !           107:                        ZVAL_NULL(*retval);
        !           108:        }
        !           109: 
        !           110:        return SUCCESS;
        !           111: }
        !           112: /* }}} */
        !           113: 
        !           114: /* {{{ xmlreader_get_property_ptr_ptr */
        !           115: zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC)
        !           116: {
        !           117:        xmlreader_object *obj;
        !           118:        zval tmp_member;
        !           119:        zval **retval = NULL;
        !           120:        xmlreader_prop_handler *hnd;
        !           121:        zend_object_handlers *std_hnd;
        !           122:        int ret = FAILURE;
        !           123: 
        !           124:        if (member->type != IS_STRING) {
        !           125:                tmp_member = *member;
        !           126:                zval_copy_ctor(&tmp_member);
        !           127:                convert_to_string(&tmp_member);
        !           128:                member = &tmp_member;
        !           129:        }
        !           130: 
        !           131:        obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
        !           132: 
        !           133:        if (obj->prop_handler != NULL) {
        !           134:                ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
        !           135:        }
        !           136:        if (ret == FAILURE) {
        !           137:                std_hnd = zend_get_std_object_handlers();
        !           138:                retval = std_hnd->get_property_ptr_ptr(object, member TSRMLS_CC);
        !           139:        }
        !           140: 
        !           141:        if (member == &tmp_member) {
        !           142:                zval_dtor(member);
        !           143:        }
        !           144:        return retval;
        !           145: }
        !           146: /* }}} */
        !           147: 
        !           148: /* {{{ xmlreader_read_property */
        !           149: zval *xmlreader_read_property(zval *object, zval *member, int type TSRMLS_DC)
        !           150: {
        !           151:        xmlreader_object *obj;
        !           152:        zval tmp_member;
        !           153:        zval *retval;
        !           154:        xmlreader_prop_handler *hnd;
        !           155:        zend_object_handlers *std_hnd;
        !           156:        int ret;
        !           157: 
        !           158:        if (member->type != IS_STRING) {
        !           159:                tmp_member = *member;
        !           160:                zval_copy_ctor(&tmp_member);
        !           161:                convert_to_string(&tmp_member);
        !           162:                member = &tmp_member;
        !           163:        }
        !           164: 
        !           165:        ret = FAILURE;
        !           166:        obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
        !           167: 
        !           168:        if (obj->prop_handler != NULL) {
        !           169:                ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
        !           170:        }
        !           171:        if (ret == SUCCESS) {
        !           172:                ret = xmlreader_property_reader(obj, hnd, &retval TSRMLS_CC);
        !           173:                if (ret == SUCCESS) {
        !           174:                        /* ensure we're creating a temporary variable */
        !           175:                        Z_SET_REFCOUNT_P(retval, 0);
        !           176:                } else {
        !           177:                        retval = EG(uninitialized_zval_ptr);
        !           178:                }
        !           179:        } else {
        !           180:                std_hnd = zend_get_std_object_handlers();
        !           181:                retval = std_hnd->read_property(object, member, type TSRMLS_CC);
        !           182:        }
        !           183: 
        !           184:        if (member == &tmp_member) {
        !           185:                zval_dtor(member);
        !           186:        }
        !           187:        return retval;
        !           188: }
        !           189: /* }}} */
        !           190: 
        !           191: /* {{{ xmlreader_write_property */
        !           192: void xmlreader_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
        !           193: {
        !           194:        xmlreader_object *obj;
        !           195:        zval tmp_member;
        !           196:        xmlreader_prop_handler *hnd;
        !           197:        zend_object_handlers *std_hnd;
        !           198:        int ret;
        !           199: 
        !           200:        if (member->type != IS_STRING) {
        !           201:                tmp_member = *member;
        !           202:                zval_copy_ctor(&tmp_member);
        !           203:                convert_to_string(&tmp_member);
        !           204:                member = &tmp_member;
        !           205:        }
        !           206: 
        !           207:        ret = FAILURE;
        !           208:        obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
        !           209: 
        !           210:        if (obj->prop_handler != NULL) {
        !           211:                ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
        !           212:        }
        !           213:        if (ret == SUCCESS) {
        !           214:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write to read-only property");
        !           215:        } else {
        !           216:                std_hnd = zend_get_std_object_handlers();
        !           217:                std_hnd->write_property(object, member, value TSRMLS_CC);
        !           218:        }
        !           219: 
        !           220:        if (member == &tmp_member) {
        !           221:                zval_dtor(member);
        !           222:        }
        !           223: }
        !           224: /* }}} */
        !           225: 
        !           226: /* {{{ _xmlreader_get_valid_file_path */
        !           227: /* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a 
        !           228:        common function in libxml extension as code is common to a few xml extensions */
        !           229: char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len  TSRMLS_DC) {
        !           230:        xmlURI *uri;
        !           231:        xmlChar *escsource;
        !           232:        char *file_dest;
        !           233:        int isFileUri = 0;
        !           234: 
        !           235:        uri = xmlCreateURI();
        !           236:        escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *)":");
        !           237:        xmlParseURIReference(uri, (const char *)escsource);
        !           238:        xmlFree(escsource);
        !           239: 
        !           240:        if (uri->scheme != NULL) {
        !           241:                /* absolute file uris - libxml only supports localhost or empty host */
        !           242:                if (strncasecmp(source, "file:///",8) == 0) {
        !           243:                        isFileUri = 1;
        !           244: #ifdef PHP_WIN32
        !           245:                        source += 8;
        !           246: #else
        !           247:                        source += 7;
        !           248: #endif
        !           249:                } else if (strncasecmp(source, "file://localhost/",17) == 0) {
        !           250:                        isFileUri = 1;
        !           251: #ifdef PHP_WIN32
        !           252:                        source += 17;
        !           253: #else
        !           254:                        source += 16;
        !           255: #endif
        !           256:                }
        !           257:        }
        !           258: 
        !           259:        file_dest = source;
        !           260: 
        !           261:        if ((uri->scheme == NULL || isFileUri)) {
        !           262:                if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
        !           263:                        xmlFreeURI(uri);
        !           264:                        return NULL;
        !           265:                }
        !           266:                file_dest = resolved_path;
        !           267:        }
        !           268: 
        !           269:        xmlFreeURI(uri);
        !           270: 
        !           271:        return file_dest;
        !           272: }
        !           273: /* }}} */
        !           274: 
        !           275: #ifdef LIBXML_SCHEMAS_ENABLED
        !           276: /* {{{ _xmlreader_get_relaxNG */
        !           277: static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, int source_len, int type, 
        !           278:                                                                                        xmlRelaxNGValidityErrorFunc error_func, 
        !           279:                                                                                        xmlRelaxNGValidityWarningFunc warn_func TSRMLS_DC)
        !           280: {
        !           281:        char *valid_file = NULL;
        !           282:        xmlRelaxNGParserCtxtPtr parser = NULL;
        !           283:        xmlRelaxNGPtr           sptr;
        !           284:        char resolved_path[MAXPATHLEN + 1];
        !           285: 
        !           286:        switch (type) {
        !           287:        case XMLREADER_LOAD_FILE:
        !           288:                valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
        !           289:                if (!valid_file) {
        !           290:                        return NULL;
        !           291:                }
        !           292:                parser = xmlRelaxNGNewParserCtxt(valid_file);
        !           293:                break;
        !           294:        case XMLREADER_LOAD_STRING:
        !           295:                parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
        !           296:                /* If loading from memory, we need to set the base directory for the document 
        !           297:                   but it is not apparent how to do that for schema's */
        !           298:                break;
        !           299:        default:
        !           300:                return NULL;
        !           301:        }
        !           302: 
        !           303:        if (parser == NULL) {
        !           304:                return NULL;
        !           305:        }
        !           306: 
        !           307:        if (error_func || warn_func) {
        !           308:                xmlRelaxNGSetParserErrors(parser,
        !           309:                        (xmlRelaxNGValidityErrorFunc) error_func,
        !           310:                        (xmlRelaxNGValidityWarningFunc) warn_func,
        !           311:                        parser);
        !           312:        }
        !           313:        sptr = xmlRelaxNGParse(parser);
        !           314:        xmlRelaxNGFreeParserCtxt(parser);
        !           315: 
        !           316:        return sptr;
        !           317: }
        !           318: /* }}} */
        !           319: #endif
        !           320: 
        !           321: static const zend_module_dep xmlreader_deps[] = {
        !           322:        ZEND_MOD_REQUIRED("libxml")
        !           323:        ZEND_MOD_END
        !           324: };
        !           325: 
        !           326: /* {{{ xmlreader_module_entry
        !           327:  */
        !           328: zend_module_entry xmlreader_module_entry = {
        !           329:        STANDARD_MODULE_HEADER_EX, NULL,
        !           330:        xmlreader_deps,
        !           331:        "xmlreader",
        !           332:        NULL,
        !           333:        PHP_MINIT(xmlreader),
        !           334:        PHP_MSHUTDOWN(xmlreader),
        !           335:        NULL,
        !           336:        NULL,
        !           337:        PHP_MINFO(xmlreader),
        !           338:        "0.1", /* Replace with version number for your extension */
        !           339:        STANDARD_MODULE_PROPERTIES
        !           340: };
        !           341: /* }}} */
        !           342: 
        !           343: #ifdef COMPILE_DL_XMLREADER
        !           344: ZEND_GET_MODULE(xmlreader)
        !           345: #endif
        !           346: 
        !           347: /* {{{ xmlreader_objects_clone */
        !           348: void xmlreader_objects_clone(void *object, void **object_clone TSRMLS_DC)
        !           349: {
        !           350:        /* TODO */
        !           351: }
        !           352: /* }}} */
        !           353: 
        !           354: /* {{{ xmlreader_free_resources */
        !           355: static void xmlreader_free_resources(xmlreader_object *intern) {
        !           356:        if (intern) {
        !           357:                if (intern->input) {
        !           358:                        xmlFreeParserInputBuffer(intern->input);
        !           359:                        intern->input = NULL;
        !           360:                }
        !           361: 
        !           362:                if (intern->ptr) {
        !           363:                        xmlFreeTextReader(intern->ptr);
        !           364:                        intern->ptr = NULL;
        !           365:                }
        !           366: #ifdef LIBXML_SCHEMAS_ENABLED
        !           367:                if (intern->schema) {
        !           368:                        xmlRelaxNGFree((xmlRelaxNGPtr) intern->schema);
        !           369:                        intern->schema = NULL;
        !           370:                }
        !           371: #endif
        !           372:        }
        !           373: }
        !           374: /* }}} */
        !           375: 
        !           376: /* {{{ xmlreader_objects_free_storage */
        !           377: void xmlreader_objects_free_storage(void *object TSRMLS_DC)
        !           378: {
        !           379:        xmlreader_object *intern = (xmlreader_object *)object;
        !           380: 
        !           381:        zend_object_std_dtor(&intern->std TSRMLS_CC);
        !           382:        
        !           383:        xmlreader_free_resources(intern);
        !           384: 
        !           385:        efree(object);
        !           386: }
        !           387: /* }}} */
        !           388: 
        !           389: /* {{{ xmlreader_objects_new */
        !           390: zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC)
        !           391: {
        !           392:        zend_object_value retval;
        !           393:        xmlreader_object *intern;
        !           394:        zval *tmp;
        !           395: 
        !           396:        intern = emalloc(sizeof(xmlreader_object));
        !           397:        memset(&intern->std, 0, sizeof(zend_object));
        !           398:        intern->ptr = NULL;
        !           399:        intern->input = NULL;
        !           400:        intern->schema = NULL;
        !           401:        intern->prop_handler = &xmlreader_prop_handlers;
        !           402: 
        !           403:        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        !           404:        zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
        !           405:        retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) xmlreader_objects_free_storage, xmlreader_objects_clone TSRMLS_CC);
        !           406:        intern->handle = retval.handle;
        !           407:        retval.handlers = &xmlreader_object_handlers;
        !           408:        return retval;
        !           409: }
        !           410: /* }}} */
        !           411: 
        !           412: /* {{{ php_xmlreader_string_arg */
        !           413: static void php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_one_char_t internal_function) {
        !           414:        zval *id;
        !           415:        int name_len = 0;
        !           416:        char *retchar = NULL;
        !           417:        xmlreader_object *intern;
        !           418:        char *name;
        !           419: 
        !           420:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        !           421:                return;
        !           422:        }
        !           423: 
        !           424:        if (!name_len) {
        !           425:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument cannot be an empty string");
        !           426:                RETURN_FALSE;
        !           427:        }
        !           428: 
        !           429:        id = getThis();
        !           430: 
        !           431:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           432:        if (intern && intern->ptr) {
        !           433:                retchar = (char *)internal_function(intern->ptr, (const unsigned char *)name);
        !           434:        }
        !           435:        if (retchar) {
        !           436:                RETVAL_STRING(retchar, 1);
        !           437:                xmlFree(retchar);
        !           438:                return;
        !           439:        } else {
        !           440:                RETVAL_NULL();
        !           441:        }
        !           442: }
        !           443: /* }}} */
        !           444: 
        !           445: /* {{{ php_xmlreader_no_arg */
        !           446: static void php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_int_t internal_function) {
        !           447:        zval *id;
        !           448:        int retval;
        !           449:        xmlreader_object *intern;
        !           450: 
        !           451:        id = getThis();
        !           452: 
        !           453:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           454:        if (intern && intern->ptr) {
        !           455:                retval = internal_function(intern->ptr);
        !           456:                if (retval == 1) {
        !           457:                        RETURN_TRUE;
        !           458:                }
        !           459:        }
        !           460: 
        !           461:        RETURN_FALSE;
        !           462: }
        !           463: /* }}} */
        !           464: 
        !           465: #if LIBXML_VERSION >= 20620
        !           466: /* {{{ php_xmlreader_no_arg_string */
        !           467: static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_char_t internal_function) {
        !           468:        zval *id;
        !           469:        char *retchar = NULL;
        !           470:        xmlreader_object *intern;
        !           471: 
        !           472:        id = getThis();
        !           473: 
        !           474:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           475:        if (intern && intern->ptr) {
        !           476:                retchar = (char *)internal_function(intern->ptr);
        !           477:        }
        !           478:        if (retchar) {
        !           479:                RETVAL_STRING(retchar, 1);
        !           480:                xmlFree(retchar);
        !           481:                return;
        !           482:        } else {
        !           483:                RETVAL_EMPTY_STRING();
        !           484:        }
        !           485: }
        !           486: /* }}} */
        !           487: #endif
        !           488: 
        !           489: /* {{{ php_xmlreader_set_relaxng_schema */
        !           490: static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int type) {
        !           491: #ifdef LIBXML_SCHEMAS_ENABLED
        !           492:        zval *id;
        !           493:        int source_len = 0, retval = -1;
        !           494:        xmlreader_object *intern;
        !           495:        xmlRelaxNGPtr schema = NULL;
        !           496:        char *source;
        !           497: 
        !           498:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &source, &source_len) == FAILURE) {
        !           499:                return;
        !           500:        }
        !           501: 
        !           502:        if (source != NULL && !source_len) {
        !           503:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source is required");
        !           504:                RETURN_FALSE;
        !           505:        }
        !           506: 
        !           507:        id = getThis();
        !           508: 
        !           509:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           510:        if (intern && intern->ptr) {
        !           511:                if (source) {
        !           512:                        schema =  _xmlreader_get_relaxNG(source, source_len, type, NULL, NULL TSRMLS_CC);
        !           513:                        if (schema) {
        !           514:                                retval = xmlTextReaderRelaxNGSetSchema(intern->ptr, schema);
        !           515:                        }
        !           516:                } else {
        !           517:                        /* unset the associated relaxNG context and schema if one exists */
        !           518:                        retval = xmlTextReaderRelaxNGSetSchema(intern->ptr, NULL);
        !           519:                }
        !           520: 
        !           521:                if (retval == 0) {
        !           522:                        if (intern->schema) {
        !           523:                                xmlRelaxNGFree((xmlRelaxNGPtr) intern->schema);
        !           524:                        }
        !           525: 
        !           526:                        intern->schema = schema;
        !           527: 
        !           528:                        RETURN_TRUE;
        !           529:                }
        !           530:        }
        !           531:        
        !           532:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
        !           533: 
        !           534:        RETURN_FALSE;
        !           535: #else
        !           536:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built into libxml.");
        !           537: 
        !           538:        RETURN_FALSE;
        !           539: #endif
        !           540: }
        !           541: /* }}} */
        !           542: 
        !           543: /* {{{ proto boolean XMLReader::close()
        !           544: Closes xmlreader - current frees resources until xmlTextReaderClose is fixed in libxml */
        !           545: PHP_METHOD(xmlreader, close)
        !           546: {
        !           547:        zval *id;
        !           548:        xmlreader_object *intern;
        !           549: 
        !           550:        id = getThis();
        !           551:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           552:        /* libxml is segfaulting in versions up to 2.6.8 using xmlTextReaderClose so for 
        !           553:        now we will free the whole reader when close is called as it would get rebuilt on 
        !           554:        a new load anyways */
        !           555:        xmlreader_free_resources(intern);
        !           556:        
        !           557:        RETURN_TRUE;
        !           558: }
        !           559: /* }}} */
        !           560: 
        !           561: /* {{{ proto string XMLReader::getAttribute(string name)
        !           562: Get value of an attribute from current element */
        !           563: PHP_METHOD(xmlreader, getAttribute)
        !           564: {
        !           565:        php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderGetAttribute);
        !           566: }
        !           567: /* }}} */
        !           568: 
        !           569: /* {{{ proto string XMLReader::getAttributeNo(int index)
        !           570: Get value of an attribute at index from current element */
        !           571: PHP_METHOD(xmlreader, getAttributeNo)
        !           572: {
        !           573:        zval *id;
        !           574:        long attr_pos;
        !           575:        char *retchar = NULL;
        !           576:        xmlreader_object *intern;
        !           577: 
        !           578:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &attr_pos) == FAILURE) {
        !           579:                return;
        !           580:        }
        !           581: 
        !           582:        id = getThis();
        !           583: 
        !           584:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           585:        if (intern && intern->ptr) {
        !           586:                retchar = (char *)xmlTextReaderGetAttributeNo(intern->ptr, attr_pos);
        !           587:        }
        !           588:        if (retchar) {
        !           589:                RETVAL_STRING(retchar, 1);
        !           590:                xmlFree(retchar);
        !           591:                return;
        !           592:        } else {
        !           593:                RETURN_EMPTY_STRING();
        !           594:        }
        !           595: }
        !           596: /* }}} */
        !           597: 
        !           598: /* {{{ proto string XMLReader::getAttributeNs(string name, string namespaceURI)
        !           599: Get value of a attribute via name and namespace from current element */
        !           600: PHP_METHOD(xmlreader, getAttributeNs)
        !           601: {
        !           602:        zval *id;
        !           603:        int name_len = 0, ns_uri_len = 0;
        !           604:        xmlreader_object *intern;
        !           605:        char *name, *ns_uri, *retchar = NULL;
        !           606: 
        !           607:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &ns_uri, &ns_uri_len) == FAILURE) {
        !           608:                return;
        !           609:        }
        !           610: 
        !           611:        if (name_len == 0 || ns_uri_len == 0) {
        !           612:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name and Namespace URI cannot be empty");
        !           613:                RETURN_FALSE;
        !           614:        }
        !           615: 
        !           616:        id = getThis();
        !           617: 
        !           618:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           619:        if (intern && intern->ptr) {
        !           620:                retchar = (char *)xmlTextReaderGetAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
        !           621:        }
        !           622:        if (retchar) {
        !           623:                RETVAL_STRING(retchar, 1);
        !           624:                xmlFree(retchar);
        !           625:                return;
        !           626:        } else {
        !           627:                RETURN_EMPTY_STRING();
        !           628:        }
        !           629: }
        !           630: /* }}} */
        !           631: 
        !           632: /* {{{ proto boolean XMLReader::getParserProperty(int property)
        !           633: Indicates whether given property (one of the parser option constants) is set or not on parser */
        !           634: PHP_METHOD(xmlreader, getParserProperty)
        !           635: {
        !           636:        zval *id;
        !           637:        long property;
        !           638:        int retval = -1;
        !           639:        xmlreader_object *intern;
        !           640: 
        !           641:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &property) == FAILURE) {
        !           642:                return;
        !           643:        }
        !           644: 
        !           645:        id = getThis();
        !           646: 
        !           647:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           648:        if (intern && intern->ptr) {
        !           649:                retval = xmlTextReaderGetParserProp(intern->ptr,property);
        !           650:        }
        !           651:        if (retval == -1) {
        !           652:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parser property");
        !           653:                RETURN_FALSE;
        !           654:        }
        !           655: 
        !           656:        RETURN_BOOL(retval);
        !           657: }
        !           658: /* }}} */
        !           659: 
        !           660: /* {{{ proto boolean XMLReader::isValid()
        !           661: Returns boolean indicating if parsed document is valid or not.
        !           662: Must set XMLREADER_LOADDTD or XMLREADER_VALIDATE parser option prior to the first call to read 
        !           663: or this method will always return FALSE */
        !           664: PHP_METHOD(xmlreader, isValid)
        !           665: {
        !           666:        php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderIsValid);
        !           667: }
        !           668: /* }}} */
        !           669: 
        !           670: /* {{{ proto string XMLReader::lookupNamespace(string prefix)
        !           671: Return namespaceURI for associated prefix on current node */
        !           672: PHP_METHOD(xmlreader, lookupNamespace)
        !           673: {
        !           674:        php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderLookupNamespace);
        !           675: }
        !           676: /* }}} */
        !           677: 
        !           678: /* {{{ proto boolean XMLReader::moveToAttribute(string name)
        !           679: Positions reader at specified attribute - Returns TRUE on success and FALSE on failure */
        !           680: PHP_METHOD(xmlreader, moveToAttribute)
        !           681: {
        !           682:        zval *id;
        !           683:        int name_len = 0, retval;
        !           684:        xmlreader_object *intern;
        !           685:        char *name;
        !           686: 
        !           687:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
        !           688:                return;
        !           689:        }
        !           690: 
        !           691:        if (name_len == 0) {
        !           692:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
        !           693:                RETURN_FALSE;
        !           694:        }
        !           695: 
        !           696:        id = getThis();
        !           697: 
        !           698:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           699:        if (intern && intern->ptr) {
        !           700:                retval = xmlTextReaderMoveToAttribute(intern->ptr, (xmlChar *)name);
        !           701:                if (retval == 1) {
        !           702:                        RETURN_TRUE;
        !           703:                }
        !           704:        }
        !           705: 
        !           706:        RETURN_FALSE;
        !           707: }
        !           708: /* }}} */
        !           709: 
        !           710: /* {{{ proto boolean XMLReader::moveToAttributeNo(int index)
        !           711: Positions reader at attribute at spcecified index.
        !           712: Returns TRUE on success and FALSE on failure */
        !           713: PHP_METHOD(xmlreader, moveToAttributeNo)
        !           714: {
        !           715:        zval *id;
        !           716:        long attr_pos;
        !           717:        int retval;
        !           718:        xmlreader_object *intern;
        !           719: 
        !           720:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &attr_pos) == FAILURE) {
        !           721:                return;
        !           722:        }
        !           723: 
        !           724:        id = getThis();
        !           725: 
        !           726:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           727:        if (intern && intern->ptr) {
        !           728:                retval = xmlTextReaderMoveToAttributeNo(intern->ptr, attr_pos);
        !           729:                if (retval == 1) {
        !           730:                        RETURN_TRUE;
        !           731:                }
        !           732:        }
        !           733: 
        !           734:        RETURN_FALSE;
        !           735: }
        !           736: /* }}} */
        !           737: 
        !           738: /* {{{ proto boolean XMLReader::moveToAttributeNs(string name, string namespaceURI)
        !           739: Positions reader at attribute spcified by name and namespaceURI.
        !           740: Returns TRUE on success and FALSE on failure */
        !           741: PHP_METHOD(xmlreader, moveToAttributeNs)
        !           742: {
        !           743:        zval *id;
        !           744:        int name_len=0, ns_uri_len=0, retval;
        !           745:        xmlreader_object *intern;
        !           746:        char *name, *ns_uri;
        !           747: 
        !           748:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &ns_uri, &ns_uri_len) == FAILURE) {
        !           749:                return;
        !           750:        }
        !           751: 
        !           752:        if (name_len == 0 || ns_uri_len == 0) {
        !           753:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name and Namespace URI cannot be empty");
        !           754:                RETURN_FALSE;
        !           755:        }
        !           756: 
        !           757:        id = getThis();
        !           758: 
        !           759:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           760:        if (intern && intern->ptr) {
        !           761:                retval = xmlTextReaderMoveToAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
        !           762:                if (retval == 1) {
        !           763:                        RETURN_TRUE;
        !           764:                }
        !           765:        }
        !           766: 
        !           767:        RETURN_FALSE;
        !           768: }
        !           769: /* }}} */
        !           770: 
        !           771: /* {{{ proto boolean XMLReader::moveToElement()
        !           772: Moves the position of the current instance to the node that contains the current Attribute node. */
        !           773: PHP_METHOD(xmlreader, moveToElement)
        !           774: {
        !           775:        php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToElement);
        !           776: }
        !           777: /* }}} */
        !           778: 
        !           779: /* {{{ proto boolean XMLReader::moveToFirstAttribute()
        !           780: Moves the position of the current instance to the first attribute associated with the current node. */
        !           781: PHP_METHOD(xmlreader, moveToFirstAttribute)
        !           782: {
        !           783:        php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToFirstAttribute);
        !           784: }
        !           785: /* }}} */
        !           786: 
        !           787: /* {{{ proto boolean XMLReader::moveToNextAttribute()
        !           788: Moves the position of the current instance to the next attribute associated with the current node. */
        !           789: PHP_METHOD(xmlreader, moveToNextAttribute)
        !           790: {
        !           791:        php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToNextAttribute);
        !           792: }
        !           793: /* }}} */
        !           794: 
        !           795: /* {{{ proto boolean XMLReader::read()
        !           796: Moves the position of the current instance to the next node in the stream. */
        !           797: PHP_METHOD(xmlreader, read)
        !           798: {
        !           799:        zval *id;
        !           800:        int retval;
        !           801:        xmlreader_object *intern;
        !           802: 
        !           803:        id = getThis();
        !           804:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           805:        if (intern != NULL && intern->ptr != NULL) {
        !           806:                retval = xmlTextReaderRead(intern->ptr);
        !           807:                if (retval == -1) {
        !           808:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while reading");
        !           809:                        RETURN_FALSE;
        !           810:                } else {
        !           811:                        RETURN_BOOL(retval);
        !           812:                }
        !           813:        }
        !           814:        
        !           815:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
        !           816:        RETURN_FALSE;
        !           817: }
        !           818: /* }}} */
        !           819: 
        !           820: /* {{{ proto boolean XMLReader::next([string localname])
        !           821: Moves the position of the current instance to the next node in the stream. */
        !           822: PHP_METHOD(xmlreader, next)
        !           823: {
        !           824:        zval *id;
        !           825:        int retval, name_len=0;
        !           826:        xmlreader_object *intern;
        !           827:        char *name = NULL;
        !           828: 
        !           829:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
        !           830:                return;
        !           831:        }
        !           832: 
        !           833:        id = getThis();
        !           834:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           835:        if (intern != NULL && intern->ptr != NULL) {
        !           836: #if LIBXML_VERSION <= 20617
        !           837:                /* Bug in libxml prevents a next in certain cases when positioned on end of element */
        !           838:                if (xmlTextReaderNodeType(intern->ptr) == XML_READER_TYPE_END_ELEMENT) {
        !           839:                        retval = xmlTextReaderRead(intern->ptr);
        !           840:                } else
        !           841: #endif
        !           842:                retval = xmlTextReaderNext(intern->ptr);
        !           843:                while (name != NULL && retval == 1) {
        !           844:                        if (xmlStrEqual(xmlTextReaderConstLocalName(intern->ptr), (xmlChar *)name)) {
        !           845:                                RETURN_TRUE;
        !           846:                        }
        !           847:                        retval = xmlTextReaderNext(intern->ptr); 
        !           848:                }
        !           849:                if (retval == -1) {
        !           850:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while reading");
        !           851:                        RETURN_FALSE;
        !           852:                } else {
        !           853:                        RETURN_BOOL(retval);
        !           854:                }
        !           855:        }
        !           856:        
        !           857:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
        !           858:        RETURN_FALSE;
        !           859: }
        !           860: /* }}} */
        !           861: 
        !           862: /* {{{ proto boolean XMLReader::open(string URI [, string encoding [, int options]])
        !           863: Sets the URI that the XMLReader will parse. */
        !           864: PHP_METHOD(xmlreader, open)
        !           865: {
        !           866:        zval *id;
        !           867:        int source_len = 0, encoding_len = 0;
        !           868:        long options = 0;
        !           869:        xmlreader_object *intern = NULL;
        !           870:        char *source, *valid_file = NULL;
        !           871:        char *encoding = NULL;
        !           872:        char resolved_path[MAXPATHLEN + 1];
        !           873:        xmlTextReaderPtr reader = NULL;
        !           874: 
        !           875:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
        !           876:                return;
        !           877:        }
        !           878: 
        !           879:        id = getThis();
        !           880:        if (id != NULL) {
        !           881:                if (! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
        !           882:                        id = NULL;
        !           883:                } else {
        !           884:                        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           885:                        xmlreader_free_resources(intern);
        !           886:                }
        !           887:        }
        !           888: 
        !           889:        if (!source_len) {
        !           890:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
        !           891:                RETURN_FALSE;
        !           892:        }
        !           893: 
        !           894:        valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
        !           895: 
        !           896:        if (valid_file) {
        !           897:                reader = xmlReaderForFile(valid_file, encoding, options);
        !           898:        }
        !           899: 
        !           900:        if (reader == NULL) {
        !           901:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open source data");
        !           902:                RETURN_FALSE;
        !           903:        }
        !           904: 
        !           905:        if (id == NULL) {
        !           906:                object_init_ex(return_value, xmlreader_class_entry);
        !           907:                intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
        !           908:                intern->ptr = reader;
        !           909:                return;
        !           910:        }
        !           911: 
        !           912:        intern->ptr = reader;
        !           913: 
        !           914:        RETURN_TRUE;
        !           915: 
        !           916: }
        !           917: /* }}} */
        !           918: 
        !           919: /* Not Yet Implemented in libxml - functions exist just not coded
        !           920: PHP_METHOD(xmlreader, resetState)
        !           921: {
        !           922: 
        !           923: }
        !           924: */
        !           925: 
        !           926: #if LIBXML_VERSION >= 20620
        !           927: /* {{{ proto string XMLReader::readInnerXml()
        !           928: Reads the contents of the current node, including child nodes and markup. */
        !           929: PHP_METHOD(xmlreader, readInnerXml)
        !           930: {
        !           931:        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
        !           932: }
        !           933: /* }}} */
        !           934: 
        !           935: /* {{{ proto boolean XMLReader::readOuterXml()
        !           936: Reads the contents of the current node, including child nodes and markup. */
        !           937: PHP_METHOD(xmlreader, readOuterXml)
        !           938: {
        !           939:        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadOuterXml);
        !           940: }
        !           941: /* }}} */
        !           942: 
        !           943: /* {{{ proto boolean XMLReader::readString()
        !           944: Reads the contents of an element or a text node as a string. */
        !           945: PHP_METHOD(xmlreader, readString)
        !           946: {
        !           947:        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
        !           948: }
        !           949: /* }}} */
        !           950: 
        !           951: /* {{{ proto boolean XMLReader::setSchema(string filename)
        !           952: Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
        !           953: PHP_METHOD(xmlreader, setSchema)
        !           954: {
        !           955: #ifdef LIBXML_SCHEMAS_ENABLED
        !           956:        zval *id;
        !           957:        int source_len = 0, retval = -1;
        !           958:        xmlreader_object *intern;
        !           959:        char *source;
        !           960: 
        !           961:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &source, &source_len) == FAILURE) {
        !           962:                return;
        !           963:        }
        !           964: 
        !           965:        if (source != NULL && !source_len) {
        !           966:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source is required");
        !           967:                RETURN_FALSE;
        !           968:        }
        !           969: 
        !           970:        id = getThis();
        !           971: 
        !           972:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !           973:        if (intern && intern->ptr) {
        !           974:                retval = xmlTextReaderSchemaValidate(intern->ptr, source);
        !           975: 
        !           976:                if (retval == 0) {
        !           977:                        RETURN_TRUE;
        !           978:                }
        !           979:        }
        !           980:        
        !           981:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
        !           982: 
        !           983:        RETURN_FALSE;
        !           984: #else
        !           985:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built into libxml.");
        !           986: 
        !           987:        RETURN_FALSE;
        !           988: #endif
        !           989: }
        !           990: /* }}} */
        !           991: #endif
        !           992: 
        !           993: /* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value)
        !           994: Sets parser property (one of the parser option constants).
        !           995: Properties must be set after open() or XML() and before the first read() is called */
        !           996: PHP_METHOD(xmlreader, setParserProperty)
        !           997: {
        !           998:        zval *id;
        !           999:        long property;
        !          1000:        int retval = -1;
        !          1001:        zend_bool value;
        !          1002:        xmlreader_object *intern;
        !          1003: 
        !          1004:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &property, &value) == FAILURE) {
        !          1005:                return;
        !          1006:        }
        !          1007: 
        !          1008:        id = getThis();
        !          1009: 
        !          1010:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !          1011:        if (intern && intern->ptr) {
        !          1012:                retval = xmlTextReaderSetParserProp(intern->ptr,property, value);
        !          1013:        }
        !          1014:        if (retval == -1) {
        !          1015:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parser property");
        !          1016:                RETURN_FALSE;
        !          1017:        }
        !          1018: 
        !          1019:        RETURN_TRUE;
        !          1020: }
        !          1021: /* }}} */
        !          1022: 
        !          1023: /* {{{ proto boolean XMLReader::setRelaxNGSchema(string filename)
        !          1024: Sets the string that the XMLReader will parse. */
        !          1025: PHP_METHOD(xmlreader, setRelaxNGSchema)
        !          1026: {
        !          1027:        php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_FILE);
        !          1028: }
        !          1029: /* }}} */
        !          1030: 
        !          1031: /* {{{ proto boolean XMLReader::setRelaxNGSchemaSource(string source)
        !          1032: Sets the string that the XMLReader will parse. */
        !          1033: PHP_METHOD(xmlreader, setRelaxNGSchemaSource)
        !          1034: {
        !          1035:        php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_STRING);
        !          1036: }
        !          1037: /* }}} */
        !          1038: 
        !          1039: /* TODO
        !          1040: XMLPUBFUN int XMLCALL          
        !          1041:                    xmlTextReaderSetSchema      (xmlTextReaderPtr reader,
        !          1042:                                                 xmlSchemaPtr schema);
        !          1043: */
        !          1044: 
        !          1045: /* {{{ proto boolean XMLReader::XML(string source [, string encoding [, int options]])
        !          1046: Sets the string that the XMLReader will parse. */
        !          1047: PHP_METHOD(xmlreader, XML)
        !          1048: {
        !          1049:        zval *id;
        !          1050:        int source_len = 0, encoding_len = 0;
        !          1051:        long options = 0;
        !          1052:        xmlreader_object *intern = NULL;
        !          1053:        char *source, *uri = NULL, *encoding = NULL;
        !          1054:        int resolved_path_len, ret = 0;
        !          1055:        char *directory=NULL, resolved_path[MAXPATHLEN];
        !          1056:        xmlParserInputBufferPtr inputbfr;
        !          1057:        xmlTextReaderPtr reader;
        !          1058: 
        !          1059:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
        !          1060:                return;
        !          1061:        }
        !          1062: 
        !          1063:        id = getThis();
        !          1064:        if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
        !          1065:                id = NULL;
        !          1066:        }
        !          1067:        if (id != NULL) {
        !          1068:                intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !          1069:                xmlreader_free_resources(intern);
        !          1070:        }
        !          1071: 
        !          1072:        if (!source_len) {
        !          1073:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
        !          1074:                RETURN_FALSE;
        !          1075:        }
        !          1076: 
        !          1077:        inputbfr = xmlParserInputBufferCreateMem(source, source_len, XML_CHAR_ENCODING_NONE);
        !          1078: 
        !          1079:     if (inputbfr != NULL) {
        !          1080: /* Get the URI of the current script so that we can set the base directory in libxml */
        !          1081: #if HAVE_GETCWD
        !          1082:                directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
        !          1083: #elif HAVE_GETWD
        !          1084:                directory = VCWD_GETWD(resolved_path);
        !          1085: #endif
        !          1086:                if (directory) {
        !          1087:                        resolved_path_len = strlen(resolved_path);
        !          1088:                        if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
        !          1089:                                resolved_path[resolved_path_len] = DEFAULT_SLASH;
        !          1090:                                resolved_path[++resolved_path_len] = '\0';
        !          1091:                        }
        !          1092:                        uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
        !          1093:                }
        !          1094:                reader = xmlNewTextReader(inputbfr, uri);
        !          1095: 
        !          1096:                if (reader != NULL) {
        !          1097: #if LIBXML_VERSION >= 20628
        !          1098:                        ret = xmlTextReaderSetup(reader, NULL, uri, encoding, options);
        !          1099: #endif
        !          1100:                        if (ret == 0) {
        !          1101:                                if (id == NULL) {
        !          1102:                                        object_init_ex(return_value, xmlreader_class_entry);
        !          1103:                                        intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
        !          1104:                                } else {
        !          1105:                                        RETVAL_TRUE;
        !          1106:                                }
        !          1107:                                intern->input = inputbfr;
        !          1108:                                intern->ptr = reader;
        !          1109: 
        !          1110:                                if (uri) {
        !          1111:                                        xmlFree(uri);
        !          1112:                                }
        !          1113: 
        !          1114:                                return;
        !          1115:                        }
        !          1116:                }
        !          1117:        }
        !          1118: 
        !          1119:        if (uri) {
        !          1120:                xmlFree(uri);
        !          1121:        }
        !          1122: 
        !          1123:        if (inputbfr) {
        !          1124:                xmlFreeParserInputBuffer(inputbfr);
        !          1125:        }
        !          1126:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load source data");
        !          1127:        RETURN_FALSE;
        !          1128: }
        !          1129: /* }}} */
        !          1130: 
        !          1131: /* {{{ proto boolean XMLReader::expand()
        !          1132: Moves the position of the current instance to the next node in the stream. */
        !          1133: PHP_METHOD(xmlreader, expand)
        !          1134: {
        !          1135: #ifdef HAVE_DOM
        !          1136:        zval *id, *rv = NULL, *basenode = NULL;
        !          1137:        int ret;
        !          1138:        xmlreader_object *intern;
        !          1139:        xmlNode *node, *nodec;
        !          1140:        xmlDocPtr docp = NULL;
        !          1141:        php_libxml_node_object *domobj = NULL;
        !          1142: 
        !          1143:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!", &id, xmlreader_class_entry, &basenode, dom_node_class_entry) == FAILURE) {
        !          1144:                return;
        !          1145:        }
        !          1146:        
        !          1147:        if (basenode != NULL) {
        !          1148:                NODE_GET_OBJ(node, basenode, xmlNodePtr, domobj);
        !          1149:                docp = node->doc;
        !          1150:        }
        !          1151: 
        !          1152:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
        !          1153: 
        !          1154:        if (intern && intern->ptr) {
        !          1155:                node = xmlTextReaderExpand(intern->ptr);
        !          1156:                
        !          1157:                if (node == NULL) {
        !          1158:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while expanding ");
        !          1159:                        RETURN_FALSE;
        !          1160:                } else {
        !          1161:                        nodec = xmlDocCopyNode(node, docp, 1);
        !          1162:                        if (nodec == NULL) {
        !          1163:                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot expand this node type");
        !          1164:                                RETURN_FALSE;
        !          1165:                        } else {
        !          1166:                                DOM_RET_OBJ(rv, nodec, &ret, (dom_object *)domobj);
        !          1167:                        }
        !          1168:                }
        !          1169:        } else {
        !          1170:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to expand");
        !          1171:                RETURN_FALSE;
        !          1172:        }
        !          1173: #else
        !          1174:        php_error(E_WARNING, "DOM support is not enabled");
        !          1175:        return;
        !          1176: #endif
        !          1177: }
        !          1178: /* }}} */
        !          1179: /* {{{ arginfo */
        !          1180: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_close, 0)
        !          1181: ZEND_END_ARG_INFO()
        !          1182: 
        !          1183: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttribute, 0)
        !          1184:        ZEND_ARG_INFO(0, name)
        !          1185: ZEND_END_ARG_INFO()
        !          1186: 
        !          1187: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNo, 0)
        !          1188:        ZEND_ARG_INFO(0, index)
        !          1189: ZEND_END_ARG_INFO()
        !          1190: 
        !          1191: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNs, 0)
        !          1192:        ZEND_ARG_INFO(0, name)
        !          1193:        ZEND_ARG_INFO(0, namespaceURI)
        !          1194: ZEND_END_ARG_INFO()
        !          1195: 
        !          1196: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getParserProperty, 0)
        !          1197:        ZEND_ARG_INFO(0, property)
        !          1198: ZEND_END_ARG_INFO()
        !          1199: 
        !          1200: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_isValid, 0)
        !          1201: ZEND_END_ARG_INFO()
        !          1202: 
        !          1203: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_lookupNamespace, 0)
        !          1204: ZEND_ARG_INFO(0, prefix)
        !          1205: ZEND_END_ARG_INFO()
        !          1206: 
        !          1207: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttribute, 0)
        !          1208:        ZEND_ARG_INFO(0, name)
        !          1209: ZEND_END_ARG_INFO()
        !          1210: 
        !          1211: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNo, 0)
        !          1212:        ZEND_ARG_INFO(0, index)
        !          1213: ZEND_END_ARG_INFO()
        !          1214: 
        !          1215: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNs, 0)
        !          1216:        ZEND_ARG_INFO(0, name)
        !          1217:        ZEND_ARG_INFO(0, namespaceURI)
        !          1218: ZEND_END_ARG_INFO()
        !          1219: 
        !          1220: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToElement, 0)
        !          1221: ZEND_END_ARG_INFO()
        !          1222: 
        !          1223: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToFirstAttribute, 0)
        !          1224: ZEND_END_ARG_INFO()
        !          1225: 
        !          1226: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToNextAttribute, 0)
        !          1227: ZEND_END_ARG_INFO()
        !          1228: 
        !          1229: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_read, 0)
        !          1230: ZEND_END_ARG_INFO()
        !          1231: 
        !          1232: ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_next, 0, 0, 0)
        !          1233:        ZEND_ARG_INFO(0, localname)
        !          1234: ZEND_END_ARG_INFO()
        !          1235: 
        !          1236: ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_open, 0, 0, 1)
        !          1237:        ZEND_ARG_INFO(0, URI)
        !          1238:        ZEND_ARG_INFO(0, encoding)
        !          1239:        ZEND_ARG_INFO(0, options)
        !          1240: ZEND_END_ARG_INFO()
        !          1241: 
        !          1242: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readInnerXml, 0)
        !          1243: ZEND_END_ARG_INFO()
        !          1244: 
        !          1245: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readOuterXml, 0)
        !          1246: ZEND_END_ARG_INFO()
        !          1247: 
        !          1248: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readString, 0)
        !          1249: ZEND_END_ARG_INFO()
        !          1250: 
        !          1251: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setSchema, 0)
        !          1252:        ZEND_ARG_INFO(0, filename)
        !          1253: ZEND_END_ARG_INFO()
        !          1254: 
        !          1255: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setParserProperty, 0)
        !          1256:        ZEND_ARG_INFO(0, property)
        !          1257:        ZEND_ARG_INFO(0, value)
        !          1258: ZEND_END_ARG_INFO()
        !          1259: 
        !          1260: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchema, 0)
        !          1261:        ZEND_ARG_INFO(0, filename)
        !          1262: ZEND_END_ARG_INFO()
        !          1263: 
        !          1264: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchemaSource, 0)
        !          1265:        ZEND_ARG_INFO(0, source)
        !          1266: ZEND_END_ARG_INFO()
        !          1267: 
        !          1268: ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_XML, 0, 0, 1)
        !          1269:        ZEND_ARG_INFO(0, source)
        !          1270:        ZEND_ARG_INFO(0, encoding)
        !          1271:        ZEND_ARG_INFO(0, options)
        !          1272: ZEND_END_ARG_INFO()
        !          1273: 
        !          1274: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_expand, 0)
        !          1275: ZEND_END_ARG_INFO()
        !          1276: /* }}} */
        !          1277: 
        !          1278: static const zend_function_entry xmlreader_functions[] = {
        !          1279:        PHP_ME(xmlreader, close, arginfo_xmlreader_close, ZEND_ACC_PUBLIC)
        !          1280:        PHP_ME(xmlreader, getAttribute, arginfo_xmlreader_getAttribute, ZEND_ACC_PUBLIC)
        !          1281:        PHP_ME(xmlreader, getAttributeNo, arginfo_xmlreader_getAttributeNo, ZEND_ACC_PUBLIC)
        !          1282:        PHP_ME(xmlreader, getAttributeNs, arginfo_xmlreader_getAttributeNs, ZEND_ACC_PUBLIC)
        !          1283:        PHP_ME(xmlreader, getParserProperty, arginfo_xmlreader_getParserProperty, ZEND_ACC_PUBLIC)
        !          1284:        PHP_ME(xmlreader, isValid, arginfo_xmlreader_isValid, ZEND_ACC_PUBLIC)
        !          1285:        PHP_ME(xmlreader, lookupNamespace, arginfo_xmlreader_lookupNamespace, ZEND_ACC_PUBLIC)
        !          1286:        PHP_ME(xmlreader, moveToAttributeNo, arginfo_xmlreader_moveToAttributeNo, ZEND_ACC_PUBLIC)
        !          1287:        PHP_ME(xmlreader, moveToAttribute, arginfo_xmlreader_moveToAttribute, ZEND_ACC_PUBLIC)
        !          1288:        PHP_ME(xmlreader, moveToAttributeNs, arginfo_xmlreader_moveToAttributeNs, ZEND_ACC_PUBLIC)
        !          1289:        PHP_ME(xmlreader, moveToElement, arginfo_xmlreader_moveToElement, ZEND_ACC_PUBLIC)
        !          1290:        PHP_ME(xmlreader, moveToFirstAttribute, arginfo_xmlreader_moveToFirstAttribute, ZEND_ACC_PUBLIC)
        !          1291:        PHP_ME(xmlreader, moveToNextAttribute, arginfo_xmlreader_moveToNextAttribute, ZEND_ACC_PUBLIC)
        !          1292:        PHP_ME(xmlreader, open, arginfo_xmlreader_open, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
        !          1293:        PHP_ME(xmlreader, read, arginfo_xmlreader_read, ZEND_ACC_PUBLIC)
        !          1294:        PHP_ME(xmlreader, next, arginfo_xmlreader_next, ZEND_ACC_PUBLIC)
        !          1295: #if LIBXML_VERSION >= 20620
        !          1296:        PHP_ME(xmlreader, readInnerXml, arginfo_xmlreader_readInnerXml, ZEND_ACC_PUBLIC)
        !          1297:        PHP_ME(xmlreader, readOuterXml, arginfo_xmlreader_readOuterXml, ZEND_ACC_PUBLIC)
        !          1298:        PHP_ME(xmlreader, readString, arginfo_xmlreader_readString, ZEND_ACC_PUBLIC)
        !          1299:        PHP_ME(xmlreader, setSchema, arginfo_xmlreader_setSchema, ZEND_ACC_PUBLIC)
        !          1300: #endif
        !          1301: /* Not Yet Implemented though defined in libxml as of 2.6.9dev
        !          1302:        PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC)
        !          1303: */
        !          1304:        PHP_ME(xmlreader, setParserProperty, arginfo_xmlreader_setParserProperty, ZEND_ACC_PUBLIC)
        !          1305:        PHP_ME(xmlreader, setRelaxNGSchema, arginfo_xmlreader_setRelaxNGSchema, ZEND_ACC_PUBLIC)
        !          1306:        PHP_ME(xmlreader, setRelaxNGSchemaSource, arginfo_xmlreader_setRelaxNGSchemaSource, ZEND_ACC_PUBLIC)
        !          1307:        PHP_ME(xmlreader, XML, arginfo_xmlreader_XML, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
        !          1308:        PHP_ME(xmlreader, expand, arginfo_xmlreader_expand, ZEND_ACC_PUBLIC)
        !          1309:        PHP_FE_END
        !          1310: };
        !          1311: 
        !          1312: /* {{{ PHP_MINIT_FUNCTION
        !          1313:  */
        !          1314: PHP_MINIT_FUNCTION(xmlreader)
        !          1315: {
        !          1316:        
        !          1317:        zend_class_entry ce;
        !          1318:        
        !          1319:        memcpy(&xmlreader_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
        !          1320:        xmlreader_object_handlers.read_property = xmlreader_read_property;
        !          1321:        xmlreader_object_handlers.write_property = xmlreader_write_property;
        !          1322:        xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
        !          1323: 
        !          1324:        INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions);
        !          1325:        ce.create_object = xmlreader_objects_new;
        !          1326:        xmlreader_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
        !          1327: 
        !          1328:        zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1);
        !          1329:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC);
        !          1330:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING TSRMLS_CC);
        !          1331:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC);
        !          1332:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC);
        !          1333:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC);
        !          1334:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC);
        !          1335:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC);
        !          1336:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderConstLocalName, IS_STRING TSRMLS_CC);
        !          1337:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderConstName, IS_STRING TSRMLS_CC);
        !          1338:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING TSRMLS_CC);
        !          1339:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC);
        !          1340:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderConstPrefix, IS_STRING TSRMLS_CC);
        !          1341:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderConstValue, IS_STRING TSRMLS_CC);
        !          1342:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderConstXmlLang, IS_STRING TSRMLS_CC);
        !          1343: 
        !          1344:        /* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */
        !          1345: 
        !          1346:        REGISTER_XMLREADER_CLASS_CONST_LONG("NONE",     XML_READER_TYPE_NONE);
        !          1347:        REGISTER_XMLREADER_CLASS_CONST_LONG("ELEMENT",  XML_READER_TYPE_ELEMENT);
        !          1348:        REGISTER_XMLREADER_CLASS_CONST_LONG("ATTRIBUTE",        XML_READER_TYPE_ATTRIBUTE);
        !          1349:        REGISTER_XMLREADER_CLASS_CONST_LONG("TEXT",     XML_READER_TYPE_TEXT);
        !          1350:        REGISTER_XMLREADER_CLASS_CONST_LONG("CDATA",    XML_READER_TYPE_CDATA);
        !          1351:        REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY_REF",       XML_READER_TYPE_ENTITY_REFERENCE);
        !          1352:        REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY",   XML_READER_TYPE_ENTITY);
        !          1353:        REGISTER_XMLREADER_CLASS_CONST_LONG("PI",       XML_READER_TYPE_PROCESSING_INSTRUCTION);
        !          1354:        REGISTER_XMLREADER_CLASS_CONST_LONG("COMMENT",  XML_READER_TYPE_COMMENT);
        !          1355:        REGISTER_XMLREADER_CLASS_CONST_LONG("DOC",      XML_READER_TYPE_DOCUMENT);
        !          1356:        REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_TYPE", XML_READER_TYPE_DOCUMENT_TYPE);
        !          1357:        REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_FRAGMENT",     XML_READER_TYPE_DOCUMENT_FRAGMENT);
        !          1358:        REGISTER_XMLREADER_CLASS_CONST_LONG("NOTATION", XML_READER_TYPE_NOTATION);
        !          1359:        REGISTER_XMLREADER_CLASS_CONST_LONG("WHITESPACE",       XML_READER_TYPE_WHITESPACE);
        !          1360:        REGISTER_XMLREADER_CLASS_CONST_LONG("SIGNIFICANT_WHITESPACE",   XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
        !          1361:        REGISTER_XMLREADER_CLASS_CONST_LONG("END_ELEMENT",      XML_READER_TYPE_END_ELEMENT);
        !          1362:        REGISTER_XMLREADER_CLASS_CONST_LONG("END_ENTITY",       XML_READER_TYPE_END_ENTITY);
        !          1363:        REGISTER_XMLREADER_CLASS_CONST_LONG("XML_DECLARATION",  XML_READER_TYPE_XML_DECLARATION);
        !          1364: 
        !          1365:        /* Constants for Parser options */
        !          1366:        REGISTER_XMLREADER_CLASS_CONST_LONG("LOADDTD",  XML_PARSER_LOADDTD);
        !          1367:        REGISTER_XMLREADER_CLASS_CONST_LONG("DEFAULTATTRS",     XML_PARSER_DEFAULTATTRS);
        !          1368:        REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDATE", XML_PARSER_VALIDATE);
        !          1369:        REGISTER_XMLREADER_CLASS_CONST_LONG("SUBST_ENTITIES",   XML_PARSER_SUBST_ENTITIES);
        !          1370: 
        !          1371:        /* Constants for Errors when loading - not yet used until we implement custom error handling
        !          1372:        REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_WARNING",         XML_PARSER_SEVERITY_VALIDITY_WARNING,   CONST_CS | CONST_PERSISTENT);
        !          1373:        REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_ERROR",           XML_PARSER_SEVERITY_VALIDITY_ERROR,             CONST_CS | CONST_PERSISTENT);
        !          1374:        REGISTER_XMLREADER_CLASS_CONST_LONG("WARNING",                          XML_PARSER_SEVERITY_WARNING,                    CONST_CS | CONST_PERSISTENT);
        !          1375:        REGISTER_XMLREADER_CLASS_CONST_LONG("ERROR",                            XML_PARSER_SEVERITY_ERROR,                              CONST_CS | CONST_PERSISTENT);
        !          1376:        */
        !          1377: 
        !          1378:        return SUCCESS;
        !          1379: }
        !          1380: /* }}} */
        !          1381: 
        !          1382: /* {{{ PHP_MSHUTDOWN_FUNCTION
        !          1383:  */
        !          1384: PHP_MSHUTDOWN_FUNCTION(xmlreader)
        !          1385: {
        !          1386:        zend_hash_destroy(&xmlreader_prop_handlers);
        !          1387:        return SUCCESS;
        !          1388: }
        !          1389: /* }}} */
        !          1390: 
        !          1391: /* {{{ PHP_MINFO_FUNCTION
        !          1392:  */
        !          1393: PHP_MINFO_FUNCTION(xmlreader)
        !          1394: {
        !          1395:        php_info_print_table_start();
        !          1396:        {
        !          1397:                php_info_print_table_row(2, "XMLReader", "enabled");
        !          1398:        }
        !          1399:        php_info_print_table_end();
        !          1400: }
        !          1401: /* }}} */
        !          1402: 
        !          1403: /*
        !          1404:  * Local variables:
        !          1405:  * tab-width: 4
        !          1406:  * c-basic-offset: 4
        !          1407:  * End:
        !          1408:  * vim600: noet sw=4 ts=4 fdm=marker
        !          1409:  * vim<600: noet sw=4 ts=4
        !          1410:  */

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