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