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