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