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