Return to php_xmlreader.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / xmlreader |
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: */