php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
php_xmlwriter.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Rob Richards <rrichards@php.net> |
14 | Pierre-A. Joye <pajoye@php.net> |
15 +----------------------------------------------------------------------+
16*/
17
18#ifdef HAVE_CONFIG_H
19#include <config.h>
20#endif
21
22
23#include "php.h"
24#include "ext/standard/info.h"
25#include "php_xmlwriter.h"
27
28static zend_class_entry *xmlwriter_class_entry_ce;
29
30typedef int (*xmlwriter_read_one_char_t)(xmlTextWriterPtr writer, const xmlChar *content);
31typedef int (*xmlwriter_read_int_t)(xmlTextWriterPtr writer);
32
33/* {{{ XMLWRITER_FROM_OBJECT */
34#define XMLWRITER_FROM_OBJECT(ptr, object) \
35 { \
36 ze_xmlwriter_object *obj = Z_XMLWRITER_P(object); \
37 ptr = obj->ptr; \
38 if (!ptr) { \
39 zend_throw_error(NULL, "Invalid or uninitialized XMLWriter object"); \
40 RETURN_THROWS(); \
41 } \
42 }
43/* }}} */
44
45static zend_object_handlers xmlwriter_object_handlers;
46
47static zend_always_inline void xmlwriter_destroy_libxml_objects(ze_xmlwriter_object *intern)
48{
49 if (intern->ptr) {
50 xmlFreeTextWriter(intern->ptr);
51 intern->ptr = NULL;
52 }
53 if (intern->output) {
54 xmlBufferFree(intern->output);
55 intern->output = NULL;
56 }
57}
58
59/* {{{{ xmlwriter_object_dtor */
60static void xmlwriter_object_dtor(zend_object *object)
61{
62 ze_xmlwriter_object *intern = php_xmlwriter_fetch_object(object);
63
64 /* freeing the resource here may leak, but otherwise we may use it after it has been freed */
65 xmlwriter_destroy_libxml_objects(intern);
67}
68/* }}} */
69
70/* {{{ xmlwriter_object_free_storage */
71static void xmlwriter_object_free_storage(zend_object *object)
72{
73 ze_xmlwriter_object *intern = php_xmlwriter_fetch_object(object);
74
75 zend_object_std_dtor(&intern->std);
76}
77/* }}} */
78
79
80/* {{{ xmlwriter_object_new */
81static zend_object *xmlwriter_object_new(zend_class_entry *class_type)
82{
83 ze_xmlwriter_object *intern;
84
85 intern = zend_object_alloc(sizeof(ze_xmlwriter_object), class_type);
86 zend_object_std_init(&intern->std, class_type);
87 object_properties_init(&intern->std, class_type);
88
89 return &intern->std;
90}
91/* }}} */
92
93#define XMLW_NAME_CHK(__arg_no, __subject) \
94 if (xmlValidateName((xmlChar *) name, 0) != 0) { \
95 zend_argument_value_error(__arg_no, "must be a valid %s, \"%s\" given", __subject, name); \
96 RETURN_THROWS(); \
97 } \
98
99/* {{{ function prototypes */
100static PHP_MINIT_FUNCTION(xmlwriter);
101static PHP_MSHUTDOWN_FUNCTION(xmlwriter);
102static PHP_MINFO_FUNCTION(xmlwriter);
103/* }}} */
104
105/* _xmlwriter_get_valid_file_path should be made a
106 common function in libxml extension as code is common to a few xml extensions */
107/* {{{ _xmlwriter_get_valid_file_path */
108static char *_xmlwriter_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len ) {
109 xmlURI *uri;
110 xmlChar *escsource;
111 char *file_dest;
112 int isFileUri = 0;
113
114 uri = xmlCreateURI();
115 if (uri == NULL) {
116 return NULL;
117 }
118 escsource = xmlURIEscapeStr((xmlChar *)source, (xmlChar *) ":");
119 xmlParseURIReference(uri, (char *)escsource);
120 xmlFree(escsource);
121
122 if (uri->scheme != NULL) {
123 /* absolute file uris - libxml only supports localhost or empty host */
124 if (strncasecmp(source, "file:///", 8) == 0) {
125 if (source[sizeof("file:///") - 1] == '\0') {
126 xmlFreeURI(uri);
127 return NULL;
128 }
129 isFileUri = 1;
130#ifdef PHP_WIN32
131 source += 8;
132#else
133 source += 7;
134#endif
135 } else if (strncasecmp(source, "file://localhost/",17) == 0) {
136 if (source[sizeof("file://localhost/") - 1] == '\0') {
137 xmlFreeURI(uri);
138 return NULL;
139 }
140
141 isFileUri = 1;
142#ifdef PHP_WIN32
143 source += 17;
144#else
145 source += 16;
146#endif
147 }
148 }
149
150 if ((uri->scheme == NULL || isFileUri)) {
151 char file_dirname[MAXPATHLEN];
152 size_t dir_len;
153
154 if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path)) {
155 xmlFreeURI(uri);
156 return NULL;
157 }
158
159 memcpy(file_dirname, source, strlen(source));
160 dir_len = zend_dirname(file_dirname, strlen(source));
161
162 if (dir_len > 0) {
163 zend_stat_t buf = {0};
164 if (php_sys_stat(file_dirname, &buf) != 0) {
165 xmlFreeURI(uri);
166 return NULL;
167 }
168 }
169
170 file_dest = resolved_path;
171 } else {
172 file_dest = source;
173 }
174
175 xmlFreeURI(uri);
176
177 return file_dest;
178}
179/* }}} */
180
181static void xml_writer_create_static(INTERNAL_FUNCTION_PARAMETERS, xmlTextWriterPtr writer, xmlBufferPtr output)
182{
185 intern->ptr = writer;
186 intern->output = output;
187 } else {
188 xmlBufferFree(output);
189 xmlFreeTextWriter(writer);
190 }
191}
192
193static const zend_module_dep xmlwriter_deps[] = {
194 ZEND_MOD_REQUIRED("libxml")
196};
197
198/* {{{ xmlwriter_module_entry */
201 xmlwriter_deps,
202 "xmlwriter",
203 ext_functions,
204 PHP_MINIT(xmlwriter),
205 PHP_MSHUTDOWN(xmlwriter),
206 NULL,
207 NULL,
208 PHP_MINFO(xmlwriter),
211};
212/* }}} */
213
214#ifdef COMPILE_DL_XMLWRITER
215ZEND_GET_MODULE(xmlwriter)
216#endif
217
218/* {{{ xmlwriter_objects_clone
219static void xmlwriter_objects_clone(void *object, void **object_clone)
220{
221 TODO
222}
223}}} */
224
225static void php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAMETERS, xmlwriter_read_one_char_t internal_function, char *subject_name)
226{
227 xmlTextWriterPtr ptr;
228 char *name;
229 size_t name_len;
230 int retval;
231 zval *self;
232
233 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &self, xmlwriter_class_entry_ce, &name, &name_len) == FAILURE) {
235 }
237
238 if (subject_name != NULL) {
239 XMLW_NAME_CHK(2, subject_name);
240 }
241
242 retval = internal_function(ptr, (xmlChar *) name);
243
244 RETURN_BOOL(retval != -1);
245}
246
247static void php_xmlwriter_end(INTERNAL_FUNCTION_PARAMETERS, xmlwriter_read_int_t internal_function)
248{
249 xmlTextWriterPtr ptr;
250 int retval;
251 zval *self;
252
253 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &self, xmlwriter_class_entry_ce) == FAILURE) {
255 }
257
258 retval = internal_function(ptr);
259
260 RETURN_BOOL(retval != -1);
261}
262
263/* {{{ Toggle indentation on/off - returns FALSE on error */
265{
266 xmlTextWriterPtr ptr;
267 int retval;
268 bool indent;
269 zval *self;
270
271 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ob", &self, xmlwriter_class_entry_ce, &indent) == FAILURE) {
273 }
275
276 retval = xmlTextWriterSetIndent(ptr, indent);
277
278 RETURN_BOOL(retval == 0);
279}
280/* }}} */
281
282/* {{{ Set string used for indenting - returns FALSE on error */
284{
285 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterSetIndentString, NULL);
286}
287/* }}} */
288
289/* {{{ Create start attribute - returns FALSE on error */
291{
292 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartAttribute, "attribute name");
293}
294/* }}} */
295
296/* {{{ End attribute - returns FALSE on error */
298{
299 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndAttribute);
300}
301/* }}} */
302
303/* {{{ Create start namespaced attribute - returns FALSE on error */
305{
306 xmlTextWriterPtr ptr;
307 char *name, *prefix, *uri;
308 size_t name_len, prefix_len, uri_len;
309 int retval;
310 zval *self;
311
312 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!ss!", &self, xmlwriter_class_entry_ce,
313 &prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
315 }
317
318 XMLW_NAME_CHK(3, "attribute name");
319
320 retval = xmlTextWriterStartAttributeNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
321
322 RETURN_BOOL(retval != -1);
323}
324/* }}} */
325
326/* {{{ Write full attribute - returns FALSE on error */
328{
329 xmlTextWriterPtr ptr;
330 char *name, *content;
331 size_t name_len, content_len;
332 int retval;
333 zval *self;
334
335 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss", &self, xmlwriter_class_entry_ce,
336 &name, &name_len, &content, &content_len) == FAILURE) {
338 }
340
341 XMLW_NAME_CHK(2, "attribute name");
342
343 retval = xmlTextWriterWriteAttribute(ptr, (xmlChar *)name, (xmlChar *)content);
344
345 RETURN_BOOL(retval != -1);
346}
347/* }}} */
348
349/* {{{ Write full namespaced attribute - returns FALSE on error */
351{
352 xmlTextWriterPtr ptr;
353 char *name, *prefix, *uri, *content;
354 size_t name_len, prefix_len, uri_len, content_len;
355 int retval;
356 zval *self;
357
358 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!ss!s", &self, xmlwriter_class_entry_ce,
359 &prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
361 }
363
364 XMLW_NAME_CHK(3, "attribute name");
365
366 retval = xmlTextWriterWriteAttributeNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)content);
367
368 RETURN_BOOL(retval != -1);
369}
370/* }}} */
371
372/* {{{ Create start element tag - returns FALSE on error */
374{
375 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartElement, "element name");
376}
377/* }}} */
378
379/* {{{ Create start namespaced element tag - returns FALSE on error */
381{
382 xmlTextWriterPtr ptr;
383 char *name, *prefix, *uri;
384 size_t name_len, prefix_len, uri_len;
385 int retval;
386 zval *self;
387
388 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!ss!", &self, xmlwriter_class_entry_ce,
389 &prefix, &prefix_len, &name, &name_len, &uri, &uri_len) == FAILURE) {
391 }
393
394 XMLW_NAME_CHK(3, "element name");
395
396 retval = xmlTextWriterStartElementNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
397
398 RETURN_BOOL(retval != -1);
399}
400/* }}} */
401
402/* {{{ End current element - returns FALSE on error */
404{
405 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndElement);
406}
407/* }}} */
408
409/* {{{ End current element - returns FALSE on error */
411{
412 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterFullEndElement);
413}
414/* }}} */
415
416/* {{{ Write full element tag - returns FALSE on error */
418{
419 xmlTextWriterPtr ptr;
420 char *name, *content = NULL;
421 size_t name_len, content_len;
422 int retval;
423 zval *self;
424
425 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|s!", &self, xmlwriter_class_entry_ce,
426 &name, &name_len, &content, &content_len) == FAILURE) {
428 }
430
431 XMLW_NAME_CHK(2, "element name");
432
433 if (!content) {
434 retval = xmlTextWriterStartElement(ptr, (xmlChar *)name);
435 if (retval == -1) {
437 }
438 retval = xmlTextWriterEndElement(ptr);
439 } else {
440 retval = xmlTextWriterWriteElement(ptr, (xmlChar *)name, (xmlChar *)content);
441 }
442
443 RETURN_BOOL(retval != -1);
444}
445/* }}} */
446
447/* {{{ Write full namesapced element tag - returns FALSE on error */
449{
450 xmlTextWriterPtr ptr;
451 char *name, *prefix, *uri, *content = NULL;
452 size_t name_len, prefix_len, uri_len, content_len;
453 int retval;
454 zval *self;
455
456 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!ss!|s!", &self, xmlwriter_class_entry_ce,
457 &prefix, &prefix_len, &name, &name_len, &uri, &uri_len, &content, &content_len) == FAILURE) {
459 }
461
462 XMLW_NAME_CHK(3, "element name");
463
464 if (!content) {
465 retval = xmlTextWriterStartElementNS(ptr,(xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri);
466 if (retval == -1) {
468 }
469 retval = xmlTextWriterEndElement(ptr);
470 } else {
471 retval = xmlTextWriterWriteElementNS(ptr, (xmlChar *)prefix, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)content);
472 }
473
474 RETURN_BOOL(retval != -1);
475}
476/* }}} */
477
478/* {{{ Create start PI tag - returns FALSE on error */
480{
481 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartPI, "PI target");
482}
483/* }}} */
484
485/* {{{ End current PI - returns FALSE on error */
487{
488 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndPI);
489}
490/* }}} */
491
492/* {{{ Write full PI tag - returns FALSE on error */
494{
495 xmlTextWriterPtr ptr;
496 char *name, *content;
497 size_t name_len, content_len;
498 int retval;
499 zval *self;
500
501 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss", &self, xmlwriter_class_entry_ce,
502 &name, &name_len, &content, &content_len) == FAILURE) {
504 }
506
507 XMLW_NAME_CHK(2, "PI target");
508
509 retval = xmlTextWriterWritePI(ptr, (xmlChar *)name, (xmlChar *)content);
510
511 RETURN_BOOL(retval != -1);
512}
513/* }}} */
514
515/* {{{ Create start CDATA tag - returns FALSE on error */
517{
518 xmlTextWriterPtr ptr;
519 int retval;
520 zval *self;
521
522 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &self, xmlwriter_class_entry_ce) == FAILURE) {
524 }
526
527 retval = xmlTextWriterStartCDATA(ptr);
528
529 RETURN_BOOL(retval != -1);
530}
531/* }}} */
532
533/* {{{ End current CDATA - returns FALSE on error */
535{
536 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndCDATA);
537}
538/* }}} */
539
540/* {{{ Write full CDATA tag - returns FALSE on error */
542{
543 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteCDATA, NULL);
544}
545/* }}} */
546
547/* {{{ Write text - returns FALSE on error */
549{
550 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteRaw, NULL);
551}
552/* }}} */
553
554/* {{{ Write text - returns FALSE on error */
556{
557 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteString, NULL);
558}
559/* }}} */
560
561/* {{{ Create start comment - returns FALSE on error */
563{
564 xmlTextWriterPtr ptr;
565 int retval;
566 zval *self;
567
568 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &self, xmlwriter_class_entry_ce) == FAILURE) {
570 }
572
573 retval = xmlTextWriterStartComment(ptr);
574
575 RETURN_BOOL(retval != -1);
576}
577/* }}} */
578
579/* {{{ Create end comment - returns FALSE on error */
581{
582 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndComment);
583}
584/* }}} */
585
586/* {{{ Write full comment tag - returns FALSE on error */
588{
589 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterWriteComment, NULL);
590}
591/* }}} */
592
593/* {{{ Create document tag - returns FALSE on error */
595{
596 xmlTextWriterPtr ptr;
597 char *version = NULL, *enc = NULL, *alone = NULL;
598 size_t version_len, enc_len, alone_len;
599 int retval;
600 zval *self;
601
602 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|s!p!s!", &self, xmlwriter_class_entry_ce, &version, &version_len, &enc, &enc_len, &alone, &alone_len) == FAILURE) {
604 }
606
607 retval = xmlTextWriterStartDocument(ptr, version, enc, alone);
608
609 RETURN_BOOL(retval != -1);
610}
611/* }}} */
612
613/* {{{ End current document - returns FALSE on error */
615{
616 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDocument);
617}
618/* }}} */
619
620/* {{{ Create start DTD tag - returns FALSE on error */
622{
623 xmlTextWriterPtr ptr;
624 char *name, *pubid = NULL, *sysid = NULL;
625 size_t name_len, pubid_len, sysid_len;
626 int retval;
627 zval *self;
628
629 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|s!s!", &self, xmlwriter_class_entry_ce, &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len) == FAILURE) {
631 }
633
634 retval = xmlTextWriterStartDTD(ptr, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid);
635
636 RETURN_BOOL(retval != -1);
637}
638/* }}} */
639
640/* {{{ End current DTD - returns FALSE on error */
642{
643 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTD);
644}
645/* }}} */
646
647/* {{{ Write full DTD tag - returns FALSE on error */
649{
650 xmlTextWriterPtr ptr;
651 char *name, *pubid = NULL, *sysid = NULL, *subset = NULL;
652 size_t name_len, pubid_len, sysid_len, subset_len;
653 int retval;
654 zval *self;
655
656 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|s!s!s!", &self, xmlwriter_class_entry_ce, &name, &name_len, &pubid, &pubid_len, &sysid, &sysid_len, &subset, &subset_len) == FAILURE) {
658 }
660
661 retval = xmlTextWriterWriteDTD(ptr, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid, (xmlChar *)subset);
662
663 RETURN_BOOL(retval != -1);
664}
665/* }}} */
666
667/* {{{ Create start DTD element - returns FALSE on error */
669{
670 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartDTDElement, "element name");
671}
672/* }}} */
673
674/* {{{ End current DTD element - returns FALSE on error */
676{
677 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDElement);
678}
679/* }}} */
680
681/* {{{ Write full DTD element tag - returns FALSE on error */
683{
684 xmlTextWriterPtr ptr;
685 char *name, *content;
686 size_t name_len, content_len;
687 int retval;
688 zval *self;
689
690 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss", &self, xmlwriter_class_entry_ce,
691 &name, &name_len, &content, &content_len) == FAILURE) {
693 }
695
696 XMLW_NAME_CHK(2, "element name");
697
698 retval = xmlTextWriterWriteDTDElement(ptr, (xmlChar *)name, (xmlChar *)content);
699
700 RETURN_BOOL(retval != -1);
701}
702/* }}} */
703
704/* {{{ Create start DTD AttList - returns FALSE on error */
706{
707 php_xmlwriter_string_arg(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterStartDTDAttlist, "element name");
708}
709/* }}} */
710
711/* {{{ End current DTD AttList - returns FALSE on error */
713{
714 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDAttlist);
715}
716/* }}} */
717
718/* {{{ Write full DTD AttList tag - returns FALSE on error */
720{
721 xmlTextWriterPtr ptr;
722 char *name, *content;
723 size_t name_len, content_len;
724 int retval;
725 zval *self;
726
727 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss", &self, xmlwriter_class_entry_ce,
728 &name, &name_len, &content, &content_len) == FAILURE) {
730 }
732
733 XMLW_NAME_CHK(2, "element name");
734
735 retval = xmlTextWriterWriteDTDAttlist(ptr, (xmlChar *)name, (xmlChar *)content);
736
737 RETURN_BOOL(retval != -1);
738}
739/* }}} */
740
741/* {{{ Create start DTD Entity - returns FALSE on error */
743{
744 xmlTextWriterPtr ptr;
745 char *name;
746 size_t name_len;
747 int retval;
748 bool isparm;
749 zval *self;
750
751 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osb", &self, xmlwriter_class_entry_ce, &name, &name_len, &isparm) == FAILURE) {
753 }
755
756 XMLW_NAME_CHK(2, "attribute name");
757
758 retval = xmlTextWriterStartDTDEntity(ptr, isparm, (xmlChar *)name);
759
760 RETURN_BOOL(retval != -1);
761}
762/* }}} */
763
764/* {{{ End current DTD Entity - returns FALSE on error */
766{
767 php_xmlwriter_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextWriterEndDTDEntity);
768}
769/* }}} */
770
771/* {{{ Write full DTD Entity tag - returns FALSE on error */
773{
774 xmlTextWriterPtr ptr;
775 char *name, *content;
776 size_t name_len, content_len;
777 int retval;
778 /* Optional parameters */
779 char *pubid = NULL, *sysid = NULL, *ndataid = NULL;
780 bool pe = 0;
781 size_t pubid_len, sysid_len, ndataid_len;
782 zval *self;
783
784 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss|bs!s!s!", &self, xmlwriter_class_entry_ce,
785 &name, &name_len, &content, &content_len, &pe, &pubid, &pubid_len,
786 &sysid, &sysid_len, &ndataid, &ndataid_len) == FAILURE) {
788 }
790
791 XMLW_NAME_CHK(2, "element name");
792
793 retval = xmlTextWriterWriteDTDEntity(ptr, pe, (xmlChar *)name, (xmlChar *)pubid, (xmlChar *)sysid, (xmlChar *)ndataid, (xmlChar *)content);
794
795 RETURN_BOOL(retval != -1);
796}
797/* }}} */
798
799/* {{{ Create new xmlwriter using source uri for output */
801{
802 char *valid_file = NULL;
803 xmlTextWriterPtr ptr;
804 char *source;
805 char resolved_path[MAXPATHLEN + 1];
806 size_t source_len;
807 zval *self = getThis();
808 ze_xmlwriter_object *ze_obj = NULL;
809
810 if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &source, &source_len) == FAILURE) {
812 }
813
814 if (self) {
815 /* We do not use XMLWRITER_FROM_OBJECT, xmlwriter init function here */
816 ze_obj = Z_XMLWRITER_P(self);
817 }
818
819 if (source_len == 0) {
822 }
823
824 valid_file = _xmlwriter_get_valid_file_path(source, resolved_path, MAXPATHLEN);
825 if (!valid_file) {
826 php_error_docref(NULL, E_WARNING, "Unable to resolve file path");
828 }
829
830 ptr = xmlNewTextWriterFilename(valid_file, 0);
831
832 if (!ptr) {
834 }
835
836 if (self) {
837 xmlwriter_destroy_libxml_objects(ze_obj);
838 ze_obj->ptr = ptr;
839 ze_obj->output = NULL;
841 } else {
842 ze_obj = php_xmlwriter_fetch_object(xmlwriter_object_new(xmlwriter_class_entry_ce));
843 ze_obj->ptr = ptr;
844 ze_obj->output = NULL;
845 RETURN_OBJ(&ze_obj->std);
846 }
847}
848/* }}} */
849
851{
852 char *source;
853 size_t source_len;
854 char resolved_path[MAXPATHLEN + 1];
855
857 Z_PARAM_PATH(source, source_len)
859
860 if (source_len == 0) {
863 }
864
865 const char *valid_file = _xmlwriter_get_valid_file_path(source, resolved_path, MAXPATHLEN);
866 if (!valid_file) {
867 zend_argument_value_error(1, "must resolve to a valid file path");
869 }
870
871 xmlTextWriterPtr writer = xmlNewTextWriterFilename(valid_file, 0);
872 if (!writer) {
873 zend_throw_error(NULL, "Could not construct libxml writer");
875 }
876
877 xml_writer_create_static(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, NULL);
878}
879
880/* {{{ Create new xmlwriter using memory for string output */
882{
883 xmlTextWriterPtr ptr;
884 xmlBufferPtr buffer;
885 zval *self = getThis();
886 ze_xmlwriter_object *ze_obj = NULL;
887
890 }
891
892 if (self) {
893 /* We do not use XMLWRITER_FROM_OBJECT, xmlwriter init function here */
894 ze_obj = Z_XMLWRITER_P(self);
895 }
896
897 buffer = xmlBufferCreate();
898
899 if (buffer == NULL) {
900 php_error_docref(NULL, E_WARNING, "Unable to create output buffer");
902 }
903
904 ptr = xmlNewTextWriterMemory(buffer, 0);
905 if (! ptr) {
906 xmlBufferFree(buffer);
908 }
909
910 if (self) {
911 xmlwriter_destroy_libxml_objects(ze_obj);
912 ze_obj->ptr = ptr;
913 ze_obj->output = buffer;
915 } else {
916 ze_obj = php_xmlwriter_fetch_object(xmlwriter_object_new(xmlwriter_class_entry_ce));
917 ze_obj->ptr = ptr;
918 ze_obj->output = buffer;
919 RETURN_OBJ(&ze_obj->std);
920 }
921
922}
923/* }}} */
924
926{
928
929 xmlBufferPtr buffer = xmlBufferCreate();
930 xmlTextWriterPtr writer = xmlNewTextWriterMemory(buffer, 0);
931
932 /* No need for an explicit buffer check as this will fail on a NULL buffer. */
933 if (!writer) {
934 xmlBufferFree(buffer);
935 zend_throw_error(NULL, "Could not construct libxml writer");
937 }
938
939 xml_writer_create_static(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, buffer);
940}
941
942static int xml_writer_stream_write(void *context, const char *buffer, int len)
943{
944 zend_resource *resource = context;
945 if (EXPECTED(resource->ptr)) {
946 php_stream *stream = resource->ptr;
947 return php_stream_write(stream, buffer, len);
948 }
949 return -1;
950}
951
952static int xml_writer_stream_close(void *context)
953{
954 zend_resource *resource = context;
955 /* Don't close it as others may still use it! We don't own the resource!
956 * Just delete our reference (and clean up if we're the last one). */
957 zend_list_delete(resource);
958 return 0;
959}
960
962{
963 zval *stream_zv;
964 php_stream *stream;
965
967 Z_PARAM_RESOURCE(stream_zv)
969
970 php_stream_from_res(stream, Z_RES_P(stream_zv));
971
972 xmlOutputBufferPtr output_buffer = xmlOutputBufferCreateIO(xml_writer_stream_write, xml_writer_stream_close, stream->res, NULL);
973 if (UNEXPECTED(output_buffer == NULL)) {
974 zend_throw_error(NULL, "Could not construct libxml output buffer");
976 }
977
978 /* When the buffer is closed (even in error paths) the reference is destroyed. */
979 Z_ADDREF_P(stream_zv);
980
981 xmlTextWriterPtr writer = xmlNewTextWriter(output_buffer);
982 if (UNEXPECTED(writer == NULL)) {
983 xmlOutputBufferClose(output_buffer);
984 zend_throw_error(NULL, "Could not construct libxml writer");
986 }
987
988 /* output_buffer is owned by writer, and so writer will clean that up for us. */
989 xml_writer_create_static(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, NULL);
990}
991
992/* {{{ php_xmlwriter_flush */
993static void php_xmlwriter_flush(INTERNAL_FUNCTION_PARAMETERS, int force_string) {
994 xmlTextWriterPtr ptr;
995 xmlBufferPtr buffer;
996 bool empty = 1;
997 int output_bytes;
998 zval *self;
999
1000 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|b", &self, xmlwriter_class_entry_ce, &empty) == FAILURE) {
1001 RETURN_THROWS();
1002 }
1004
1005 buffer = Z_XMLWRITER_P(self)->output;
1006 if (force_string == 1 && buffer == NULL) {
1008 }
1009 output_bytes = xmlTextWriterFlush(ptr);
1010 if (buffer) {
1011 const xmlChar *content = xmlBufferContent(buffer);
1012 RETVAL_STRING((const char *) content);
1013 if (empty) {
1014 xmlBufferEmpty(buffer);
1015 }
1016 } else {
1017 RETVAL_LONG(output_bytes);
1018 }
1019}
1020/* }}} */
1021
1022/* {{{ Output current buffer as string */
1027/* }}} */
1028
1029/* {{{ Output current buffer */
1031{
1032 php_xmlwriter_flush(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1033}
1034/* }}} */
1035
1036/* {{{ PHP_MINIT_FUNCTION */
1037static PHP_MINIT_FUNCTION(xmlwriter)
1038{
1039 memcpy(&xmlwriter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
1040 xmlwriter_object_handlers.offset = XtOffsetOf(ze_xmlwriter_object, std);
1041 xmlwriter_object_handlers.dtor_obj = xmlwriter_object_dtor;
1042 xmlwriter_object_handlers.free_obj = xmlwriter_object_free_storage;
1043 xmlwriter_object_handlers.clone_obj = NULL;
1044 xmlwriter_class_entry_ce = register_class_XMLWriter();
1045 xmlwriter_class_entry_ce->create_object = xmlwriter_object_new;
1046 xmlwriter_class_entry_ce->default_object_handlers = &xmlwriter_object_handlers;
1047
1048 return SUCCESS;
1049}
1050/* }}} */
1051
1052/* {{{ PHP_MSHUTDOWN_FUNCTION */
1053static PHP_MSHUTDOWN_FUNCTION(xmlwriter)
1054{
1055 return SUCCESS;
1056}
1057/* }}} */
1058
1059/* {{{ PHP_MINFO_FUNCTION */
1060static PHP_MINFO_FUNCTION(xmlwriter)
1061{
1063 {
1064 php_info_print_table_row(2, "XMLWriter", "enabled");
1065 }
1067}
1068/* }}} */
size_t len
Definition apprentice.c:174
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
#define NULL
Definition gdcache.h:45
#define prefix
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
Definition main.c:1173
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
Definition info.c:1074
#define PHP_FUNCTION
Definition php.h:364
#define PHP_MSHUTDOWN_FUNCTION
Definition php.h:401
#define PHP_MINFO
Definition php.h:396
#define PHP_MINIT_FUNCTION
Definition php.h:400
#define PHP_MSHUTDOWN
Definition php.h:393
#define PHP_MINFO_FUNCTION
Definition php.h:404
#define PHP_MINIT
Definition php.h:392
#define PHP_METHOD
Definition php.h:365
struct _php_stream php_stream
Definition php_streams.h:96
#define php_stream_from_res(xstr, res)
#define php_stream_write(stream, buf, count)
zend_module_entry xmlwriter_module_entry
#define XMLW_NAME_CHK(__arg_no, __subject)
int(* xmlwriter_read_int_t)(xmlTextWriterPtr writer)
#define XMLWRITER_FROM_OBJECT(ptr, object)
int(* xmlwriter_read_one_char_t)(xmlTextWriterPtr writer, const xmlChar *content)
#define PHP_XMLWRITER_VERSION
#define Z_XMLWRITER_P(zv)
struct _ze_xmlwriter_object ze_xmlwriter_object
xmlwriter_write_pi(XMLWriter $writer, string $target, string $content)
xmlwriter_output_memory(XMLWriter $writer, bool $flush=true)
xmlwriter_end_dtd_entity(XMLWriter $writer)
xmlwriter_end_document(XMLWriter $writer)
xmlwriter_write_dtd_element(XMLWriter $writer, string $name, string $content)
xmlwriter_start_cdata(XMLWriter $writer)
xmlwriter_text(XMLWriter $writer, string $content)
xmlwriter_start_pi(XMLWriter $writer, string $target)
xmlwriter_start_dtd(XMLWriter $writer, string $qualifiedName, ?string $publicId=null, ?string $systemId=null)
xmlwriter_end_pi(XMLWriter $writer)
xmlwriter_end_comment(XMLWriter $writer)
xmlwriter_start_dtd_attlist(XMLWriter $writer, string $name)
xmlwriter_start_attribute(XMLWriter $writer, string $name)
xmlwriter_write_raw(XMLWriter $writer, string $content)
xmlwriter_start_dtd_element(XMLWriter $writer, string $qualifiedName)
xmlwriter_start_element_ns(XMLWriter $writer, ?string $prefix, string $name, ?string $namespace)
xmlwriter_end_dtd_attlist(XMLWriter $writer)
xmlwriter_write_cdata(XMLWriter $writer, string $content)
xmlwriter_flush(XMLWriter $writer, bool $empty=true)
xmlwriter_write_element_ns(XMLWriter $writer, ?string $prefix, string $name, ?string $namespace, ?string $content=null)
xmlwriter_write_dtd_entity(XMLWriter $writer, string $name, string $content, bool $isParam=false, ?string $publicId=null, ?string $systemId=null, ?string $notationData=null)
xmlwriter_write_comment(XMLWriter $writer, string $content)
xmlwriter_start_attribute_ns(XMLWriter $writer, ?string $prefix, string $name, ?string $namespace)
xmlwriter_end_attribute(XMLWriter $writer)
xmlwriter_open_memory()
xmlwriter_set_indent(XMLWriter $writer, bool $enable)
xmlwriter_full_end_element(XMLWriter $writer)
xmlwriter_end_dtd_element(XMLWriter $writer)
xmlwriter_write_attribute(XMLWriter $writer, string $name, string $value)
xmlwriter_write_attribute_ns(XMLWriter $writer, ?string $prefix, string $name, ?string $namespace, string $value)
xmlwriter_end_cdata(XMLWriter $writer)
xmlwriter_start_dtd_entity(XMLWriter $writer, string $name, bool $isParam)
xmlwriter_open_uri(string $uri)
xmlwriter_start_document(XMLWriter $writer, ?string $version="1.0", ?string $encoding=null, ?string $standalone=null)
xmlwriter_write_dtd_attlist(XMLWriter $writer, string $name, string $content)
xmlwriter_end_dtd(XMLWriter $writer)
xmlwriter_set_indent_string(XMLWriter $writer, string $indentation)
xmlwriter_end_element(XMLWriter $writer)
xmlwriter_start_element(XMLWriter $writer, string $name)
xmlwriter_write_element(XMLWriter $writer, string $name, ?string $content=null)
xmlwriter_write_dtd(XMLWriter $writer, string $name, ?string $publicId=null, ?string $systemId=null, ?string $content=null)
xmlwriter_start_comment(XMLWriter $writer)
zend_resource * res
xmlTextWriterPtr ptr
Definition file.h:177
Definition dce.c:49
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
#define INTERNAL_FUNCTION_PARAMETERS
Definition zend.h:49
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
Definition zend.h:50
ZEND_API zend_result object_init_with_constructor(zval *arg, zend_class_entry *class_type, uint32_t param_count, zval *params, HashTable *named_params)
Definition zend_API.c:1855
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
Definition zend_API.c:1300
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type)
Definition zend_API.c:1688
ZEND_API ZEND_COLD void zend_argument_must_not_be_empty_error(uint32_t arg_num)
Definition zend_API.c:443
ZEND_API zend_result zend_parse_method_parameters(uint32_t num_args, zval *this_ptr, const char *type_spec,...)
Definition zend_API.c:1314
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
Definition zend_API.c:433
#define ZEND_NUM_ARGS()
Definition zend_API.h:530
#define RETURN_OBJ(r)
Definition zend_API.h:1052
#define ZEND_PARSE_PARAMETERS_END()
Definition zend_API.h:1641
#define RETURN_FALSE
Definition zend_API.h:1058
#define RETVAL_STRING(s)
Definition zend_API.h:1017
#define Z_PARAM_RESOURCE(dest)
Definition zend_API.h:2056
#define ZEND_PARSE_PARAMETERS_NONE()
Definition zend_API.h:1623
#define ZEND_GET_MODULE(name)
Definition zend_API.h:241
#define zend_parse_parameters_none()
Definition zend_API.h:353
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
Definition zend_API.h:1620
#define RETURN_BOOL(b)
Definition zend_API.h:1035
#define RETURN_THROWS()
Definition zend_API.h:1060
#define ZEND_THIS
Definition zend_API.h:523
#define RETVAL_LONG(l)
Definition zend_API.h:1011
#define RETURN_EMPTY_STRING()
Definition zend_API.h:1047
#define Z_PARAM_PATH(dest, dest_len)
Definition zend_API.h:2026
#define getThis()
Definition zend_API.h:526
#define RETURN_TRUE
Definition zend_API.h:1059
struct _zval_struct zval
strlen(string $string)
ZEND_API size_t zend_dirname(char *path, size_t len)
#define strncasecmp(s1, s2, n)
#define E_WARNING
Definition zend_errors.h:24
ZEND_API zend_result ZEND_FASTCALL zend_list_delete(zend_resource *res)
Definition zend_list.c:46
#define ZEND_MOD_END
struct _zend_module_dep zend_module_dep
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES
#define ZEND_MOD_REQUIRED(name)
#define STANDARD_MODULE_HEADER_EX
ZEND_API const zend_object_handlers std_object_handlers
ZEND_API void zend_objects_destroy_object(zend_object *object)
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
#define EXPECTED(condition)
#define zend_always_inline
#define XtOffsetOf(s_type, field)
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
struct stat zend_stat_t
Definition zend_stream.h:94
struct _zend_resource zend_resource
Definition zend_types.h:99
#define Z_ADDREF_P(pz)
@ FAILURE
Definition zend_types.h:61
#define Z_CE_P(zval_p)
#define Z_RES_P(zval_p)
struct _zend_object_handlers zend_object_handlers
Definition zend_types.h:88
#define php_sys_stat
#define MAXPATHLEN
#define VCWD_REALPATH(path, real_path)
zval retval
zval * return_value
zend_string * name