1/*
2  +----------------------------------------------------------------------+
3  | PHP Version 7                                                        |
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
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 [, int 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