root/ext/xmlreader/php_xmlreader.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xmlreader_register_prop_handler
  2. xmlreader_property_reader
  3. xmlreader_get_property_ptr_ptr
  4. xmlreader_read_property
  5. xmlreader_write_property
  6. _xmlreader_get_valid_file_path
  7. _xmlreader_get_relaxNG
  8. ZEND_GET_MODULE
  9. xmlreader_free_resources
  10. xmlreader_objects_free_storage
  11. xmlreader_objects_new
  12. php_xmlreader_string_arg
  13. php_xmlreader_no_arg
  14. php_xmlreader_no_arg_string
  15. php_xmlreader_set_relaxng_schema
  16. PHP_METHOD
  17. PHP_METHOD
  18. PHP_METHOD
  19. PHP_METHOD
  20. PHP_METHOD
  21. PHP_METHOD
  22. PHP_METHOD
  23. PHP_METHOD
  24. PHP_METHOD
  25. PHP_METHOD
  26. PHP_METHOD
  27. PHP_METHOD
  28. PHP_METHOD
  29. PHP_METHOD
  30. PHP_METHOD
  31. PHP_METHOD
  32. PHP_METHOD
  33. PHP_METHOD
  34. PHP_METHOD
  35. PHP_METHOD
  36. PHP_METHOD
  37. PHP_METHOD
  38. PHP_METHOD
  39. PHP_METHOD
  40. PHP_METHOD
  41. PHP_MINIT_FUNCTION
  42. PHP_MSHUTDOWN_FUNCTION
  43. PHP_MINFO_FUNCTION

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 5                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 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$ */
  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/xmlreader.h>
  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 */
 116 zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
 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();
 139                 retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
 140         }
 141 
 142         if (member == &tmp_member) {
 143                 zval_dtor(member);
 144         }
 145         return retval;
 146 }
 147 /* }}} */
 148 
 149 /* {{{ xmlreader_read_property */
 150 zval *xmlreader_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
 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();
 182                 retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
 183         }
 184 
 185         if (member == &tmp_member) {
 186                 zval_dtor(member);
 187         }
 188         return retval;
 189 }
 190 /* }}} */
 191 
 192 /* {{{ xmlreader_write_property */
 193 void xmlreader_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
 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();
 218                 std_hnd->write_property(object, member, value, key TSRMLS_CC);
 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);
 404         object_properties_init(&intern->std, class_type);
 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, "p!", &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         }
 592 }
 593 /* }}} */
 594 
 595 /* {{{ proto string XMLReader::getAttributeNs(string name, string namespaceURI)
 596 Get value of a attribute via name and namespace from current element */
 597 PHP_METHOD(xmlreader, getAttributeNs)
 598 {
 599         zval *id;
 600         int name_len = 0, ns_uri_len = 0;
 601         xmlreader_object *intern;
 602         char *name, *ns_uri, *retchar = NULL;
 603 
 604         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &ns_uri, &ns_uri_len) == FAILURE) {
 605                 return;
 606         }
 607 
 608         if (name_len == 0 || ns_uri_len == 0) {
 609                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name and Namespace URI cannot be empty");
 610                 RETURN_FALSE;
 611         }
 612 
 613         id = getThis();
 614 
 615         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 616         if (intern && intern->ptr) {
 617                 retchar = (char *)xmlTextReaderGetAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
 618         }
 619         if (retchar) {
 620                 RETVAL_STRING(retchar, 1);
 621                 xmlFree(retchar);
 622         }
 623 }
 624 /* }}} */
 625 
 626 /* {{{ proto boolean XMLReader::getParserProperty(int property)
 627 Indicates whether given property (one of the parser option constants) is set or not on parser */
 628 PHP_METHOD(xmlreader, getParserProperty)
 629 {
 630         zval *id;
 631         long property;
 632         int retval = -1;
 633         xmlreader_object *intern;
 634 
 635         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &property) == FAILURE) {
 636                 return;
 637         }
 638 
 639         id = getThis();
 640 
 641         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 642         if (intern && intern->ptr) {
 643                 retval = xmlTextReaderGetParserProp(intern->ptr,property);
 644         }
 645         if (retval == -1) {
 646                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parser property");
 647                 RETURN_FALSE;
 648         }
 649 
 650         RETURN_BOOL(retval);
 651 }
 652 /* }}} */
 653 
 654 /* {{{ proto boolean XMLReader::isValid()
 655 Returns boolean indicating if parsed document is valid or not.
 656 Must set XMLREADER_LOADDTD or XMLREADER_VALIDATE parser option prior to the first call to read
 657 or this method will always return FALSE */
 658 PHP_METHOD(xmlreader, isValid)
 659 {
 660         php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderIsValid);
 661 }
 662 /* }}} */
 663 
 664 /* {{{ proto string XMLReader::lookupNamespace(string prefix)
 665 Return namespaceURI for associated prefix on current node */
 666 PHP_METHOD(xmlreader, lookupNamespace)
 667 {
 668         php_xmlreader_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderLookupNamespace);
 669 }
 670 /* }}} */
 671 
 672 /* {{{ proto boolean XMLReader::moveToAttribute(string name)
 673 Positions reader at specified attribute - Returns TRUE on success and FALSE on failure */
 674 PHP_METHOD(xmlreader, moveToAttribute)
 675 {
 676         zval *id;
 677         int name_len = 0, retval;
 678         xmlreader_object *intern;
 679         char *name;
 680 
 681         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
 682                 return;
 683         }
 684 
 685         if (name_len == 0) {
 686                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
 687                 RETURN_FALSE;
 688         }
 689 
 690         id = getThis();
 691 
 692         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 693         if (intern && intern->ptr) {
 694                 retval = xmlTextReaderMoveToAttribute(intern->ptr, (xmlChar *)name);
 695                 if (retval == 1) {
 696                         RETURN_TRUE;
 697                 }
 698         }
 699 
 700         RETURN_FALSE;
 701 }
 702 /* }}} */
 703 
 704 /* {{{ proto boolean XMLReader::moveToAttributeNo(int index)
 705 Positions reader at attribute at specified index.
 706 Returns TRUE on success and FALSE on failure */
 707 PHP_METHOD(xmlreader, moveToAttributeNo)
 708 {
 709         zval *id;
 710         long attr_pos;
 711         int retval;
 712         xmlreader_object *intern;
 713 
 714         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &attr_pos) == FAILURE) {
 715                 return;
 716         }
 717 
 718         id = getThis();
 719 
 720         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 721         if (intern && intern->ptr) {
 722                 retval = xmlTextReaderMoveToAttributeNo(intern->ptr, attr_pos);
 723                 if (retval == 1) {
 724                         RETURN_TRUE;
 725                 }
 726         }
 727 
 728         RETURN_FALSE;
 729 }
 730 /* }}} */
 731 
 732 /* {{{ proto boolean XMLReader::moveToAttributeNs(string name, string namespaceURI)
 733 Positions reader at attribute spcified by name and namespaceURI.
 734 Returns TRUE on success and FALSE on failure */
 735 PHP_METHOD(xmlreader, moveToAttributeNs)
 736 {
 737         zval *id;
 738         int name_len=0, ns_uri_len=0, retval;
 739         xmlreader_object *intern;
 740         char *name, *ns_uri;
 741 
 742         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &ns_uri, &ns_uri_len) == FAILURE) {
 743                 return;
 744         }
 745 
 746         if (name_len == 0 || ns_uri_len == 0) {
 747                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name and Namespace URI cannot be empty");
 748                 RETURN_FALSE;
 749         }
 750 
 751         id = getThis();
 752 
 753         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 754         if (intern && intern->ptr) {
 755                 retval = xmlTextReaderMoveToAttributeNs(intern->ptr, (xmlChar *)name, (xmlChar *)ns_uri);
 756                 if (retval == 1) {
 757                         RETURN_TRUE;
 758                 }
 759         }
 760 
 761         RETURN_FALSE;
 762 }
 763 /* }}} */
 764 
 765 /* {{{ proto boolean XMLReader::moveToElement()
 766 Moves the position of the current instance to the node that contains the current Attribute node. */
 767 PHP_METHOD(xmlreader, moveToElement)
 768 {
 769         php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToElement);
 770 }
 771 /* }}} */
 772 
 773 /* {{{ proto boolean XMLReader::moveToFirstAttribute()
 774 Moves the position of the current instance to the first attribute associated with the current node. */
 775 PHP_METHOD(xmlreader, moveToFirstAttribute)
 776 {
 777         php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToFirstAttribute);
 778 }
 779 /* }}} */
 780 
 781 /* {{{ proto boolean XMLReader::moveToNextAttribute()
 782 Moves the position of the current instance to the next attribute associated with the current node. */
 783 PHP_METHOD(xmlreader, moveToNextAttribute)
 784 {
 785         php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderMoveToNextAttribute);
 786 }
 787 /* }}} */
 788 
 789 /* {{{ proto boolean XMLReader::read()
 790 Moves the position of the current instance to the next node in the stream. */
 791 PHP_METHOD(xmlreader, read)
 792 {
 793         zval *id;
 794         int retval;
 795         xmlreader_object *intern;
 796 
 797         id = getThis();
 798         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 799         if (intern != NULL && intern->ptr != NULL) {
 800                 retval = xmlTextReaderRead(intern->ptr);
 801                 if (retval == -1) {
 802                         RETURN_FALSE;
 803                 } else {
 804                         RETURN_BOOL(retval);
 805                 }
 806         }
 807 
 808         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
 809         RETURN_FALSE;
 810 }
 811 /* }}} */
 812 
 813 /* {{{ proto boolean XMLReader::next([string localname])
 814 Moves the position of the current instance to the next node in the stream. */
 815 PHP_METHOD(xmlreader, next)
 816 {
 817         zval *id;
 818         int retval, name_len=0;
 819         xmlreader_object *intern;
 820         char *name = NULL;
 821 
 822         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
 823                 return;
 824         }
 825 
 826         id = getThis();
 827         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 828         if (intern != NULL && intern->ptr != NULL) {
 829 #if LIBXML_VERSION <= 20617
 830                 /* Bug in libxml prevents a next in certain cases when positioned on end of element */
 831                 if (xmlTextReaderNodeType(intern->ptr) == XML_READER_TYPE_END_ELEMENT) {
 832                         retval = xmlTextReaderRead(intern->ptr);
 833                 } else
 834 #endif
 835                 retval = xmlTextReaderNext(intern->ptr);
 836                 while (name != NULL && retval == 1) {
 837                         if (xmlStrEqual(xmlTextReaderConstLocalName(intern->ptr), (xmlChar *)name)) {
 838                                 RETURN_TRUE;
 839                         }
 840                         retval = xmlTextReaderNext(intern->ptr);
 841                 }
 842                 if (retval == -1) {
 843                         RETURN_FALSE;
 844                 } else {
 845                         RETURN_BOOL(retval);
 846                 }
 847         }
 848 
 849         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
 850         RETURN_FALSE;
 851 }
 852 /* }}} */
 853 
 854 /* {{{ proto boolean XMLReader::open(string URI [, string encoding [, int options]])
 855 Sets the URI that the XMLReader will parse. */
 856 PHP_METHOD(xmlreader, open)
 857 {
 858         zval *id;
 859         int source_len = 0, encoding_len = 0;
 860         long options = 0;
 861         xmlreader_object *intern = NULL;
 862         char *source, *valid_file = NULL;
 863         char *encoding = NULL;
 864         char resolved_path[MAXPATHLEN + 1];
 865         xmlTextReaderPtr reader = NULL;
 866 
 867         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
 868                 return;
 869         }
 870 
 871         id = getThis();
 872         if (id != NULL) {
 873                 if (! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
 874                         id = NULL;
 875                 } else {
 876                         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 877                         xmlreader_free_resources(intern);
 878                 }
 879         }
 880 
 881         if (!source_len) {
 882                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
 883                 RETURN_FALSE;
 884         }
 885 
 886         valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN  TSRMLS_CC);
 887 
 888         if (valid_file) {
 889                 reader = xmlReaderForFile(valid_file, encoding, options);
 890         }
 891 
 892         if (reader == NULL) {
 893                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open source data");
 894                 RETURN_FALSE;
 895         }
 896 
 897         if (id == NULL) {
 898                 object_init_ex(return_value, xmlreader_class_entry);
 899                 intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
 900                 intern->ptr = reader;
 901                 return;
 902         }
 903 
 904         intern->ptr = reader;
 905 
 906         RETURN_TRUE;
 907 
 908 }
 909 /* }}} */
 910 
 911 /* Not Yet Implemented in libxml - functions exist just not coded
 912 PHP_METHOD(xmlreader, resetState)
 913 {
 914 
 915 }
 916 */
 917 
 918 #if LIBXML_VERSION >= 20620
 919 /* {{{ proto string XMLReader::readInnerXml()
 920 Reads the contents of the current node, including child nodes and markup. */
 921 PHP_METHOD(xmlreader, readInnerXml)
 922 {
 923         php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
 924 }
 925 /* }}} */
 926 
 927 /* {{{ proto boolean XMLReader::readOuterXml()
 928 Reads the contents of the current node, including child nodes and markup. */
 929 PHP_METHOD(xmlreader, readOuterXml)
 930 {
 931         php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadOuterXml);
 932 }
 933 /* }}} */
 934 
 935 /* {{{ proto boolean XMLReader::readString()
 936 Reads the contents of an element or a text node as a string. */
 937 PHP_METHOD(xmlreader, readString)
 938 {
 939         php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
 940 }
 941 /* }}} */
 942 
 943 /* {{{ proto boolean XMLReader::setSchema(string filename)
 944 Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
 945 PHP_METHOD(xmlreader, setSchema)
 946 {
 947 #ifdef LIBXML_SCHEMAS_ENABLED
 948         zval *id;
 949         int source_len = 0, retval = -1;
 950         xmlreader_object *intern;
 951         char *source;
 952 
 953         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p!", &source, &source_len) == FAILURE) {
 954                 return;
 955         }
 956 
 957         if (source != NULL && !source_len) {
 958                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source is required");
 959                 RETURN_FALSE;
 960         }
 961 
 962         id = getThis();
 963 
 964         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
 965         if (intern && intern->ptr) {
 966                 retval = xmlTextReaderSchemaValidate(intern->ptr, source);
 967 
 968                 if (retval == 0) {
 969                         RETURN_TRUE;
 970                 }
 971         }
 972 
 973         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
 974 
 975         RETURN_FALSE;
 976 #else
 977         php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built into libxml.");
 978 
 979         RETURN_FALSE;
 980 #endif
 981 }
 982 /* }}} */
 983 #endif
 984 
 985 /* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value)
 986 Sets parser property (one of the parser option constants).
 987 Properties must be set after open() or XML() and before the first read() is called */
 988 PHP_METHOD(xmlreader, setParserProperty)
 989 {
 990         zval *id;
 991         long property;
 992         int retval = -1;
 993         zend_bool value;
 994         xmlreader_object *intern;
 995 
 996         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &property, &value) == FAILURE) {
 997                 return;
 998         }
 999 
1000         id = getThis();
1001 
1002         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
1003         if (intern && intern->ptr) {
1004                 retval = xmlTextReaderSetParserProp(intern->ptr,property, value);
1005         }
1006         if (retval == -1) {
1007                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parser property");
1008                 RETURN_FALSE;
1009         }
1010 
1011         RETURN_TRUE;
1012 }
1013 /* }}} */
1014 
1015 /* {{{ proto boolean XMLReader::setRelaxNGSchema(string filename)
1016 Sets the string that the XMLReader will parse. */
1017 PHP_METHOD(xmlreader, setRelaxNGSchema)
1018 {
1019         php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_FILE);
1020 }
1021 /* }}} */
1022 
1023 /* {{{ proto boolean XMLReader::setRelaxNGSchemaSource(string source)
1024 Sets the string that the XMLReader will parse. */
1025 PHP_METHOD(xmlreader, setRelaxNGSchemaSource)
1026 {
1027         php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_STRING);
1028 }
1029 /* }}} */
1030 
1031 /* TODO
1032 XMLPUBFUN int XMLCALL
1033                     xmlTextReaderSetSchema      (xmlTextReaderPtr reader,
1034                                                  xmlSchemaPtr schema);
1035 */
1036 
1037 /* {{{ proto boolean XMLReader::XML(string source [, string encoding [, int options]])
1038 Sets the string that the XMLReader will parse. */
1039 PHP_METHOD(xmlreader, XML)
1040 {
1041         zval *id;
1042         int source_len = 0, encoding_len = 0;
1043         long options = 0;
1044         xmlreader_object *intern = NULL;
1045         char *source, *uri = NULL, *encoding = NULL;
1046         int resolved_path_len, ret = 0;
1047         char *directory=NULL, resolved_path[MAXPATHLEN];
1048         xmlParserInputBufferPtr inputbfr;
1049         xmlTextReaderPtr reader;
1050 
1051         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
1052                 return;
1053         }
1054 
1055         id = getThis();
1056         if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
1057                 id = NULL;
1058         }
1059         if (id != NULL) {
1060                 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
1061                 xmlreader_free_resources(intern);
1062         }
1063 
1064         if (!source_len) {
1065                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
1066                 RETURN_FALSE;
1067         }
1068 
1069         inputbfr = xmlParserInputBufferCreateMem(source, source_len, XML_CHAR_ENCODING_NONE);
1070 
1071     if (inputbfr != NULL) {
1072 /* Get the URI of the current script so that we can set the base directory in libxml */
1073 #if HAVE_GETCWD
1074                 directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
1075 #elif HAVE_GETWD
1076                 directory = VCWD_GETWD(resolved_path);
1077 #endif
1078                 if (directory) {
1079                         resolved_path_len = strlen(resolved_path);
1080                         if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
1081                                 resolved_path[resolved_path_len] = DEFAULT_SLASH;
1082                                 resolved_path[++resolved_path_len] = '\0';
1083                         }
1084                         uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
1085                 }
1086                 reader = xmlNewTextReader(inputbfr, uri);
1087 
1088                 if (reader != NULL) {
1089 #if LIBXML_VERSION >= 20628
1090                         ret = xmlTextReaderSetup(reader, NULL, uri, encoding, options);
1091 #endif
1092                         if (ret == 0) {
1093                                 if (id == NULL) {
1094                                         object_init_ex(return_value, xmlreader_class_entry);
1095                                         intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
1096                                 } else {
1097                                         RETVAL_TRUE;
1098                                 }
1099                                 intern->input = inputbfr;
1100                                 intern->ptr = reader;
1101 
1102                                 if (uri) {
1103                                         xmlFree(uri);
1104                                 }
1105 
1106                                 return;
1107                         }
1108                 }
1109         }
1110 
1111         if (uri) {
1112                 xmlFree(uri);
1113         }
1114 
1115         if (inputbfr) {
1116                 xmlFreeParserInputBuffer(inputbfr);
1117         }
1118         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load source data");
1119         RETURN_FALSE;
1120 }
1121 /* }}} */
1122 
1123 /* {{{ proto boolean XMLReader::expand()
1124 Moves the position of the current instance to the next node in the stream. */
1125 PHP_METHOD(xmlreader, expand)
1126 {
1127 #ifdef HAVE_DOM
1128         zval *id, *basenode = NULL;
1129         int ret;
1130         xmlreader_object *intern;
1131         xmlNode *node, *nodec;
1132         xmlDocPtr docp = NULL;
1133         php_libxml_node_object *domobj = NULL;
1134 
1135         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!", &id, xmlreader_class_entry, &basenode, dom_node_class_entry) == FAILURE) {
1136                 return;
1137         }
1138 
1139         if (basenode != NULL) {
1140                 NODE_GET_OBJ(node, basenode, xmlNodePtr, domobj);
1141                 docp = node->doc;
1142         }
1143 
1144         intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
1145 
1146         if (intern && intern->ptr) {
1147                 node = xmlTextReaderExpand(intern->ptr);
1148 
1149                 if (node == NULL) {
1150                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occurred while expanding ");
1151                         RETURN_FALSE;
1152                 } else {
1153                         nodec = xmlDocCopyNode(node, docp, 1);
1154                         if (nodec == NULL) {
1155                                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot expand this node type");
1156                                 RETURN_FALSE;
1157                         } else {
1158                                 DOM_RET_OBJ(nodec, &ret, (dom_object *)domobj);
1159                         }
1160                 }
1161         } else {
1162                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to expand");
1163                 RETURN_FALSE;
1164         }
1165 #else
1166         php_error(E_WARNING, "DOM support is not enabled");
1167         return;
1168 #endif
1169 }
1170 /* }}} */
1171 /* {{{ arginfo */
1172 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_close, 0)
1173 ZEND_END_ARG_INFO()
1174 
1175 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttribute, 0)
1176         ZEND_ARG_INFO(0, name)
1177 ZEND_END_ARG_INFO()
1178 
1179 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNo, 0)
1180         ZEND_ARG_INFO(0, index)
1181 ZEND_END_ARG_INFO()
1182 
1183 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNs, 0)
1184         ZEND_ARG_INFO(0, name)
1185         ZEND_ARG_INFO(0, namespaceURI)
1186 ZEND_END_ARG_INFO()
1187 
1188 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getParserProperty, 0)
1189         ZEND_ARG_INFO(0, property)
1190 ZEND_END_ARG_INFO()
1191 
1192 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_isValid, 0)
1193 ZEND_END_ARG_INFO()
1194 
1195 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_lookupNamespace, 0)
1196 ZEND_ARG_INFO(0, prefix)
1197 ZEND_END_ARG_INFO()
1198 
1199 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttribute, 0)
1200         ZEND_ARG_INFO(0, name)
1201 ZEND_END_ARG_INFO()
1202 
1203 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNo, 0)
1204         ZEND_ARG_INFO(0, index)
1205 ZEND_END_ARG_INFO()
1206 
1207 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNs, 0)
1208         ZEND_ARG_INFO(0, name)
1209         ZEND_ARG_INFO(0, namespaceURI)
1210 ZEND_END_ARG_INFO()
1211 
1212 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToElement, 0)
1213 ZEND_END_ARG_INFO()
1214 
1215 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToFirstAttribute, 0)
1216 ZEND_END_ARG_INFO()
1217 
1218 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToNextAttribute, 0)
1219 ZEND_END_ARG_INFO()
1220 
1221 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_read, 0)
1222 ZEND_END_ARG_INFO()
1223 
1224 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_next, 0, 0, 0)
1225         ZEND_ARG_INFO(0, localname)
1226 ZEND_END_ARG_INFO()
1227 
1228 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_open, 0, 0, 1)
1229         ZEND_ARG_INFO(0, URI)
1230         ZEND_ARG_INFO(0, encoding)
1231         ZEND_ARG_INFO(0, options)
1232 ZEND_END_ARG_INFO()
1233 
1234 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readInnerXml, 0)
1235 ZEND_END_ARG_INFO()
1236 
1237 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readOuterXml, 0)
1238 ZEND_END_ARG_INFO()
1239 
1240 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readString, 0)
1241 ZEND_END_ARG_INFO()
1242 
1243 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setSchema, 0)
1244         ZEND_ARG_INFO(0, filename)
1245 ZEND_END_ARG_INFO()
1246 
1247 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setParserProperty, 0)
1248         ZEND_ARG_INFO(0, property)
1249         ZEND_ARG_INFO(0, value)
1250 ZEND_END_ARG_INFO()
1251 
1252 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchema, 0)
1253         ZEND_ARG_INFO(0, filename)
1254 ZEND_END_ARG_INFO()
1255 
1256 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchemaSource, 0)
1257         ZEND_ARG_INFO(0, source)
1258 ZEND_END_ARG_INFO()
1259 
1260 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_XML, 0, 0, 1)
1261         ZEND_ARG_INFO(0, source)
1262         ZEND_ARG_INFO(0, encoding)
1263         ZEND_ARG_INFO(0, options)
1264 ZEND_END_ARG_INFO()
1265 
1266 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_expand, 0)
1267 ZEND_END_ARG_INFO()
1268 /* }}} */
1269 
1270 static const zend_function_entry xmlreader_functions[] = {
1271         PHP_ME(xmlreader, close, arginfo_xmlreader_close, ZEND_ACC_PUBLIC)
1272         PHP_ME(xmlreader, getAttribute, arginfo_xmlreader_getAttribute, ZEND_ACC_PUBLIC)
1273         PHP_ME(xmlreader, getAttributeNo, arginfo_xmlreader_getAttributeNo, ZEND_ACC_PUBLIC)
1274         PHP_ME(xmlreader, getAttributeNs, arginfo_xmlreader_getAttributeNs, ZEND_ACC_PUBLIC)
1275         PHP_ME(xmlreader, getParserProperty, arginfo_xmlreader_getParserProperty, ZEND_ACC_PUBLIC)
1276         PHP_ME(xmlreader, isValid, arginfo_xmlreader_isValid, ZEND_ACC_PUBLIC)
1277         PHP_ME(xmlreader, lookupNamespace, arginfo_xmlreader_lookupNamespace, ZEND_ACC_PUBLIC)
1278         PHP_ME(xmlreader, moveToAttributeNo, arginfo_xmlreader_moveToAttributeNo, ZEND_ACC_PUBLIC)
1279         PHP_ME(xmlreader, moveToAttribute, arginfo_xmlreader_moveToAttribute, ZEND_ACC_PUBLIC)
1280         PHP_ME(xmlreader, moveToAttributeNs, arginfo_xmlreader_moveToAttributeNs, ZEND_ACC_PUBLIC)
1281         PHP_ME(xmlreader, moveToElement, arginfo_xmlreader_moveToElement, ZEND_ACC_PUBLIC)
1282         PHP_ME(xmlreader, moveToFirstAttribute, arginfo_xmlreader_moveToFirstAttribute, ZEND_ACC_PUBLIC)
1283         PHP_ME(xmlreader, moveToNextAttribute, arginfo_xmlreader_moveToNextAttribute, ZEND_ACC_PUBLIC)
1284         PHP_ME(xmlreader, open, arginfo_xmlreader_open, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
1285         PHP_ME(xmlreader, read, arginfo_xmlreader_read, ZEND_ACC_PUBLIC)
1286         PHP_ME(xmlreader, next, arginfo_xmlreader_next, ZEND_ACC_PUBLIC)
1287 #if LIBXML_VERSION >= 20620
1288         PHP_ME(xmlreader, readInnerXml, arginfo_xmlreader_readInnerXml, ZEND_ACC_PUBLIC)
1289         PHP_ME(xmlreader, readOuterXml, arginfo_xmlreader_readOuterXml, ZEND_ACC_PUBLIC)
1290         PHP_ME(xmlreader, readString, arginfo_xmlreader_readString, ZEND_ACC_PUBLIC)
1291         PHP_ME(xmlreader, setSchema, arginfo_xmlreader_setSchema, ZEND_ACC_PUBLIC)
1292 #endif
1293 /* Not Yet Implemented though defined in libxml as of 2.6.9dev
1294         PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC)
1295 */
1296         PHP_ME(xmlreader, setParserProperty, arginfo_xmlreader_setParserProperty, ZEND_ACC_PUBLIC)
1297         PHP_ME(xmlreader, setRelaxNGSchema, arginfo_xmlreader_setRelaxNGSchema, ZEND_ACC_PUBLIC)
1298         PHP_ME(xmlreader, setRelaxNGSchemaSource, arginfo_xmlreader_setRelaxNGSchemaSource, ZEND_ACC_PUBLIC)
1299         PHP_ME(xmlreader, XML, arginfo_xmlreader_XML, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
1300         PHP_ME(xmlreader, expand, arginfo_xmlreader_expand, ZEND_ACC_PUBLIC)
1301         PHP_FE_END
1302 };
1303 
1304 /* {{{ PHP_MINIT_FUNCTION
1305  */
1306 PHP_MINIT_FUNCTION(xmlreader)
1307 {
1308 
1309         zend_class_entry ce;
1310 
1311         memcpy(&xmlreader_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1312         xmlreader_object_handlers.read_property = xmlreader_read_property;
1313         xmlreader_object_handlers.write_property = xmlreader_write_property;
1314         xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
1315         xmlreader_object_handlers.clone_obj = NULL;
1316 
1317         INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions);
1318         ce.create_object = xmlreader_objects_new;
1319         xmlreader_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
1320 
1321         zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1);
1322         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC);
1323         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING TSRMLS_CC);
1324         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC);
1325         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC);
1326         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC);
1327         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC);
1328         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC);
1329         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderConstLocalName, IS_STRING TSRMLS_CC);
1330         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderConstName, IS_STRING TSRMLS_CC);
1331         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING TSRMLS_CC);
1332         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC);
1333         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderConstPrefix, IS_STRING TSRMLS_CC);
1334         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderConstValue, IS_STRING TSRMLS_CC);
1335         xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderConstXmlLang, IS_STRING TSRMLS_CC);
1336 
1337         /* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */
1338 
1339         REGISTER_XMLREADER_CLASS_CONST_LONG("NONE",     XML_READER_TYPE_NONE);
1340         REGISTER_XMLREADER_CLASS_CONST_LONG("ELEMENT",  XML_READER_TYPE_ELEMENT);
1341         REGISTER_XMLREADER_CLASS_CONST_LONG("ATTRIBUTE",        XML_READER_TYPE_ATTRIBUTE);
1342         REGISTER_XMLREADER_CLASS_CONST_LONG("TEXT",     XML_READER_TYPE_TEXT);
1343         REGISTER_XMLREADER_CLASS_CONST_LONG("CDATA",    XML_READER_TYPE_CDATA);
1344         REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY_REF",       XML_READER_TYPE_ENTITY_REFERENCE);
1345         REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY",   XML_READER_TYPE_ENTITY);
1346         REGISTER_XMLREADER_CLASS_CONST_LONG("PI",       XML_READER_TYPE_PROCESSING_INSTRUCTION);
1347         REGISTER_XMLREADER_CLASS_CONST_LONG("COMMENT",  XML_READER_TYPE_COMMENT);
1348         REGISTER_XMLREADER_CLASS_CONST_LONG("DOC",      XML_READER_TYPE_DOCUMENT);
1349         REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_TYPE", XML_READER_TYPE_DOCUMENT_TYPE);
1350         REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_FRAGMENT",     XML_READER_TYPE_DOCUMENT_FRAGMENT);
1351         REGISTER_XMLREADER_CLASS_CONST_LONG("NOTATION", XML_READER_TYPE_NOTATION);
1352         REGISTER_XMLREADER_CLASS_CONST_LONG("WHITESPACE",       XML_READER_TYPE_WHITESPACE);
1353         REGISTER_XMLREADER_CLASS_CONST_LONG("SIGNIFICANT_WHITESPACE",   XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
1354         REGISTER_XMLREADER_CLASS_CONST_LONG("END_ELEMENT",      XML_READER_TYPE_END_ELEMENT);
1355         REGISTER_XMLREADER_CLASS_CONST_LONG("END_ENTITY",       XML_READER_TYPE_END_ENTITY);
1356         REGISTER_XMLREADER_CLASS_CONST_LONG("XML_DECLARATION",  XML_READER_TYPE_XML_DECLARATION);
1357 
1358         /* Constants for Parser options */
1359         REGISTER_XMLREADER_CLASS_CONST_LONG("LOADDTD",  XML_PARSER_LOADDTD);
1360         REGISTER_XMLREADER_CLASS_CONST_LONG("DEFAULTATTRS",     XML_PARSER_DEFAULTATTRS);
1361         REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDATE", XML_PARSER_VALIDATE);
1362         REGISTER_XMLREADER_CLASS_CONST_LONG("SUBST_ENTITIES",   XML_PARSER_SUBST_ENTITIES);
1363 
1364         /* Constants for Errors when loading - not yet used until we implement custom error handling
1365         REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_WARNING",         XML_PARSER_SEVERITY_VALIDITY_WARNING,   CONST_CS | CONST_PERSISTENT);
1366         REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_ERROR",           XML_PARSER_SEVERITY_VALIDITY_ERROR,             CONST_CS | CONST_PERSISTENT);
1367         REGISTER_XMLREADER_CLASS_CONST_LONG("WARNING",                          XML_PARSER_SEVERITY_WARNING,                    CONST_CS | CONST_PERSISTENT);
1368         REGISTER_XMLREADER_CLASS_CONST_LONG("ERROR",                            XML_PARSER_SEVERITY_ERROR,                              CONST_CS | CONST_PERSISTENT);
1369         */
1370 
1371         return SUCCESS;
1372 }
1373 /* }}} */
1374 
1375 /* {{{ PHP_MSHUTDOWN_FUNCTION
1376  */
1377 PHP_MSHUTDOWN_FUNCTION(xmlreader)
1378 {
1379         zend_hash_destroy(&xmlreader_prop_handlers);
1380         return SUCCESS;
1381 }
1382 /* }}} */
1383 
1384 /* {{{ PHP_MINFO_FUNCTION
1385  */
1386 PHP_MINFO_FUNCTION(xmlreader)
1387 {
1388         php_info_print_table_start();
1389         {
1390                 php_info_print_table_row(2, "XMLReader", "enabled");
1391         }
1392         php_info_print_table_end();
1393 }
1394 /* }}} */
1395 
1396 /*
1397  * Local variables:
1398  * tab-width: 4
1399  * c-basic-offset: 4
1400  * End:
1401  * vim600: noet sw=4 ts=4 fdm=marker
1402  * vim<600: noet sw=4 ts=4
1403  */

/* [<][>][^][v][top][bottom][index][help] */