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