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