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