/src/libreoffice/tools/source/xml/XmlWriter.cxx
Line | Count | Source (jump to first uncovered line) |
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 | 8.47k | { |
21 | 8.47k | SvStream* pStream = static_cast<SvStream*>(pContext); |
22 | 8.47k | return static_cast<int>(pStream->WriteBytes(sBuffer, nLen)); |
23 | 8.47k | } |
24 | | |
25 | | int funcCloseCallback(void* pContext) |
26 | 8.47k | { |
27 | 8.47k | SvStream* pStream = static_cast<SvStream*>(pContext); |
28 | 8.47k | pStream->Flush(); |
29 | 8.47k | return 0; // 0 or -1 in case of error |
30 | 8.47k | } |
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 | | XmlWriterImpl(SvStream* pStream) |
46 | 8.47k | : mpStream(pStream) |
47 | 8.47k | , mpWriter(nullptr) |
48 | 8.47k | , mbWriteXmlHeader(true) |
49 | 8.47k | { |
50 | 8.47k | } |
51 | | |
52 | | SvStream* mpStream; |
53 | | xmlTextWriterPtr mpWriter; |
54 | | bool mbWriteXmlHeader; |
55 | | }; |
56 | | |
57 | | XmlWriter::XmlWriter(SvStream* pStream) |
58 | 8.47k | : mpImpl(std::make_unique<XmlWriterImpl>(pStream)) |
59 | 8.47k | { |
60 | 8.47k | } |
61 | | |
62 | | XmlWriter::~XmlWriter() |
63 | 8.47k | { |
64 | 8.47k | if (mpImpl && mpImpl->mpWriter != nullptr) |
65 | 0 | endDocument(); |
66 | 8.47k | } |
67 | | |
68 | | bool XmlWriter::startDocument(sal_Int32 nIndent, bool bWriteXmlHeader) |
69 | 8.47k | { |
70 | 8.47k | mpImpl->mbWriteXmlHeader = bWriteXmlHeader; |
71 | 8.47k | xmlCharEncodingHandlerPtr pEncodingHandler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8); |
72 | 8.47k | xmlOutputBufferPtr xmlOutBuffer = xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback, |
73 | 8.47k | mpImpl->mpStream, pEncodingHandler); |
74 | 8.47k | mpImpl->mpWriter = xmlNewTextWriter(xmlOutBuffer); |
75 | 8.47k | if (mpImpl->mpWriter == nullptr) |
76 | 0 | return false; |
77 | 8.47k | xmlTextWriterSetIndent(mpImpl->mpWriter, nIndent); |
78 | 8.47k | if (mpImpl->mbWriteXmlHeader) |
79 | 0 | (void)xmlTextWriterStartDocument(mpImpl->mpWriter, nullptr, "UTF-8", nullptr); |
80 | 8.47k | return true; |
81 | 8.47k | } |
82 | | |
83 | | void XmlWriter::endDocument() |
84 | 8.47k | { |
85 | 8.47k | if (mpImpl->mbWriteXmlHeader) |
86 | 0 | (void)xmlTextWriterEndDocument(mpImpl->mpWriter); |
87 | 8.47k | xmlFreeTextWriter(mpImpl->mpWriter); |
88 | 8.47k | mpImpl->mpWriter = nullptr; |
89 | 8.47k | } |
90 | | |
91 | | void XmlWriter::startElement(const OString& sPrefix, const OString& sName, |
92 | | const OString& sNamespaceUri) |
93 | 16.9k | { |
94 | 16.9k | xmlChar* xmlName = BAD_CAST(sName.getStr()); |
95 | 16.9k | xmlChar* xmlPrefix = nullptr; |
96 | 16.9k | xmlChar* xmlNamespaceUri = nullptr; |
97 | 16.9k | if (!sPrefix.isEmpty()) |
98 | 16.9k | xmlPrefix = BAD_CAST(sPrefix.getStr()); |
99 | 16.9k | if (!sNamespaceUri.isEmpty()) |
100 | 16.9k | xmlNamespaceUri = BAD_CAST(sNamespaceUri.getStr()); |
101 | | |
102 | 16.9k | (void)xmlTextWriterStartElementNS(mpImpl->mpWriter, xmlPrefix, xmlName, xmlNamespaceUri); |
103 | 16.9k | } |
104 | | |
105 | | void XmlWriter::startElement(const char* pName) |
106 | 71.0k | { |
107 | 71.0k | xmlChar* xmlName = BAD_CAST(pName); |
108 | 71.0k | (void)xmlTextWriterStartElement(mpImpl->mpWriter, xmlName); |
109 | 71.0k | } |
110 | | |
111 | 88.0k | void XmlWriter::endElement() { (void)xmlTextWriterEndElement(mpImpl->mpWriter); } |
112 | | |
113 | | void XmlWriter::attributeBase64(const char* pName, std::vector<sal_uInt8> const& rValueInBytes) |
114 | 0 | { |
115 | 0 | attributeBase64_impl(mpImpl->mpWriter, pName, rValueInBytes.data(), rValueInBytes.size()); |
116 | 0 | } |
117 | | |
118 | | void XmlWriter::attributeBase64(const char* pName, std::vector<char> const& rValueInBytes) |
119 | 0 | { |
120 | 0 | attributeBase64_impl(mpImpl->mpWriter, pName, rValueInBytes.data(), rValueInBytes.size()); |
121 | 0 | } |
122 | | |
123 | | void XmlWriter::attribute(const char* name, const OString& value) |
124 | 37.6k | { |
125 | 37.6k | xmlChar* xmlName = BAD_CAST(name); |
126 | 37.6k | xmlChar* xmlValue = BAD_CAST(value.getStr()); |
127 | 37.6k | (void)xmlTextWriterWriteAttribute(mpImpl->mpWriter, xmlName, xmlValue); |
128 | 37.6k | } |
129 | | |
130 | | void XmlWriter::attribute(const char* name, std::u16string_view value) |
131 | 0 | { |
132 | 0 | attribute(name, OUStringToOString(value, RTL_TEXTENCODING_UTF8)); |
133 | 0 | } |
134 | | |
135 | | void XmlWriter::attribute(const char* name, const sal_Int64 aNumber) |
136 | 0 | { |
137 | 0 | attribute(name, OString::number(aNumber)); |
138 | 0 | } |
139 | | |
140 | | void XmlWriter::attributeDouble(const char* name, const double aNumber) |
141 | 0 | { |
142 | 0 | attribute(name, OString::number(aNumber)); |
143 | 0 | } |
144 | | |
145 | | void XmlWriter::content(const OString& sValue) |
146 | 47.4k | { |
147 | 47.4k | xmlChar* xmlValue = BAD_CAST(sValue.getStr()); |
148 | 47.4k | (void)xmlTextWriterWriteString(mpImpl->mpWriter, xmlValue); |
149 | 47.4k | } |
150 | | |
151 | | void XmlWriter::content(std::u16string_view sValue) |
152 | 0 | { |
153 | 0 | content(OUStringToOString(sValue, RTL_TEXTENCODING_UTF8)); |
154 | 0 | } |
155 | | |
156 | | void XmlWriter::element(const char* sName) |
157 | 0 | { |
158 | 0 | startElement(sName); |
159 | 0 | endElement(); |
160 | 0 | } |
161 | | |
162 | | } // end tools namespace |
163 | | |
164 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |