1/*
2  +----------------------------------------------------------------------+
3  | PHP Version 7                                                        |
4  +----------------------------------------------------------------------+
5  | Copyright (c) 1997-2014 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 unitialized 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) + sizeof(zval) * (class_type->default_properties_count - 1));
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    "0.1",
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        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
713    }
714
715    if (err_string != NULL) {
716        XMLW_NAME_CHK(err_string);
717    }
718
719    ptr = intern->ptr;
720
721    if (ptr) {
722        retval = internal_function(ptr, (xmlChar *) name);
723        if (retval != -1) {
724            RETURN_TRUE;
725        }
726    }
727
728    RETURN_FALSE;
729}
730
731static void php_xmlwriter_end(INTERNAL_FUNCTION_PARAMETERS, xmlwriter_read_int_t internal_function)
732{
733    zval *pind;
734    xmlwriter_object *intern;
735    xmlTextWriterPtr ptr;
736    int retval;
737    zval *self = getThis();
738
739    if (self) {
740        XMLWRITER_FROM_OBJECT(intern, self);
741        if (zend_parse_parameters_none() == FAILURE) {
742            return;
743        }
744    } else {
745        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
746            return;
747        }
748        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
749    }
750
751    ptr = intern->ptr;
752
753    if (ptr) {
754        retval = internal_function(ptr);
755        if (retval != -1) {
756            RETURN_TRUE;
757        }
758    }
759
760    RETURN_FALSE;
761}
762
763#if LIBXML_VERSION >= 20605
764/* {{{ proto bool xmlwriter_set_indent(resource xmlwriter, bool indent)
765Toggle indentation on/off - returns FALSE on error */
766static PHP_FUNCTION(xmlwriter_set_indent)
767{
768    zval *pind;
769    xmlwriter_object *intern;
770    xmlTextWriterPtr ptr;
771    int retval;
772    zend_bool indent;
773
774    zval *self = getThis();
775
776    if (self) {
777        if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &indent) == FAILURE) {
778            return;
779        }
780        XMLWRITER_FROM_OBJECT(intern, self);
781    } else {
782        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &pind, &indent) == FAILURE) {
783            return;
784        }
785        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
786    }
787
788
789    ptr = intern->ptr;
790    if (ptr) {
791        retval = xmlTextWriterSetIndent(ptr, indent);
792        if (retval == 0) {
793            RETURN_TRUE;
794        }
795    }
796
797    RETURN_FALSE;
798}
799/* }}} */
800
801/* {{{ proto bool xmlwriter_set_indent_string(resource xmlwriter, string indentString)
802Set string used for indenting - returns FALSE on error */
803static PHP_FUNCTION(xmlwriter_set_indent_string)
804{
805    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterSetIndentString, NULL);
806}
807/* }}} */
808
809#endif
810
811/* {{{ proto bool xmlwriter_start_attribute(resource xmlwriter, string name)
812Create start attribute - returns FALSE on error */
813static PHP_FUNCTION(xmlwriter_start_attribute)
814{
815    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartAttribute, "Invalid Attribute Name");
816}
817/* }}} */
818
819/* {{{ proto bool xmlwriter_end_attribute(resource xmlwriter)
820End attribute - returns FALSE on error */
821static PHP_FUNCTION(xmlwriter_end_attribute)
822{
823    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndAttribute);
824}
825/* }}} */
826
827#if LIBXML_VERSION > 20617
828/* {{{ proto bool xmlwriter_start_attribute_ns(resource xmlwriter, string prefix, string name, string uri)
829Create start namespaced attribute - returns FALSE on error */
830static PHP_FUNCTION(xmlwriter_start_attribute_ns)
831{
832    zval *pind;
833    xmlwriter_object *intern;
834    xmlTextWriterPtr ptr;
835    char *name, *prefix, *uri;
836    size_t name_len, prefix_len, uri_len;
837    int retval;
838    zval *self = getThis();
839
840    if (self) {
841        if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss!",
842            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
843            return;
844        }
845        XMLWRITER_FROM_OBJECT(intern, self);
846    } else {
847        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsss!", &pind,
848            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
849            return;
850        }
851        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
852    }
853
854    XMLW_NAME_CHK("Invalid Attribute Name");
855
856    ptr = intern->ptr;
857
858    if (ptr) {
859        retval = xmlTextWriterStartAttributeNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
860        if (retval != -1) {
861            RETURN_TRUE;
862        }
863    }
864
865    RETURN_FALSE;
866}
867/* }}} */
868#endif
869
870/* {{{ proto bool xmlwriter_write_attribute(resource xmlwriter, string name, string content)
871Write full attribute - returns FALSE on error */
872static PHP_FUNCTION(xmlwriter_write_attribute)
873{
874    zval *pind;
875    xmlwriter_object *intern;
876    xmlTextWriterPtr ptr;
877    char *name, *content;
878    size_t name_len, content_len;
879    int retval;
880    zval *self = getThis();
881
882    if (self) {
883        if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
884            &name, &name_len, &content, &content_len) == FAILURE) {
885            return;
886        }
887        XMLWRITER_FROM_OBJECT(intern, self);
888    } else {
889        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pind,
890            &name, &name_len, &content, &content_len) == FAILURE) {
891            return;
892        }
893        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
894    }
895
896    XMLW_NAME_CHK("Invalid Attribute Name");
897
898    ptr = intern->ptr;
899
900    if (ptr) {
901        retval = xmlTextWriterWriteAttribute(ptr, (xmlChar *)name, (xmlChar *)content);
902        if (retval != -1) {
903            RETURN_TRUE;
904        }
905    }
906
907    RETURN_FALSE;
908}
909/* }}} */
910
911#if LIBXML_VERSION > 20617
912/* {{{ proto bool xmlwriter_write_attribute_ns(resource xmlwriter, string prefix, string name, string uri, string content)
913Write full namespaced attribute - returns FALSE on error */
914static PHP_FUNCTION(xmlwriter_write_attribute_ns)
915{
916    zval *pind;
917    xmlwriter_object *intern;
918    xmlTextWriterPtr ptr;
919    char *name, *prefix, *uri, *content;
920    size_t name_len, prefix_len, uri_len, content_len;
921    int retval;
922
923    zval *self = getThis();
924
925    if (self) {
926        if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss!s",
927            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
928            return;
929        }
930        XMLWRITER_FROM_OBJECT(intern, self);
931    } else {
932        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsss!s", &pind,
933            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
934            return;
935        }
936        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
937    }
938
939    XMLW_NAME_CHK("Invalid Attribute Name");
940
941    ptr = intern->ptr;
942
943    if (ptr) {
944        retval = xmlTextWriterWriteAttributeNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)content);
945        if (retval != -1) {
946            RETURN_TRUE;
947        }
948    }
949
950    RETURN_FALSE;
951}
952/* }}} */
953#endif
954
955/* {{{ proto bool xmlwriter_start_element(resource xmlwriter, string name)
956Create start element tag - returns FALSE on error */
957static PHP_FUNCTION(xmlwriter_start_element)
958{
959    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartElement, "Invalid Element Name");
960}
961/* }}} */
962
963/* {{{ proto bool xmlwriter_start_element_ns(resource xmlwriter, string prefix, string name, string uri)
964Create start namespaced element tag - returns FALSE on error */
965static PHP_FUNCTION(xmlwriter_start_element_ns)
966{
967    zval *pind;
968    xmlwriter_object *intern;
969    xmlTextWriterPtr ptr;
970    char *name, *prefix, *uri;
971    size_t name_len, prefix_len, uri_len;
972    int retval;
973    zval *self = getThis();
974
975    if (self) {
976        if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!ss!",
977            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
978            return;
979        }
980        XMLWRITER_FROM_OBJECT(intern, self);
981    } else {
982        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!ss!", &pind,
983            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
984            return;
985        }
986        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
987    }
988
989    XMLW_NAME_CHK("Invalid Element Name");
990
991    ptr = intern->ptr;
992
993    if (ptr) {
994        retval = xmlTextWriterStartElementNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
995        if (retval != -1) {
996            RETURN_TRUE;
997        }
998
999    }
1000
1001    RETURN_FALSE;
1002}
1003/* }}} */
1004
1005/* {{{ proto bool xmlwriter_end_element(resource xmlwriter)
1006End current element - returns FALSE on error */
1007static PHP_FUNCTION(xmlwriter_end_element)
1008{
1009    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndElement);
1010}
1011/* }}} */
1012
1013/* {{{ proto bool xmlwriter_full_end_element(resource xmlwriter)
1014End current element - returns FALSE on error */
1015static PHP_FUNCTION(xmlwriter_full_end_element)
1016{
1017    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterFullEndElement);
1018}
1019/* }}} */
1020
1021/* {{{ proto bool xmlwriter_write_element(resource xmlwriter, string name[, string content])
1022Write full element tag - returns FALSE on error */
1023static PHP_FUNCTION(xmlwriter_write_element)
1024{
1025    zval *pind;
1026    xmlwriter_object *intern;
1027    xmlTextWriterPtr ptr;
1028    char *name, *content = NULL;
1029    size_t name_len, content_len;
1030    int retval;
1031    zval *self = getThis();
1032
1033    if (self) {
1034        if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s!",
1035            &name, &name_len, &content, &content_len) == FAILURE) {
1036            return;
1037        }
1038        XMLWRITER_FROM_OBJECT(intern, self);
1039    } else {
1040        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|s!", &pind,
1041            &name, &name_len, &content, &content_len) == FAILURE) {
1042            return;
1043        }
1044        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1045    }
1046
1047    XMLW_NAME_CHK("Invalid Element Name");
1048
1049    ptr = intern->ptr;
1050
1051    if (ptr) {
1052        if (!content) {
1053            retval = xmlTextWriterStartElement(ptr, (xmlChar *)name);
1054            if (retval == -1) {
1055                RETURN_FALSE;
1056            }
1057            xmlTextWriterEndElement(ptr);
1058            if (retval == -1) {
1059                RETURN_FALSE;
1060            }
1061        } else {
1062            retval = xmlTextWriterWriteElement(ptr, (xmlChar *)name, (xmlChar *)content);
1063        }
1064        if (retval != -1) {
1065            RETURN_TRUE;
1066        }
1067    }
1068
1069    RETURN_FALSE;
1070}
1071/* }}} */
1072
1073/* {{{ proto bool xmlwriter_write_element_ns(resource xmlwriter, string prefix, string name, string uri[, string content])
1074Write full namesapced element tag - returns FALSE on error */
1075static PHP_FUNCTION(xmlwriter_write_element_ns)
1076{
1077    zval *pind;
1078    xmlwriter_object *intern;
1079    xmlTextWriterPtr ptr;
1080    char *name, *prefix, *uri, *content = NULL;
1081    size_t name_len, prefix_len, uri_len, content_len;
1082    int retval;
1083    zval *self = getThis();
1084
1085    if (self) {
1086        if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!ss!|s!",
1087            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
1088            return;
1089        }
1090        XMLWRITER_FROM_OBJECT(intern, self);
1091    } else {
1092        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs!ss!|s!", &pind,
1093            &prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
1094            return;
1095        }
1096        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1097    }
1098
1099    XMLW_NAME_CHK("Invalid Element Name");
1100
1101    ptr = intern->ptr;
1102
1103    if (ptr) {
1104        if (!content) {
1105            retval = xmlTextWriterStartElementNS(ptr,(xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
1106            if (retval == -1) {
1107                RETURN_FALSE;
1108            }
1109            retval = xmlTextWriterEndElement(ptr);
1110            if (retval == -1) {
1111                RETURN_FALSE;
1112            }
1113        } else {
1114            retval = xmlTextWriterWriteElementNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)content);
1115        }
1116        if (retval != -1) {
1117            RETURN_TRUE;
1118        }
1119    }
1120
1121    RETURN_FALSE;
1122}
1123/* }}} */
1124
1125/* {{{ proto bool xmlwriter_start_pi(resource xmlwriter, string target)
1126Create start PI tag - returns FALSE on error */
1127static PHP_FUNCTION(xmlwriter_start_pi)
1128{
1129    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartPI, "Invalid PI Target");
1130}
1131/* }}} */
1132
1133/* {{{ proto bool xmlwriter_end_pi(resource xmlwriter)
1134End current PI - returns FALSE on error */
1135static PHP_FUNCTION(xmlwriter_end_pi)
1136{
1137    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndPI);
1138}
1139/* }}} */
1140
1141/* {{{ proto bool xmlwriter_write_pi(resource xmlwriter, string target, string content)
1142Write full PI tag - returns FALSE on error */
1143static PHP_FUNCTION(xmlwriter_write_pi)
1144{
1145    zval *pind;
1146    xmlwriter_object *intern;
1147    xmlTextWriterPtr ptr;
1148    char *name, *content;
1149    size_t name_len, content_len;
1150    int retval;
1151
1152    zval *self = getThis();
1153
1154    if (self) {
1155        if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
1156            &name, &name_len, &content, &content_len) == FAILURE) {
1157            return;
1158        }
1159        XMLWRITER_FROM_OBJECT(intern, self);
1160    } else {
1161        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pind,
1162            &name, &name_len, &content, &content_len) == FAILURE) {
1163            return;
1164        }
1165        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1166    }
1167
1168    XMLW_NAME_CHK("Invalid PI Target");
1169
1170    ptr = intern->ptr;
1171
1172    if (ptr) {
1173        retval = xmlTextWriterWritePI(ptr, (xmlChar *)name, (xmlChar *)content);
1174        if (retval != -1) {
1175            RETURN_TRUE;
1176        }
1177    }
1178
1179    RETURN_FALSE;
1180}
1181/* }}} */
1182
1183/* {{{ proto bool xmlwriter_start_cdata(resource xmlwriter)
1184Create start CDATA tag - returns FALSE on error */
1185static PHP_FUNCTION(xmlwriter_start_cdata)
1186{
1187    zval *pind;
1188    xmlwriter_object *intern;
1189    xmlTextWriterPtr ptr;
1190    int retval;
1191    zval *self = getThis();
1192
1193    if (self) {
1194        XMLWRITER_FROM_OBJECT(intern, self);
1195    } else {
1196        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
1197            return;
1198        }
1199        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1200    }
1201
1202    ptr = intern->ptr;
1203
1204    if (ptr) {
1205        retval = xmlTextWriterStartCDATA(ptr);
1206        if (retval != -1) {
1207            RETURN_TRUE;
1208        }
1209    }
1210
1211    RETURN_FALSE;
1212}
1213/* }}} */
1214
1215/* {{{ proto bool xmlwriter_end_cdata(resource xmlwriter)
1216End current CDATA - returns FALSE on error */
1217static PHP_FUNCTION(xmlwriter_end_cdata)
1218{
1219    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndCDATA);
1220}
1221/* }}} */
1222
1223/* {{{ proto bool xmlwriter_write_cdata(resource xmlwriter, string content)
1224Write full CDATA tag - returns FALSE on error */
1225static PHP_FUNCTION(xmlwriter_write_cdata)
1226{
1227    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteCDATA, NULL);
1228}
1229/* }}} */
1230
1231/* {{{ proto bool xmlwriter_write_raw(resource xmlwriter, string content)
1232Write text - returns FALSE on error */
1233static PHP_FUNCTION(xmlwriter_write_raw)
1234{
1235    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteRaw, NULL);
1236}
1237/* }}} */
1238
1239/* {{{ proto bool xmlwriter_text(resource xmlwriter, string content)
1240Write text - returns FALSE on error */
1241static PHP_FUNCTION(xmlwriter_text)
1242{
1243    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteString, NULL);
1244}
1245/* }}} */
1246
1247#if LIBXML_VERSION >= 20607
1248/* {{{ proto bool xmlwriter_start_comment(resource xmlwriter)
1249Create start comment - returns FALSE on error */
1250static PHP_FUNCTION(xmlwriter_start_comment)
1251{
1252    zval *pind;
1253    xmlwriter_object *intern;
1254    xmlTextWriterPtr ptr;
1255    int retval;
1256    zval *self = getThis();
1257
1258    if (self) {
1259        XMLWRITER_FROM_OBJECT(intern, self);
1260    } else {
1261        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &pind) == FAILURE) {
1262            return;
1263        }
1264        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1265    }
1266
1267    ptr = intern->ptr;
1268
1269    if (ptr) {
1270        retval = xmlTextWriterStartComment(ptr);
1271        if (retval != -1) {
1272            RETURN_TRUE;
1273        }
1274    }
1275
1276    RETURN_FALSE;
1277}
1278/* }}} */
1279
1280/* {{{ proto bool xmlwriter_end_comment(resource xmlwriter)
1281Create end comment - returns FALSE on error */
1282static PHP_FUNCTION(xmlwriter_end_comment)
1283{
1284    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndComment);
1285}
1286/* }}} */
1287#endif  /* LIBXML_VERSION >= 20607 */
1288
1289
1290/* {{{ proto bool xmlwriter_write_comment(resource xmlwriter, string content)
1291Write full comment tag - returns FALSE on error */
1292static PHP_FUNCTION(xmlwriter_write_comment)
1293{
1294    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteComment, NULL);
1295}
1296/* }}} */
1297
1298/* {{{ proto bool xmlwriter_start_document(resource xmlwriter, string version, string encoding, string standalone)
1299Create document tag - returns FALSE on error */
1300static PHP_FUNCTION(xmlwriter_start_document)
1301{
1302    zval *pind;
1303    xmlwriter_object *intern;
1304    xmlTextWriterPtr ptr;
1305    char *version = NULL, *enc = NULL, *alone = NULL;
1306    size_t version_len, enc_len, alone_len;
1307    int retval;
1308
1309    zval *self = getThis();
1310
1311    if (self) {
1312        if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!s!s!", &version, &version_len, &enc, &enc_len, &alone, &alone_len) == FAILURE) {
1313            return;
1314        }
1315        XMLWRITER_FROM_OBJECT(intern, self);
1316    } else {
1317        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|s!s!s!", &pind, &version, &version_len, &enc, &enc_len, &alone, &alone_len) == FAILURE) {
1318            return;
1319        }
1320        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1321    }
1322
1323    ptr = intern->ptr;
1324
1325    if (ptr) {
1326        retval = xmlTextWriterStartDocument(ptr, version, enc, alone);
1327        if (retval != -1) {
1328            RETURN_TRUE;
1329        }
1330    }
1331
1332    RETURN_FALSE;
1333}
1334/* }}} */
1335
1336/* {{{ proto bool xmlwriter_end_document(resource xmlwriter)
1337End current document - returns FALSE on error */
1338static PHP_FUNCTION(xmlwriter_end_document)
1339{
1340    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDocument);
1341}
1342/* }}} */
1343
1344/* {{{ proto bool xmlwriter_start_dtd(resource xmlwriter, string name, string pubid, string sysid)
1345Create start DTD tag - returns FALSE on error */
1346static PHP_FUNCTION(xmlwriter_start_dtd)
1347{
1348    zval *pind;
1349    xmlwriter_object *intern;
1350    xmlTextWriterPtr ptr;
1351    char *name, *pubid = NULL, *sysid = NULL;
1352    size_t name_len, pubid_len, sysid_len;
1353    int retval;
1354    zval *self = getThis();
1355
1356    if (self) {
1357        if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s!s!", &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len) == FAILURE) {
1358            return;
1359        }
1360
1361        XMLWRITER_FROM_OBJECT(intern, self);
1362    } else {
1363        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|s!s!", &pind, &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len) == FAILURE) {
1364            return;
1365        }
1366
1367        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1368    }
1369    ptr = intern->ptr;
1370
1371    if (ptr) {
1372        retval = xmlTextWriterStartDTD(ptr, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid);
1373        if (retval != -1) {
1374            RETURN_TRUE;
1375        }
1376    }
1377
1378    RETURN_FALSE;
1379}
1380/* }}} */
1381
1382/* {{{ proto bool xmlwriter_end_dtd(resource xmlwriter)
1383End current DTD - returns FALSE on error */
1384static PHP_FUNCTION(xmlwriter_end_dtd)
1385{
1386    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTD);
1387}
1388/* }}} */
1389
1390/* {{{ proto bool xmlwriter_write_dtd(resource xmlwriter, string name, string pubid, string sysid, string subset)
1391Write full DTD tag - returns FALSE on error */
1392static PHP_FUNCTION(xmlwriter_write_dtd)
1393{
1394    zval *pind;
1395    xmlwriter_object *intern;
1396    xmlTextWriterPtr ptr;
1397    char *name, *pubid = NULL, *sysid = NULL, *subset = NULL;
1398    size_t name_len, pubid_len, sysid_len, subset_len;
1399    int retval;
1400    zval *self = getThis();
1401
1402    if (self) {
1403        if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|s!s!s!", &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len, &subset, &subset_len) == FAILURE) {
1404            return;
1405        }
1406
1407        XMLWRITER_FROM_OBJECT(intern, self);
1408    } else {
1409        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) {
1410            return;
1411        }
1412
1413        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1414    }
1415
1416    ptr = intern->ptr;
1417
1418    if (ptr) {
1419        retval = xmlTextWriterWriteDTD(ptr, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid, (xmlChar *)subset);
1420        if (retval != -1) {
1421            RETURN_TRUE;
1422        }
1423    }
1424
1425    RETURN_FALSE;
1426}
1427/* }}} */
1428
1429/* {{{ proto bool xmlwriter_start_dtd_element(resource xmlwriter, string name)
1430Create start DTD element - returns FALSE on error */
1431static PHP_FUNCTION(xmlwriter_start_dtd_element)
1432{
1433    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartDTDElement, "Invalid Element Name");
1434}
1435/* }}} */
1436
1437/* {{{ proto bool xmlwriter_end_dtd_element(resource xmlwriter)
1438End current DTD element - returns FALSE on error */
1439static PHP_FUNCTION(xmlwriter_end_dtd_element)
1440{
1441    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDElement);
1442}
1443/* }}} */
1444
1445/* {{{ proto bool xmlwriter_write_dtd_element(resource xmlwriter, string name, string content)
1446Write full DTD element tag - returns FALSE on error */
1447static PHP_FUNCTION(xmlwriter_write_dtd_element)
1448{
1449    zval *pind;
1450    xmlwriter_object *intern;
1451    xmlTextWriterPtr ptr;
1452    char *name, *content;
1453    size_t name_len, content_len;
1454    int retval;
1455    zval *self = getThis();
1456
1457    if (self) {
1458        if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &content, &content_len) == FAILURE) {
1459            return;
1460        }
1461        XMLWRITER_FROM_OBJECT(intern, self);
1462    } else {
1463        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pind,
1464            &name, &name_len, &content, &content_len) == FAILURE) {
1465            return;
1466        }
1467        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1468    }
1469
1470    XMLW_NAME_CHK("Invalid Element Name");
1471
1472    ptr = intern->ptr;
1473
1474    if (ptr) {
1475        retval = xmlTextWriterWriteDTDElement(ptr, (xmlChar *)name, (xmlChar *)content);
1476        if (retval != -1) {
1477            RETURN_TRUE;
1478        }
1479    }
1480
1481    RETURN_FALSE;
1482}
1483/* }}} */
1484
1485#if LIBXML_VERSION > 20608
1486/* {{{ proto bool xmlwriter_start_dtd_attlist(resource xmlwriter, string name)
1487Create start DTD AttList - returns FALSE on error */
1488static PHP_FUNCTION(xmlwriter_start_dtd_attlist)
1489{
1490    php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartDTDAttlist, "Invalid Element Name");
1491}
1492/* }}} */
1493
1494/* {{{ proto bool xmlwriter_end_dtd_attlist(resource xmlwriter)
1495End current DTD AttList - returns FALSE on error */
1496static PHP_FUNCTION(xmlwriter_end_dtd_attlist)
1497{
1498    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDAttlist);
1499}
1500/* }}} */
1501
1502/* {{{ proto bool xmlwriter_write_dtd_attlist(resource xmlwriter, string name, string content)
1503Write full DTD AttList tag - returns FALSE on error */
1504static PHP_FUNCTION(xmlwriter_write_dtd_attlist)
1505{
1506    zval *pind;
1507    xmlwriter_object *intern;
1508    xmlTextWriterPtr ptr;
1509    char *name, *content;
1510    size_t name_len, content_len;
1511    int retval;
1512    zval *self = getThis();
1513
1514    if (self) {
1515        if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss",
1516            &name, &name_len, &content, &content_len) == FAILURE) {
1517            return;
1518        }
1519        XMLWRITER_FROM_OBJECT(intern, self);
1520    } else {
1521        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss", &pind,
1522            &name, &name_len, &content, &content_len) == FAILURE) {
1523            return;
1524        }
1525        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1526    }
1527
1528    XMLW_NAME_CHK("Invalid Element Name");
1529
1530    ptr = intern->ptr;
1531
1532    if (ptr) {
1533        retval = xmlTextWriterWriteDTDAttlist(ptr, (xmlChar *)name, (xmlChar *)content);
1534        if (retval != -1) {
1535            RETURN_TRUE;
1536        }
1537    }
1538
1539    RETURN_FALSE;
1540}
1541/* }}} */
1542
1543/* {{{ proto bool xmlwriter_start_dtd_entity(resource xmlwriter, string name, bool isparam)
1544Create start DTD Entity - returns FALSE on error */
1545static PHP_FUNCTION(xmlwriter_start_dtd_entity)
1546{
1547    zval *pind;
1548    xmlwriter_object *intern;
1549    xmlTextWriterPtr ptr;
1550    char *name;
1551    size_t name_len, retval;
1552    zend_bool isparm;
1553    zval *self = getThis();
1554
1555    if (self) {
1556        if (zend_parse_parameters(ZEND_NUM_ARGS(), "sb", &name, &name_len, &isparm) == FAILURE) {
1557            return;
1558        }
1559        XMLWRITER_FROM_OBJECT(intern, self);
1560    } else {
1561        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsb", &pind, &name, &name_len, &isparm) == FAILURE) {
1562            return;
1563        }
1564        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1565    }
1566
1567    XMLW_NAME_CHK("Invalid Attribute Name");
1568
1569    ptr = intern->ptr;
1570
1571    if (ptr) {
1572        retval = xmlTextWriterStartDTDEntity(ptr, isparm, (xmlChar *)name);
1573        if (retval != -1) {
1574            RETURN_TRUE;
1575        }
1576    }
1577
1578    RETURN_FALSE;
1579}
1580/* }}} */
1581
1582/* {{{ proto bool xmlwriter_end_dtd_entity(resource xmlwriter)
1583End current DTD Entity - returns FALSE on error */
1584static PHP_FUNCTION(xmlwriter_end_dtd_entity)
1585{
1586    php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDEntity);
1587}
1588/* }}} */
1589
1590/* {{{ proto bool xmlwriter_write_dtd_entity(resource xmlwriter, string name, string content [, int pe [, string pubid [, string sysid [, string ndataid]]]])
1591Write full DTD Entity tag - returns FALSE on error */
1592static PHP_FUNCTION(xmlwriter_write_dtd_entity)
1593{
1594    zval *pind;
1595    xmlwriter_object *intern;
1596    xmlTextWriterPtr ptr;
1597    char *name, *content;
1598    size_t name_len, content_len;
1599    int retval;
1600    /* Optional parameters */
1601    char *pubid = NULL, *sysid = NULL, *ndataid = NULL;
1602    zend_bool pe = 0;
1603    size_t pubid_len, sysid_len, ndataid_len;
1604    zval *self = getThis();
1605
1606    if (self) {
1607        if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|bsss",
1608            &name, &name_len, &content, &content_len, &pe, &pubid, &pubid_len,
1609            &sysid, &sysid_len, &ndataid, &ndataid_len) == FAILURE) {
1610            return;
1611        }
1612        XMLWRITER_FROM_OBJECT(intern, self);
1613    } else {
1614        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rss|bsss", &pind,
1615            &name, &name_len, &content, &content_len, &pe, &pubid, &pubid_len,
1616            &sysid, &sysid_len, &ndataid, &ndataid_len) == FAILURE) {
1617            return;
1618        }
1619        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1620    }
1621
1622    XMLW_NAME_CHK("Invalid Element Name");
1623
1624    ptr = intern->ptr;
1625
1626    if (ptr) {
1627        retval = xmlTextWriterWriteDTDEntity(ptr, pe, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid, (xmlChar *)ndataid, (xmlChar *)content);
1628        if (retval != -1) {
1629            RETURN_TRUE;
1630        }
1631    }
1632
1633    RETURN_FALSE;
1634}
1635/* }}} */
1636#endif
1637
1638/* {{{ proto resource xmlwriter_open_uri(resource xmlwriter, string source)
1639Create new xmlwriter using source uri for output */
1640static PHP_FUNCTION(xmlwriter_open_uri)
1641{
1642    char *valid_file = NULL;
1643    xmlwriter_object *intern;
1644    xmlTextWriterPtr ptr;
1645    char *source;
1646    char resolved_path[MAXPATHLEN + 1];
1647    size_t source_len;
1648    zval *self = getThis();
1649    ze_xmlwriter_object *ze_obj = NULL;
1650
1651    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &source, &source_len) == FAILURE) {
1652        return;
1653    }
1654
1655    if (self) {
1656        /* We do not use XMLWRITER_FROM_OBJECT, xmlwriter init function here */
1657        ze_obj = Z_XMLWRITER_P(self);
1658    }
1659
1660    if (source_len == 0) {
1661        php_error_docref(NULL, E_WARNING, "Empty string as source");
1662        RETURN_FALSE;
1663    }
1664
1665    valid_file = _xmlwriter_get_valid_file_path(source, resolved_path, MAXPATHLEN);
1666    if (!valid_file) {
1667        php_error_docref(NULL, E_WARNING, "Unable to resolve file path");
1668        RETURN_FALSE;
1669    }
1670
1671    ptr = xmlNewTextWriterFilename(valid_file, 0);
1672
1673    if (!ptr) {
1674        RETURN_FALSE;
1675    }
1676
1677    intern = emalloc(sizeof(xmlwriter_object));
1678    intern->ptr = ptr;
1679    intern->output = NULL;
1680    if (self) {
1681        if (ze_obj->xmlwriter_ptr) {
1682            xmlwriter_free_resource_ptr(ze_obj->xmlwriter_ptr);
1683        }
1684        ze_obj->xmlwriter_ptr = intern;
1685        RETURN_TRUE;
1686    } else {
1687        ZEND_REGISTER_RESOURCE(return_value,intern,le_xmlwriter);
1688    }
1689}
1690/* }}} */
1691
1692/* {{{ proto resource xmlwriter_open_memory()
1693Create new xmlwriter using memory for string output */
1694static PHP_FUNCTION(xmlwriter_open_memory)
1695{
1696    xmlwriter_object *intern;
1697    xmlTextWriterPtr ptr;
1698    xmlBufferPtr buffer;
1699    zval *self = getThis();
1700    ze_xmlwriter_object *ze_obj = NULL;
1701
1702    if (self) {
1703        /* We do not use XMLWRITER_FROM_OBJECT, xmlwriter init function here */
1704        ze_obj = Z_XMLWRITER_P(self);
1705    }
1706
1707    buffer = xmlBufferCreate();
1708
1709    if (buffer == NULL) {
1710        php_error_docref(NULL, E_WARNING, "Unable to create output buffer");
1711        RETURN_FALSE;
1712    }
1713
1714    ptr = xmlNewTextWriterMemory(buffer, 0);
1715    if (! ptr) {
1716        xmlBufferFree(buffer);
1717        RETURN_FALSE;
1718    }
1719
1720    intern = emalloc(sizeof(xmlwriter_object));
1721    intern->ptr = ptr;
1722    intern->output = buffer;
1723    if (self) {
1724        if (ze_obj->xmlwriter_ptr) {
1725            xmlwriter_free_resource_ptr(ze_obj->xmlwriter_ptr);
1726        }
1727        ze_obj->xmlwriter_ptr = intern;
1728        RETURN_TRUE;
1729    } else {
1730        ZEND_REGISTER_RESOURCE(return_value,intern,le_xmlwriter);
1731    }
1732
1733}
1734/* }}} */
1735
1736/* {{{ php_xmlwriter_flush */
1737static void php_xmlwriter_flush(INTERNAL_FUNCTION_PARAMETERS, int force_string) {
1738    zval *pind;
1739    xmlwriter_object *intern;
1740    xmlTextWriterPtr ptr;
1741    xmlBufferPtr buffer;
1742    zend_bool empty = 1;
1743    int output_bytes;
1744    zval *self = getThis();
1745
1746    if (self) {
1747        if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &empty) == FAILURE) {
1748            return;
1749        }
1750        XMLWRITER_FROM_OBJECT(intern, self);
1751    } else {
1752        if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &pind, &empty) == FAILURE) {
1753            return;
1754        }
1755
1756        ZEND_FETCH_RESOURCE(intern, xmlwriter_object *, pind, -1, "XMLWriter", le_xmlwriter);
1757    }
1758    ptr = intern->ptr;
1759
1760    if (ptr) {
1761        buffer = intern->output;
1762        if (force_string == 1 && buffer == NULL) {
1763            RETURN_EMPTY_STRING();
1764        }
1765        output_bytes = xmlTextWriterFlush(ptr);
1766        if (buffer) {
1767            RETVAL_STRING((char *) buffer->content);
1768            if (empty) {
1769                xmlBufferEmpty(buffer);
1770            }
1771        } else {
1772            RETVAL_LONG(output_bytes);
1773        }
1774        return;
1775    }
1776
1777    RETURN_EMPTY_STRING();
1778}
1779/* }}} */
1780
1781/* {{{ proto string xmlwriter_output_memory(resource xmlwriter [,bool flush])
1782Output current buffer as string */
1783static PHP_FUNCTION(xmlwriter_output_memory)
1784{
1785    php_xmlwriter_flush(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
1786}
1787/* }}} */
1788
1789/* {{{ proto mixed xmlwriter_flush(resource xmlwriter [,bool empty])
1790Output current buffer */
1791static PHP_FUNCTION(xmlwriter_flush)
1792{
1793    php_xmlwriter_flush(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1794}
1795/* }}} */
1796
1797/* {{{ PHP_MINIT_FUNCTION
1798 */
1799static PHP_MINIT_FUNCTION(xmlwriter)
1800{
1801    zend_class_entry ce;
1802    le_xmlwriter = zend_register_list_destructors_ex(xmlwriter_dtor, NULL, "xmlwriter", module_number);
1803
1804    memcpy(&xmlwriter_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1805    xmlwriter_object_handlers.offset = XtOffsetOf(ze_xmlwriter_object, std);
1806    xmlwriter_object_handlers.free_obj = xmlwriter_object_free_storage;
1807    xmlwriter_object_handlers.clone_obj = NULL;
1808    INIT_CLASS_ENTRY(ce, "XMLWriter", xmlwriter_class_functions);
1809    ce.create_object = xmlwriter_object_new;
1810    xmlwriter_class_entry_ce = zend_register_internal_class(&ce);
1811
1812    return SUCCESS;
1813}
1814/* }}} */
1815
1816/* {{{ PHP_MSHUTDOWN_FUNCTION
1817 */
1818static PHP_MSHUTDOWN_FUNCTION(xmlwriter)
1819{
1820    return SUCCESS;
1821}
1822/* }}} */
1823
1824/* {{{ PHP_MINFO_FUNCTION
1825 */
1826static PHP_MINFO_FUNCTION(xmlwriter)
1827{
1828    php_info_print_table_start();
1829    {
1830        php_info_print_table_row(2, "XMLWriter", "enabled");
1831    }
1832    php_info_print_table_end();
1833}
1834/* }}} */
1835
1836/*
1837 * Local variables:
1838 * tab-width: 4
1839 * c-basic-offset: 4
1840 * End:
1841 * vim600: noet sw=4 ts=4 fdm=marker
1842 * vim<600: noet sw=4 ts=4
1843 */
1844