/src/libreoffice/tools/source/xml/XmlWriter.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | */ |
9 | | |
10 | | #include <tools/stream.hxx> |
11 | | #include <tools/XmlWriter.hxx> |
12 | | |
13 | | #include <libxml/xmlwriter.h> |
14 | | |
15 | | namespace tools |
16 | | { |
17 | | namespace |
18 | | { |
19 | | int funcWriteCallback(void* pContext, const char* sBuffer, int nLen) |
20 | 4.16k | { |
21 | 4.16k | SvStream* pStream = static_cast<SvStream*>(pContext); |
22 | 4.16k | return static_cast<int>(pStream->WriteBytes(sBuffer, nLen)); |
23 | 4.16k | } |
24 | | |
25 | | int funcCloseCallback(void* pContext) |
26 | 4.16k | { |
27 | 4.16k | SvStream* pStream = static_cast<SvStream*>(pContext); |
28 | 4.16k | pStream->Flush(); |
29 | 4.16k | return 0; // 0 or -1 in case of error |
30 | 4.16k | } |
31 | | |
32 | | template <typename T> |
33 | | requires(sizeof(T) == sizeof(char)) void attributeBase64_impl(xmlTextWriterPtr writer, |
34 | | const char* name, const T* value, |
35 | | int size) |
36 | 0 | { |
37 | 0 | (void)xmlTextWriterStartAttribute(writer, BAD_CAST(name)); |
38 | 0 | (void)xmlTextWriterWriteBase64(writer, reinterpret_cast<const char*>(value), 0, size); |
39 | 0 | (void)xmlTextWriterEndAttribute(writer); |
40 | 0 | } Unexecuted instantiation: XmlWriter.cxx:_ZN5tools12_GLOBAL__N_120attributeBase64_implIhQeqstT_Lm1EEEvP14_xmlTextWriterPKcPKS2_i Unexecuted instantiation: XmlWriter.cxx:_ZN5tools12_GLOBAL__N_120attributeBase64_implIcQeqstT_Lm1EEEvP14_xmlTextWriterPKcPKS2_i |
41 | | } // end anonymous namespace |
42 | | |
43 | | struct XmlWriterImpl |
44 | | { |
45 | | SvStream* mpStream = nullptr; |
46 | | xmlTextWriterPtr mpWriter = nullptr; |
47 | | bool mbWriteXmlHeader = true; |
48 | | bool mbExternalXmlWriter = false; |
49 | | |
50 | | XmlWriterImpl(SvStream* pStream) |
51 | 4.16k | : mpStream(pStream) |
52 | 4.16k | { |
53 | 4.16k | } |
54 | | |
55 | | XmlWriterImpl(xmlTextWriterPtr pWriter) |
56 | 0 | : mpWriter(pWriter) |
57 | 0 | , mbWriteXmlHeader(false) |
58 | 0 | , mbExternalXmlWriter(true) |
59 | 0 | { |
60 | 0 | } |
61 | | }; |
62 | | |
63 | | XmlWriter::XmlWriter(SvStream* pStream) |
64 | 4.16k | : mpImpl(std::make_unique<XmlWriterImpl>(pStream)) |
65 | 4.16k | { |
66 | 4.16k | } |
67 | | |
68 | | XmlWriter::XmlWriter(xmlTextWriterPtr pWriter) |
69 | 0 | : mpImpl(std::make_unique<XmlWriterImpl>(pWriter)) |
70 | 0 | { |
71 | 0 | } |
72 | | |
73 | | XmlWriter::~XmlWriter() |
74 | 4.16k | { |
75 | 4.16k | if (mpImpl) |
76 | 4.16k | endDocument(); |
77 | 4.16k | } |
78 | | |
79 | | bool XmlWriter::startDocument(sal_Int32 nIndent, bool bWriteXmlHeader) |
80 | 4.16k | { |
81 | 4.16k | if (mpImpl->mpWriter) |
82 | 0 | return false; |
83 | | |
84 | 4.16k | mpImpl->mbWriteXmlHeader = bWriteXmlHeader; |
85 | 4.16k | xmlCharEncodingHandlerPtr pEncodingHandler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8); |
86 | 4.16k | xmlOutputBufferPtr xmlOutBuffer = xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback, |
87 | 4.16k | mpImpl->mpStream, pEncodingHandler); |
88 | 4.16k | mpImpl->mpWriter = xmlNewTextWriter(xmlOutBuffer); |
89 | 4.16k | if (!mpImpl->mpWriter) |
90 | 0 | return false; |
91 | 4.16k | xmlTextWriterSetIndent(mpImpl->mpWriter, nIndent); |
92 | 4.16k | if (mpImpl->mbWriteXmlHeader) |
93 | 0 | (void)xmlTextWriterStartDocument(mpImpl->mpWriter, nullptr, "UTF-8", nullptr); |
94 | | |
95 | 4.16k | return true; |
96 | 4.16k | } |
97 | | |
98 | | void XmlWriter::endDocument() |
99 | 8.32k | { |
100 | 8.32k | if (!mpImpl->mpWriter || mpImpl->mbExternalXmlWriter) |
101 | 4.16k | return; |
102 | | |
103 | 4.16k | if (mpImpl->mbWriteXmlHeader) |
104 | 0 | (void)xmlTextWriterEndDocument(mpImpl->mpWriter); |
105 | 4.16k | xmlFreeTextWriter(mpImpl->mpWriter); |
106 | 4.16k | mpImpl->mpWriter = nullptr; |
107 | 4.16k | } |
108 | | |
109 | | void XmlWriter::startElement(const OString& sPrefix, const OString& sName, |
110 | | const OString& sNamespaceUri) |
111 | 8.32k | { |
112 | 8.32k | xmlChar* xmlName = BAD_CAST(sName.getStr()); |
113 | 8.32k | xmlChar* xmlPrefix = nullptr; |
114 | 8.32k | xmlChar* xmlNamespaceUri = nullptr; |
115 | 8.32k | if (!sPrefix.isEmpty()) |
116 | 8.32k | xmlPrefix = BAD_CAST(sPrefix.getStr()); |
117 | 8.32k | if (!sNamespaceUri.isEmpty()) |
118 | 8.32k | xmlNamespaceUri = BAD_CAST(sNamespaceUri.getStr()); |
119 | | |
120 | 8.32k | (void)xmlTextWriterStartElementNS(mpImpl->mpWriter, xmlPrefix, xmlName, xmlNamespaceUri); |
121 | 8.32k | } |
122 | | |
123 | | void XmlWriter::startElement(const char* pName) |
124 | 35.6k | { |
125 | 35.6k | xmlChar* xmlName = BAD_CAST(pName); |
126 | 35.6k | (void)xmlTextWriterStartElement(mpImpl->mpWriter, xmlName); |
127 | 35.6k | } |
128 | | |
129 | 43.9k | void XmlWriter::endElement() { (void)xmlTextWriterEndElement(mpImpl->mpWriter); } |
130 | | |
131 | | void XmlWriter::attributeBase64(const char* pName, std::vector<sal_uInt8> const& rValueInBytes) |
132 | 0 | { |
133 | 0 | attributeBase64_impl(mpImpl->mpWriter, pName, rValueInBytes.data(), rValueInBytes.size()); |
134 | 0 | } |
135 | | |
136 | | void XmlWriter::attributeBase64(const char* pName, std::vector<char> const& rValueInBytes) |
137 | 0 | { |
138 | 0 | attributeBase64_impl(mpImpl->mpWriter, pName, rValueInBytes.data(), rValueInBytes.size()); |
139 | 0 | } |
140 | | |
141 | | void XmlWriter::attribute(const char* name, std::string_view value) |
142 | 18.6k | { |
143 | 18.6k | xmlChar* xmlName = BAD_CAST(name); |
144 | 18.6k | (void)xmlTextWriterWriteFormatAttribute(mpImpl->mpWriter, xmlName, "%.*s", int(value.size()), |
145 | 18.6k | value.data()); |
146 | 18.6k | } |
147 | | |
148 | | void XmlWriter::attribute(const char* name, std::u16string_view value) |
149 | 0 | { |
150 | 0 | attribute(name, OUStringToOString(value, RTL_TEXTENCODING_UTF8)); |
151 | 0 | } |
152 | | |
153 | | void XmlWriter::attribute(const char* name, const sal_Int64 aNumber) |
154 | 0 | { |
155 | 0 | attribute(name, OString::number(aNumber)); |
156 | 0 | } |
157 | | |
158 | | void XmlWriter::attribute(const char* name, const double aNumber) |
159 | 0 | { |
160 | 0 | attribute(name, OString::number(aNumber)); |
161 | 0 | } |
162 | | |
163 | | void XmlWriter::content(std::string_view value) |
164 | 23.3k | { |
165 | 23.3k | (void)xmlTextWriterWriteFormatString(mpImpl->mpWriter, "%.*s", int(value.size()), value.data()); |
166 | 23.3k | } |
167 | | |
168 | | void XmlWriter::content(std::u16string_view sValue) |
169 | 0 | { |
170 | 0 | content(OUStringToOString(sValue, RTL_TEXTENCODING_UTF8)); |
171 | 0 | } |
172 | | |
173 | | void XmlWriter::element(const char* sName) |
174 | 0 | { |
175 | 0 | startElement(sName); |
176 | 0 | endElement(); |
177 | 0 | } |
178 | | |
179 | | } // end tools namespace |
180 | | |
181 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |