Avoid potential negative array index access to cached text.
[LibreOffice.git] / tools / source / xml / XmlWriter.cxx
blob424b13c67b0176220e264faf3a18f47c67ad4157
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <tools/stream.hxx>
11 #include <tools/XmlWriter.hxx>
13 #include <libxml/xmlwriter.h>
15 namespace tools
17 namespace
19 int funcWriteCallback(void* pContext, const char* sBuffer, int nLen)
21 SvStream* pStream = static_cast<SvStream*>(pContext);
22 return static_cast<int>(pStream->WriteBytes(sBuffer, nLen));
25 int funcCloseCallback(void* pContext)
27 SvStream* pStream = static_cast<SvStream*>(pContext);
28 pStream->Flush();
29 return 0; // 0 or -1 in case of error
32 } // end anonymous namespace
34 struct XmlWriterImpl
36 XmlWriterImpl(SvStream* pStream)
37 : mpStream(pStream)
38 , mpWriter(nullptr)
39 , mbWriteXmlHeader(true)
43 SvStream* mpStream;
44 xmlTextWriterPtr mpWriter;
45 bool mbWriteXmlHeader;
48 XmlWriter::XmlWriter(SvStream* pStream)
49 : mpImpl(std::make_unique<XmlWriterImpl>(pStream))
53 XmlWriter::~XmlWriter()
55 if (mpImpl && mpImpl->mpWriter != nullptr)
56 endDocument();
59 bool XmlWriter::startDocument(sal_Int32 nIndent, bool bWriteXmlHeader)
61 mpImpl->mbWriteXmlHeader = bWriteXmlHeader;
62 xmlCharEncodingHandlerPtr pEncodingHandler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8);
63 xmlOutputBufferPtr xmlOutBuffer = xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback,
64 mpImpl->mpStream, pEncodingHandler);
65 mpImpl->mpWriter = xmlNewTextWriter(xmlOutBuffer);
66 if (mpImpl->mpWriter == nullptr)
67 return false;
68 xmlTextWriterSetIndent(mpImpl->mpWriter, nIndent);
69 if (mpImpl->mbWriteXmlHeader)
70 (void)xmlTextWriterStartDocument(mpImpl->mpWriter, nullptr, "UTF-8", nullptr);
71 return true;
74 void XmlWriter::endDocument()
76 if (mpImpl->mbWriteXmlHeader)
77 (void)xmlTextWriterEndDocument(mpImpl->mpWriter);
78 xmlFreeTextWriter(mpImpl->mpWriter);
79 mpImpl->mpWriter = nullptr;
82 void XmlWriter::startElement(const OString& sPrefix, const OString& sName,
83 const OString& sNamespaceUri)
85 xmlChar* xmlName = BAD_CAST(sName.getStr());
86 xmlChar* xmlPrefix = nullptr;
87 xmlChar* xmlNamespaceUri = nullptr;
88 if (!sPrefix.isEmpty())
89 xmlPrefix = BAD_CAST(sPrefix.getStr());
90 if (!sNamespaceUri.isEmpty())
91 xmlNamespaceUri = BAD_CAST(sNamespaceUri.getStr());
93 (void)xmlTextWriterStartElementNS(mpImpl->mpWriter, xmlPrefix, xmlName, xmlNamespaceUri);
96 void XmlWriter::startElement(const char* pName)
98 xmlChar* xmlName = BAD_CAST(pName);
99 (void)xmlTextWriterStartElement(mpImpl->mpWriter, xmlName);
102 void XmlWriter::startElement(const OString& rName)
104 xmlChar* xmlName = BAD_CAST(rName.getStr());
105 (void)xmlTextWriterStartElement(mpImpl->mpWriter, xmlName);
108 void XmlWriter::endElement() { (void)xmlTextWriterEndElement(mpImpl->mpWriter); }
110 void XmlWriter::attributeBase64(const char* pName, std::vector<sal_uInt8> const& rValueInBytes)
112 std::vector<char> aSignedBytes(rValueInBytes.begin(), rValueInBytes.end());
113 attributeBase64(pName, aSignedBytes);
116 void XmlWriter::attributeBase64(const char* pName, std::vector<char> const& rValueInBytes)
118 xmlChar* xmlName = BAD_CAST(pName);
119 (void)xmlTextWriterStartAttribute(mpImpl->mpWriter, xmlName);
120 (void)xmlTextWriterWriteBase64(mpImpl->mpWriter, rValueInBytes.data(), 0, rValueInBytes.size());
121 (void)xmlTextWriterEndAttribute(mpImpl->mpWriter);
124 void XmlWriter::attribute(const char* name, const OString& value)
126 xmlChar* xmlName = BAD_CAST(name);
127 xmlChar* xmlValue = BAD_CAST(value.getStr());
128 (void)xmlTextWriterWriteAttribute(mpImpl->mpWriter, xmlName, xmlValue);
131 void XmlWriter::attribute(const OString& name, const OString& value)
133 xmlChar* xmlName = BAD_CAST(name.getStr());
134 xmlChar* xmlValue = BAD_CAST(value.getStr());
135 (void)xmlTextWriterWriteAttribute(mpImpl->mpWriter, xmlName, xmlValue);
138 void XmlWriter::attribute(const char* name, std::u16string_view value)
140 attribute(name, OUStringToOString(value, RTL_TEXTENCODING_UTF8));
143 void XmlWriter::attribute(const char* name, const sal_Int32 aNumber)
145 attribute(name, OString::number(aNumber));
148 void XmlWriter::attributeDouble(const char* name, const double aNumber)
150 attribute(name, OString::number(aNumber));
153 void XmlWriter::content(const OString& sValue)
155 xmlChar* xmlValue = BAD_CAST(sValue.getStr());
156 (void)xmlTextWriterWriteString(mpImpl->mpWriter, xmlValue);
159 void XmlWriter::content(std::u16string_view sValue)
161 content(OUStringToOString(sValue, RTL_TEXTENCODING_UTF8));
164 void XmlWriter::element(const char* sName)
166 startElement(sName);
167 endElement();
170 } // end tools namespace
172 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */