Annotation of embedaddon/php/ext/xmlreader/php_xmlreader.c, revision 1.1.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>