xref: /PHP-5.5/ext/xmlwriter/php_xmlwriter.c (revision 4435b914)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2015 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   |         Pierre-A. Joye <pajoye@php.net>                              |
17   +----------------------------------------------------------------------+
18 */
19 
20 /* $Id$ */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 
27 #include "php.h"
28 #include "php_ini.h"
29 #include "ext/standard/info.h"
30 #include "php_xmlwriter.h"
31 #include "ext/standard/php_string.h"
32 
33 #if LIBXML_VERSION >= 20605
34 static PHP_FUNCTION(xmlwriter_set_indent);
35 static PHP_FUNCTION(xmlwriter_set_indent_string);
36 #endif
37 static PHP_FUNCTION(xmlwriter_start_attribute);
38 static PHP_FUNCTION(xmlwriter_end_attribute);
39 static PHP_FUNCTION(xmlwriter_write_attribute);
40 #if LIBXML_VERSION > 20617
41 static PHP_FUNCTION(xmlwriter_start_attribute_ns);
42 static PHP_FUNCTION(xmlwriter_write_attribute_ns);
43 #endif
44 static PHP_FUNCTION(xmlwriter_start_element);
45 static PHP_FUNCTION(xmlwriter_end_element);
46 static PHP_FUNCTION(xmlwriter_full_end_element);
47 static PHP_FUNCTION(xmlwriter_start_element_ns);
48 static PHP_FUNCTION(xmlwriter_write_element);
49 static PHP_FUNCTION(xmlwriter_write_element_ns);
50 static PHP_FUNCTION(xmlwriter_start_pi);
51 static PHP_FUNCTION(xmlwriter_end_pi);
52 static PHP_FUNCTION(xmlwriter_write_pi);
53 static PHP_FUNCTION(xmlwriter_start_cdata);
54 static PHP_FUNCTION(xmlwriter_end_cdata);
55 static PHP_FUNCTION(xmlwriter_write_cdata);
56 static PHP_FUNCTION(xmlwriter_text);
57 static PHP_FUNCTION(xmlwriter_write_raw);
58 static PHP_FUNCTION(xmlwriter_start_document);
59 static PHP_FUNCTION(xmlwriter_end_document);
60 #if LIBXML_VERSION >= 20607
61 static PHP_FUNCTION(xmlwriter_start_comment);
62 static PHP_FUNCTION(xmlwriter_end_comment);
63 #endif
64 static PHP_FUNCTION(xmlwriter_write_comment);
65 static PHP_FUNCTION(xmlwriter_start_dtd);
66 static PHP_FUNCTION(xmlwriter_end_dtd);
67 static PHP_FUNCTION(xmlwriter_write_dtd);
68 static PHP_FUNCTION(xmlwriter_start_dtd_element);
69 static PHP_FUNCTION(xmlwriter_end_dtd_element);
70 static PHP_FUNCTION(xmlwriter_write_dtd_element);
71 #if LIBXML_VERSION > 20608
72 static PHP_FUNCTION(xmlwriter_start_dtd_attlist);
73 static PHP_FUNCTION(xmlwriter_end_dtd_attlist);
74 static PHP_FUNCTION(xmlwriter_write_dtd_attlist);
75 static PHP_FUNCTION(xmlwriter_start_dtd_entity);
76 static PHP_FUNCTION(xmlwriter_end_dtd_entity);
77 static PHP_FUNCTION(xmlwriter_write_dtd_entity);
78 #endif
79 static PHP_FUNCTION(xmlwriter_open_uri);
80 static PHP_FUNCTION(xmlwriter_open_memory);
81 static PHP_FUNCTION(xmlwriter_output_memory);
82 static PHP_FUNCTION(xmlwriter_flush);
83 
84 static zend_class_entry *xmlwriter_class_entry_ce;
85 
86 static void xmlwriter_free_resource_ptr(xmlwriter_object *intern TSRMLS_DC);
87 static void xmlwriter_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC);
88 
89 typedef int (*xmlwriter_read_one_char_t)(xmlTextWriterPtr writer, const xmlChar *content);
90 typedef int (*xmlwriter_read_int_t)(xmlTextWriterPtr writer);
91 
92 /* {{{ xmlwriter_object_free_storage */
xmlwriter_free_resource_ptr(xmlwriter_object * intern TSRMLS_DC)93 static void xmlwriter_free_resource_ptr(xmlwriter_object *intern TSRMLS_DC)
94 {
95 	if (intern) {
96 		if (intern->ptr) {
97 			xmlFreeTextWriter(intern->ptr);
98 			intern->ptr = NULL;
99 		}
100 		if (intern->output) {
101 			xmlBufferFree(intern->output);
102 			intern->output = NULL;
103 		}
104 		efree(intern);
105 	}
106 }
107 /* }}} */
108 
109 #ifdef ZEND_ENGINE_2
110 /* {{{ XMLWRITER_FROM_OBJECT */
111 #define XMLWRITER_FROM_OBJECT(intern, object) \
112 	{ \
113 		ze_xmlwriter_object *obj = (ze_xmlwriter_object*) zend_object_store_get_object(object TSRMLS_CC); \
114 		intern = obj->xmlwriter_ptr; \
115 		if (!intern) { \
116 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or uninitialized XMLWriter object"); \
117 			RETURN_FALSE; \
118 		} \
119 	}
120 /* }}} */
121 
122 static zend_object_handlers xmlwriter_object_handlers;
123 
124 /* {{{ xmlwriter_object_free_storage */
xmlwriter_object_free_storage(void * object TSRMLS_DC)125 static void xmlwriter_object_free_storage(void *object TSRMLS_DC)
126 {
127 	ze_xmlwriter_object * intern = (ze_xmlwriter_object *) object;
128 	if (!intern) {
129 		return;
130 	}
131 	if (intern->xmlwriter_ptr) {
132 		xmlwriter_free_resource_ptr(intern->xmlwriter_ptr TSRMLS_CC);
133 	}
134 	intern->xmlwriter_ptr = NULL;
135 	zend_object_std_dtor(&intern->zo TSRMLS_CC);
136 
137 	efree(intern);
138 }
139 /* }}} */
140 
141 
142 /* {{{ xmlwriter_object_new */
xmlwriter_object_new(zend_class_entry * class_type TSRMLS_DC)143 static zend_object_value xmlwriter_object_new(zend_class_entry *class_type TSRMLS_DC)
144 {
145 	ze_xmlwriter_object *intern;
146 	zend_object_value retval;
147 
148 	intern = emalloc(sizeof(ze_xmlwriter_object));
149 	memset(&intern->zo, 0, sizeof(zend_object));
150 	intern->xmlwriter_ptr = NULL;
151 
152 	zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
153 	object_properties_init(&intern->zo, class_type);
154 
155 	retval.handle = zend_objects_store_put(intern,
156 						NULL,
157 						(zend_objects_free_object_storage_t) xmlwriter_object_free_storage,
158 						NULL TSRMLS_CC);
159 
160 	retval.handlers = (zend_object_handlers *) & xmlwriter_object_handlers;
161 
162 	return retval;
163 }
164 /* }}} */
165 #endif
166 
167 #define XMLW_NAME_CHK(__err) \
168 	if (xmlValidateName((xmlChar *) name, 0) != 0) {	\
169 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", __err);	\
170 		RETURN_FALSE;	\
171 	}	\
172 
173 /* {{{ arginfo */
174 ZEND_BEGIN_ARG_INFO(arginfo_xmlwriter_void, 0)
175 ZEND_END_ARG_INFO()
176 
177 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_resource, 0, 0, 1)
178 	ZEND_ARG_INFO(0, xmlwriter)
179 ZEND_END_ARG_INFO()
180 
181 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_open_uri, 0, 0, 1)
182 	ZEND_ARG_INFO(0, uri)
183 ZEND_END_ARG_INFO()
184 
185 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_set_indent, 0, 0, 2)
186 	ZEND_ARG_INFO(0, xmlwriter)
187 	ZEND_ARG_INFO(0, indent)
188 ZEND_END_ARG_INFO()
189 
190 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_set_indent, 0, 0, 1)
191 	ZEND_ARG_INFO(0, indent)
192 ZEND_END_ARG_INFO()
193 
194 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_set_indent_string, 0, 0, 2)
195 	ZEND_ARG_INFO(0, xmlwriter)
196 	ZEND_ARG_INFO(0, indentString)
197 ZEND_END_ARG_INFO()
198 
199 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_set_indent_string, 0, 0, 1)
200 	ZEND_ARG_INFO(0, indentString)
201 ZEND_END_ARG_INFO()
202 
203 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_attribute, 0, 0, 2)
204 	ZEND_ARG_INFO(0, xmlwriter)
205 	ZEND_ARG_INFO(0, name)
206 ZEND_END_ARG_INFO()
207 
208 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_attribute, 0, 0, 1)
209 	ZEND_ARG_INFO(0, name)
210 ZEND_END_ARG_INFO()
211 
212 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_attribute_ns, 0, 0, 4)
213 	ZEND_ARG_INFO(0, xmlwriter)
214 	ZEND_ARG_INFO(0, prefix)
215 	ZEND_ARG_INFO(0, name)
216 	ZEND_ARG_INFO(0, uri)
217 ZEND_END_ARG_INFO()
218 
219 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_attribute_ns, 0, 0, 3)
220 	ZEND_ARG_INFO(0, prefix)
221 	ZEND_ARG_INFO(0, name)
222 	ZEND_ARG_INFO(0, uri)
223 ZEND_END_ARG_INFO()
224 
225 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_attribute_ns, 0, 0, 5)
226 	ZEND_ARG_INFO(0, xmlwriter)
227 	ZEND_ARG_INFO(0, prefix)
228 	ZEND_ARG_INFO(0, name)
229 	ZEND_ARG_INFO(0, uri)
230 	ZEND_ARG_INFO(0, content)
231 ZEND_END_ARG_INFO()
232 
233 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_attribute_ns, 0, 0, 4)
234 	ZEND_ARG_INFO(0, prefix)
235 	ZEND_ARG_INFO(0, name)
236 	ZEND_ARG_INFO(0, uri)
237 	ZEND_ARG_INFO(0, content)
238 ZEND_END_ARG_INFO()
239 
240 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_attribute, 0, 0, 3)
241 	ZEND_ARG_INFO(0, xmlwriter)
242 	ZEND_ARG_INFO(0, name)
243 	ZEND_ARG_INFO(0, value)
244 ZEND_END_ARG_INFO()
245 
246 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_attribute, 0, 0, 2)
247 	ZEND_ARG_INFO(0, name)
248 	ZEND_ARG_INFO(0, value)
249 ZEND_END_ARG_INFO()
250 
251 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_element, 0, 0, 2)
252 	ZEND_ARG_INFO(0, xmlwriter)
253 	ZEND_ARG_INFO(0, name)
254 ZEND_END_ARG_INFO()
255 
256 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_element, 0, 0, 1)
257 	ZEND_ARG_INFO(0, name)
258 ZEND_END_ARG_INFO()
259 
260 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_element_ns, 0, 0, 4)
261 	ZEND_ARG_INFO(0, xmlwriter)
262 	ZEND_ARG_INFO(0, prefix)
263 	ZEND_ARG_INFO(0, name)
264 	ZEND_ARG_INFO(0, uri)
265 ZEND_END_ARG_INFO()
266 
267 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_element_ns, 0, 0, 3)
268 	ZEND_ARG_INFO(0, prefix)
269 	ZEND_ARG_INFO(0, name)
270 	ZEND_ARG_INFO(0, uri)
271 ZEND_END_ARG_INFO()
272 
273 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_element, 0, 0, 2)
274 	ZEND_ARG_INFO(0, xmlwriter)
275 	ZEND_ARG_INFO(0, name)
276 	ZEND_ARG_INFO(0, content)
277 ZEND_END_ARG_INFO()
278 
279 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_element, 0, 0, 1)
280 	ZEND_ARG_INFO(0, name)
281 	ZEND_ARG_INFO(0, content)
282 ZEND_END_ARG_INFO()
283 
284 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_element_ns, 0, 0, 4)
285 	ZEND_ARG_INFO(0, xmlwriter)
286 	ZEND_ARG_INFO(0, prefix)
287 	ZEND_ARG_INFO(0, name)
288 	ZEND_ARG_INFO(0, uri)
289 	ZEND_ARG_INFO(0, content)
290 ZEND_END_ARG_INFO()
291 
292 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_element_ns, 0, 0, 3)
293 	ZEND_ARG_INFO(0, prefix)
294 	ZEND_ARG_INFO(0, name)
295 	ZEND_ARG_INFO(0, uri)
296 	ZEND_ARG_INFO(0, content)
297 ZEND_END_ARG_INFO()
298 
299 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_pi, 0, 0, 2)
300 	ZEND_ARG_INFO(0, xmlwriter)
301 	ZEND_ARG_INFO(0, target)
302 ZEND_END_ARG_INFO()
303 
304 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_pi, 0, 0, 1)
305 	ZEND_ARG_INFO(0, target)
306 ZEND_END_ARG_INFO()
307 
308 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_pi, 0, 0, 3)
309 	ZEND_ARG_INFO(0, xmlwriter)
310 	ZEND_ARG_INFO(0, target)
311 	ZEND_ARG_INFO(0, content)
312 ZEND_END_ARG_INFO()
313 
314 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_pi, 0, 0, 2)
315 	ZEND_ARG_INFO(0, target)
316 	ZEND_ARG_INFO(0, content)
317 ZEND_END_ARG_INFO()
318 
319 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_cdata, 0, 0, 2)
320 	ZEND_ARG_INFO(0, xmlwriter)
321 	ZEND_ARG_INFO(0, content)
322 ZEND_END_ARG_INFO()
323 
324 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_cdata, 0, 0, 1)
325 	ZEND_ARG_INFO(0, content)
326 ZEND_END_ARG_INFO()
327 
328 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_text, 0, 0, 2)
329 	ZEND_ARG_INFO(0, xmlwriter)
330 	ZEND_ARG_INFO(0, content)
331 ZEND_END_ARG_INFO()
332 
333 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_text, 0, 0, 1)
334 	ZEND_ARG_INFO(0, content)
335 ZEND_END_ARG_INFO()
336 
337 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_raw, 0, 0, 2)
338 	ZEND_ARG_INFO(0, xmlwriter)
339 	ZEND_ARG_INFO(0, content)
340 ZEND_END_ARG_INFO()
341 
342 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_raw, 0, 0, 1)
343 	ZEND_ARG_INFO(0, content)
344 ZEND_END_ARG_INFO()
345 
346 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_document, 0, 0, 1)
347 	ZEND_ARG_INFO(0, xmlwriter)
348 	ZEND_ARG_INFO(0, version)
349 	ZEND_ARG_INFO(0, encoding)
350 	ZEND_ARG_INFO(0, standalone)
351 ZEND_END_ARG_INFO()
352 
353 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_document, 0, 0, 0)
354 	ZEND_ARG_INFO(0, version)
355 	ZEND_ARG_INFO(0, encoding)
356 	ZEND_ARG_INFO(0, standalone)
357 ZEND_END_ARG_INFO()
358 
359 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_comment, 0, 0, 2)
360 	ZEND_ARG_INFO(0, xmlwriter)
361 	ZEND_ARG_INFO(0, content)
362 ZEND_END_ARG_INFO()
363 
364 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_comment, 0, 0, 1)
365 	ZEND_ARG_INFO(0, content)
366 ZEND_END_ARG_INFO()
367 
368 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_dtd, 0, 0, 2)
369 	ZEND_ARG_INFO(0, xmlwriter)
370 	ZEND_ARG_INFO(0, qualifiedName)
371 	ZEND_ARG_INFO(0, publicId)
372 	ZEND_ARG_INFO(0, systemId)
373 ZEND_END_ARG_INFO()
374 
375 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_dtd, 0, 0, 1)
376 	ZEND_ARG_INFO(0, qualifiedName)
377 	ZEND_ARG_INFO(0, publicId)
378 	ZEND_ARG_INFO(0, systemId)
379 ZEND_END_ARG_INFO()
380 
381 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_dtd, 0, 0, 2)
382 	ZEND_ARG_INFO(0, xmlwriter)
383 	ZEND_ARG_INFO(0, name)
384 	ZEND_ARG_INFO(0, publicId)
385 	ZEND_ARG_INFO(0, systemId)
386 	ZEND_ARG_INFO(0, subset)
387 ZEND_END_ARG_INFO()
388 
389 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_dtd, 0, 0, 1)
390 	ZEND_ARG_INFO(0, name)
391 	ZEND_ARG_INFO(0, publicId)
392 	ZEND_ARG_INFO(0, systemId)
393 	ZEND_ARG_INFO(0, subset)
394 ZEND_END_ARG_INFO()
395 
396 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_dtd_element, 0, 0, 2)
397 	ZEND_ARG_INFO(0, xmlwriter)
398 	ZEND_ARG_INFO(0, qualifiedName)
399 ZEND_END_ARG_INFO()
400 
401 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_dtd_element, 0, 0, 1)
402 	ZEND_ARG_INFO(0, qualifiedName)
403 ZEND_END_ARG_INFO()
404 
405 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_dtd_element, 0, 0, 3)
406 	ZEND_ARG_INFO(0, xmlwriter)
407 	ZEND_ARG_INFO(0, name)
408 	ZEND_ARG_INFO(0, content)
409 ZEND_END_ARG_INFO()
410 
411 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_dtd_element, 0, 0, 2)
412 	ZEND_ARG_INFO(0, name)
413 	ZEND_ARG_INFO(0, content)
414 ZEND_END_ARG_INFO()
415 
416 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_dtd_attlist, 0, 0, 2)
417 	ZEND_ARG_INFO(0, xmlwriter)
418 	ZEND_ARG_INFO(0, name)
419 ZEND_END_ARG_INFO()
420 
421 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_dtd_attlist, 0, 0, 1)
422 	ZEND_ARG_INFO(0, name)
423 ZEND_END_ARG_INFO()
424 
425 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_dtd_attlist, 0, 0, 3)
426 	ZEND_ARG_INFO(0, xmlwriter)
427 	ZEND_ARG_INFO(0, name)
428 	ZEND_ARG_INFO(0, content)
429 ZEND_END_ARG_INFO()
430 
431 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_dtd_attlist, 0, 0, 2)
432 	ZEND_ARG_INFO(0, name)
433 	ZEND_ARG_INFO(0, content)
434 ZEND_END_ARG_INFO()
435 
436 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_start_dtd_entity, 0, 0, 3)
437 	ZEND_ARG_INFO(0, xmlwriter)
438 	ZEND_ARG_INFO(0, name)
439 	ZEND_ARG_INFO(0, isparam)
440 ZEND_END_ARG_INFO()
441 
442 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_start_dtd_entity, 0, 0, 2)
443 	ZEND_ARG_INFO(0, name)
444 	ZEND_ARG_INFO(0, isparam)
445 ZEND_END_ARG_INFO()
446 
447 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_write_dtd_entity, 0, 0, 3)
448 	ZEND_ARG_INFO(0, xmlwriter)
449 	ZEND_ARG_INFO(0, name)
450 	ZEND_ARG_INFO(0, content)
451 ZEND_END_ARG_INFO()
452 
453 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_write_dtd_entity, 0, 0, 2)
454 	ZEND_ARG_INFO(0, name)
455 	ZEND_ARG_INFO(0, content)
456 ZEND_END_ARG_INFO()
457 
458 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_output_memory, 0, 0, 1)
459 	ZEND_ARG_INFO(0, xmlwriter)
460 	ZEND_ARG_INFO(0, flush)
461 ZEND_END_ARG_INFO()
462 
463 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_output_memory, 0, 0, 0)
464 	ZEND_ARG_INFO(0, flush)
465 ZEND_END_ARG_INFO()
466 
467 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_flush, 0, 0, 1)
468 	ZEND_ARG_INFO(0, xmlwriter)
469 	ZEND_ARG_INFO(0, empty)
470 ZEND_END_ARG_INFO()
471 
472 ZEND_BEGIN_ARG_INFO_EX(arginfo_xmlwriter_method_flush, 0, 0, 0)
473 	ZEND_ARG_INFO(0, empty)
474 ZEND_END_ARG_INFO()
475 /* }}} */
476 
477 /* {{{ xmlwriter_functions */
478 static const zend_function_entry xmlwriter_functions[] = {
479 	PHP_FE(xmlwriter_open_uri,			arginfo_xmlwriter_open_uri)
480 	PHP_FE(xmlwriter_open_memory,		arginfo_xmlwriter_void)
481 #if LIBXML_VERSION >= 20605
482 	PHP_FE(xmlwriter_set_indent,		arginfo_xmlwriter_set_indent)
483 	PHP_FE(xmlwriter_set_indent_string, arginfo_xmlwriter_set_indent_string)
484 #endif
485 #if LIBXML_VERSION >= 20607
486 	PHP_FE(xmlwriter_start_comment,		arginfo_xmlwriter_resource)
487 	PHP_FE(xmlwriter_end_comment,		arginfo_xmlwriter_resource)
488 #endif
489 	PHP_FE(xmlwriter_start_attribute,	arginfo_xmlwriter_start_attribute)
490 	PHP_FE(xmlwriter_end_attribute,		arginfo_xmlwriter_resource)
491 	PHP_FE(xmlwriter_write_attribute,	arginfo_xmlwriter_write_attribute)
492 #if LIBXML_VERSION > 20617
493 	PHP_FE(xmlwriter_start_attribute_ns,arginfo_xmlwriter_start_attribute_ns)
494 	PHP_FE(xmlwriter_write_attribute_ns,arginfo_xmlwriter_write_attribute_ns)
495 #endif
496 	PHP_FE(xmlwriter_start_element,		arginfo_xmlwriter_start_element)
497 	PHP_FE(xmlwriter_end_element,		arginfo_xmlwriter_resource)
498 	PHP_FE(xmlwriter_full_end_element,	arginfo_xmlwriter_resource)
499 	PHP_FE(xmlwriter_start_element_ns,	arginfo_xmlwriter_start_element_ns)
500 	PHP_FE(xmlwriter_write_element,		arginfo_xmlwriter_write_element)
501 	PHP_FE(xmlwriter_write_element_ns,	arginfo_xmlwriter_write_element_ns)
502 	PHP_FE(xmlwriter_start_pi,			arginfo_xmlwriter_start_pi)
503 	PHP_FE(xmlwriter_end_pi,			arginfo_xmlwriter_resource)
504 	PHP_FE(xmlwriter_write_pi,			arginfo_xmlwriter_write_pi)
505 	PHP_FE(xmlwriter_start_cdata,		arginfo_xmlwriter_resource)
506 	PHP_FE(xmlwriter_end_cdata,			arginfo_xmlwriter_resource)
507 	PHP_FE(xmlwriter_write_cdata,		arginfo_xmlwriter_write_cdata)
508 	PHP_FE(xmlwriter_text,				arginfo_xmlwriter_text)
509 	PHP_FE(xmlwriter_write_raw,			arginfo_xmlwriter_write_raw)
510 	PHP_FE(xmlwriter_start_document,	arginfo_xmlwriter_start_document)
511 	PHP_FE(xmlwriter_end_document,		arginfo_xmlwriter_resource)
512 	PHP_FE(xmlwriter_write_comment,		arginfo_xmlwriter_write_comment)
513 	PHP_FE(xmlwriter_start_dtd,			arginfo_xmlwriter_start_dtd)
514 	PHP_FE(xmlwriter_end_dtd,			arginfo_xmlwriter_resource)
515 	PHP_FE(xmlwriter_write_dtd,			arginfo_xmlwriter_write_dtd)
516 	PHP_FE(xmlwriter_start_dtd_element,	arginfo_xmlwriter_start_dtd_element)
517 	PHP_FE(xmlwriter_end_dtd_element,	arginfo_xmlwriter_resource)
518 	PHP_FE(xmlwriter_write_dtd_element,	arginfo_xmlwriter_write_dtd_element)
519 #if LIBXML_VERSION > 20608
520 	PHP_FE(xmlwriter_start_dtd_attlist,	arginfo_xmlwriter_start_dtd_attlist)
521 	PHP_FE(xmlwriter_end_dtd_attlist,	arginfo_xmlwriter_resource)
522 	PHP_FE(xmlwriter_write_dtd_attlist,	arginfo_xmlwriter_write_dtd_attlist)
523 	PHP_FE(xmlwriter_start_dtd_entity,	arginfo_xmlwriter_start_dtd_entity)
524 	PHP_FE(xmlwriter_end_dtd_entity,	arginfo_xmlwriter_resource)
525 	PHP_FE(xmlwriter_write_dtd_entity,	arginfo_xmlwriter_write_dtd_entity)
526 #endif
527 	PHP_FE(xmlwriter_output_memory,		arginfo_xmlwriter_output_memory)
528 	PHP_FE(xmlwriter_flush,				arginfo_xmlwriter_flush)
529 	PHP_FE_END
530 };
531 /* }}} */
532 
533 #ifdef ZEND_ENGINE_2
534 /* {{{ xmlwriter_class_functions */
535 static const zend_function_entry xmlwriter_class_functions[] = {
536 	PHP_ME_MAPPING(openUri,		xmlwriter_open_uri,		arginfo_xmlwriter_open_uri, 0)
537 	PHP_ME_MAPPING(openMemory,	xmlwriter_open_memory, 	arginfo_xmlwriter_void, 0)
538 #if LIBXML_VERSION >= 20605
539 	PHP_ME_MAPPING(setIndent,	xmlwriter_set_indent,	arginfo_xmlwriter_method_set_indent, 0)
540 	PHP_ME_MAPPING(setIndentString,	xmlwriter_set_indent_string, arginfo_xmlwriter_method_set_indent_string, 0)
541 #endif
542 #if LIBXML_VERSION >= 20607
543 	PHP_ME_MAPPING(startComment,	xmlwriter_start_comment,	arginfo_xmlwriter_void, 0)
544 	PHP_ME_MAPPING(endComment,		xmlwriter_end_comment,		arginfo_xmlwriter_void, 0)
545 #endif
546 	PHP_ME_MAPPING(startAttribute,	xmlwriter_start_attribute,	arginfo_xmlwriter_method_start_attribute, 0)
547 	PHP_ME_MAPPING(endAttribute,	xmlwriter_end_attribute,	arginfo_xmlwriter_void, 0)
548 	PHP_ME_MAPPING(writeAttribute,	xmlwriter_write_attribute,	arginfo_xmlwriter_method_write_attribute, 0)
549 #if LIBXML_VERSION > 20617
550 	PHP_ME_MAPPING(startAttributeNs,	xmlwriter_start_attribute_ns,arginfo_xmlwriter_method_start_attribute_ns, 0)
551 	PHP_ME_MAPPING(writeAttributeNs,	xmlwriter_write_attribute_ns,arginfo_xmlwriter_method_write_attribute_ns, 0)
552 #endif
553 	PHP_ME_MAPPING(startElement,	xmlwriter_start_element,	arginfo_xmlwriter_method_start_element, 0)
554 	PHP_ME_MAPPING(endElement,		xmlwriter_end_element,		arginfo_xmlwriter_void, 0)
555 	PHP_ME_MAPPING(fullEndElement,	xmlwriter_full_end_element,	arginfo_xmlwriter_void, 0)
556 	PHP_ME_MAPPING(startElementNs,	xmlwriter_start_element_ns,	arginfo_xmlwriter_method_start_element_ns, 0)
557 	PHP_ME_MAPPING(writeElement,	xmlwriter_write_element,	arginfo_xmlwriter_method_write_element, 0)
558 	PHP_ME_MAPPING(writeElementNs,	xmlwriter_write_element_ns,	arginfo_xmlwriter_method_write_element_ns, 0)
559 	PHP_ME_MAPPING(startPi,			xmlwriter_start_pi,			arginfo_xmlwriter_method_start_pi, 0)
560 	PHP_ME_MAPPING(endPi,			xmlwriter_end_pi,			arginfo_xmlwriter_void, 0)
561 	PHP_ME_MAPPING(writePi,			xmlwriter_write_pi,			arginfo_xmlwriter_method_write_pi, 0)
562 	PHP_ME_MAPPING(startCdata,		xmlwriter_start_cdata,		arginfo_xmlwriter_void, 0)
563 	PHP_ME_MAPPING(endCdata,		xmlwriter_end_cdata,		arginfo_xmlwriter_void, 0)
564 	PHP_ME_MAPPING(writeCdata,		xmlwriter_write_cdata,		arginfo_xmlwriter_method_write_cdata, 0)
565 	PHP_ME_MAPPING(text,			xmlwriter_text,				arginfo_xmlwriter_method_text, 0)
566 	PHP_ME_MAPPING(writeRaw,		xmlwriter_write_raw,		arginfo_xmlwriter_method_write_raw, 0)
567 	PHP_ME_MAPPING(startDocument,	xmlwriter_start_document,	arginfo_xmlwriter_method_start_document, 0)
568 	PHP_ME_MAPPING(endDocument,		xmlwriter_end_document,		arginfo_xmlwriter_void, 0)
569 	PHP_ME_MAPPING(writeComment,	xmlwriter_write_comment,	arginfo_xmlwriter_method_write_comment, 0)
570 	PHP_ME_MAPPING(startDtd,		xmlwriter_start_dtd,		arginfo_xmlwriter_method_start_dtd, 0)
571 	PHP_ME_MAPPING(endDtd,			xmlwriter_end_dtd,			arginfo_xmlwriter_void, 0)
572 	PHP_ME_MAPPING(writeDtd,		xmlwriter_write_dtd,		arginfo_xmlwriter_method_write_dtd, 0)
573 	PHP_ME_MAPPING(startDtdElement,	xmlwriter_start_dtd_element,arginfo_xmlwriter_method_start_dtd_element, 0)
574 	PHP_ME_MAPPING(endDtdElement,	xmlwriter_end_dtd_element,	arginfo_xmlwriter_void, 0)
575 	PHP_ME_MAPPING(writeDtdElement,	xmlwriter_write_dtd_element,	arginfo_xmlwriter_method_write_dtd_element, 0)
576 #if LIBXML_VERSION > 20608
577 	PHP_ME_MAPPING(startDtdAttlist,	xmlwriter_start_dtd_attlist,	arginfo_xmlwriter_method_start_dtd_attlist, 0)
578 	PHP_ME_MAPPING(endDtdAttlist,	xmlwriter_end_dtd_attlist,	arginfo_xmlwriter_void, 0)
579 	PHP_ME_MAPPING(writeDtdAttlist,	xmlwriter_write_dtd_attlist,	arginfo_xmlwriter_method_write_dtd_attlist, 0)
580 	PHP_ME_MAPPING(startDtdEntity,	xmlwriter_start_dtd_entity,	arginfo_xmlwriter_method_start_dtd_entity, 0)
581 	PHP_ME_MAPPING(endDtdEntity,	xmlwriter_end_dtd_entity,	arginfo_xmlwriter_void, 0)
582 	PHP_ME_MAPPING(writeDtdEntity,	xmlwriter_write_dtd_entity,	arginfo_xmlwriter_method_write_dtd_entity, 0)
583 #endif
584 	PHP_ME_MAPPING(outputMemory,	xmlwriter_output_memory,	arginfo_xmlwriter_method_output_memory, 0)
585 	PHP_ME_MAPPING(flush,			xmlwriter_flush,			arginfo_xmlwriter_method_flush, 0)
586 	{NULL, NULL, NULL}
587 };
588 /* }}} */
589 #endif
590 
591 /* {{{ function prototypes */
592 static PHP_MINIT_FUNCTION(xmlwriter);
593 static PHP_MSHUTDOWN_FUNCTION(xmlwriter);
594 static PHP_MINFO_FUNCTION(xmlwriter);
595 
596 static int le_xmlwriter;
597 /* }}} */
598 
599 /* _xmlwriter_get_valid_file_path should be made a
600 	common function in libxml extension as code is common to a few xml extensions */
601 /* {{{ _xmlwriter_get_valid_file_path */
_xmlwriter_get_valid_file_path(char * source,char * resolved_path,int resolved_path_len TSRMLS_DC)602 static char *_xmlwriter_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len  TSRMLS_DC) {
603 	xmlURI *uri;
604 	xmlChar *escsource;
605 	char *file_dest;
606 	int isFileUri = 0;
607 
608 	uri = xmlCreateURI();
609 	escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *) ":");
610 	xmlParseURIReference(uri, (char *)escsource);
611 	xmlFree(escsource);
612 
613 	if (uri->scheme != NULL) {
614 		/* absolute file uris - libxml only supports localhost or empty host */
615 		if (strncasecmp(source, "file:///", 8) == 0) {
616 			if (source[sizeof("file:///") - 1] == '\0') {
617 				xmlFreeURI(uri);
618 				return NULL;
619 			}
620 			isFileUri = 1;
621 #ifdef PHP_WIN32
622 			source += 8;
623 #else
624 			source += 7;
625 #endif
626 		} else if (strncasecmp(source, "file://localhost/",17) == 0) {
627 			if (source[sizeof("file://localhost/") - 1] == '\0') {
628 				xmlFreeURI(uri);
629 				return NULL;
630 			}
631 
632 			isFileUri = 1;
633 #ifdef PHP_WIN32
634 			source += 17;
635 #else
636 			source += 16;
637 #endif
638 		}
639 	}
640 
641 	if ((uri->scheme == NULL || isFileUri)) {
642 		char file_dirname[MAXPATHLEN];
643 		size_t dir_len;
644 
645 		if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
646 			xmlFreeURI(uri);
647 			return NULL;
648 		}
649 
650 		memcpy(file_dirname, source, strlen(source));
651 		dir_len = php_dirname(file_dirname, strlen(source));
652 
653 		if (dir_len > 0) {
654 			struct stat buf;
655 			if (php_sys_stat(file_dirname, &buf) != 0) {
656 				xmlFreeURI(uri);
657 				return NULL;
658 			}
659 		}
660 
661 		file_dest = resolved_path;
662 	} else {
663 		file_dest = source;
664 	}
665 
666 	xmlFreeURI(uri);
667 
668 	return file_dest;
669 }
670 /* }}} */
671 
672 #ifndef ZEND_ENGINE_2
673 /* Channel libxml file io layer through the PHP streams subsystem.
674  * This allows use of ftps:// and https:// urls */
675 
676 /* {{{ php_xmlwriter_streams_IO_open_write_wrapper */
php_xmlwriter_streams_IO_open_write_wrapper(const char * filename TSRMLS_DC)677 static void *php_xmlwriter_streams_IO_open_write_wrapper(const char *filename TSRMLS_DC)
678 {
679 	php_stream_wrapper *wrapper = NULL;
680 	void *ret_val = NULL;
681 
682 	ret_val = php_stream_open_wrapper_ex((char *)filename, "wb", REPORT_ERRORS, NULL, NULL);
683 	return ret_val;
684 }
685 /* }}} */
686 
687 /* {{{ php_xmlwriter_streams_IO_write */
php_xmlwriter_streams_IO_write(void * context,const char * buffer,int len)688 static int php_xmlwriter_streams_IO_write(void *context, const char *buffer, int len)
689 {
690 	TSRMLS_FETCH();
691 	return php_stream_write((php_stream*)context, buffer, len);
692 }
693 /* }}} */
694 
695 /* {{{ php_xmlwriter_streams_IO_close */
php_xmlwriter_streams_IO_close(void * context)696 static int php_xmlwriter_streams_IO_close(void *context)
697 {
698 	TSRMLS_FETCH();
699 	return php_stream_close((php_stream*)context);
700 }
701 /* }}} */
702 #endif
703 
704 /* {{{ xmlwriter_module_entry
705  */
706 zend_module_entry xmlwriter_module_entry = {
707 	STANDARD_MODULE_HEADER,
708 	"xmlwriter",
709 	xmlwriter_functions,
710 	PHP_MINIT(xmlwriter),
711 	PHP_MSHUTDOWN(xmlwriter),
712 	NULL,
713 	NULL,
714 	PHP_MINFO(xmlwriter),
715 	"0.1",
716 	STANDARD_MODULE_PROPERTIES
717 };
718 /* }}} */
719 
720 #ifdef COMPILE_DL_XMLWRITER
ZEND_GET_MODULE(xmlwriter)721 ZEND_GET_MODULE(xmlwriter)
722 #endif
723 
724 /* {{{ xmlwriter_objects_clone
725 static void xmlwriter_objects_clone(void *object, void **object_clone TSRMLS_DC)
726 {
727 	TODO
728 }
729 }}} */
730 
731 /* {{{ xmlwriter_dtor */
732 static void xmlwriter_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
733 	xmlwriter_object *intern;
734 
735 	intern = (xmlwriter_object *) rsrc->ptr;
736 	xmlwriter_free_resource_ptr(intern TSRMLS_CC);
737 }
738 /* }}} */
739 
php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAMETERS,xmlwriter_read_one_char_t internal_function,char * err_string)740 static void php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlwriter_read_one_char_t internal_function, char *err_string)
741 {
742 	zval *pind;
743 	xmlwriter_object *intern;
744 	xmlTextWriterPtr ptr;
745 	char *name;
746 	int name_len, retval;
747 
748 #ifdef ZEND_ENGINE_2
749 	zval *this = getThis();
750 
751 	if (this) {
752 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
753 			return;
754 		}
755 		XMLWRITER_FROM_OBJECT(intern, this);
756 	} else
757 #endif
758 	{
759 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pind, &name, &name_len) == FAILURE) {
760 			return;
761 		}
762 
763 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
764 	}
765 
766 	if (err_string != NULL) {
767 		XMLW_NAME_CHK(err_string);
768 	}
769 
770 	ptr = intern->ptr;
771 
772 	if (ptr) {
773 		retval = internal_function(ptr, (xmlChar *) name);
774 		if (retval != -1) {
775 			RETURN_TRUE;
776 		}
777 	}
778 
779 	RETURN_FALSE;
780 }
781 
php_xmlwriter_end(INTERNAL_FUNCTION_PARAMETERS,xmlwriter_read_int_t internal_function)782 static void php_xmlwriter_end(INTERNAL_FUNCTION_PARAMETERS, xmlwriter_read_int_t internal_function)
783 {
784 	zval *pind;
785 	xmlwriter_object *intern;
786 	xmlTextWriterPtr ptr;
787 	int retval;
788 #ifdef ZEND_ENGINE_2
789 	zval *this = getThis();
790 
791 	if (this) {
792 		XMLWRITER_FROM_OBJECT(intern, this);
793 		if (zend_parse_parameters_none() == FAILURE) {
794 			return;
795 		}
796 	} else
797 #endif
798 	{
799 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
800 			return;
801 		}
802 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
803 	}
804 
805 	ptr = intern->ptr;
806 
807 	if (ptr) {
808 		retval = internal_function(ptr);
809 		if (retval != -1) {
810 			RETURN_TRUE;
811 		}
812 	}
813 
814 	RETURN_FALSE;
815 }
816 
817 #if LIBXML_VERSION >= 20605
818 /* {{{ proto bool xmlwriter_set_indent(resource xmlwriter, bool indent)
819 Toggle indentation on/off - returns FALSE on error */
PHP_FUNCTION(xmlwriter_set_indent)820 static PHP_FUNCTION(xmlwriter_set_indent)
821 {
822 	zval *pind;
823 	xmlwriter_object *intern;
824 	xmlTextWriterPtr ptr;
825 	int retval;
826 	zend_bool indent;
827 
828 #ifdef ZEND_ENGINE_2
829 	zval *this = getThis();
830 
831 	if (this) {
832 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &indent) == FAILURE) {
833 			return;
834 		}
835 		XMLWRITER_FROM_OBJECT(intern, this);
836 	} else
837 #endif
838 	{
839 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &pind, &indent) == FAILURE) {
840 			return;
841 		}
842 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
843 	}
844 
845 
846 	ptr = intern->ptr;
847 	if (ptr) {
848 		retval = xmlTextWriterSetIndent(ptr, indent);
849 		if (retval == 0) {
850 			RETURN_TRUE;
851 		}
852 	}
853 
854 	RETURN_FALSE;
855 }
856 /* }}} */
857 
858 /* {{{ proto bool xmlwriter_set_indent_string(resource xmlwriter, string indentString)
859 Set string used for indenting - returns FALSE on error */
PHP_FUNCTION(xmlwriter_set_indent_string)860 static PHP_FUNCTION(xmlwriter_set_indent_string)
861 {
862 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterSetIndentString, NULL);
863 }
864 /* }}} */
865 
866 #endif
867 
868 /* {{{ proto bool xmlwriter_start_attribute(resource xmlwriter, string name)
869 Create start attribute - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_attribute)870 static PHP_FUNCTION(xmlwriter_start_attribute)
871 {
872 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartAttribute, "Invalid Attribute Name");
873 }
874 /* }}} */
875 
876 /* {{{ proto bool xmlwriter_end_attribute(resource xmlwriter)
877 End attribute - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_attribute)878 static PHP_FUNCTION(xmlwriter_end_attribute)
879 {
880 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndAttribute);
881 }
882 /* }}} */
883 
884 #if LIBXML_VERSION > 20617
885 /* {{{ proto bool xmlwriter_start_attribute_ns(resource xmlwriter, string prefix, string name, string uri)
886 Create start namespaced attribute - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_attribute_ns)887 static PHP_FUNCTION(xmlwriter_start_attribute_ns)
888 {
889 	zval *pind;
890 	xmlwriter_object *intern;
891 	xmlTextWriterPtr ptr;
892 	char *name, *prefix, *uri;
893 	int name_len, prefix_len, uri_len, retval;
894 #ifdef ZEND_ENGINE_2
895 	zval *this = getThis();
896 
897 	if (this) {
898 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss!",
899 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
900 			return;
901 		}
902 		XMLWRITER_FROM_OBJECT(intern, this);
903 	} else
904 #endif
905 	{
906 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss!", &pind,
907 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
908 			return;
909 		}
910 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
911 	}
912 
913 	XMLW_NAME_CHK("Invalid Attribute Name");
914 
915 	ptr = intern->ptr;
916 
917 	if (ptr) {
918 		retval = xmlTextWriterStartAttributeNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
919 		if (retval != -1) {
920 			RETURN_TRUE;
921 		}
922 	}
923 
924 	RETURN_FALSE;
925 }
926 /* }}} */
927 #endif
928 
929 /* {{{ proto bool xmlwriter_write_attribute(resource xmlwriter, string name, string content)
930 Write full attribute - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_attribute)931 static PHP_FUNCTION(xmlwriter_write_attribute)
932 {
933 	zval *pind;
934 	xmlwriter_object *intern;
935 	xmlTextWriterPtr ptr;
936 	char *name, *content;
937 	int name_len, content_len, retval;
938 
939 #ifdef ZEND_ENGINE_2
940 	zval *this = getThis();
941 
942 	if (this) {
943 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
944 			&name, &name_len, &content, &content_len) == FAILURE) {
945 			return;
946 		}
947 		XMLWRITER_FROM_OBJECT(intern, this);
948 	} else
949 #endif
950 	{
951 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pind,
952 			&name, &name_len, &content, &content_len) == FAILURE) {
953 			return;
954 		}
955 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
956 	}
957 
958 	XMLW_NAME_CHK("Invalid Attribute Name");
959 
960 	ptr = intern->ptr;
961 
962 	if (ptr) {
963 		retval = xmlTextWriterWriteAttribute(ptr, (xmlChar *)name, (xmlChar *)content);
964 		if (retval != -1) {
965 			RETURN_TRUE;
966 		}
967 	}
968 
969 	RETURN_FALSE;
970 }
971 /* }}} */
972 
973 #if LIBXML_VERSION > 20617
974 /* {{{ proto bool xmlwriter_write_attribute_ns(resource xmlwriter, string prefix, string name, string uri, string content)
975 Write full namespaced attribute - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_attribute_ns)976 static PHP_FUNCTION(xmlwriter_write_attribute_ns)
977 {
978 	zval *pind;
979 	xmlwriter_object *intern;
980 	xmlTextWriterPtr ptr;
981 	char *name, *prefix, *uri, *content;
982 	int name_len, prefix_len, uri_len, content_len, retval;
983 
984 #ifdef ZEND_ENGINE_2
985 	zval *this = getThis();
986 
987 	if (this) {
988 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss!s",
989 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
990 			return;
991 		}
992 		XMLWRITER_FROM_OBJECT(intern, this);
993 	} else
994 #endif
995 	{
996 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsss!s", &pind,
997 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
998 			return;
999 		}
1000 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1001 	}
1002 
1003 	XMLW_NAME_CHK("Invalid Attribute Name");
1004 
1005 	ptr = intern->ptr;
1006 
1007 	if (ptr) {
1008 		retval = xmlTextWriterWriteAttributeNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)content);
1009 		if (retval != -1) {
1010 			RETURN_TRUE;
1011 		}
1012 	}
1013 
1014 	RETURN_FALSE;
1015 }
1016 /* }}} */
1017 #endif
1018 
1019 /* {{{ proto bool xmlwriter_start_element(resource xmlwriter, string name)
1020 Create start element tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_element)1021 static PHP_FUNCTION(xmlwriter_start_element)
1022 {
1023 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartElement, "Invalid Element Name");
1024 }
1025 /* }}} */
1026 
1027 /* {{{ proto bool xmlwriter_start_element_ns(resource xmlwriter, string prefix, string name, string uri)
1028 Create start namespaced element tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_element_ns)1029 static PHP_FUNCTION(xmlwriter_start_element_ns)
1030 {
1031 	zval *pind;
1032 	xmlwriter_object *intern;
1033 	xmlTextWriterPtr ptr;
1034 	char *name, *prefix, *uri;
1035 	int name_len, prefix_len, uri_len, retval;
1036 #ifdef ZEND_ENGINE_2
1037 	zval *this = getThis();
1038 
1039 	if (this) {
1040 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!ss!",
1041 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
1042 			return;
1043 		}
1044 		XMLWRITER_FROM_OBJECT(intern, this);
1045 	} else
1046 #endif
1047 	{
1048 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!ss!", &pind,
1049 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
1050 			return;
1051 		}
1052 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1053 	}
1054 
1055 	XMLW_NAME_CHK("Invalid Element Name");
1056 
1057 	ptr = intern->ptr;
1058 
1059 	if (ptr) {
1060 		retval = xmlTextWriterStartElementNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
1061 		if (retval != -1) {
1062 			RETURN_TRUE;
1063 		}
1064 
1065 	}
1066 
1067 	RETURN_FALSE;
1068 }
1069 /* }}} */
1070 
1071 /* {{{ proto bool xmlwriter_end_element(resource xmlwriter)
1072 End current element - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_element)1073 static PHP_FUNCTION(xmlwriter_end_element)
1074 {
1075 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndElement);
1076 }
1077 /* }}} */
1078 
1079 /* {{{ proto bool xmlwriter_full_end_element(resource xmlwriter)
1080 End current element - returns FALSE on error */
PHP_FUNCTION(xmlwriter_full_end_element)1081 static PHP_FUNCTION(xmlwriter_full_end_element)
1082 {
1083 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterFullEndElement);
1084 }
1085 /* }}} */
1086 
1087 /* {{{ proto bool xmlwriter_write_element(resource xmlwriter, string name[, string content])
1088 Write full element tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_element)1089 static PHP_FUNCTION(xmlwriter_write_element)
1090 {
1091 	zval *pind;
1092 	xmlwriter_object *intern;
1093 	xmlTextWriterPtr ptr;
1094 	char *name, *content = NULL;
1095 	int name_len, content_len, retval;
1096 
1097 #ifdef ZEND_ENGINE_2
1098 	zval *this = getThis();
1099 
1100 	if (this) {
1101 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!",
1102 			&name, &name_len, &content, &content_len) == FAILURE) {
1103 			return;
1104 		}
1105 		XMLWRITER_FROM_OBJECT(intern, this);
1106 	} else
1107 #endif
1108 	{
1109 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s!", &pind,
1110 			&name, &name_len, &content, &content_len) == FAILURE) {
1111 			return;
1112 		}
1113 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1114 	}
1115 
1116 	XMLW_NAME_CHK("Invalid Element Name");
1117 
1118 	ptr = intern->ptr;
1119 
1120 	if (ptr) {
1121 		if (!content) {
1122 			retval = xmlTextWriterStartElement(ptr, (xmlChar *)name);
1123             if (retval == -1) {
1124                 RETURN_FALSE;
1125             }
1126 			xmlTextWriterEndElement(ptr);
1127             if (retval == -1) {
1128                 RETURN_FALSE;
1129             }
1130 		} else {
1131 			retval = xmlTextWriterWriteElement(ptr, (xmlChar *)name, (xmlChar *)content);
1132 		}
1133 		if (retval != -1) {
1134 			RETURN_TRUE;
1135 		}
1136 	}
1137 
1138 	RETURN_FALSE;
1139 }
1140 /* }}} */
1141 
1142 /* {{{ proto bool xmlwriter_write_element_ns(resource xmlwriter, string prefix, string name, string uri[, string content])
1143 Write full namesapced element tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_element_ns)1144 static PHP_FUNCTION(xmlwriter_write_element_ns)
1145 {
1146 	zval *pind;
1147 	xmlwriter_object *intern;
1148 	xmlTextWriterPtr ptr;
1149 	char *name, *prefix, *uri, *content = NULL;
1150 	int name_len, prefix_len, uri_len, content_len, retval;
1151 
1152 #ifdef ZEND_ENGINE_2
1153 	zval *this = getThis();
1154 
1155 	if (this) {
1156 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!ss!|s!",
1157 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
1158 			return;
1159 		}
1160 		XMLWRITER_FROM_OBJECT(intern, this);
1161 	} else
1162 #endif
1163 	{
1164 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!ss!|s!", &pind,
1165 			&prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
1166 			return;
1167 		}
1168 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1169 	}
1170 
1171 	XMLW_NAME_CHK("Invalid Element Name");
1172 
1173 	ptr = intern->ptr;
1174 
1175 	if (ptr) {
1176 		if (!content) {
1177 			retval = xmlTextWriterStartElementNS(ptr,(xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
1178             if (retval == -1) {
1179                 RETURN_FALSE;
1180             }
1181 			retval = xmlTextWriterEndElement(ptr);
1182             if (retval == -1) {
1183                 RETURN_FALSE;
1184             }
1185 		} else {
1186 			retval = xmlTextWriterWriteElementNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)content);
1187 		}
1188 		if (retval != -1) {
1189 			RETURN_TRUE;
1190 		}
1191 	}
1192 
1193 	RETURN_FALSE;
1194 }
1195 /* }}} */
1196 
1197 /* {{{ proto bool xmlwriter_start_pi(resource xmlwriter, string target)
1198 Create start PI tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_pi)1199 static PHP_FUNCTION(xmlwriter_start_pi)
1200 {
1201 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartPI, "Invalid PI Target");
1202 }
1203 /* }}} */
1204 
1205 /* {{{ proto bool xmlwriter_end_pi(resource xmlwriter)
1206 End current PI - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_pi)1207 static PHP_FUNCTION(xmlwriter_end_pi)
1208 {
1209 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndPI);
1210 }
1211 /* }}} */
1212 
1213 /* {{{ proto bool xmlwriter_write_pi(resource xmlwriter, string target, string content)
1214 Write full PI tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_pi)1215 static PHP_FUNCTION(xmlwriter_write_pi)
1216 {
1217 	zval *pind;
1218 	xmlwriter_object *intern;
1219 	xmlTextWriterPtr ptr;
1220 	char *name, *content;
1221 	int name_len, content_len, retval;
1222 
1223 #ifdef ZEND_ENGINE_2
1224 	zval *this = getThis();
1225 
1226 	if (this) {
1227 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
1228 			&name, &name_len, &content, &content_len) == FAILURE) {
1229 			return;
1230 		}
1231 		XMLWRITER_FROM_OBJECT(intern, this);
1232 	} else
1233 #endif
1234 	{
1235 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pind,
1236 			&name, &name_len, &content, &content_len) == FAILURE) {
1237 			return;
1238 		}
1239 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1240 	}
1241 
1242 	XMLW_NAME_CHK("Invalid PI Target");
1243 
1244 	ptr = intern->ptr;
1245 
1246 	if (ptr) {
1247 		retval = xmlTextWriterWritePI(ptr, (xmlChar *)name, (xmlChar *)content);
1248 		if (retval != -1) {
1249 			RETURN_TRUE;
1250 		}
1251 	}
1252 
1253 	RETURN_FALSE;
1254 }
1255 /* }}} */
1256 
1257 /* {{{ proto bool xmlwriter_start_cdata(resource xmlwriter)
1258 Create start CDATA tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_cdata)1259 static PHP_FUNCTION(xmlwriter_start_cdata)
1260 {
1261 	zval *pind;
1262 	xmlwriter_object *intern;
1263 	xmlTextWriterPtr ptr;
1264 	int retval;
1265 #ifdef ZEND_ENGINE_2
1266 	zval *this = getThis();
1267 
1268 	if (this) {
1269 		XMLWRITER_FROM_OBJECT(intern, this);
1270 	} else
1271 #endif
1272 	{
1273 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
1274 			return;
1275 		}
1276 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1277 	}
1278 
1279 	ptr = intern->ptr;
1280 
1281 	if (ptr) {
1282 		retval = xmlTextWriterStartCDATA(ptr);
1283 		if (retval != -1) {
1284 			RETURN_TRUE;
1285 		}
1286 	}
1287 
1288 	RETURN_FALSE;
1289 }
1290 /* }}} */
1291 
1292 /* {{{ proto bool xmlwriter_end_cdata(resource xmlwriter)
1293 End current CDATA - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_cdata)1294 static PHP_FUNCTION(xmlwriter_end_cdata)
1295 {
1296 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndCDATA);
1297 }
1298 /* }}} */
1299 
1300 /* {{{ proto bool xmlwriter_write_cdata(resource xmlwriter, string content)
1301 Write full CDATA tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_cdata)1302 static PHP_FUNCTION(xmlwriter_write_cdata)
1303 {
1304 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteCDATA, NULL);
1305 }
1306 /* }}} */
1307 
1308 /* {{{ proto bool xmlwriter_write_raw(resource xmlwriter, string content)
1309 Write text - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_raw)1310 static PHP_FUNCTION(xmlwriter_write_raw)
1311 {
1312 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteRaw, NULL);
1313 }
1314 /* }}} */
1315 
1316 /* {{{ proto bool xmlwriter_text(resource xmlwriter, string content)
1317 Write text - returns FALSE on error */
PHP_FUNCTION(xmlwriter_text)1318 static PHP_FUNCTION(xmlwriter_text)
1319 {
1320 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteString, NULL);
1321 }
1322 /* }}} */
1323 
1324 #if LIBXML_VERSION >= 20607
1325 /* {{{ proto bool xmlwriter_start_comment(resource xmlwriter)
1326 Create start comment - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_comment)1327 static PHP_FUNCTION(xmlwriter_start_comment)
1328 {
1329 	zval *pind;
1330 	xmlwriter_object *intern;
1331 	xmlTextWriterPtr ptr;
1332 	int retval;
1333 #ifdef ZEND_ENGINE_2
1334 	zval *this = getThis();
1335 
1336 	if (this) {
1337 		XMLWRITER_FROM_OBJECT(intern, this);
1338 	} else
1339 #endif
1340 	{
1341 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &pind) == FAILURE) {
1342 			return;
1343 		}
1344 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1345 	}
1346 
1347 	ptr = intern->ptr;
1348 
1349 	if (ptr) {
1350 		retval = xmlTextWriterStartComment(ptr);
1351 		if (retval != -1) {
1352 			RETURN_TRUE;
1353 		}
1354 	}
1355 
1356 	RETURN_FALSE;
1357 }
1358 /* }}} */
1359 
1360 /* {{{ proto bool xmlwriter_end_comment(resource xmlwriter)
1361 Create end comment - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_comment)1362 static PHP_FUNCTION(xmlwriter_end_comment)
1363 {
1364 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndComment);
1365 }
1366 /* }}} */
1367 #endif  /* LIBXML_VERSION >= 20607 */
1368 
1369 
1370 /* {{{ proto bool xmlwriter_write_comment(resource xmlwriter, string content)
1371 Write full comment tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_comment)1372 static PHP_FUNCTION(xmlwriter_write_comment)
1373 {
1374 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteComment, NULL);
1375 }
1376 /* }}} */
1377 
1378 /* {{{ proto bool xmlwriter_start_document(resource xmlwriter, string version, string encoding, string standalone)
1379 Create document tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_document)1380 static PHP_FUNCTION(xmlwriter_start_document)
1381 {
1382 	zval *pind;
1383 	xmlwriter_object *intern;
1384 	xmlTextWriterPtr ptr;
1385 	char *version = NULL, *enc = NULL, *alone = NULL;
1386 	int version_len, enc_len, alone_len, retval;
1387 
1388 #ifdef ZEND_ENGINE_2
1389 	zval *this = getThis();
1390 
1391 	if (this) {
1392 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!", &version, &version_len, &enc, &enc_len, &alone, &alone_len) == FAILURE) {
1393 			return;
1394 		}
1395 		XMLWRITER_FROM_OBJECT(intern, this);
1396 	} else
1397 #endif
1398 	{
1399 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!s!s!", &pind, &version, &version_len, &enc, &enc_len, &alone, &alone_len) == FAILURE) {
1400 			return;
1401 		}
1402 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1403 	}
1404 
1405 	ptr = intern->ptr;
1406 
1407 	if (ptr) {
1408 		retval = xmlTextWriterStartDocument(ptr, version, enc, alone);
1409 		if (retval != -1) {
1410 			RETURN_TRUE;
1411 		}
1412 	}
1413 
1414 	RETURN_FALSE;
1415 }
1416 /* }}} */
1417 
1418 /* {{{ proto bool xmlwriter_end_document(resource xmlwriter)
1419 End current document - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_document)1420 static PHP_FUNCTION(xmlwriter_end_document)
1421 {
1422 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDocument);
1423 }
1424 /* }}} */
1425 
1426 /* {{{ proto bool xmlwriter_start_dtd(resource xmlwriter, string name, string pubid, string sysid)
1427 Create start DTD tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_dtd)1428 static PHP_FUNCTION(xmlwriter_start_dtd)
1429 {
1430 	zval *pind;
1431 	xmlwriter_object *intern;
1432 	xmlTextWriterPtr ptr;
1433 	char *name, *pubid = NULL, *sysid = NULL;
1434 	int name_len, pubid_len, sysid_len, retval;
1435 
1436 #ifdef ZEND_ENGINE_2
1437 	zval *this = getThis();
1438 
1439 	if (this) {
1440 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!", &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len) == FAILURE) {
1441 			return;
1442 		}
1443 
1444 		XMLWRITER_FROM_OBJECT(intern, this);
1445 	} else
1446 #endif
1447 	{
1448 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s!s!", &pind, &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len) == FAILURE) {
1449 			return;
1450 		}
1451 
1452 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1453 	}
1454 	ptr = intern->ptr;
1455 
1456 	if (ptr) {
1457 		retval = xmlTextWriterStartDTD(ptr, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid);
1458 		if (retval != -1) {
1459 			RETURN_TRUE;
1460 		}
1461 	}
1462 
1463 	RETURN_FALSE;
1464 }
1465 /* }}} */
1466 
1467 /* {{{ proto bool xmlwriter_end_dtd(resource xmlwriter)
1468 End current DTD - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_dtd)1469 static PHP_FUNCTION(xmlwriter_end_dtd)
1470 {
1471 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTD);
1472 }
1473 /* }}} */
1474 
1475 /* {{{ proto bool xmlwriter_write_dtd(resource xmlwriter, string name, string pubid, string sysid, string subset)
1476 Write full DTD tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_dtd)1477 static PHP_FUNCTION(xmlwriter_write_dtd)
1478 {
1479 	zval *pind;
1480 	xmlwriter_object *intern;
1481 	xmlTextWriterPtr ptr;
1482 	char *name, *pubid = NULL, *sysid = NULL, *subset = NULL;
1483 	int name_len, pubid_len, sysid_len, subset_len, retval;
1484 
1485 #ifdef ZEND_ENGINE_2
1486 	zval *this = getThis();
1487 
1488 	if (this) {
1489 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!s!", &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len, &subset, &subset_len) == FAILURE) {
1490 			return;
1491 		}
1492 
1493 		XMLWRITER_FROM_OBJECT(intern, this);
1494 	} else
1495 #endif
1496 	{
1497 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s!s!s!", &pind, &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len, &subset, &subset_len) == FAILURE) {
1498 			return;
1499 		}
1500 
1501 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1502 	}
1503 
1504 	ptr = intern->ptr;
1505 
1506 	if (ptr) {
1507 		retval = xmlTextWriterWriteDTD(ptr, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid, (xmlChar *)subset);
1508 		if (retval != -1) {
1509 			RETURN_TRUE;
1510 		}
1511 	}
1512 
1513 	RETURN_FALSE;
1514 }
1515 /* }}} */
1516 
1517 /* {{{ proto bool xmlwriter_start_dtd_element(resource xmlwriter, string name)
1518 Create start DTD element - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_dtd_element)1519 static PHP_FUNCTION(xmlwriter_start_dtd_element)
1520 {
1521 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartDTDElement, "Invalid Element Name");
1522 }
1523 /* }}} */
1524 
1525 /* {{{ proto bool xmlwriter_end_dtd_element(resource xmlwriter)
1526 End current DTD element - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_dtd_element)1527 static PHP_FUNCTION(xmlwriter_end_dtd_element)
1528 {
1529 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDElement);
1530 }
1531 /* }}} */
1532 
1533 /* {{{ proto bool xmlwriter_write_dtd_element(resource xmlwriter, string name, string content)
1534 Write full DTD element tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_dtd_element)1535 static PHP_FUNCTION(xmlwriter_write_dtd_element)
1536 {
1537 	zval *pind;
1538 	xmlwriter_object *intern;
1539 	xmlTextWriterPtr ptr;
1540 	char *name, *content;
1541 	int name_len, content_len, retval;
1542 
1543 #ifdef ZEND_ENGINE_2
1544 	zval *this = getThis();
1545 
1546 	if (this) {
1547 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &content, &content_len) == FAILURE) {
1548 			return;
1549 		}
1550 		XMLWRITER_FROM_OBJECT(intern, this);
1551 	} else
1552 #endif
1553 	{
1554 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pind,
1555 			&name, &name_len, &content, &content_len) == FAILURE) {
1556 			return;
1557 		}
1558 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1559 	}
1560 
1561 	XMLW_NAME_CHK("Invalid Element Name");
1562 
1563 	ptr = intern->ptr;
1564 
1565 	if (ptr) {
1566 		retval = xmlTextWriterWriteDTDElement(ptr, (xmlChar *)name, (xmlChar *)content);
1567 		if (retval != -1) {
1568 			RETURN_TRUE;
1569 		}
1570 	}
1571 
1572 	RETURN_FALSE;
1573 }
1574 /* }}} */
1575 
1576 #if LIBXML_VERSION > 20608
1577 /* {{{ proto bool xmlwriter_start_dtd_attlist(resource xmlwriter, string name)
1578 Create start DTD AttList - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_dtd_attlist)1579 static PHP_FUNCTION(xmlwriter_start_dtd_attlist)
1580 {
1581 	php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartDTDAttlist, "Invalid Element Name");
1582 }
1583 /* }}} */
1584 
1585 /* {{{ proto bool xmlwriter_end_dtd_attlist(resource xmlwriter)
1586 End current DTD AttList - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_dtd_attlist)1587 static PHP_FUNCTION(xmlwriter_end_dtd_attlist)
1588 {
1589 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDAttlist);
1590 }
1591 /* }}} */
1592 
1593 /* {{{ proto bool xmlwriter_write_dtd_attlist(resource xmlwriter, string name, string content)
1594 Write full DTD AttList tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_dtd_attlist)1595 static PHP_FUNCTION(xmlwriter_write_dtd_attlist)
1596 {
1597 	zval *pind;
1598 	xmlwriter_object *intern;
1599 	xmlTextWriterPtr ptr;
1600 	char *name, *content;
1601 	int name_len, content_len, retval;
1602 
1603 
1604 #ifdef ZEND_ENGINE_2
1605 	zval *this = getThis();
1606 
1607 	if (this) {
1608 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
1609 			&name, &name_len, &content, &content_len) == FAILURE) {
1610 			return;
1611 		}
1612 		XMLWRITER_FROM_OBJECT(intern, this);
1613 	} else
1614 #endif
1615 	{
1616 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &pind,
1617 			&name, &name_len, &content, &content_len) == FAILURE) {
1618 			return;
1619 		}
1620 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1621 	}
1622 
1623 	XMLW_NAME_CHK("Invalid Element Name");
1624 
1625 	ptr = intern->ptr;
1626 
1627 	if (ptr) {
1628 		retval = xmlTextWriterWriteDTDAttlist(ptr, (xmlChar *)name, (xmlChar *)content);
1629 		if (retval != -1) {
1630 			RETURN_TRUE;
1631 		}
1632 	}
1633 
1634 	RETURN_FALSE;
1635 }
1636 /* }}} */
1637 
1638 /* {{{ proto bool xmlwriter_start_dtd_entity(resource xmlwriter, string name, bool isparam)
1639 Create start DTD Entity - returns FALSE on error */
PHP_FUNCTION(xmlwriter_start_dtd_entity)1640 static PHP_FUNCTION(xmlwriter_start_dtd_entity)
1641 {
1642 	zval *pind;
1643 	xmlwriter_object *intern;
1644 	xmlTextWriterPtr ptr;
1645 	char *name;
1646 	int name_len, retval;
1647 	zend_bool isparm;
1648 
1649 
1650 #ifdef ZEND_ENGINE_2
1651 	zval *this = getThis();
1652 
1653 	if (this) {
1654 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb", &name, &name_len, &isparm) == FAILURE) {
1655 			return;
1656 		}
1657 		XMLWRITER_FROM_OBJECT(intern, this);
1658 	} else
1659 #endif
1660 	{
1661 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsb", &pind, &name, &name_len, &isparm) == FAILURE) {
1662 			return;
1663 		}
1664 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1665 	}
1666 
1667 	XMLW_NAME_CHK("Invalid Attribute Name");
1668 
1669 	ptr = intern->ptr;
1670 
1671 	if (ptr) {
1672 		retval = xmlTextWriterStartDTDEntity(ptr, isparm, (xmlChar *)name);
1673 		if (retval != -1) {
1674 			RETURN_TRUE;
1675 		}
1676 	}
1677 
1678 	RETURN_FALSE;
1679 }
1680 /* }}} */
1681 
1682 /* {{{ proto bool xmlwriter_end_dtd_entity(resource xmlwriter)
1683 End current DTD Entity - returns FALSE on error */
PHP_FUNCTION(xmlwriter_end_dtd_entity)1684 static PHP_FUNCTION(xmlwriter_end_dtd_entity)
1685 {
1686 	php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDEntity);
1687 }
1688 /* }}} */
1689 
1690 /* {{{ proto bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, int pe [, string pubid [, string sysid [, string ndataid]]]])
1691 Write full DTD Entity tag - returns FALSE on error */
PHP_FUNCTION(xmlwriter_write_dtd_entity)1692 static PHP_FUNCTION(xmlwriter_write_dtd_entity)
1693 {
1694 	zval *pind;
1695 	xmlwriter_object *intern;
1696 	xmlTextWriterPtr ptr;
1697 	char *name, *content;
1698 	int name_len, content_len, retval;
1699 	/* Optional parameters */
1700 	char *pubid = NULL, *sysid = NULL, *ndataid = NULL;
1701 	zend_bool pe = 0;
1702 	int pubid_len, sysid_len, ndataid_len;
1703 
1704 #ifdef ZEND_ENGINE_2
1705 	zval *this = getThis();
1706 
1707 	if (this) {
1708 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|bsss",
1709 			&name, &name_len, &content, &content_len, &pe, &pubid, &pubid_len,
1710 			&sysid, &sysid_len, &ndataid, &ndataid_len) == FAILURE) {
1711 			return;
1712 		}
1713 		XMLWRITER_FROM_OBJECT(intern, this);
1714 	} else
1715 #endif
1716 	{
1717 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss|bsss", &pind,
1718 			&name, &name_len, &content, &content_len, &pe, &pubid, &pubid_len,
1719 			&sysid, &sysid_len, &ndataid, &ndataid_len) == FAILURE) {
1720 			return;
1721 		}
1722 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1723 	}
1724 
1725 	XMLW_NAME_CHK("Invalid Element Name");
1726 
1727 	ptr = intern->ptr;
1728 
1729 	if (ptr) {
1730 		retval = xmlTextWriterWriteDTDEntity(ptr, pe, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid, (xmlChar *)ndataid, (xmlChar *)content);
1731 		if (retval != -1) {
1732 			RETURN_TRUE;
1733 		}
1734 	}
1735 
1736 	RETURN_FALSE;
1737 }
1738 /* }}} */
1739 #endif
1740 
1741 /* {{{ proto resource xmlwriter_open_uri(string source)
1742 Create new xmlwriter using source uri for output */
PHP_FUNCTION(xmlwriter_open_uri)1743 static PHP_FUNCTION(xmlwriter_open_uri)
1744 {
1745 	char *valid_file = NULL;
1746 	xmlwriter_object *intern;
1747 	xmlTextWriterPtr ptr;
1748 	char *source;
1749 	char resolved_path[MAXPATHLEN + 1];
1750 	int source_len;
1751 
1752 #ifdef ZEND_ENGINE_2
1753 	zval *this = getThis();
1754 	ze_xmlwriter_object *ze_obj = NULL;
1755 #endif
1756 
1757 #ifndef ZEND_ENGINE_2
1758 	xmlOutputBufferPtr out_buffer;
1759 	void *ioctx;
1760 #endif
1761 
1762 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &source, &source_len) == FAILURE) {
1763 		return;
1764 	}
1765 
1766 #ifdef ZEND_ENGINE_2
1767 	if (this) {
1768 		/* We do not use XMLWRITER_FROM_OBJECT, xmlwriter init function here */
1769 		ze_obj = (ze_xmlwriter_object*) zend_object_store_get_object(this TSRMLS_CC);
1770 	}
1771 #endif
1772 
1773 	if (source_len == 0) {
1774 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source");
1775 		RETURN_FALSE;
1776 	}
1777 
1778 	valid_file = _xmlwriter_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
1779 	if (!valid_file) {
1780 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to resolve file path");
1781 		RETURN_FALSE;
1782 	}
1783 
1784 	/* TODO: Fix either the PHP stream or libxml APIs: it can then detect when a given
1785 		 path is valid and not report out of memory error. Once it is done, remove the
1786 		 directory check in _xmlwriter_get_valid_file_path */
1787 #ifndef ZEND_ENGINE_2
1788 	ioctx = php_xmlwriter_streams_IO_open_write_wrapper(valid_file TSRMLS_CC);
1789 	if (ioctx == NULL) {
1790 		RETURN_FALSE;
1791 	}
1792 
1793 	out_buffer = xmlOutputBufferCreateIO(php_xmlwriter_streams_IO_write,
1794 		php_xmlwriter_streams_IO_close, ioctx, NULL);
1795 
1796 	if (out_buffer == NULL) {
1797 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create output buffer");
1798 		RETURN_FALSE;
1799 	}
1800 	ptr = xmlNewTextWriter(out_buffer);
1801 #else
1802 	ptr = xmlNewTextWriterFilename(valid_file, 0);
1803 #endif
1804 
1805 	if (!ptr) {
1806 		RETURN_FALSE;
1807 	}
1808 
1809 	intern = emalloc(sizeof(xmlwriter_object));
1810 	intern->ptr = ptr;
1811 	intern->output = NULL;
1812 #ifndef ZEND_ENGINE_2
1813 	intern->uri_output = out_buffer;
1814 #else
1815 	if (this) {
1816 		if (ze_obj->xmlwriter_ptr) {
1817 			xmlwriter_free_resource_ptr(ze_obj->xmlwriter_ptr TSRMLS_CC);
1818 		}
1819 		ze_obj->xmlwriter_ptr = intern;
1820 		RETURN_TRUE;
1821 	} else
1822 #endif
1823 	{
1824 		ZEND_REGISTER_RESOURCE(return_value,intern,le_xmlwriter);
1825 	}
1826 }
1827 /* }}} */
1828 
1829 /* {{{ proto resource xmlwriter_open_memory()
1830 Create new xmlwriter using memory for string output */
PHP_FUNCTION(xmlwriter_open_memory)1831 static PHP_FUNCTION(xmlwriter_open_memory)
1832 {
1833 	xmlwriter_object *intern;
1834 	xmlTextWriterPtr ptr;
1835 	xmlBufferPtr buffer;
1836 
1837 #ifdef ZEND_ENGINE_2
1838 	zval *this = getThis();
1839 	ze_xmlwriter_object *ze_obj = NULL;
1840 #endif
1841 
1842 #ifdef ZEND_ENGINE_2
1843 	if (this) {
1844 		/* We do not use XMLWRITER_FROM_OBJECT, xmlwriter init function here */
1845 		ze_obj = (ze_xmlwriter_object*) zend_object_store_get_object(this TSRMLS_CC);
1846 	}
1847 #endif
1848 
1849 	buffer = xmlBufferCreate();
1850 
1851 	if (buffer == NULL) {
1852 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create output buffer");
1853 		RETURN_FALSE;
1854 	}
1855 
1856 	ptr = xmlNewTextWriterMemory(buffer, 0);
1857 	if (! ptr) {
1858 		xmlBufferFree(buffer);
1859 		RETURN_FALSE;
1860 	}
1861 
1862 	intern = emalloc(sizeof(xmlwriter_object));
1863 	intern->ptr = ptr;
1864 	intern->output = buffer;
1865 #ifndef ZEND_ENGINE_2
1866 	intern->uri_output = NULL;
1867 #else
1868 	if (this) {
1869 		if (ze_obj->xmlwriter_ptr) {
1870 			xmlwriter_free_resource_ptr(ze_obj->xmlwriter_ptr TSRMLS_CC);
1871 		}
1872 		ze_obj->xmlwriter_ptr = intern;
1873 		RETURN_TRUE;
1874 	} else
1875 #endif
1876 	{
1877 		ZEND_REGISTER_RESOURCE(return_value,intern,le_xmlwriter);
1878 	}
1879 
1880 }
1881 /* }}} */
1882 
1883 /* {{{ php_xmlwriter_flush */
php_xmlwriter_flush(INTERNAL_FUNCTION_PARAMETERS,int force_string)1884 static void php_xmlwriter_flush(INTERNAL_FUNCTION_PARAMETERS, int force_string) {
1885 	zval *pind;
1886 	xmlwriter_object *intern;
1887 	xmlTextWriterPtr ptr;
1888 	xmlBufferPtr buffer;
1889 	zend_bool empty = 1;
1890 	int output_bytes;
1891 
1892 
1893 #ifdef ZEND_ENGINE_2
1894 	zval *this = getThis();
1895 
1896 	if (this) {
1897 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &empty) == FAILURE) {
1898 			return;
1899 		}
1900 		XMLWRITER_FROM_OBJECT(intern, this);
1901 	} else
1902 #endif
1903 	{
1904 		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &pind, &empty) == FAILURE) {
1905 			return;
1906 		}
1907 
1908 		ZEND_FETCH_RESOURCE(intern,xmlwriter_object *, &pind, -1, "XMLWriter", le_xmlwriter);
1909 	}
1910 	ptr = intern->ptr;
1911 
1912 	if (ptr) {
1913 		buffer = intern->output;
1914 		if (force_string == 1 && buffer == NULL) {
1915 			RETURN_EMPTY_STRING();
1916 		}
1917 		output_bytes = xmlTextWriterFlush(ptr);
1918 		if (buffer) {
1919 			RETVAL_STRING((char *) buffer->content, 1);
1920 			if (empty) {
1921 				xmlBufferEmpty(buffer);
1922 			}
1923 		} else {
1924 			RETVAL_LONG(output_bytes);
1925 		}
1926 		return;
1927 	}
1928 
1929 	RETURN_EMPTY_STRING();
1930 }
1931 /* }}} */
1932 
1933 /* {{{ proto string xmlwriter_output_memory(resource xmlwriter [,bool flush])
1934 Output current buffer as string */
PHP_FUNCTION(xmlwriter_output_memory)1935 static PHP_FUNCTION(xmlwriter_output_memory)
1936 {
1937 	php_xmlwriter_flush(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1938 }
1939 /* }}} */
1940 
1941 /* {{{ proto mixed xmlwriter_flush(resource xmlwriter [,bool empty])
1942 Output current buffer */
PHP_FUNCTION(xmlwriter_flush)1943 static PHP_FUNCTION(xmlwriter_flush)
1944 {
1945 	php_xmlwriter_flush(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1946 }
1947 /* }}} */
1948 
1949 /* {{{ PHP_MINIT_FUNCTION
1950  */
PHP_MINIT_FUNCTION(xmlwriter)1951 static PHP_MINIT_FUNCTION(xmlwriter)
1952 {
1953 #ifdef ZEND_ENGINE_2
1954 	zend_class_entry ce;
1955 #endif
1956 
1957 	le_xmlwriter = zend_register_list_destructors_ex(xmlwriter_dtor, NULL, "xmlwriter", module_number);
1958 
1959 #ifdef ZEND_ENGINE_2
1960 	memcpy(&xmlwriter_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1961 	xmlwriter_object_handlers.clone_obj      = NULL;
1962 	INIT_CLASS_ENTRY(ce, "XMLWriter", xmlwriter_class_functions);
1963 	ce.create_object = xmlwriter_object_new;
1964 	xmlwriter_class_entry_ce = zend_register_internal_class(&ce TSRMLS_CC);
1965 #endif
1966 	return SUCCESS;
1967 }
1968 /* }}} */
1969 
1970 /* {{{ PHP_MSHUTDOWN_FUNCTION
1971  */
PHP_MSHUTDOWN_FUNCTION(xmlwriter)1972 static PHP_MSHUTDOWN_FUNCTION(xmlwriter)
1973 {
1974 	return SUCCESS;
1975 }
1976 /* }}} */
1977 
1978 /* {{{ PHP_MINFO_FUNCTION
1979  */
PHP_MINFO_FUNCTION(xmlwriter)1980 static PHP_MINFO_FUNCTION(xmlwriter)
1981 {
1982 	php_info_print_table_start();
1983 	{
1984 		php_info_print_table_row(2, "XMLWriter", "enabled");
1985 	}
1986 	php_info_print_table_end();
1987 }
1988 /* }}} */
1989 
1990 /*
1991  * Local variables:
1992  * tab-width: 4
1993  * c-basic-offset: 4
1994  * End:
1995  * vim600: noet sw=4 ts=4 fdm=marker
1996  * vim<600: noet sw=4 ts=4
1997  */
1998