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