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