Skip to content

Commit 0c490ad

Browse files
committed
Handle dumping document to file
1 parent 4ae3be3 commit 0c490ad

File tree

6 files changed

+48
-9
lines changed

6 files changed

+48
-9
lines changed

ext/dom/document.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ PHP_METHOD(DOMDocument, save)
15401540
zval *id;
15411541
xmlDoc *docp;
15421542
size_t file_len = 0;
1543-
int bytes, format, saveempty = 0;
1543+
int saveempty = 0;
15441544
dom_object *intern;
15451545
char *file;
15461546
zend_long options = 0;
@@ -1560,13 +1560,12 @@ PHP_METHOD(DOMDocument, save)
15601560
/* encoding handled by property on doc */
15611561

15621562
libxml_doc_props const* doc_props = dom_get_doc_props_read_only(intern->document);
1563-
format = doc_props->formatoutput;
1563+
bool format = doc_props->formatoutput;
15641564
if (options & LIBXML_SAVE_NOEMPTYTAG) {
15651565
saveempty = xmlSaveNoEmptyTags;
15661566
xmlSaveNoEmptyTags = 1;
15671567
}
1568-
// TODO: use modern API when necessary
1569-
bytes = xmlSaveFormatFileEnc(file, docp, NULL, format);
1568+
zend_long bytes = intern->document->handlers->dump_doc_to_file(file, docp, format, (const char *) docp->encoding);
15701569
if (options & LIBXML_SAVE_NOEMPTYTAG) {
15711570
xmlSaveNoEmptyTags = saveempty;
15721571
}

ext/dom/tests/modern/xml/XMLDocument_fromString_02.phpt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ dom
66
<?php
77

88
$dom = Dom\XMLDocument::createFromString('<?xml version="1.0"?><container/>');
9-
var_dump($dom->saveXmlFile("php://stdout"));
9+
var_dump($dom->saveXmlFile(__DIR__ . "/fromString_02.xml"));
10+
echo file_get_contents(__DIR__ . "/fromString_02.xml");
1011

12+
?>
13+
--CLEAN--
14+
<?php
15+
@unlink(__DIR__ . "/fromString_02.xml");
1116
?>
1217
--EXPECT--
18+
int(51)
1319
<?xml version="1.0" encoding="UTF-8"?>
1420
<container/>
15-
int(52)

ext/dom/xml_document.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,36 @@ static zend_string *php_new_dom_dump_doc_to_str(xmlDocPtr doc, int options, cons
293293
return php_new_dom_dump_node_to_str(doc, (xmlNodePtr) doc, options & XML_SAVE_FORMAT, encoding);
294294
}
295295

296+
static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding)
297+
{
298+
xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler(encoding);
299+
xmlOutputBufferPtr out = xmlOutputBufferCreateFilename(filename, handler, 0);
300+
if (!out) {
301+
xmlCharEncCloseFunc(handler);
302+
return -1;
303+
}
304+
305+
php_stream *stream = out->context;
306+
307+
int status = -1;
308+
xmlSaveCtxtPtr ctxt = xmlSaveToIO(out->writecallback, NULL, stream, encoding, XML_SAVE_AS_XML);
309+
if (EXPECTED(ctxt != NULL)) {
310+
status = dom_xml_serialize(ctxt, out, (xmlNodePtr) doc, format);
311+
status |= xmlOutputBufferFlush(out);
312+
(void) xmlSaveClose(ctxt);
313+
}
314+
315+
size_t offset = php_stream_tell(stream);
316+
317+
(void) xmlOutputBufferClose(out);
318+
319+
return status < 0 ? status : (zend_long) offset;
320+
}
321+
296322
static const php_libxml_document_handlers php_new_dom_default_document_handlers = {
297323
.dump_node_to_str = php_new_dom_dump_node_to_str,
298324
.dump_doc_to_str = php_new_dom_dump_doc_to_str,
325+
.dump_doc_to_file = php_new_dom_dump_doc_to_file,
299326
};
300327

301328
void dom_set_xml_class(php_libxml_ref_obj *document)

ext/libxml/libxml.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static zend_result php_libxml_post_deactivate(void);
8383

8484
static zend_string *php_libxml_default_dump_node_to_str(xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding);
8585
static zend_string *php_libxml_default_dump_doc_to_str(xmlDocPtr doc, int options, const char *encoding);
86+
static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding);
8687

8788
/* }}} */
8889

@@ -108,6 +109,7 @@ zend_module_entry libxml_module_entry = {
108109
static const php_libxml_document_handlers php_libxml_default_document_handlers = {
109110
.dump_node_to_str = php_libxml_default_dump_node_to_str,
110111
.dump_doc_to_str = php_libxml_default_dump_doc_to_str,
112+
.dump_doc_to_file = php_libxml_default_dump_doc_to_file,
111113
};
112114

113115
static void php_libxml_set_old_ns_list(xmlDocPtr doc, xmlNsPtr first, xmlNsPtr last)
@@ -1533,6 +1535,11 @@ static zend_string *php_libxml_default_dump_node_to_str(xmlDocPtr doc, xmlNodePt
15331535
return str;
15341536
}
15351537

1538+
static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding)
1539+
{
1540+
return xmlSaveFormatFileEnc(filename, doc, encoding, format);
1541+
}
1542+
15361543
#if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML)
15371544
PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
15381545
{

ext/libxml/php_libxml.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ typedef struct _php_libxml_private_data_header {
7575
typedef struct php_libxml_document_handlers {
7676
zend_string *(*dump_node_to_str)(xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding);
7777
zend_string *(*dump_doc_to_str)(xmlDocPtr doc, int options, const char *encoding);
78+
zend_long (*dump_doc_to_file)(const char *filename, xmlDocPtr doc, bool format, const char *encoding);
7879
} php_libxml_document_handlers;
7980

8081
/**

ext/simplexml/simplexml.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,10 +1358,11 @@ PHP_METHOD(SimpleXMLElement, asXML)
13581358
RETURN_FALSE;
13591359
}
13601360

1361+
xmlDocPtr doc = sxe->document->ptr;
1362+
13611363
if (filename) {
13621364
if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
1363-
int bytes;
1364-
bytes = xmlSaveFile(filename, (xmlDocPtr) sxe->document->ptr);
1365+
zend_long bytes = sxe->document->handlers->dump_doc_to_file(filename, doc, false, (const char *) doc->encoding);
13651366
if (bytes == -1) {
13661367
RETURN_FALSE;
13671368
} else {
@@ -1380,7 +1381,6 @@ PHP_METHOD(SimpleXMLElement, asXML)
13801381
}
13811382
}
13821383

1383-
xmlDocPtr doc = sxe->document->ptr;
13841384
zend_string *result;
13851385
if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
13861386
result = sxe->document->handlers->dump_doc_to_str(doc, 0, (const char *) doc->encoding);

0 commit comments

Comments
 (0)