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