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

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.4 ! misho       5:   | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       6:   +----------------------------------------------------------------------+
                      7:   | This source file is subject to version 3.01 of the PHP license,      |
                      8:   | that is bundled with this package in the file LICENSE, and is        |
                      9:   | available through the world-wide-web at the following url:           |
                     10:   | http://www.php.net/license/3_01.txt                                  |
                     11:   | If you did not receive a copy of the PHP license and are unable to   |
                     12:   | obtain it through the world-wide-web, please send a note to          |
                     13:   | license@php.net so we can mail you a copy immediately.               |
                     14:   +----------------------------------------------------------------------+
                     15:   | Author: Rob Richards <rrichards@php.net>                             |
                     16:   +----------------------------------------------------------------------+
                     17: */
                     18: 
1.1.1.2   misho      19: /* $Id$ */
1.1       misho      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
1.1.1.2   misho      33: #include <libxml/xmlreader.h>
1.1       misho      34: #include <libxml/uri.h>
                     35: 
                     36: zend_class_entry *xmlreader_class_entry;
                     37: 
                     38: static zend_object_handlers xmlreader_object_handlers;
                     39: 
                     40: static HashTable xmlreader_prop_handlers;
                     41: 
                     42: typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
                     43: typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
                     44: typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr reader);
                     45: typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval TSRMLS_DC);
                     46: 
                     47: typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, const unsigned char *);
                     48: 
                     49: typedef struct _xmlreader_prop_handler {
                     50:        xmlreader_read_int_t read_int_func;
                     51:        xmlreader_read_const_char_t read_char_func;
                     52:        xmlreader_write_t write_func;
                     53:        int type;
                     54: } xmlreader_prop_handler;
                     55: 
                     56: #define XMLREADER_LOAD_STRING 0
                     57: #define XMLREADER_LOAD_FILE 1
                     58: 
                     59: /* {{{ xmlreader_register_prop_handler */
                     60: 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)
                     61: {
                     62:        xmlreader_prop_handler hnd;
                     63:        
                     64:        hnd.read_char_func = read_char_func;
                     65:        hnd.read_int_func = read_int_func;
                     66:        hnd.type = rettype;
                     67:        zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(xmlreader_prop_handler), NULL);
                     68: }
                     69: /* }}} */
                     70: 
                     71: /* {{{ xmlreader_property_reader */
                     72: static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC)
                     73: {
                     74:        const xmlChar *retchar = NULL;
                     75:        int retint = 0;
                     76: 
                     77:        if (obj->ptr != NULL) {
                     78:                if (hnd->read_char_func) {
                     79:                        retchar = hnd->read_char_func(obj->ptr);
                     80:                } else {
                     81:                        if (hnd->read_int_func) {
                     82:                                retint = hnd->read_int_func(obj->ptr);
                     83:                                if (retint == -1) {
                     84:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal libxml error returned");
                     85:                                        return FAILURE;
                     86:                                }
                     87:                        }
                     88:                }
                     89:        }
                     90: 
                     91:        ALLOC_ZVAL(*retval);
                     92: 
                     93:        switch (hnd->type) {
                     94:                case IS_STRING:
                     95:                        if (retchar) {
                     96:                                ZVAL_STRING(*retval, (char *) retchar, 1);
                     97:                        } else {
                     98:                                ZVAL_EMPTY_STRING(*retval);
                     99:                        }
                    100:                        break;
                    101:                case IS_BOOL:
                    102:                        ZVAL_BOOL(*retval, retint);
                    103:                        break;
                    104:                case IS_LONG:
                    105:                        ZVAL_LONG(*retval, retint);
                    106:                        break;
                    107:                default:
                    108:                        ZVAL_NULL(*retval);
                    109:        }
                    110: 
                    111:        return SUCCESS;
                    112: }
                    113: /* }}} */
                    114: 
                    115: /* {{{ xmlreader_get_property_ptr_ptr */
1.1.1.2   misho     116: zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC)
1.1       misho     117: {
                    118:        xmlreader_object *obj;
                    119:        zval tmp_member;
                    120:        zval **retval = NULL;
                    121:        xmlreader_prop_handler *hnd;
                    122:        zend_object_handlers *std_hnd;
                    123:        int ret = FAILURE;
                    124: 
                    125:        if (member->type != IS_STRING) {
                    126:                tmp_member = *member;
                    127:                zval_copy_ctor(&tmp_member);
                    128:                convert_to_string(&tmp_member);
                    129:                member = &tmp_member;
                    130:        }
                    131: 
                    132:        obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
                    133: 
                    134:        if (obj->prop_handler != NULL) {
                    135:                ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
                    136:        }
                    137:        if (ret == FAILURE) {
                    138:                std_hnd = zend_get_std_object_handlers();
1.1.1.2   misho     139:                retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
1.1       misho     140:        }
                    141: 
                    142:        if (member == &tmp_member) {
                    143:                zval_dtor(member);
                    144:        }
                    145:        return retval;
                    146: }
                    147: /* }}} */
                    148: 
                    149: /* {{{ xmlreader_read_property */
1.1.1.2   misho     150: zval *xmlreader_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
1.1       misho     151: {
                    152:        xmlreader_object *obj;
                    153:        zval tmp_member;
                    154:        zval *retval;
                    155:        xmlreader_prop_handler *hnd;
                    156:        zend_object_handlers *std_hnd;
                    157:        int ret;
                    158: 
                    159:        if (member->type != IS_STRING) {
                    160:                tmp_member = *member;
                    161:                zval_copy_ctor(&tmp_member);
                    162:                convert_to_string(&tmp_member);
                    163:                member = &tmp_member;
                    164:        }
                    165: 
                    166:        ret = FAILURE;
                    167:        obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
                    168: 
                    169:        if (obj->prop_handler != NULL) {
                    170:                ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
                    171:        }
                    172:        if (ret == SUCCESS) {
                    173:                ret = xmlreader_property_reader(obj, hnd, &retval TSRMLS_CC);
                    174:                if (ret == SUCCESS) {
                    175:                        /* ensure we're creating a temporary variable */
                    176:                        Z_SET_REFCOUNT_P(retval, 0);
                    177:                } else {
                    178:                        retval = EG(uninitialized_zval_ptr);
                    179:                }
                    180:        } else {
                    181:                std_hnd = zend_get_std_object_handlers();
1.1.1.2   misho     182:                retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
1.1       misho     183:        }
                    184: 
                    185:        if (member == &tmp_member) {
                    186:                zval_dtor(member);
                    187:        }
                    188:        return retval;
                    189: }
                    190: /* }}} */
                    191: 
                    192: /* {{{ xmlreader_write_property */
1.1.1.2   misho     193: void xmlreader_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
1.1       misho     194: {
                    195:        xmlreader_object *obj;
                    196:        zval tmp_member;
                    197:        xmlreader_prop_handler *hnd;
                    198:        zend_object_handlers *std_hnd;
                    199:        int ret;
                    200: 
                    201:        if (member->type != IS_STRING) {
                    202:                tmp_member = *member;
                    203:                zval_copy_ctor(&tmp_member);
                    204:                convert_to_string(&tmp_member);
                    205:                member = &tmp_member;
                    206:        }
                    207: 
                    208:        ret = FAILURE;
                    209:        obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
                    210: 
                    211:        if (obj->prop_handler != NULL) {
                    212:                ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
                    213:        }
                    214:        if (ret == SUCCESS) {
                    215:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write to read-only property");
                    216:        } else {
                    217:                std_hnd = zend_get_std_object_handlers();
1.1.1.2   misho     218:                std_hnd->write_property(object, member, value, key TSRMLS_CC);
1.1       misho     219:        }
                    220: 
                    221:        if (member == &tmp_member) {
                    222:                zval_dtor(member);
                    223:        }
                    224: }
                    225: /* }}} */
                    226: 
                    227: /* {{{ _xmlreader_get_valid_file_path */
                    228: /* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a 
                    229:        common function in libxml extension as code is common to a few xml extensions */
                    230: char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len  TSRMLS_DC) {
                    231:        xmlURI *uri;
                    232:        xmlChar *escsource;
                    233:        char *file_dest;
                    234:        int isFileUri = 0;
                    235: 
                    236:        uri = xmlCreateURI();
                    237:        escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *)":");
                    238:        xmlParseURIReference(uri, (const char *)escsource);
                    239:        xmlFree(escsource);
                    240: 
                    241:        if (uri->scheme != NULL) {
                    242:                /* absolute file uris - libxml only supports localhost or empty host */
                    243:                if (strncasecmp(source, "file:///",8) == 0) {
                    244:                        isFileUri = 1;
                    245: #ifdef PHP_WIN32
                    246:                        source += 8;
                    247: #else
                    248:                        source += 7;
                    249: #endif
                    250:                } else if (strncasecmp(source, "file://localhost/",17) == 0) {
                    251:                        isFileUri = 1;
                    252: #ifdef PHP_WIN32
                    253:                        source += 17;
                    254: #else
                    255:                        source += 16;
                    256: #endif
                    257:                }
                    258:        }
                    259: 
                    260:        file_dest = source;
                    261: 
                    262:        if ((uri->scheme == NULL || isFileUri)) {
                    263:                if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
                    264:                        xmlFreeURI(uri);
                    265:                        return NULL;
                    266:                }
                    267:                file_dest = resolved_path;
                    268:        }
                    269: 
                    270:        xmlFreeURI(uri);
                    271: 
                    272:        return file_dest;
                    273: }
                    274: /* }}} */
                    275: 
                    276: #ifdef LIBXML_SCHEMAS_ENABLED
                    277: /* {{{ _xmlreader_get_relaxNG */
                    278: static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, int source_len, int type, 
                    279:                                                                                        xmlRelaxNGValidityErrorFunc error_func, 
                    280:                                                                                        xmlRelaxNGValidityWarningFunc warn_func TSRMLS_DC)
                    281: {
                    282:        char *valid_file = NULL;
                    283:        xmlRelaxNGParserCtxtPtr parser = NULL;
                    284:        xmlRelaxNGPtr           sptr;
                    285:        char resolved_path[MAXPATHLEN + 1];
                    286: 
                    287:        switch (type) {
                    288:        case XMLREADER_LOAD_FILE:
                    289:                valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
                    290:                if (!valid_file) {
                    291:                        return NULL;
                    292:                }
                    293:                parser = xmlRelaxNGNewParserCtxt(valid_file);
                    294:                break;
                    295:        case XMLREADER_LOAD_STRING:
                    296:                parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
                    297:                /* If loading from memory, we need to set the base directory for the document 
                    298:                   but it is not apparent how to do that for schema's */
                    299:                break;
                    300:        default:
                    301:                return NULL;
                    302:        }
                    303: 
                    304:        if (parser == NULL) {
                    305:                return NULL;
                    306:        }
                    307: 
                    308:        if (error_func || warn_func) {
                    309:                xmlRelaxNGSetParserErrors(parser,
                    310:                        (xmlRelaxNGValidityErrorFunc) error_func,
                    311:                        (xmlRelaxNGValidityWarningFunc) warn_func,
                    312:                        parser);
                    313:        }
                    314:        sptr = xmlRelaxNGParse(parser);
                    315:        xmlRelaxNGFreeParserCtxt(parser);
                    316: 
                    317:        return sptr;
                    318: }
                    319: /* }}} */
                    320: #endif
                    321: 
                    322: static const zend_module_dep xmlreader_deps[] = {
                    323:        ZEND_MOD_REQUIRED("libxml")
                    324:        ZEND_MOD_END
                    325: };
                    326: 
                    327: /* {{{ xmlreader_module_entry
                    328:  */
                    329: zend_module_entry xmlreader_module_entry = {
                    330:        STANDARD_MODULE_HEADER_EX, NULL,
                    331:        xmlreader_deps,
                    332:        "xmlreader",
                    333:        NULL,
                    334:        PHP_MINIT(xmlreader),
                    335:        PHP_MSHUTDOWN(xmlreader),
                    336:        NULL,
                    337:        NULL,
                    338:        PHP_MINFO(xmlreader),
                    339:        "0.1", /* Replace with version number for your extension */
                    340:        STANDARD_MODULE_PROPERTIES
                    341: };
                    342: /* }}} */
                    343: 
                    344: #ifdef COMPILE_DL_XMLREADER
                    345: ZEND_GET_MODULE(xmlreader)
                    346: #endif
                    347: 
                    348: /* {{{ xmlreader_objects_clone */
                    349: void xmlreader_objects_clone(void *object, void **object_clone TSRMLS_DC)
                    350: {
                    351:        /* TODO */
                    352: }
                    353: /* }}} */
                    354: 
                    355: /* {{{ xmlreader_free_resources */
                    356: static void xmlreader_free_resources(xmlreader_object *intern) {
                    357:        if (intern) {
                    358:                if (intern->input) {
                    359:                        xmlFreeParserInputBuffer(intern->input);
                    360:                        intern->input = NULL;
                    361:                }
                    362: 
                    363:                if (intern->ptr) {
                    364:                        xmlFreeTextReader(intern->ptr);
                    365:                        intern->ptr = NULL;
                    366:                }
                    367: #ifdef LIBXML_SCHEMAS_ENABLED
                    368:                if (intern->schema) {
                    369:                        xmlRelaxNGFree((xmlRelaxNGPtr) intern->schema);
                    370:                        intern->schema = NULL;
                    371:                }
                    372: #endif
                    373:        }
                    374: }
                    375: /* }}} */
                    376: 
                    377: /* {{{ xmlreader_objects_free_storage */
                    378: void xmlreader_objects_free_storage(void *object TSRMLS_DC)
                    379: {
                    380:        xmlreader_object *intern = (xmlreader_object *)object;
                    381: 
                    382:        zend_object_std_dtor(&intern->std TSRMLS_CC);
                    383:        
                    384:        xmlreader_free_resources(intern);
                    385: 
                    386:        efree(object);
                    387: }
                    388: /* }}} */
                    389: 
                    390: /* {{{ xmlreader_objects_new */
                    391: zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC)
                    392: {
                    393:        zend_object_value retval;
                    394:        xmlreader_object *intern;
                    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);
1.1.1.2   misho     404:        object_properties_init(&intern->std, class_type);
1.1       misho     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: 
1.1.1.2   misho     498:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p!", &source, &source_len) == FAILURE) {
1.1       misho     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)
1.1.1.3   misho     711: Positions reader at attribute at specified index.
1.1       misho     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:                        RETURN_FALSE;
                    809:                } else {
                    810:                        RETURN_BOOL(retval);
                    811:                }
                    812:        }
                    813:        
                    814:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
                    815:        RETURN_FALSE;
                    816: }
                    817: /* }}} */
                    818: 
                    819: /* {{{ proto boolean XMLReader::next([string localname])
                    820: Moves the position of the current instance to the next node in the stream. */
                    821: PHP_METHOD(xmlreader, next)
                    822: {
                    823:        zval *id;
                    824:        int retval, name_len=0;
                    825:        xmlreader_object *intern;
                    826:        char *name = NULL;
                    827: 
                    828:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
                    829:                return;
                    830:        }
                    831: 
                    832:        id = getThis();
                    833:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
                    834:        if (intern != NULL && intern->ptr != NULL) {
                    835: #if LIBXML_VERSION <= 20617
                    836:                /* Bug in libxml prevents a next in certain cases when positioned on end of element */
                    837:                if (xmlTextReaderNodeType(intern->ptr) == XML_READER_TYPE_END_ELEMENT) {
                    838:                        retval = xmlTextReaderRead(intern->ptr);
                    839:                } else
                    840: #endif
                    841:                retval = xmlTextReaderNext(intern->ptr);
                    842:                while (name != NULL && retval == 1) {
                    843:                        if (xmlStrEqual(xmlTextReaderConstLocalName(intern->ptr), (xmlChar *)name)) {
                    844:                                RETURN_TRUE;
                    845:                        }
                    846:                        retval = xmlTextReaderNext(intern->ptr); 
                    847:                }
                    848:                if (retval == -1) {
                    849:                        RETURN_FALSE;
                    850:                } else {
                    851:                        RETURN_BOOL(retval);
                    852:                }
                    853:        }
                    854:        
                    855:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
                    856:        RETURN_FALSE;
                    857: }
                    858: /* }}} */
                    859: 
                    860: /* {{{ proto boolean XMLReader::open(string URI [, string encoding [, int options]])
                    861: Sets the URI that the XMLReader will parse. */
                    862: PHP_METHOD(xmlreader, open)
                    863: {
                    864:        zval *id;
                    865:        int source_len = 0, encoding_len = 0;
                    866:        long options = 0;
                    867:        xmlreader_object *intern = NULL;
                    868:        char *source, *valid_file = NULL;
                    869:        char *encoding = NULL;
                    870:        char resolved_path[MAXPATHLEN + 1];
                    871:        xmlTextReaderPtr reader = NULL;
                    872: 
1.1.1.2   misho     873:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
1.1       misho     874:                return;
                    875:        }
                    876: 
                    877:        id = getThis();
                    878:        if (id != NULL) {
                    879:                if (! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
                    880:                        id = NULL;
                    881:                } else {
                    882:                        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
                    883:                        xmlreader_free_resources(intern);
                    884:                }
                    885:        }
                    886: 
                    887:        if (!source_len) {
                    888:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
                    889:                RETURN_FALSE;
                    890:        }
                    891: 
                    892:        valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
                    893: 
                    894:        if (valid_file) {
                    895:                reader = xmlReaderForFile(valid_file, encoding, options);
                    896:        }
                    897: 
                    898:        if (reader == NULL) {
                    899:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open source data");
                    900:                RETURN_FALSE;
                    901:        }
                    902: 
                    903:        if (id == NULL) {
                    904:                object_init_ex(return_value, xmlreader_class_entry);
                    905:                intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
                    906:                intern->ptr = reader;
                    907:                return;
                    908:        }
                    909: 
                    910:        intern->ptr = reader;
                    911: 
                    912:        RETURN_TRUE;
                    913: 
                    914: }
                    915: /* }}} */
                    916: 
                    917: /* Not Yet Implemented in libxml - functions exist just not coded
                    918: PHP_METHOD(xmlreader, resetState)
                    919: {
                    920: 
                    921: }
                    922: */
                    923: 
                    924: #if LIBXML_VERSION >= 20620
                    925: /* {{{ proto string XMLReader::readInnerXml()
                    926: Reads the contents of the current node, including child nodes and markup. */
                    927: PHP_METHOD(xmlreader, readInnerXml)
                    928: {
                    929:        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
                    930: }
                    931: /* }}} */
                    932: 
                    933: /* {{{ proto boolean XMLReader::readOuterXml()
                    934: Reads the contents of the current node, including child nodes and markup. */
                    935: PHP_METHOD(xmlreader, readOuterXml)
                    936: {
                    937:        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadOuterXml);
                    938: }
                    939: /* }}} */
                    940: 
                    941: /* {{{ proto boolean XMLReader::readString()
                    942: Reads the contents of an element or a text node as a string. */
                    943: PHP_METHOD(xmlreader, readString)
                    944: {
                    945:        php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
                    946: }
                    947: /* }}} */
                    948: 
                    949: /* {{{ proto boolean XMLReader::setSchema(string filename)
                    950: Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
                    951: PHP_METHOD(xmlreader, setSchema)
                    952: {
                    953: #ifdef LIBXML_SCHEMAS_ENABLED
                    954:        zval *id;
                    955:        int source_len = 0, retval = -1;
                    956:        xmlreader_object *intern;
                    957:        char *source;
                    958: 
1.1.1.2   misho     959:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p!", &source, &source_len) == FAILURE) {
1.1       misho     960:                return;
                    961:        }
                    962: 
                    963:        if (source != NULL && !source_len) {
                    964:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source is required");
                    965:                RETURN_FALSE;
                    966:        }
                    967: 
                    968:        id = getThis();
                    969: 
                    970:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
                    971:        if (intern && intern->ptr) {
                    972:                retval = xmlTextReaderSchemaValidate(intern->ptr, source);
                    973: 
                    974:                if (retval == 0) {
                    975:                        RETURN_TRUE;
                    976:                }
                    977:        }
                    978:        
                    979:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
                    980: 
                    981:        RETURN_FALSE;
                    982: #else
                    983:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built into libxml.");
                    984: 
                    985:        RETURN_FALSE;
                    986: #endif
                    987: }
                    988: /* }}} */
                    989: #endif
                    990: 
                    991: /* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value)
                    992: Sets parser property (one of the parser option constants).
                    993: Properties must be set after open() or XML() and before the first read() is called */
                    994: PHP_METHOD(xmlreader, setParserProperty)
                    995: {
                    996:        zval *id;
                    997:        long property;
                    998:        int retval = -1;
                    999:        zend_bool value;
                   1000:        xmlreader_object *intern;
                   1001: 
                   1002:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &property, &value) == FAILURE) {
                   1003:                return;
                   1004:        }
                   1005: 
                   1006:        id = getThis();
                   1007: 
                   1008:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
                   1009:        if (intern && intern->ptr) {
                   1010:                retval = xmlTextReaderSetParserProp(intern->ptr,property, value);
                   1011:        }
                   1012:        if (retval == -1) {
                   1013:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parser property");
                   1014:                RETURN_FALSE;
                   1015:        }
                   1016: 
                   1017:        RETURN_TRUE;
                   1018: }
                   1019: /* }}} */
                   1020: 
                   1021: /* {{{ proto boolean XMLReader::setRelaxNGSchema(string filename)
                   1022: Sets the string that the XMLReader will parse. */
                   1023: PHP_METHOD(xmlreader, setRelaxNGSchema)
                   1024: {
                   1025:        php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_FILE);
                   1026: }
                   1027: /* }}} */
                   1028: 
                   1029: /* {{{ proto boolean XMLReader::setRelaxNGSchemaSource(string source)
                   1030: Sets the string that the XMLReader will parse. */
                   1031: PHP_METHOD(xmlreader, setRelaxNGSchemaSource)
                   1032: {
                   1033:        php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_STRING);
                   1034: }
                   1035: /* }}} */
                   1036: 
                   1037: /* TODO
                   1038: XMLPUBFUN int XMLCALL          
                   1039:                    xmlTextReaderSetSchema      (xmlTextReaderPtr reader,
                   1040:                                                 xmlSchemaPtr schema);
                   1041: */
                   1042: 
                   1043: /* {{{ proto boolean XMLReader::XML(string source [, string encoding [, int options]])
                   1044: Sets the string that the XMLReader will parse. */
                   1045: PHP_METHOD(xmlreader, XML)
                   1046: {
                   1047:        zval *id;
                   1048:        int source_len = 0, encoding_len = 0;
                   1049:        long options = 0;
                   1050:        xmlreader_object *intern = NULL;
                   1051:        char *source, *uri = NULL, *encoding = NULL;
                   1052:        int resolved_path_len, ret = 0;
                   1053:        char *directory=NULL, resolved_path[MAXPATHLEN];
                   1054:        xmlParserInputBufferPtr inputbfr;
                   1055:        xmlTextReaderPtr reader;
                   1056: 
                   1057:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
                   1058:                return;
                   1059:        }
                   1060: 
                   1061:        id = getThis();
                   1062:        if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
                   1063:                id = NULL;
                   1064:        }
                   1065:        if (id != NULL) {
                   1066:                intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
                   1067:                xmlreader_free_resources(intern);
                   1068:        }
                   1069: 
                   1070:        if (!source_len) {
                   1071:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
                   1072:                RETURN_FALSE;
                   1073:        }
                   1074: 
                   1075:        inputbfr = xmlParserInputBufferCreateMem(source, source_len, XML_CHAR_ENCODING_NONE);
                   1076: 
                   1077:     if (inputbfr != NULL) {
                   1078: /* Get the URI of the current script so that we can set the base directory in libxml */
                   1079: #if HAVE_GETCWD
                   1080:                directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
                   1081: #elif HAVE_GETWD
                   1082:                directory = VCWD_GETWD(resolved_path);
                   1083: #endif
                   1084:                if (directory) {
                   1085:                        resolved_path_len = strlen(resolved_path);
                   1086:                        if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
                   1087:                                resolved_path[resolved_path_len] = DEFAULT_SLASH;
                   1088:                                resolved_path[++resolved_path_len] = '\0';
                   1089:                        }
                   1090:                        uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
                   1091:                }
                   1092:                reader = xmlNewTextReader(inputbfr, uri);
                   1093: 
                   1094:                if (reader != NULL) {
                   1095: #if LIBXML_VERSION >= 20628
                   1096:                        ret = xmlTextReaderSetup(reader, NULL, uri, encoding, options);
                   1097: #endif
                   1098:                        if (ret == 0) {
                   1099:                                if (id == NULL) {
                   1100:                                        object_init_ex(return_value, xmlreader_class_entry);
                   1101:                                        intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
                   1102:                                } else {
                   1103:                                        RETVAL_TRUE;
                   1104:                                }
                   1105:                                intern->input = inputbfr;
                   1106:                                intern->ptr = reader;
                   1107: 
                   1108:                                if (uri) {
                   1109:                                        xmlFree(uri);
                   1110:                                }
                   1111: 
                   1112:                                return;
                   1113:                        }
                   1114:                }
                   1115:        }
                   1116: 
                   1117:        if (uri) {
                   1118:                xmlFree(uri);
                   1119:        }
                   1120: 
                   1121:        if (inputbfr) {
                   1122:                xmlFreeParserInputBuffer(inputbfr);
                   1123:        }
                   1124:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load source data");
                   1125:        RETURN_FALSE;
                   1126: }
                   1127: /* }}} */
                   1128: 
                   1129: /* {{{ proto boolean XMLReader::expand()
                   1130: Moves the position of the current instance to the next node in the stream. */
                   1131: PHP_METHOD(xmlreader, expand)
                   1132: {
                   1133: #ifdef HAVE_DOM
1.1.1.2   misho    1134:        zval *id, *basenode = NULL;
1.1       misho    1135:        int ret;
                   1136:        xmlreader_object *intern;
                   1137:        xmlNode *node, *nodec;
                   1138:        xmlDocPtr docp = NULL;
                   1139:        php_libxml_node_object *domobj = NULL;
                   1140: 
                   1141:        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!", &id, xmlreader_class_entry, &basenode, dom_node_class_entry) == FAILURE) {
                   1142:                return;
                   1143:        }
                   1144:        
                   1145:        if (basenode != NULL) {
                   1146:                NODE_GET_OBJ(node, basenode, xmlNodePtr, domobj);
                   1147:                docp = node->doc;
                   1148:        }
                   1149: 
                   1150:        intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
                   1151: 
                   1152:        if (intern && intern->ptr) {
                   1153:                node = xmlTextReaderExpand(intern->ptr);
                   1154:                
                   1155:                if (node == NULL) {
1.1.1.3   misho    1156:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occurred while expanding ");
1.1       misho    1157:                        RETURN_FALSE;
                   1158:                } else {
                   1159:                        nodec = xmlDocCopyNode(node, docp, 1);
                   1160:                        if (nodec == NULL) {
                   1161:                                php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot expand this node type");
                   1162:                                RETURN_FALSE;
                   1163:                        } else {
1.1.1.2   misho    1164:                                DOM_RET_OBJ(nodec, &ret, (dom_object *)domobj);
1.1       misho    1165:                        }
                   1166:                }
                   1167:        } else {
                   1168:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to expand");
                   1169:                RETURN_FALSE;
                   1170:        }
                   1171: #else
                   1172:        php_error(E_WARNING, "DOM support is not enabled");
                   1173:        return;
                   1174: #endif
                   1175: }
                   1176: /* }}} */
                   1177: /* {{{ arginfo */
                   1178: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_close, 0)
                   1179: ZEND_END_ARG_INFO()
                   1180: 
                   1181: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttribute, 0)
                   1182:        ZEND_ARG_INFO(0, name)
                   1183: ZEND_END_ARG_INFO()
                   1184: 
                   1185: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNo, 0)
                   1186:        ZEND_ARG_INFO(0, index)
                   1187: ZEND_END_ARG_INFO()
                   1188: 
                   1189: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNs, 0)
                   1190:        ZEND_ARG_INFO(0, name)
                   1191:        ZEND_ARG_INFO(0, namespaceURI)
                   1192: ZEND_END_ARG_INFO()
                   1193: 
                   1194: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getParserProperty, 0)
                   1195:        ZEND_ARG_INFO(0, property)
                   1196: ZEND_END_ARG_INFO()
                   1197: 
                   1198: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_isValid, 0)
                   1199: ZEND_END_ARG_INFO()
                   1200: 
                   1201: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_lookupNamespace, 0)
                   1202: ZEND_ARG_INFO(0, prefix)
                   1203: ZEND_END_ARG_INFO()
                   1204: 
                   1205: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttribute, 0)
                   1206:        ZEND_ARG_INFO(0, name)
                   1207: ZEND_END_ARG_INFO()
                   1208: 
                   1209: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNo, 0)
                   1210:        ZEND_ARG_INFO(0, index)
                   1211: ZEND_END_ARG_INFO()
                   1212: 
                   1213: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNs, 0)
                   1214:        ZEND_ARG_INFO(0, name)
                   1215:        ZEND_ARG_INFO(0, namespaceURI)
                   1216: ZEND_END_ARG_INFO()
                   1217: 
                   1218: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToElement, 0)
                   1219: ZEND_END_ARG_INFO()
                   1220: 
                   1221: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToFirstAttribute, 0)
                   1222: ZEND_END_ARG_INFO()
                   1223: 
                   1224: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToNextAttribute, 0)
                   1225: ZEND_END_ARG_INFO()
                   1226: 
                   1227: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_read, 0)
                   1228: ZEND_END_ARG_INFO()
                   1229: 
                   1230: ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_next, 0, 0, 0)
                   1231:        ZEND_ARG_INFO(0, localname)
                   1232: ZEND_END_ARG_INFO()
                   1233: 
                   1234: ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_open, 0, 0, 1)
                   1235:        ZEND_ARG_INFO(0, URI)
                   1236:        ZEND_ARG_INFO(0, encoding)
                   1237:        ZEND_ARG_INFO(0, options)
                   1238: ZEND_END_ARG_INFO()
                   1239: 
                   1240: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readInnerXml, 0)
                   1241: ZEND_END_ARG_INFO()
                   1242: 
                   1243: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readOuterXml, 0)
                   1244: ZEND_END_ARG_INFO()
                   1245: 
                   1246: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readString, 0)
                   1247: ZEND_END_ARG_INFO()
                   1248: 
                   1249: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setSchema, 0)
                   1250:        ZEND_ARG_INFO(0, filename)
                   1251: ZEND_END_ARG_INFO()
                   1252: 
                   1253: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setParserProperty, 0)
                   1254:        ZEND_ARG_INFO(0, property)
                   1255:        ZEND_ARG_INFO(0, value)
                   1256: ZEND_END_ARG_INFO()
                   1257: 
                   1258: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchema, 0)
                   1259:        ZEND_ARG_INFO(0, filename)
                   1260: ZEND_END_ARG_INFO()
                   1261: 
                   1262: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchemaSource, 0)
                   1263:        ZEND_ARG_INFO(0, source)
                   1264: ZEND_END_ARG_INFO()
                   1265: 
                   1266: ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_XML, 0, 0, 1)
                   1267:        ZEND_ARG_INFO(0, source)
                   1268:        ZEND_ARG_INFO(0, encoding)
                   1269:        ZEND_ARG_INFO(0, options)
                   1270: ZEND_END_ARG_INFO()
                   1271: 
                   1272: ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_expand, 0)
                   1273: ZEND_END_ARG_INFO()
                   1274: /* }}} */
                   1275: 
                   1276: static const zend_function_entry xmlreader_functions[] = {
                   1277:        PHP_ME(xmlreader, close, arginfo_xmlreader_close, ZEND_ACC_PUBLIC)
                   1278:        PHP_ME(xmlreader, getAttribute, arginfo_xmlreader_getAttribute, ZEND_ACC_PUBLIC)
                   1279:        PHP_ME(xmlreader, getAttributeNo, arginfo_xmlreader_getAttributeNo, ZEND_ACC_PUBLIC)
                   1280:        PHP_ME(xmlreader, getAttributeNs, arginfo_xmlreader_getAttributeNs, ZEND_ACC_PUBLIC)
                   1281:        PHP_ME(xmlreader, getParserProperty, arginfo_xmlreader_getParserProperty, ZEND_ACC_PUBLIC)
                   1282:        PHP_ME(xmlreader, isValid, arginfo_xmlreader_isValid, ZEND_ACC_PUBLIC)
                   1283:        PHP_ME(xmlreader, lookupNamespace, arginfo_xmlreader_lookupNamespace, ZEND_ACC_PUBLIC)
                   1284:        PHP_ME(xmlreader, moveToAttributeNo, arginfo_xmlreader_moveToAttributeNo, ZEND_ACC_PUBLIC)
                   1285:        PHP_ME(xmlreader, moveToAttribute, arginfo_xmlreader_moveToAttribute, ZEND_ACC_PUBLIC)
                   1286:        PHP_ME(xmlreader, moveToAttributeNs, arginfo_xmlreader_moveToAttributeNs, ZEND_ACC_PUBLIC)
                   1287:        PHP_ME(xmlreader, moveToElement, arginfo_xmlreader_moveToElement, ZEND_ACC_PUBLIC)
                   1288:        PHP_ME(xmlreader, moveToFirstAttribute, arginfo_xmlreader_moveToFirstAttribute, ZEND_ACC_PUBLIC)
                   1289:        PHP_ME(xmlreader, moveToNextAttribute, arginfo_xmlreader_moveToNextAttribute, ZEND_ACC_PUBLIC)
                   1290:        PHP_ME(xmlreader, open, arginfo_xmlreader_open, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
                   1291:        PHP_ME(xmlreader, read, arginfo_xmlreader_read, ZEND_ACC_PUBLIC)
                   1292:        PHP_ME(xmlreader, next, arginfo_xmlreader_next, ZEND_ACC_PUBLIC)
                   1293: #if LIBXML_VERSION >= 20620
                   1294:        PHP_ME(xmlreader, readInnerXml, arginfo_xmlreader_readInnerXml, ZEND_ACC_PUBLIC)
                   1295:        PHP_ME(xmlreader, readOuterXml, arginfo_xmlreader_readOuterXml, ZEND_ACC_PUBLIC)
                   1296:        PHP_ME(xmlreader, readString, arginfo_xmlreader_readString, ZEND_ACC_PUBLIC)
                   1297:        PHP_ME(xmlreader, setSchema, arginfo_xmlreader_setSchema, ZEND_ACC_PUBLIC)
                   1298: #endif
                   1299: /* Not Yet Implemented though defined in libxml as of 2.6.9dev
                   1300:        PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC)
                   1301: */
                   1302:        PHP_ME(xmlreader, setParserProperty, arginfo_xmlreader_setParserProperty, ZEND_ACC_PUBLIC)
                   1303:        PHP_ME(xmlreader, setRelaxNGSchema, arginfo_xmlreader_setRelaxNGSchema, ZEND_ACC_PUBLIC)
                   1304:        PHP_ME(xmlreader, setRelaxNGSchemaSource, arginfo_xmlreader_setRelaxNGSchemaSource, ZEND_ACC_PUBLIC)
                   1305:        PHP_ME(xmlreader, XML, arginfo_xmlreader_XML, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
                   1306:        PHP_ME(xmlreader, expand, arginfo_xmlreader_expand, ZEND_ACC_PUBLIC)
                   1307:        PHP_FE_END
                   1308: };
                   1309: 
                   1310: /* {{{ PHP_MINIT_FUNCTION
                   1311:  */
                   1312: PHP_MINIT_FUNCTION(xmlreader)
                   1313: {
                   1314:        
                   1315:        zend_class_entry ce;
                   1316:        
                   1317:        memcpy(&xmlreader_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
                   1318:        xmlreader_object_handlers.read_property = xmlreader_read_property;
                   1319:        xmlreader_object_handlers.write_property = xmlreader_write_property;
                   1320:        xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
1.1.1.4 ! misho    1321:        xmlreader_object_handlers.clone_obj = NULL;
1.1       misho    1322: 
                   1323:        INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions);
                   1324:        ce.create_object = xmlreader_objects_new;
                   1325:        xmlreader_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
                   1326: 
                   1327:        zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1);
                   1328:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC);
                   1329:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING TSRMLS_CC);
                   1330:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC);
                   1331:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC);
                   1332:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC);
                   1333:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC);
                   1334:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC);
                   1335:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderConstLocalName, IS_STRING TSRMLS_CC);
                   1336:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderConstName, IS_STRING TSRMLS_CC);
                   1337:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING TSRMLS_CC);
                   1338:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC);
                   1339:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderConstPrefix, IS_STRING TSRMLS_CC);
                   1340:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderConstValue, IS_STRING TSRMLS_CC);
                   1341:        xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderConstXmlLang, IS_STRING TSRMLS_CC);
                   1342: 
                   1343:        /* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */
                   1344: 
                   1345:        REGISTER_XMLREADER_CLASS_CONST_LONG("NONE",     XML_READER_TYPE_NONE);
                   1346:        REGISTER_XMLREADER_CLASS_CONST_LONG("ELEMENT",  XML_READER_TYPE_ELEMENT);
                   1347:        REGISTER_XMLREADER_CLASS_CONST_LONG("ATTRIBUTE",        XML_READER_TYPE_ATTRIBUTE);
                   1348:        REGISTER_XMLREADER_CLASS_CONST_LONG("TEXT",     XML_READER_TYPE_TEXT);
                   1349:        REGISTER_XMLREADER_CLASS_CONST_LONG("CDATA",    XML_READER_TYPE_CDATA);
                   1350:        REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY_REF",       XML_READER_TYPE_ENTITY_REFERENCE);
                   1351:        REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY",   XML_READER_TYPE_ENTITY);
                   1352:        REGISTER_XMLREADER_CLASS_CONST_LONG("PI",       XML_READER_TYPE_PROCESSING_INSTRUCTION);
                   1353:        REGISTER_XMLREADER_CLASS_CONST_LONG("COMMENT",  XML_READER_TYPE_COMMENT);
                   1354:        REGISTER_XMLREADER_CLASS_CONST_LONG("DOC",      XML_READER_TYPE_DOCUMENT);
                   1355:        REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_TYPE", XML_READER_TYPE_DOCUMENT_TYPE);
                   1356:        REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_FRAGMENT",     XML_READER_TYPE_DOCUMENT_FRAGMENT);
                   1357:        REGISTER_XMLREADER_CLASS_CONST_LONG("NOTATION", XML_READER_TYPE_NOTATION);
                   1358:        REGISTER_XMLREADER_CLASS_CONST_LONG("WHITESPACE",       XML_READER_TYPE_WHITESPACE);
                   1359:        REGISTER_XMLREADER_CLASS_CONST_LONG("SIGNIFICANT_WHITESPACE",   XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
                   1360:        REGISTER_XMLREADER_CLASS_CONST_LONG("END_ELEMENT",      XML_READER_TYPE_END_ELEMENT);
                   1361:        REGISTER_XMLREADER_CLASS_CONST_LONG("END_ENTITY",       XML_READER_TYPE_END_ENTITY);
                   1362:        REGISTER_XMLREADER_CLASS_CONST_LONG("XML_DECLARATION",  XML_READER_TYPE_XML_DECLARATION);
                   1363: 
                   1364:        /* Constants for Parser options */
                   1365:        REGISTER_XMLREADER_CLASS_CONST_LONG("LOADDTD",  XML_PARSER_LOADDTD);
                   1366:        REGISTER_XMLREADER_CLASS_CONST_LONG("DEFAULTATTRS",     XML_PARSER_DEFAULTATTRS);
                   1367:        REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDATE", XML_PARSER_VALIDATE);
                   1368:        REGISTER_XMLREADER_CLASS_CONST_LONG("SUBST_ENTITIES",   XML_PARSER_SUBST_ENTITIES);
                   1369: 
                   1370:        /* Constants for Errors when loading - not yet used until we implement custom error handling
                   1371:        REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_WARNING",         XML_PARSER_SEVERITY_VALIDITY_WARNING,   CONST_CS | CONST_PERSISTENT);
                   1372:        REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_ERROR",           XML_PARSER_SEVERITY_VALIDITY_ERROR,             CONST_CS | CONST_PERSISTENT);
                   1373:        REGISTER_XMLREADER_CLASS_CONST_LONG("WARNING",                          XML_PARSER_SEVERITY_WARNING,                    CONST_CS | CONST_PERSISTENT);
                   1374:        REGISTER_XMLREADER_CLASS_CONST_LONG("ERROR",                            XML_PARSER_SEVERITY_ERROR,                              CONST_CS | CONST_PERSISTENT);
                   1375:        */
                   1376: 
                   1377:        return SUCCESS;
                   1378: }
                   1379: /* }}} */
                   1380: 
                   1381: /* {{{ PHP_MSHUTDOWN_FUNCTION
                   1382:  */
                   1383: PHP_MSHUTDOWN_FUNCTION(xmlreader)
                   1384: {
                   1385:        zend_hash_destroy(&xmlreader_prop_handlers);
                   1386:        return SUCCESS;
                   1387: }
                   1388: /* }}} */
                   1389: 
                   1390: /* {{{ PHP_MINFO_FUNCTION
                   1391:  */
                   1392: PHP_MINFO_FUNCTION(xmlreader)
                   1393: {
                   1394:        php_info_print_table_start();
                   1395:        {
                   1396:                php_info_print_table_row(2, "XMLReader", "enabled");
                   1397:        }
                   1398:        php_info_print_table_end();
                   1399: }
                   1400: /* }}} */
                   1401: 
                   1402: /*
                   1403:  * Local variables:
                   1404:  * tab-width: 4
                   1405:  * c-basic-offset: 4
                   1406:  * End:
                   1407:  * vim600: noet sw=4 ts=4 fdm=marker
                   1408:  * vim<600: noet sw=4 ts=4
                   1409:  */

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