1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 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/uri.h>
34
35 zend_class_entry *xmlreader_class_entry;
36
37 static zend_object_handlers xmlreader_object_handlers;
38
39 static HashTable xmlreader_prop_handlers;
40
41 typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
42 typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
43 typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr reader);
44 typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval TSRMLS_DC);
45
46 typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, const unsigned char *);
47
48 typedef struct _xmlreader_prop_handler {
49 xmlreader_read_int_t read_int_func;
50 xmlreader_read_const_char_t read_char_func;
51 xmlreader_write_t write_func;
52 int type;
53 } xmlreader_prop_handler;
54
55 #define XMLREADER_LOAD_STRING 0
56 #define XMLREADER_LOAD_FILE 1
57
58 /* {{{ xmlreader_register_prop_handler */
xmlreader_register_prop_handler(HashTable * prop_handler,char * name,xmlreader_read_int_t read_int_func,xmlreader_read_const_char_t read_char_func,int rettype TSRMLS_DC)59 static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name, xmlreader_read_int_t read_int_func, xmlreader_read_const_char_t read_char_func, int rettype TSRMLS_DC)
60 {
61 xmlreader_prop_handler hnd;
62
63 hnd.read_char_func = read_char_func;
64 hnd.read_int_func = read_int_func;
65 hnd.type = rettype;
66 zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(xmlreader_prop_handler), NULL);
67 }
68 /* }}} */
69
70 /* {{{ xmlreader_property_reader */
xmlreader_property_reader(xmlreader_object * obj,xmlreader_prop_handler * hnd,zval ** retval TSRMLS_DC)71 static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC)
72 {
73 const xmlChar *retchar = NULL;
74 int retint = 0;
75
76 if (obj->ptr != NULL) {
77 if (hnd->read_char_func) {
78 retchar = hnd->read_char_func(obj->ptr);
79 } else {
80 if (hnd->read_int_func) {
81 retint = hnd->read_int_func(obj->ptr);
82 if (retint == -1) {
83 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal libxml error returned");
84 return FAILURE;
85 }
86 }
87 }
88 }
89
90 ALLOC_ZVAL(*retval);
91
92 switch (hnd->type) {
93 case IS_STRING:
94 if (retchar) {
95 ZVAL_STRING(*retval, (char *) retchar, 1);
96 } else {
97 ZVAL_EMPTY_STRING(*retval);
98 }
99 break;
100 case IS_BOOL:
101 ZVAL_BOOL(*retval, retint);
102 break;
103 case IS_LONG:
104 ZVAL_LONG(*retval, retint);
105 break;
106 default:
107 ZVAL_NULL(*retval);
108 }
109
110 return SUCCESS;
111 }
112 /* }}} */
113
114 /* {{{ xmlreader_get_property_ptr_ptr */
xmlreader_get_property_ptr_ptr(zval * object,zval * member TSRMLS_DC)115 zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC)
116 {
117 xmlreader_object *obj;
118 zval tmp_member;
119 zval **retval = NULL;
120 xmlreader_prop_handler *hnd;
121 zend_object_handlers *std_hnd;
122 int ret = FAILURE;
123
124 if (member->type != 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 = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
132
133 if (obj->prop_handler != NULL) {
134 ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
135 }
136 if (ret == FAILURE) {
137 std_hnd = zend_get_std_object_handlers();
138 retval = std_hnd->get_property_ptr_ptr(object, member TSRMLS_CC);
139 }
140
141 if (member == &tmp_member) {
142 zval_dtor(member);
143 }
144 return retval;
145 }
146 /* }}} */
147
148 /* {{{ xmlreader_read_property */
xmlreader_read_property(zval * object,zval * member,int type TSRMLS_DC)149 zval *xmlreader_read_property(zval *object, zval *member, int type TSRMLS_DC)
150 {
151 xmlreader_object *obj;
152 zval tmp_member;
153 zval *retval;
154 xmlreader_prop_handler *hnd;
155 zend_object_handlers *std_hnd;
156 int ret;
157
158 if (member->type != IS_STRING) {
159 tmp_member = *member;
160 zval_copy_ctor(&tmp_member);
161 convert_to_string(&tmp_member);
162 member = &tmp_member;
163 }
164
165 ret = FAILURE;
166 obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
167
168 if (obj->prop_handler != NULL) {
169 ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
170 }
171 if (ret == SUCCESS) {
172 ret = xmlreader_property_reader(obj, hnd, &retval TSRMLS_CC);
173 if (ret == SUCCESS) {
174 /* ensure we're creating a temporary variable */
175 Z_SET_REFCOUNT_P(retval, 0);
176 } else {
177 retval = EG(uninitialized_zval_ptr);
178 }
179 } else {
180 std_hnd = zend_get_std_object_handlers();
181 retval = std_hnd->read_property(object, member, type TSRMLS_CC);
182 }
183
184 if (member == &tmp_member) {
185 zval_dtor(member);
186 }
187 return retval;
188 }
189 /* }}} */
190
191 /* {{{ xmlreader_write_property */
xmlreader_write_property(zval * object,zval * member,zval * value TSRMLS_DC)192 void xmlreader_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
193 {
194 xmlreader_object *obj;
195 zval tmp_member;
196 xmlreader_prop_handler *hnd;
197 zend_object_handlers *std_hnd;
198 int ret;
199
200 if (member->type != IS_STRING) {
201 tmp_member = *member;
202 zval_copy_ctor(&tmp_member);
203 convert_to_string(&tmp_member);
204 member = &tmp_member;
205 }
206
207 ret = FAILURE;
208 obj = (xmlreader_object *)zend_objects_get_address(object TSRMLS_CC);
209
210 if (obj->prop_handler != NULL) {
211 ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
212 }
213 if (ret == SUCCESS) {
214 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write to read-only property");
215 } else {
216 std_hnd = zend_get_std_object_handlers();
217 std_hnd->write_property(object, member, value TSRMLS_CC);
218 }
219
220 if (member == &tmp_member) {
221 zval_dtor(member);
222 }
223 }
224 /* }}} */
225
226 /* {{{ _xmlreader_get_valid_file_path */
227 /* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a
228 common function in libxml extension as code is common to a few xml extensions */
_xmlreader_get_valid_file_path(char * source,char * resolved_path,int resolved_path_len TSRMLS_DC)229 char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len TSRMLS_DC) {
230 xmlURI *uri;
231 xmlChar *escsource;
232 char *file_dest;
233 int isFileUri = 0;
234
235 uri = xmlCreateURI();
236 escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *)":");
237 xmlParseURIReference(uri, (const char *)escsource);
238 xmlFree(escsource);
239
240 if (uri->scheme != NULL) {
241 /* absolute file uris - libxml only supports localhost or empty host */
242 if (strncasecmp(source, "file:///",8) == 0) {
243 isFileUri = 1;
244 #ifdef PHP_WIN32
245 source += 8;
246 #else
247 source += 7;
248 #endif
249 } else if (strncasecmp(source, "file://localhost/",17) == 0) {
250 isFileUri = 1;
251 #ifdef PHP_WIN32
252 source += 17;
253 #else
254 source += 16;
255 #endif
256 }
257 }
258
259 file_dest = source;
260
261 if ((uri->scheme == NULL || isFileUri)) {
262 if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
263 xmlFreeURI(uri);
264 return NULL;
265 }
266 file_dest = resolved_path;
267 }
268
269 xmlFreeURI(uri);
270
271 return file_dest;
272 }
273 /* }}} */
274
275 #ifdef LIBXML_SCHEMAS_ENABLED
276 /* {{{ _xmlreader_get_relaxNG */
_xmlreader_get_relaxNG(char * source,int source_len,int type,xmlRelaxNGValidityErrorFunc error_func,xmlRelaxNGValidityWarningFunc warn_func TSRMLS_DC)277 static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, int source_len, int type,
278 xmlRelaxNGValidityErrorFunc error_func,
279 xmlRelaxNGValidityWarningFunc warn_func TSRMLS_DC)
280 {
281 char *valid_file = NULL;
282 xmlRelaxNGParserCtxtPtr parser = NULL;
283 xmlRelaxNGPtr sptr;
284 char resolved_path[MAXPATHLEN + 1];
285
286 switch (type) {
287 case XMLREADER_LOAD_FILE:
288 valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
289 if (!valid_file) {
290 return NULL;
291 }
292 parser = xmlRelaxNGNewParserCtxt(valid_file);
293 break;
294 case XMLREADER_LOAD_STRING:
295 parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
296 /* If loading from memory, we need to set the base directory for the document
297 but it is not apparent how to do that for schema's */
298 break;
299 default:
300 return NULL;
301 }
302
303 if (parser == NULL) {
304 return NULL;
305 }
306
307 if (error_func || warn_func) {
308 xmlRelaxNGSetParserErrors(parser,
309 (xmlRelaxNGValidityErrorFunc) error_func,
310 (xmlRelaxNGValidityWarningFunc) warn_func,
311 parser);
312 }
313 sptr = xmlRelaxNGParse(parser);
314 xmlRelaxNGFreeParserCtxt(parser);
315
316 return sptr;
317 }
318 /* }}} */
319 #endif
320
321 static const zend_module_dep xmlreader_deps[] = {
322 ZEND_MOD_REQUIRED("libxml")
323 ZEND_MOD_END
324 };
325
326 /* {{{ xmlreader_module_entry
327 */
328 zend_module_entry xmlreader_module_entry = {
329 STANDARD_MODULE_HEADER_EX, NULL,
330 xmlreader_deps,
331 "xmlreader",
332 NULL,
333 PHP_MINIT(xmlreader),
334 PHP_MSHUTDOWN(xmlreader),
335 NULL,
336 NULL,
337 PHP_MINFO(xmlreader),
338 "0.1", /* Replace with version number for your extension */
339 STANDARD_MODULE_PROPERTIES
340 };
341 /* }}} */
342
343 #ifdef COMPILE_DL_XMLREADER
ZEND_GET_MODULE(xmlreader)344 ZEND_GET_MODULE(xmlreader)
345 #endif
346
347 /* {{{ xmlreader_objects_clone */
348 void xmlreader_objects_clone(void *object, void **object_clone TSRMLS_DC)
349 {
350 /* TODO */
351 }
352 /* }}} */
353
354 /* {{{ xmlreader_free_resources */
xmlreader_free_resources(xmlreader_object * intern)355 static void xmlreader_free_resources(xmlreader_object *intern) {
356 if (intern) {
357 if (intern->input) {
358 xmlFreeParserInputBuffer(intern->input);
359 intern->input = NULL;
360 }
361
362 if (intern->ptr) {
363 xmlFreeTextReader(intern->ptr);
364 intern->ptr = NULL;
365 }
366 #ifdef LIBXML_SCHEMAS_ENABLED
367 if (intern->schema) {
368 xmlRelaxNGFree((xmlRelaxNGPtr) intern->schema);
369 intern->schema = NULL;
370 }
371 #endif
372 }
373 }
374 /* }}} */
375
376 /* {{{ xmlreader_objects_free_storage */
xmlreader_objects_free_storage(void * object TSRMLS_DC)377 void xmlreader_objects_free_storage(void *object TSRMLS_DC)
378 {
379 xmlreader_object *intern = (xmlreader_object *)object;
380
381 zend_object_std_dtor(&intern->std TSRMLS_CC);
382
383 xmlreader_free_resources(intern);
384
385 efree(object);
386 }
387 /* }}} */
388
389 /* {{{ xmlreader_objects_new */
xmlreader_objects_new(zend_class_entry * class_type TSRMLS_DC)390 zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC)
391 {
392 zend_object_value retval;
393 xmlreader_object *intern;
394 zval *tmp;
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 zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_property_ctor, (void *) &tmp, sizeof(zval *));
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, "s!", &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 spcecified 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 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while reading");
809 RETURN_FALSE;
810 } else {
811 RETURN_BOOL(retval);
812 }
813 }
814
815 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
816 RETURN_FALSE;
817 }
818 /* }}} */
819
820 /* {{{ proto boolean XMLReader::next([string localname])
821 Moves the position of the current instance to the next node in the stream. */
PHP_METHOD(xmlreader,next)822 PHP_METHOD(xmlreader, next)
823 {
824 zval *id;
825 int retval, name_len=0;
826 xmlreader_object *intern;
827 char *name = NULL;
828
829 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
830 return;
831 }
832
833 id = getThis();
834 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
835 if (intern != NULL && intern->ptr != NULL) {
836 #if LIBXML_VERSION <= 20617
837 /* Bug in libxml prevents a next in certain cases when positioned on end of element */
838 if (xmlTextReaderNodeType(intern->ptr) == XML_READER_TYPE_END_ELEMENT) {
839 retval = xmlTextReaderRead(intern->ptr);
840 } else
841 #endif
842 retval = xmlTextReaderNext(intern->ptr);
843 while (name != NULL && retval == 1) {
844 if (xmlStrEqual(xmlTextReaderConstLocalName(intern->ptr), (xmlChar *)name)) {
845 RETURN_TRUE;
846 }
847 retval = xmlTextReaderNext(intern->ptr);
848 }
849 if (retval == -1) {
850 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while reading");
851 RETURN_FALSE;
852 } else {
853 RETURN_BOOL(retval);
854 }
855 }
856
857 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
858 RETURN_FALSE;
859 }
860 /* }}} */
861
862 /* {{{ proto boolean XMLReader::open(string URI [, string encoding [, int options]])
863 Sets the URI that the XMLReader will parse. */
PHP_METHOD(xmlreader,open)864 PHP_METHOD(xmlreader, open)
865 {
866 zval *id;
867 int source_len = 0, encoding_len = 0;
868 long options = 0;
869 xmlreader_object *intern = NULL;
870 char *source, *valid_file = NULL;
871 char *encoding = NULL;
872 char resolved_path[MAXPATHLEN + 1];
873 xmlTextReaderPtr reader = NULL;
874
875 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
876 return;
877 }
878
879 id = getThis();
880 if (id != NULL) {
881 if (! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
882 id = NULL;
883 } else {
884 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
885 xmlreader_free_resources(intern);
886 }
887 }
888
889 if (!source_len) {
890 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
891 RETURN_FALSE;
892 }
893
894 valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
895
896 if (valid_file) {
897 reader = xmlReaderForFile(valid_file, encoding, options);
898 }
899
900 if (reader == NULL) {
901 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open source data");
902 RETURN_FALSE;
903 }
904
905 if (id == NULL) {
906 object_init_ex(return_value, xmlreader_class_entry);
907 intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
908 intern->ptr = reader;
909 return;
910 }
911
912 intern->ptr = reader;
913
914 RETURN_TRUE;
915
916 }
917 /* }}} */
918
919 /* Not Yet Implemented in libxml - functions exist just not coded
920 PHP_METHOD(xmlreader, resetState)
921 {
922
923 }
924 */
925
926 #if LIBXML_VERSION >= 20620
927 /* {{{ proto string XMLReader::readInnerXml()
928 Reads the contents of the current node, including child nodes and markup. */
PHP_METHOD(xmlreader,readInnerXml)929 PHP_METHOD(xmlreader, readInnerXml)
930 {
931 php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
932 }
933 /* }}} */
934
935 /* {{{ proto boolean XMLReader::readOuterXml()
936 Reads the contents of the current node, including child nodes and markup. */
PHP_METHOD(xmlreader,readOuterXml)937 PHP_METHOD(xmlreader, readOuterXml)
938 {
939 php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadOuterXml);
940 }
941 /* }}} */
942
943 /* {{{ proto boolean XMLReader::readString()
944 Reads the contents of an element or a text node as a string. */
PHP_METHOD(xmlreader,readString)945 PHP_METHOD(xmlreader, readString)
946 {
947 php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
948 }
949 /* }}} */
950
951 /* {{{ proto boolean XMLReader::setSchema(string filename)
952 Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
PHP_METHOD(xmlreader,setSchema)953 PHP_METHOD(xmlreader, setSchema)
954 {
955 #ifdef LIBXML_SCHEMAS_ENABLED
956 zval *id;
957 int source_len = 0, retval = -1;
958 xmlreader_object *intern;
959 char *source;
960
961 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &source, &source_len) == FAILURE) {
962 return;
963 }
964
965 if (source != NULL && !source_len) {
966 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source is required");
967 RETURN_FALSE;
968 }
969
970 id = getThis();
971
972 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
973 if (intern && intern->ptr) {
974 retval = xmlTextReaderSchemaValidate(intern->ptr, source);
975
976 if (retval == 0) {
977 RETURN_TRUE;
978 }
979 }
980
981 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
982
983 RETURN_FALSE;
984 #else
985 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built into libxml.");
986
987 RETURN_FALSE;
988 #endif
989 }
990 /* }}} */
991 #endif
992
993 /* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value)
994 Sets parser property (one of the parser option constants).
995 Properties must be set after open() or XML() and before the first read() is called */
PHP_METHOD(xmlreader,setParserProperty)996 PHP_METHOD(xmlreader, setParserProperty)
997 {
998 zval *id;
999 long property;
1000 int retval = -1;
1001 zend_bool value;
1002 xmlreader_object *intern;
1003
1004 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lb", &property, &value) == FAILURE) {
1005 return;
1006 }
1007
1008 id = getThis();
1009
1010 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
1011 if (intern && intern->ptr) {
1012 retval = xmlTextReaderSetParserProp(intern->ptr,property, value);
1013 }
1014 if (retval == -1) {
1015 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parser property");
1016 RETURN_FALSE;
1017 }
1018
1019 RETURN_TRUE;
1020 }
1021 /* }}} */
1022
1023 /* {{{ proto boolean XMLReader::setRelaxNGSchema(string filename)
1024 Sets the string that the XMLReader will parse. */
PHP_METHOD(xmlreader,setRelaxNGSchema)1025 PHP_METHOD(xmlreader, setRelaxNGSchema)
1026 {
1027 php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_FILE);
1028 }
1029 /* }}} */
1030
1031 /* {{{ proto boolean XMLReader::setRelaxNGSchemaSource(string source)
1032 Sets the string that the XMLReader will parse. */
PHP_METHOD(xmlreader,setRelaxNGSchemaSource)1033 PHP_METHOD(xmlreader, setRelaxNGSchemaSource)
1034 {
1035 php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAM_PASSTHRU, XMLREADER_LOAD_STRING);
1036 }
1037 /* }}} */
1038
1039 /* TODO
1040 XMLPUBFUN int XMLCALL
1041 xmlTextReaderSetSchema (xmlTextReaderPtr reader,
1042 xmlSchemaPtr schema);
1043 */
1044
1045 /* {{{ proto boolean XMLReader::XML(string source [, string encoding [, int options]])
1046 Sets the string that the XMLReader will parse. */
PHP_METHOD(xmlreader,XML)1047 PHP_METHOD(xmlreader, XML)
1048 {
1049 zval *id;
1050 int source_len = 0, encoding_len = 0;
1051 long options = 0;
1052 xmlreader_object *intern = NULL;
1053 char *source, *uri = NULL, *encoding = NULL;
1054 int resolved_path_len, ret = 0;
1055 char *directory=NULL, resolved_path[MAXPATHLEN];
1056 xmlParserInputBufferPtr inputbfr;
1057 xmlTextReaderPtr reader;
1058
1059 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
1060 return;
1061 }
1062
1063 id = getThis();
1064 if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), xmlreader_class_entry TSRMLS_CC)) {
1065 id = NULL;
1066 }
1067 if (id != NULL) {
1068 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
1069 xmlreader_free_resources(intern);
1070 }
1071
1072 if (!source_len) {
1073 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
1074 RETURN_FALSE;
1075 }
1076
1077 inputbfr = xmlParserInputBufferCreateMem(source, source_len, XML_CHAR_ENCODING_NONE);
1078
1079 if (inputbfr != NULL) {
1080 /* Get the URI of the current script so that we can set the base directory in libxml */
1081 #if HAVE_GETCWD
1082 directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
1083 #elif HAVE_GETWD
1084 directory = VCWD_GETWD(resolved_path);
1085 #endif
1086 if (directory) {
1087 resolved_path_len = strlen(resolved_path);
1088 if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
1089 resolved_path[resolved_path_len] = DEFAULT_SLASH;
1090 resolved_path[++resolved_path_len] = '\0';
1091 }
1092 uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
1093 }
1094 reader = xmlNewTextReader(inputbfr, uri);
1095
1096 if (reader != NULL) {
1097 #if LIBXML_VERSION >= 20628
1098 ret = xmlTextReaderSetup(reader, NULL, uri, encoding, options);
1099 #endif
1100 if (ret == 0) {
1101 if (id == NULL) {
1102 object_init_ex(return_value, xmlreader_class_entry);
1103 intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
1104 } else {
1105 RETVAL_TRUE;
1106 }
1107 intern->input = inputbfr;
1108 intern->ptr = reader;
1109
1110 if (uri) {
1111 xmlFree(uri);
1112 }
1113
1114 return;
1115 }
1116 }
1117 }
1118
1119 if (uri) {
1120 xmlFree(uri);
1121 }
1122
1123 if (inputbfr) {
1124 xmlFreeParserInputBuffer(inputbfr);
1125 }
1126 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load source data");
1127 RETURN_FALSE;
1128 }
1129 /* }}} */
1130
1131 /* {{{ proto boolean XMLReader::expand()
1132 Moves the position of the current instance to the next node in the stream. */
PHP_METHOD(xmlreader,expand)1133 PHP_METHOD(xmlreader, expand)
1134 {
1135 #ifdef HAVE_DOM
1136 zval *id, *rv = NULL, *basenode = NULL;
1137 int ret;
1138 xmlreader_object *intern;
1139 xmlNode *node, *nodec;
1140 xmlDocPtr docp = NULL;
1141 php_libxml_node_object *domobj = NULL;
1142
1143 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!", &id, xmlreader_class_entry, &basenode, dom_node_class_entry) == FAILURE) {
1144 return;
1145 }
1146
1147 if (basenode != NULL) {
1148 NODE_GET_OBJ(node, basenode, xmlNodePtr, domobj);
1149 docp = node->doc;
1150 }
1151
1152 intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
1153
1154 if (intern && intern->ptr) {
1155 node = xmlTextReaderExpand(intern->ptr);
1156
1157 if (node == NULL) {
1158 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occured while expanding ");
1159 RETURN_FALSE;
1160 } else {
1161 nodec = xmlDocCopyNode(node, docp, 1);
1162 if (nodec == NULL) {
1163 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot expand this node type");
1164 RETURN_FALSE;
1165 } else {
1166 DOM_RET_OBJ(rv, nodec, &ret, (dom_object *)domobj);
1167 }
1168 }
1169 } else {
1170 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to expand");
1171 RETURN_FALSE;
1172 }
1173 #else
1174 php_error(E_WARNING, "DOM support is not enabled");
1175 return;
1176 #endif
1177 }
1178 /* }}} */
1179 /* {{{ arginfo */
1180 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_close, 0)
1181 ZEND_END_ARG_INFO()
1182
1183 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttribute, 0)
1184 ZEND_ARG_INFO(0, name)
1185 ZEND_END_ARG_INFO()
1186
1187 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNo, 0)
1188 ZEND_ARG_INFO(0, index)
1189 ZEND_END_ARG_INFO()
1190
1191 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getAttributeNs, 0)
1192 ZEND_ARG_INFO(0, name)
1193 ZEND_ARG_INFO(0, namespaceURI)
1194 ZEND_END_ARG_INFO()
1195
1196 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_getParserProperty, 0)
1197 ZEND_ARG_INFO(0, property)
1198 ZEND_END_ARG_INFO()
1199
1200 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_isValid, 0)
1201 ZEND_END_ARG_INFO()
1202
1203 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_lookupNamespace, 0)
1204 ZEND_ARG_INFO(0, prefix)
1205 ZEND_END_ARG_INFO()
1206
1207 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttribute, 0)
1208 ZEND_ARG_INFO(0, name)
1209 ZEND_END_ARG_INFO()
1210
1211 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNo, 0)
1212 ZEND_ARG_INFO(0, index)
1213 ZEND_END_ARG_INFO()
1214
1215 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToAttributeNs, 0)
1216 ZEND_ARG_INFO(0, name)
1217 ZEND_ARG_INFO(0, namespaceURI)
1218 ZEND_END_ARG_INFO()
1219
1220 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToElement, 0)
1221 ZEND_END_ARG_INFO()
1222
1223 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToFirstAttribute, 0)
1224 ZEND_END_ARG_INFO()
1225
1226 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_moveToNextAttribute, 0)
1227 ZEND_END_ARG_INFO()
1228
1229 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_read, 0)
1230 ZEND_END_ARG_INFO()
1231
1232 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_next, 0, 0, 0)
1233 ZEND_ARG_INFO(0, localname)
1234 ZEND_END_ARG_INFO()
1235
1236 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_open, 0, 0, 1)
1237 ZEND_ARG_INFO(0, URI)
1238 ZEND_ARG_INFO(0, encoding)
1239 ZEND_ARG_INFO(0, options)
1240 ZEND_END_ARG_INFO()
1241
1242 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readInnerXml, 0)
1243 ZEND_END_ARG_INFO()
1244
1245 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readOuterXml, 0)
1246 ZEND_END_ARG_INFO()
1247
1248 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_readString, 0)
1249 ZEND_END_ARG_INFO()
1250
1251 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setSchema, 0)
1252 ZEND_ARG_INFO(0, filename)
1253 ZEND_END_ARG_INFO()
1254
1255 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setParserProperty, 0)
1256 ZEND_ARG_INFO(0, property)
1257 ZEND_ARG_INFO(0, value)
1258 ZEND_END_ARG_INFO()
1259
1260 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchema, 0)
1261 ZEND_ARG_INFO(0, filename)
1262 ZEND_END_ARG_INFO()
1263
1264 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_setRelaxNGSchemaSource, 0)
1265 ZEND_ARG_INFO(0, source)
1266 ZEND_END_ARG_INFO()
1267
1268 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlreader_XML, 0, 0, 1)
1269 ZEND_ARG_INFO(0, source)
1270 ZEND_ARG_INFO(0, encoding)
1271 ZEND_ARG_INFO(0, options)
1272 ZEND_END_ARG_INFO()
1273
1274 ZEND_BEGIN_ARG_INFO(arginfo_xmlreader_expand, 0)
1275 ZEND_END_ARG_INFO()
1276 /* }}} */
1277
1278 static const zend_function_entry xmlreader_functions[] = {
1279 PHP_ME(xmlreader, close, arginfo_xmlreader_close, ZEND_ACC_PUBLIC)
1280 PHP_ME(xmlreader, getAttribute, arginfo_xmlreader_getAttribute, ZEND_ACC_PUBLIC)
1281 PHP_ME(xmlreader, getAttributeNo, arginfo_xmlreader_getAttributeNo, ZEND_ACC_PUBLIC)
1282 PHP_ME(xmlreader, getAttributeNs, arginfo_xmlreader_getAttributeNs, ZEND_ACC_PUBLIC)
1283 PHP_ME(xmlreader, getParserProperty, arginfo_xmlreader_getParserProperty, ZEND_ACC_PUBLIC)
1284 PHP_ME(xmlreader, isValid, arginfo_xmlreader_isValid, ZEND_ACC_PUBLIC)
1285 PHP_ME(xmlreader, lookupNamespace, arginfo_xmlreader_lookupNamespace, ZEND_ACC_PUBLIC)
1286 PHP_ME(xmlreader, moveToAttributeNo, arginfo_xmlreader_moveToAttributeNo, ZEND_ACC_PUBLIC)
1287 PHP_ME(xmlreader, moveToAttribute, arginfo_xmlreader_moveToAttribute, ZEND_ACC_PUBLIC)
1288 PHP_ME(xmlreader, moveToAttributeNs, arginfo_xmlreader_moveToAttributeNs, ZEND_ACC_PUBLIC)
1289 PHP_ME(xmlreader, moveToElement, arginfo_xmlreader_moveToElement, ZEND_ACC_PUBLIC)
1290 PHP_ME(xmlreader, moveToFirstAttribute, arginfo_xmlreader_moveToFirstAttribute, ZEND_ACC_PUBLIC)
1291 PHP_ME(xmlreader, moveToNextAttribute, arginfo_xmlreader_moveToNextAttribute, ZEND_ACC_PUBLIC)
1292 PHP_ME(xmlreader, open, arginfo_xmlreader_open, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
1293 PHP_ME(xmlreader, read, arginfo_xmlreader_read, ZEND_ACC_PUBLIC)
1294 PHP_ME(xmlreader, next, arginfo_xmlreader_next, ZEND_ACC_PUBLIC)
1295 #if LIBXML_VERSION >= 20620
1296 PHP_ME(xmlreader, readInnerXml, arginfo_xmlreader_readInnerXml, ZEND_ACC_PUBLIC)
1297 PHP_ME(xmlreader, readOuterXml, arginfo_xmlreader_readOuterXml, ZEND_ACC_PUBLIC)
1298 PHP_ME(xmlreader, readString, arginfo_xmlreader_readString, ZEND_ACC_PUBLIC)
1299 PHP_ME(xmlreader, setSchema, arginfo_xmlreader_setSchema, ZEND_ACC_PUBLIC)
1300 #endif
1301 /* Not Yet Implemented though defined in libxml as of 2.6.9dev
1302 PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC)
1303 */
1304 PHP_ME(xmlreader, setParserProperty, arginfo_xmlreader_setParserProperty, ZEND_ACC_PUBLIC)
1305 PHP_ME(xmlreader, setRelaxNGSchema, arginfo_xmlreader_setRelaxNGSchema, ZEND_ACC_PUBLIC)
1306 PHP_ME(xmlreader, setRelaxNGSchemaSource, arginfo_xmlreader_setRelaxNGSchemaSource, ZEND_ACC_PUBLIC)
1307 PHP_ME(xmlreader, XML, arginfo_xmlreader_XML, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
1308 PHP_ME(xmlreader, expand, arginfo_xmlreader_expand, ZEND_ACC_PUBLIC)
1309 PHP_FE_END
1310 };
1311
1312 /* {{{ PHP_MINIT_FUNCTION
1313 */
PHP_MINIT_FUNCTION(xmlreader)1314 PHP_MINIT_FUNCTION(xmlreader)
1315 {
1316
1317 zend_class_entry ce;
1318
1319 memcpy(&xmlreader_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1320 xmlreader_object_handlers.read_property = xmlreader_read_property;
1321 xmlreader_object_handlers.write_property = xmlreader_write_property;
1322 xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr;
1323
1324 INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions);
1325 ce.create_object = xmlreader_objects_new;
1326 xmlreader_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
1327
1328 zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1);
1329 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC);
1330 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING TSRMLS_CC);
1331 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC);
1332 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC);
1333 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC);
1334 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC);
1335 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC);
1336 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderConstLocalName, IS_STRING TSRMLS_CC);
1337 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderConstName, IS_STRING TSRMLS_CC);
1338 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING TSRMLS_CC);
1339 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC);
1340 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderConstPrefix, IS_STRING TSRMLS_CC);
1341 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderConstValue, IS_STRING TSRMLS_CC);
1342 xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderConstXmlLang, IS_STRING TSRMLS_CC);
1343
1344 /* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */
1345
1346 REGISTER_XMLREADER_CLASS_CONST_LONG("NONE", XML_READER_TYPE_NONE);
1347 REGISTER_XMLREADER_CLASS_CONST_LONG("ELEMENT", XML_READER_TYPE_ELEMENT);
1348 REGISTER_XMLREADER_CLASS_CONST_LONG("ATTRIBUTE", XML_READER_TYPE_ATTRIBUTE);
1349 REGISTER_XMLREADER_CLASS_CONST_LONG("TEXT", XML_READER_TYPE_TEXT);
1350 REGISTER_XMLREADER_CLASS_CONST_LONG("CDATA", XML_READER_TYPE_CDATA);
1351 REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY_REF", XML_READER_TYPE_ENTITY_REFERENCE);
1352 REGISTER_XMLREADER_CLASS_CONST_LONG("ENTITY", XML_READER_TYPE_ENTITY);
1353 REGISTER_XMLREADER_CLASS_CONST_LONG("PI", XML_READER_TYPE_PROCESSING_INSTRUCTION);
1354 REGISTER_XMLREADER_CLASS_CONST_LONG("COMMENT", XML_READER_TYPE_COMMENT);
1355 REGISTER_XMLREADER_CLASS_CONST_LONG("DOC", XML_READER_TYPE_DOCUMENT);
1356 REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_TYPE", XML_READER_TYPE_DOCUMENT_TYPE);
1357 REGISTER_XMLREADER_CLASS_CONST_LONG("DOC_FRAGMENT", XML_READER_TYPE_DOCUMENT_FRAGMENT);
1358 REGISTER_XMLREADER_CLASS_CONST_LONG("NOTATION", XML_READER_TYPE_NOTATION);
1359 REGISTER_XMLREADER_CLASS_CONST_LONG("WHITESPACE", XML_READER_TYPE_WHITESPACE);
1360 REGISTER_XMLREADER_CLASS_CONST_LONG("SIGNIFICANT_WHITESPACE", XML_READER_TYPE_SIGNIFICANT_WHITESPACE);
1361 REGISTER_XMLREADER_CLASS_CONST_LONG("END_ELEMENT", XML_READER_TYPE_END_ELEMENT);
1362 REGISTER_XMLREADER_CLASS_CONST_LONG("END_ENTITY", XML_READER_TYPE_END_ENTITY);
1363 REGISTER_XMLREADER_CLASS_CONST_LONG("XML_DECLARATION", XML_READER_TYPE_XML_DECLARATION);
1364
1365 /* Constants for Parser options */
1366 REGISTER_XMLREADER_CLASS_CONST_LONG("LOADDTD", XML_PARSER_LOADDTD);
1367 REGISTER_XMLREADER_CLASS_CONST_LONG("DEFAULTATTRS", XML_PARSER_DEFAULTATTRS);
1368 REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDATE", XML_PARSER_VALIDATE);
1369 REGISTER_XMLREADER_CLASS_CONST_LONG("SUBST_ENTITIES", XML_PARSER_SUBST_ENTITIES);
1370
1371 /* Constants for Errors when loading - not yet used until we implement custom error handling
1372 REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_WARNING", XML_PARSER_SEVERITY_VALIDITY_WARNING, CONST_CS | CONST_PERSISTENT);
1373 REGISTER_XMLREADER_CLASS_CONST_LONG("VALIDITY_ERROR", XML_PARSER_SEVERITY_VALIDITY_ERROR, CONST_CS | CONST_PERSISTENT);
1374 REGISTER_XMLREADER_CLASS_CONST_LONG("WARNING", XML_PARSER_SEVERITY_WARNING, CONST_CS | CONST_PERSISTENT);
1375 REGISTER_XMLREADER_CLASS_CONST_LONG("ERROR", XML_PARSER_SEVERITY_ERROR, CONST_CS | CONST_PERSISTENT);
1376 */
1377
1378 return SUCCESS;
1379 }
1380 /* }}} */
1381
1382 /* {{{ PHP_MSHUTDOWN_FUNCTION
1383 */
PHP_MSHUTDOWN_FUNCTION(xmlreader)1384 PHP_MSHUTDOWN_FUNCTION(xmlreader)
1385 {
1386 zend_hash_destroy(&xmlreader_prop_handlers);
1387 return SUCCESS;
1388 }
1389 /* }}} */
1390
1391 /* {{{ PHP_MINFO_FUNCTION
1392 */
PHP_MINFO_FUNCTION(xmlreader)1393 PHP_MINFO_FUNCTION(xmlreader)
1394 {
1395 php_info_print_table_start();
1396 {
1397 php_info_print_table_row(2, "XMLReader", "enabled");
1398 }
1399 php_info_print_table_end();
1400 }
1401 /* }}} */
1402
1403 /*
1404 * Local variables:
1405 * tab-width: 4
1406 * c-basic-offset: 4
1407 * End:
1408 * vim600: noet sw=4 ts=4 fdm=marker
1409 * vim<600: noet sw=4 ts=4
1410 */
1411