[Libreoffice-commits] core.git: include/tools opencl/inc tools/Library_tl.mk tools/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Wed Nov 1 22:42:27 UTC 2017


 include/tools/XmlWalker.hxx          |   55 ++++++++++
 include/tools/XmlWriter.hxx          |   58 +++++++++++
 opencl/inc/opencl_device_selection.h |  182 +----------------------------------
 tools/Library_tl.mk                  |    4 
 tools/source/xml/XmlWalker.cxx       |  112 +++++++++++++++++++++
 tools/source/xml/XmlWriter.cxx       |  119 ++++++++++++++++++++++
 6 files changed, 356 insertions(+), 174 deletions(-)

New commits:
commit 1f8c3e3b78e0abb96d06a51eca354ae7ade5deb2
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Wed Nov 1 12:46:35 2017 +0900

    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 at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/include/tools/XmlWalker.hxx b/include/tools/XmlWalker.hxx
new file mode 100644
index 000000000000..4d4bc88f363c
--- /dev/null
+++ b/include/tools/XmlWalker.hxx
@@ -0,0 +1,55 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_TOOLS_XMLWALKER_HXX
+#define INCLUDED_TOOLS_XMLWALKER_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/stream.hxx>
+#include <memory>
+
+namespace tools {
+
+struct XmlWalkerImpl;
+
+/**
+ * XmlWalker main purpose is to make it easier for walking the
+ * parsed XML DOM tree.
+ *
+ * It hides all the libxml2 and C -isms and makes the usage more
+ * comfortable from LO developer point of view.
+ *
+ */
+class TOOLS_DLLPUBLIC XmlWalker final
+{
+private:
+    std::unique_ptr<XmlWalkerImpl> mpImpl;
+
+public:
+    XmlWalker();
+
+    ~XmlWalker();
+
+    bool open(SvStream* pStream);
+
+    OString name();
+
+    OString content();
+    void children();
+    void parent();
+    void next();
+    bool isValid() const;
+    OString attribute(OString sName);
+};
+
+} // end tools namespace
+
+#endif // INCLUDED_TOOLS_XMLWRITER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/XmlWriter.hxx b/include/tools/XmlWriter.hxx
new file mode 100644
index 000000000000..c454f4139803
--- /dev/null
+++ b/include/tools/XmlWriter.hxx
@@ -0,0 +1,58 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_TOOLS_XMLWRITER_HXX
+#define INCLUDED_TOOLS_XMLWRITER_HXX
+
+#include <tools/toolsdllapi.h>
+#include <tools/stream.hxx>
+#include <memory>
+
+namespace tools {
+
+struct XmlWriterImpl;
+
+/**
+ * XmlWriter writes a XML to a SvStream. It uses libxml2 for writing but hides
+ * all the internal libxml2 workings and uses types that are native for LO
+ * development.
+ *
+ * The codepage used for XML is always "utf-8" and the output is indented so it
+ * is easier to read.
+ *
+ */
+class TOOLS_DLLPUBLIC XmlWriter final
+{
+private:
+    std::unique_ptr<XmlWriterImpl> mpImpl;
+public:
+
+    XmlWriter(SvStream* pStream);
+
+    ~XmlWriter();
+
+    bool startDocument();
+    void endDocument();
+
+    void startElement(const OString& sName);
+    void endElement();
+
+    void attribute(const OString& sTagName, const OString& aValue);
+    void attribute(const OString& sTagName, const OUString& aValue);
+    void attribute(const OString& sTagName, sal_Int32 aNumber);
+
+    void content(const OString& sValue);
+    void content(const OUString& sValue);
+};
+
+} // end tools namespace
+
+#endif // INCLUDED_TOOLS_XMLWRITER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/opencl/inc/opencl_device_selection.h b/opencl/inc/opencl_device_selection.h
index 54caf183f2aa..5ebc87a9410c 100644
--- a/opencl/inc/opencl_device_selection.h
+++ b/opencl/inc/opencl_device_selection.h
@@ -21,9 +21,9 @@
 #include <string.h>
 
 #include <clew/clew.h>
-#include <libxml/xmlwriter.h>
-#include <libxml/xmlstring.h>
 #include <tools/stream.hxx>
+#include <tools/XmlWriter.hxx>
+#include <tools/XmlWalker.hxx>
 #include <rtl/math.hxx>
 
 #include <opencl/OpenCLZone.hxx>
@@ -235,172 +235,6 @@ inline ds_status initDSProfile(std::unique_ptr<ds_profile>& rProfile, OString co
     return DS_SUCCESS;
 }
 
-/**
- * XmlWriter writes a XML to a SvStream. It uses libxml2 for writing but hides
- * all the internal libxml2 workings and uses types that are native for LO
- * development.
- *
- * The codepage used for XML is always "utf-8" and the output is indented so it
- * is easier to read.
- *
- * TODO: move to common code
- */
-class XmlWriter
-{
-private:
-    SvStream* mpStream;
-    xmlTextWriterPtr mpWriter;
-
-    static int funcWriteCallback(void* pContext, const char* sBuffer, int nLen)
-    {
-        SvStream* pStream = static_cast<SvStream*>(pContext);
-        return static_cast<int>(pStream->WriteBytes(sBuffer, nLen));
-    }
-
-    static int funcCloseCallback(void* pContext)
-    {
-        SvStream* pStream = static_cast<SvStream*>(pContext);
-        pStream->Flush();
-        return 0; // 0 or -1 in case of error
-    }
-
-public:
-
-    XmlWriter(SvStream* pStream)
-        : mpStream(pStream)
-        , mpWriter(nullptr)
-    {
-    }
-
-    ~XmlWriter()
-    {
-        if (mpWriter != nullptr)
-            endDocument();
-    }
-
-    bool startDocument()
-    {
-        xmlOutputBufferPtr xmlOutBuffer = xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback, mpStream, nullptr);
-        mpWriter = xmlNewTextWriter(xmlOutBuffer);
-        if (mpWriter == nullptr)
-            return false;
-        xmlTextWriterSetIndent(mpWriter, 1);
-        xmlTextWriterStartDocument(mpWriter, nullptr, "UTF-8", nullptr);
-        return true;
-    }
-
-    void endDocument()
-    {
-        xmlTextWriterEndDocument(mpWriter);
-        xmlFreeTextWriter(mpWriter);
-        mpWriter = nullptr;
-    }
-
-    void startElement(const OString& sName)
-    {
-        xmlChar* xmlName = xmlCharStrdup(sName.getStr());
-        xmlTextWriterStartElement(mpWriter, xmlName);
-        xmlFree(xmlName);
-    }
-
-    void endElement()
-    {
-        xmlTextWriterEndElement(mpWriter);
-    }
-
-    void content(const OString& sValue)
-    {
-        xmlChar* xmlValue = xmlCharStrdup(sValue.getStr());
-        xmlTextWriterWriteString(mpWriter, xmlValue);
-        xmlFree(xmlValue);
-    }
-};
-
-/**
- * XmlWalker main purpose is to make it easier for walking the
- * parsed XML DOM tree.
- *
- * It hides all the libxml2 and C -isms and makes the usage more
- * comfortable from LO developer point of view.
- *
- * TODO: move to common code
- */
-class XmlWalker
-{
-private:
-    xmlDocPtr mpDocPtr;
-    xmlNodePtr mpRoot;
-    xmlNodePtr mpCurrent;
-
-    std::vector<xmlNodePtr> mpStack;
-
-public:
-    XmlWalker()
-        : mpDocPtr(nullptr)
-        , mpRoot(nullptr)
-        , mpCurrent(nullptr)
-    {}
-
-    ~XmlWalker()
-    {
-        xmlFreeDoc(mpDocPtr);
-    }
-
-    bool open(SvStream* pStream)
-    {
-        std::size_t nSize = pStream->remainingSize();
-        std::vector<sal_uInt8> aBuffer(nSize + 1);
-        pStream->ReadBytes(aBuffer.data(), nSize);
-        aBuffer[nSize] = 0;
-        mpDocPtr = xmlParseDoc(reinterpret_cast<xmlChar*>(aBuffer.data()));
-        if (mpDocPtr == nullptr)
-            return false;
-        mpRoot = xmlDocGetRootElement(mpDocPtr);
-        mpCurrent = mpRoot;
-        mpStack.push_back(mpCurrent);
-        return true;
-    }
-
-    OString name()
-    {
-        return OString(reinterpret_cast<const char*>(mpCurrent->name));
-    }
-
-    OString content()
-    {
-        OString aContent;
-        if (mpCurrent->xmlChildrenNode != nullptr)
-        {
-            xmlChar* pContent = xmlNodeListGetString(mpDocPtr, mpCurrent->xmlChildrenNode, 1);
-            aContent = OString(reinterpret_cast<const char*>(pContent));
-            xmlFree(pContent);
-        }
-        return aContent;
-    }
-
-    void children()
-    {
-        mpStack.push_back(mpCurrent);
-        mpCurrent = mpCurrent->xmlChildrenNode;
-    }
-
-    void parent()
-    {
-        mpCurrent = mpStack.back();
-        mpStack.pop_back();
-    }
-
-    void next()
-    {
-        mpCurrent = mpCurrent->next;
-    }
-
-    bool isValid() const
-    {
-        return mpCurrent != nullptr;
-    }
-};
-
 inline ds_status writeProfile(const OUString& rStreamName, std::unique_ptr<ds_profile> const & pProfile)
 {
     if (pProfile == nullptr)
@@ -411,7 +245,7 @@ inline ds_status writeProfile(const OUString& rStreamName, std::unique_ptr<ds_pr
     std::unique_ptr<SvStream> pStream;
     pStream.reset(new SvFileStream(rStreamName, StreamMode::STD_READWRITE | StreamMode::TRUNC));
 
-    XmlWriter aXmlWriter(pStream.get());
+    tools::XmlWriter aXmlWriter(pStream.get());
 
     if (!aXmlWriter.startDocument())
         return DS_FILE_ERROR;
@@ -430,12 +264,12 @@ inline ds_status writeProfile(const OUString& rStreamName, std::unique_ptr<ds_pr
         {
             case DeviceType::NativeCPU:
                 aXmlWriter.startElement("type");
-                aXmlWriter.content("native");
+                aXmlWriter.content(OString("native"));
                 aXmlWriter.endElement();
                 break;
             case DeviceType::OpenCLDevice:
                 aXmlWriter.startElement("type");
-                aXmlWriter.content("opencl");
+                aXmlWriter.content(OString("opencl"));
                 aXmlWriter.endElement();
 
                 aXmlWriter.startElement("name");
@@ -452,13 +286,13 @@ inline ds_status writeProfile(const OUString& rStreamName, std::unique_ptr<ds_pr
 
         aXmlWriter.startElement("time");
         if (rtl::math::approxEqual(rDevice.fTime, DBL_MAX))
-            aXmlWriter.content("max");
+            aXmlWriter.content(OString("max"));
         else
             aXmlWriter.content(OString::number(rDevice.fTime));
         aXmlWriter.endElement();
 
         aXmlWriter.startElement("errors");
-        aXmlWriter.content(rDevice.bErrors ? "true" : "false");
+        aXmlWriter.content(rDevice.bErrors ? OString("true") : OString("false"));
         aXmlWriter.endElement();
 
         aXmlWriter.endElement();
@@ -479,7 +313,7 @@ inline ds_status readProfile(const OUString& rStreamName, std::unique_ptr<ds_pro
 
     std::unique_ptr<SvStream> pStream;
     pStream.reset(new SvFileStream(rStreamName, StreamMode::READ));
-    XmlWalker aWalker;
+    tools::XmlWalker aWalker;
 
     if (!aWalker.open(pStream.get()))
         return DS_FILE_ERROR;
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: */


More information about the Libreoffice-commits mailing list