summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2017-11-01 12:46:35 +0900
committerTomaž Vajngerl <quikee@gmail.com>2017-11-01 23:42:02 +0100
commit1f8c3e3b78e0abb96d06a51eca354ae7ade5deb2 (patch)
tree6c402b0638d4294315444e72899e66c8ff5d93f9 /tools
parentecbaf980625a9e7b06abe91c7c70e78f6ad469a7 (diff)
Extract XmlWriter and XmlWalker from opencl into tools
In opencl we read and writer the profile xml with custom classes XmlWriter and XmlWalker for reading. This classes are useful in other places (very similar XmlWriter is used in test), so extract the code from opencl and move it to a more common place - tools. Refactoring of other usages will follow. Change-Id: I8363e87b7c30083d299080adec3f99cb33ebe4cc Reviewed-on: https://gerrit.libreoffice.org/44149 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/Library_tl.mk4
-rw-r--r--tools/source/xml/XmlWalker.cxx112
-rw-r--r--tools/source/xml/XmlWriter.cxx119
3 files changed, 235 insertions, 0 deletions
diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk
index f82338d746cf..ec19ac5100c4 100644
--- a/tools/Library_tl.mk
+++ b/tools/Library_tl.mk
@@ -74,7 +74,10 @@ $(eval $(call gb_Library_add_exception_objects,tl,\
tools/source/stream/vcompat \
tools/source/string/tenccvt \
tools/source/zcodec/zcodec \
+ tools/source/xml/XmlWriter \
+ tools/source/xml/XmlWalker \
))
+
ifeq ($(OS),WNT)
$(eval $(call gb_Library_add_exception_objects,tl, \
tools/source/stream/strmwnt \
@@ -92,6 +95,7 @@ $(eval $(call gb_Library_add_generated_exception_objects,tl,\
$(eval $(call gb_Library_use_externals,tl,\
boost_headers \
zlib \
+ libxml2 \
))
ifeq ($(OS),LINUX)
diff --git a/tools/source/xml/XmlWalker.cxx b/tools/source/xml/XmlWalker.cxx
new file mode 100644
index 000000000000..9bec6d9dd534
--- /dev/null
+++ b/tools/source/xml/XmlWalker.cxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <tools/XmlWalker.hxx>
+#include <o3tl/make_unique.hxx>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xmlstring.h>
+#include <vector>
+
+namespace tools {
+
+struct XmlWalkerImpl
+{
+ XmlWalkerImpl()
+ : mpDocPtr(nullptr)
+ , mpRoot(nullptr)
+ , mpCurrent(nullptr)
+ {}
+
+ xmlDocPtr mpDocPtr;
+ xmlNodePtr mpRoot;
+ xmlNodePtr mpCurrent;
+
+ std::vector<xmlNodePtr> mpStack;
+};
+
+XmlWalker::XmlWalker()
+ : mpImpl(o3tl::make_unique<XmlWalkerImpl>())
+{}
+
+XmlWalker::~XmlWalker()
+{
+ if (mpImpl)
+ xmlFreeDoc(mpImpl->mpDocPtr);
+}
+
+bool XmlWalker::open(SvStream* pStream)
+{
+ std::size_t nSize = pStream->remainingSize();
+ std::vector<sal_uInt8> aBuffer(nSize + 1);
+ pStream->ReadBytes(aBuffer.data(), nSize);
+ aBuffer[nSize] = 0;
+ mpImpl->mpDocPtr = xmlParseDoc(reinterpret_cast<xmlChar*>(aBuffer.data()));
+ if (mpImpl->mpDocPtr == nullptr)
+ return false;
+ mpImpl->mpRoot = xmlDocGetRootElement(mpImpl->mpDocPtr);
+ mpImpl->mpCurrent = mpImpl->mpRoot;
+ mpImpl->mpStack.push_back(mpImpl->mpCurrent);
+ return true;
+}
+
+OString XmlWalker::name()
+{
+ return OString(reinterpret_cast<const char*>(mpImpl->mpCurrent->name));
+}
+
+OString XmlWalker::content()
+{
+ OString aContent;
+ if (mpImpl->mpCurrent->xmlChildrenNode != nullptr)
+ {
+ xmlChar* pContent = xmlNodeListGetString(mpImpl->mpDocPtr, mpImpl->mpCurrent->xmlChildrenNode, 1);
+ aContent = OString(reinterpret_cast<const char*>(pContent));
+ xmlFree(pContent);
+ }
+ return aContent;
+}
+
+void XmlWalker::children()
+{
+ mpImpl->mpStack.push_back(mpImpl->mpCurrent);
+ mpImpl->mpCurrent = mpImpl->mpCurrent->xmlChildrenNode;
+}
+
+void XmlWalker::parent()
+{
+ mpImpl->mpCurrent = mpImpl->mpStack.back();
+ mpImpl->mpStack.pop_back();
+}
+
+OString XmlWalker::attribute(OString sName)
+{
+ xmlChar* xmlName = xmlCharStrdup(sName.getStr());
+ xmlChar* xmlAttribute = xmlGetProp(mpImpl->mpCurrent, xmlName);
+ OString aAttributeContent = OString(reinterpret_cast<const char*>(xmlAttribute));
+ xmlFree(xmlAttribute);
+ xmlFree(xmlName);
+
+ return aAttributeContent;
+}
+
+void XmlWalker::next()
+{
+ mpImpl->mpCurrent = mpImpl->mpCurrent->next;
+}
+
+bool XmlWalker::isValid() const
+{
+ return mpImpl->mpCurrent != nullptr;
+}
+
+} // end tools namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tools/source/xml/XmlWriter.cxx b/tools/source/xml/XmlWriter.cxx
new file mode 100644
index 000000000000..014252bc39aa
--- /dev/null
+++ b/tools/source/xml/XmlWriter.cxx
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <tools/XmlWriter.hxx>
+#include <o3tl/make_unique.hxx>
+
+#include <libxml/xmlwriter.h>
+
+namespace tools {
+
+namespace {
+
+int funcWriteCallback(void* pContext, const char* sBuffer, int nLen)
+{
+ SvStream* pStream = static_cast<SvStream*>(pContext);
+ return static_cast<int>(pStream->WriteBytes(sBuffer, nLen));
+}
+
+int funcCloseCallback(void* pContext)
+{
+ SvStream* pStream = static_cast<SvStream*>(pContext);
+ pStream->Flush();
+ return 0; // 0 or -1 in case of error
+}
+
+} // end anonymous namespace
+
+struct XmlWriterImpl
+{
+ XmlWriterImpl(SvStream* pStream)
+ : mpStream(pStream)
+ , mpWriter(nullptr)
+ {}
+
+ SvStream* mpStream;
+ xmlTextWriterPtr mpWriter;
+};
+
+XmlWriter::XmlWriter(SvStream* pStream)
+ : mpImpl(o3tl::make_unique<XmlWriterImpl>(pStream))
+{}
+
+XmlWriter::~XmlWriter()
+{
+
+ if (mpImpl && mpImpl->mpWriter != nullptr)
+ endDocument();
+}
+
+bool XmlWriter::startDocument()
+{
+ xmlOutputBufferPtr xmlOutBuffer = xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback, mpImpl->mpStream, nullptr);
+ mpImpl->mpWriter = xmlNewTextWriter(xmlOutBuffer);
+ if (mpImpl->mpWriter == nullptr)
+ return false;
+ xmlTextWriterSetIndent(mpImpl->mpWriter, 1);
+ xmlTextWriterStartDocument(mpImpl->mpWriter, nullptr, "UTF-8", nullptr);
+ return true;
+}
+
+void XmlWriter::endDocument()
+{
+ xmlTextWriterEndDocument(mpImpl->mpWriter);
+ xmlFreeTextWriter(mpImpl->mpWriter);
+ mpImpl->mpWriter = nullptr;
+}
+
+void XmlWriter::startElement(const OString& sName)
+{
+ xmlChar* xmlName = xmlCharStrdup(sName.getStr());
+ xmlTextWriterStartElement(mpImpl->mpWriter, xmlName);
+ xmlFree(xmlName);
+}
+
+void XmlWriter::endElement()
+{
+ xmlTextWriterEndElement(mpImpl->mpWriter);
+}
+
+void XmlWriter::attribute(const OString& name, const OString & value)
+{
+ xmlChar* xmlName = xmlCharStrdup(name.getStr());
+ xmlChar* xmlValue = xmlCharStrdup(value.getStr());
+ xmlTextWriterWriteAttribute(mpImpl->mpWriter, xmlName, xmlValue);
+ xmlFree(xmlValue);
+ xmlFree(xmlName);
+}
+
+void XmlWriter::attribute(const OString& name, const OUString& value)
+{
+ attribute(name, OUStringToOString(value, RTL_TEXTENCODING_UTF8).getStr());
+}
+
+void XmlWriter::attribute(const OString& name, const sal_Int32 aNumber)
+{
+ attribute(name, OUString::number(aNumber));
+}
+
+void XmlWriter::content(const OString& sValue)
+{
+ xmlChar* xmlValue = xmlCharStrdup(sValue.getStr());
+ xmlTextWriterWriteString(mpImpl->mpWriter, xmlValue);
+ xmlFree(xmlValue);
+}
+
+void XmlWriter::content(const OUString& sValue)
+{
+ content(OUStringToOString(sValue, RTL_TEXTENCODING_UTF8));
+}
+
+} // end tools namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */