Commit b8b1566f07600e8abac7d4c7770034e228c6d35d

Authored by Peter M. Groen
1 parent f12cc090

Finished setting up code..

CMakeLists.txt
... ... @@ -7,6 +7,9 @@ LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
7 7 include(projectheader)
8 8 project_header(osdev_xml)
9 9  
  10 +# First we build all the artifacts / dependencies
  11 +add_subdirectory(submodules/logger)
  12 +
10 13 add_subdirectory(src)
11 14 #add_subdirectory(test)
12 15 #add_subdirectory(examples)
... ...
src/xmlbase.cpp
1   -#include "dcxmlbase.h"
  1 +/* ****************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a *
  5 + * copy of this software and associated documentation files (the "Software"), *
  6 + * to deal in the Software without restriction, including without limitation *
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  8 + * and/or sell copies of the Software, and to permit persons to whom the *
  9 + * Software is furnished to do so, subject to the following conditions: *
  10 + * *
  11 + * The above copyright notice and this permission notice shall be included in *
  12 + * all copies or substantial portions of the Software. *
  13 + * *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
  17 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  18 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
  19 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
  20 + * DEALINGS IN THE SOFTWARE. *
  21 + * ***************************************************************************/
  22 +
  23 +#include "xmlbase.h"
2 24 #include "log.h"
3 25  
4 26 /*
... ... @@ -27,24 +49,24 @@ void xml_string_writer::write(const void* data, size_t size)
27 49 result += std::string(static_cast<const char*>(data), size);
28 50 }
29 51  
30   -DcXmlBase::DcXmlBase(const QString& xmlFile)
  52 +XmlBase::XmlBase(const QString& xmlFile)
31 53 : m_xmldoc()
32 54 , m_xPathHash()
33 55 {
34 56 if (!xmlFile.isNull() || !xmlFile.isEmpty()) {
35 57 if (parseFile(xmlFile)) {
36   - LogDebug("[DcXmlBase::DcXmlBase]", QString("File : %1 ..............[OK].").arg(xmlFile).toStdString());
  58 + LogDebug("[XmlBase::XmlBase]", QString("File : %1 ..............[OK].").arg(xmlFile).toStdString());
37 59 }
38 60 else {
39   - LogError("[DcXmlBase::DcXmlBase]", QString("File : %1 ..............[Failed].").arg(xmlFile).toStdString());
40   - throw std::runtime_error("[DcXmlBase::DcXmlBase] parseFile failed");
  61 + LogError("[XmlBase::XmlBase]", QString("File : %1 ..............[Failed].").arg(xmlFile).toStdString());
  62 + throw std::runtime_error("[XmlBase::XmlBase] parseFile failed");
41 63 }
42 64 }
43 65 }
44 66  
45   -DcXmlBase::~DcXmlBase() = default;
  67 +XmlBase::~XmlBase() = default;
46 68  
47   -bool DcXmlBase::parseString(const QString& qsXml)
  69 +bool XmlBase::parseString(const QString& qsXml)
48 70 {
49 71 bool bResult = false;
50 72  
... ... @@ -58,7 +80,7 @@ bool DcXmlBase::parseString(const QString&amp; qsXml)
58 80 return bResult;
59 81 }
60 82  
61   -bool DcXmlBase::parseFile(const QString& qsXml)
  83 +bool XmlBase::parseFile(const QString& qsXml)
62 84 {
63 85 bool bResult = false;
64 86  
... ... @@ -70,7 +92,7 @@ bool DcXmlBase::parseFile(const QString&amp; qsXml)
70 92 return bResult;
71 93 }
72 94  
73   -bool DcXmlBase::checkError(pugi::xml_parse_status _parseStatus)
  95 +bool XmlBase::checkError(pugi::xml_parse_status _parseStatus)
74 96 {
75 97 bool bResult = false;
76 98 QString sLogMessage = "An unknown error occured.";
... ... @@ -134,47 +156,48 @@ bool DcXmlBase::checkError(pugi::xml_parse_status _parseStatus)
134 156 // case pugi::status_no_document_element:
135 157 }
136 158 #pragma GCC diagnostic pop
137   - LogDebug("[DcXmlBase::checkError]", sLogMessage.toStdString());
  159 + LogDebug("[XmlBase::checkError]", sLogMessage.toStdString());
138 160 return bResult;
139 161 }
140 162  
141   -void DcXmlBase::addXPath(const QString& qsName, const QString& qsXPath)
  163 +void XmlBase::addXPath(const QString& qsName, const QString& qsXPath)
142 164 {
143 165 if (m_xPathHash.contains(qsName)) {
144   - LogWarning("[DcXmlBase::addXPath]", std::string( "XPath already registered : " + qsName.toStdString()));
  166 + LogWarning("[XmlBase::addXPath]", QString( "XPath already registered : " + qsName).toStdString());
145 167 }
146 168 m_xPathHash.insert(qsName, qsXPath);
147 169  
148   - LogDebug("[DcXmlBase::addXPath]", std::string("XPath" + qsXPath.toStdString() + " registered with key : " + qsName.toStdString()));
  170 + LogDebug("[XmlBase::addXPath]", QString("XPath" + qsXPath + " registered with key : " + qsName).toStdString());
149 171 }
150 172  
151   -QString DcXmlBase::getXPath(const QString& qsXPathSelect) const
  173 +QString XmlBase::getXPath(const QString& qsXPathSelect) const
152 174 {
153 175 QString qsXPath = m_xPathHash.value(qsXPathSelect);
154 176  
155 177 if (qsXPath.isEmpty()) {
156   - LogWarning("dcxml", "XPath not registered : " + qsXPathSelect);
  178 + LogWarning("[XmlBase::getXPath]", QString("XPath not registered : " + qsXPathSelect).toStdString());
157 179 }
158 180  
159 181 return qsXPath;
160 182 }
161 183  
162   -QString DcXmlBase::evaluateXPath(const QString& qsXPathSelect,
  184 +QString XmlBase::evaluateXPath(const QString& qsXPathSelect,
163 185 const QList<QVariant>& arguments) const
164 186 {
165 187 QString qsResult = getXPath(qsXPathSelect);
166 188  
167   - // LogInfo( "DcXmlBase::evaluateXPath", QString( "Found XPathExpression : " + qsResult + " for selection : " + qsXPathSelect ) );
  189 + LogDebug( "[XmlBase::evaluateXPath]", QString( "Found XPathExpression : " + qsResult + " for selection : " + qsXPathSelect ).toStdString() );
168 190  
169   - for (auto& value : arguments) {
  191 + for (auto& value : arguments)
  192 + {
170 193 qsResult = qsResult.arg(value.toString());
171 194 }
172 195  
173   - // LogInfo( "DcXmlBase::evaluateXPath", QString( "Resulting XPathExpression : " + qsResult ) );
  196 + LogInfo("[XmlBase::evaluateXPath]", QString("Resulting XPathExpression : " + qsResult).toStdString());
174 197 return qsResult;
175 198 }
176 199  
177   -void DcXmlBase::setSimpleData(const QString& qsXPathSelect,
  200 +void XmlBase::setSimpleData(const QString& qsXPathSelect,
178 201 const QList<QVariant>& arguments,
179 202 const QVariant& data)
180 203 {
... ... @@ -182,14 +205,14 @@ void DcXmlBase::setSimpleData(const QString&amp; qsXPathSelect,
182 205 setNodeData(qsXPath, data);
183 206 }
184 207  
185   -void DcXmlBase::setSimpleData(const QString& qsXPathSelect, const QVariant& data)
  208 +void XmlBase::setSimpleData(const QString& qsXPathSelect, const QVariant& data)
186 209 {
187 210 QString qsXPath = getXPath(qsXPathSelect);
188 211  
189 212 setNodeData(qsXPath, data);
190 213 }
191 214  
192   -QVariant DcXmlBase::getSimpleData(const QString& qsXPathSelect,
  215 +QVariant XmlBase::getSimpleData(const QString& qsXPathSelect,
193 216 const QList<QVariant>& arguments) const
194 217 {
195 218 QString qsXPath = evaluateXPath(qsXPathSelect, arguments);
... ... @@ -200,7 +223,7 @@ QVariant DcXmlBase::getSimpleData(const QString&amp; qsXPathSelect,
200 223 }
201 224  
202 225 // static
203   -bool DcXmlBase::getBoolean(const QVariant& value)
  226 +bool XmlBase::getBoolean(const QVariant& value)
204 227 {
205 228 bool b_result = false;
206 229  
... ... @@ -220,7 +243,7 @@ bool DcXmlBase::getBoolean(const QVariant&amp; value)
220 243 }
221 244  
222 245 // static
223   -QString DcXmlBase::getAttributeValue(const pugi::xml_node& xmlNode, const char* attributeName)
  246 +QString XmlBase::getAttributeValue(const pugi::xml_node& xmlNode, const char* attributeName)
224 247 {
225 248 const auto attr = xmlNode.attribute(attributeName);
226 249 if (attr.empty()) {
... ... @@ -229,12 +252,12 @@ QString DcXmlBase::getAttributeValue(const pugi::xml_node&amp; xmlNode, const char*
229 252 return attr.value();
230 253 }
231 254  
232   -pugi::xpath_node DcXmlBase::selectNode(const QString& qsXPath) const
  255 +pugi::xpath_node XmlBase::selectNode(const QString& qsXPath) const
233 256 {
234 257 return m_xmldoc.select_node(qsXPath.toStdString().c_str());
235 258 }
236 259  
237   -QList<pugi::xpath_node> DcXmlBase::selectNodes(const QString& qsXPath) const
  260 +QList<pugi::xpath_node> XmlBase::selectNodes(const QString& qsXPath) const
238 261 {
239 262 QList<pugi::xpath_node> lstResult;
240 263  
... ... @@ -246,7 +269,7 @@ QList&lt;pugi::xpath_node&gt; DcXmlBase::selectNodes(const QString&amp; qsXPath) const
246 269 return lstResult;
247 270 }
248 271  
249   -void DcXmlBase::setNodeData(const QString& qsXPath, const QVariant& qsData)
  272 +void XmlBase::setNodeData(const QString& qsXPath, const QVariant& qsData)
250 273 {
251 274 pugi::xml_node selectedNode;
252 275 selectedNode = selectNode(qsXPath).node();
... ... @@ -255,13 +278,11 @@ void DcXmlBase::setNodeData(const QString&amp; qsXPath, const QVariant&amp; qsData)
255 278 selectedNode.set_value(qsData.toString().toStdString().c_str());
256 279 }
257 280 else {
258   - LogError("dcxml",
259   - QString("No node(s) found for XPath expression : '%1'")
260   - .arg(qsXPath));
  281 + LogError("[XmlBase::setNodeData]", QString("No node(s) found for XPath expression : '%1'").arg(qsXPath).toStdString());
261 282 }
262 283 }
263 284  
264   -QVariant DcXmlBase::getNodeData(const QString& qsXPath) const
  285 +QVariant XmlBase::getNodeData(const QString& qsXPath) const
265 286 {
266 287 QVariant qvResult;
267 288 pugi::xml_node selectedNode = selectNode(qsXPath).node();
... ... @@ -271,7 +292,7 @@ QVariant DcXmlBase::getNodeData(const QString&amp; qsXPath) const
271 292 return qvResult;
272 293 }
273 294  
274   -QString DcXmlBase::asString() const
  295 +QString XmlBase::asString() const
275 296 {
276 297 xml_string_writer writer;
277 298 m_xmldoc.save(writer);
... ...
src/xmlbase.h
1 1 /* ****************************************************************************
2   - * Copyright 2022 Open Systems Development BV *
  2 + * Copyright 2019 Open Systems Development BV *
3 3 * *
4 4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 5 * copy of this software and associated documentation files (the "Software"), *
... ... @@ -19,23 +19,22 @@
19 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
20 20 * DEALINGS IN THE SOFTWARE. *
21 21 * ***************************************************************************/
22   -
23 22 #pragma once
24 23  
25 24 #include <pugixml.hpp>
26 25 #include <string>
27   -#include <vector>
28   -#include <variant>
  26 +
  27 +#include <QtCore>
29 28  
30 29 namespace osdev {
31 30 namespace components {
32 31 namespace xml {
33 32  
34 33 /*!
35   - * \brief xml_string_writer
36   - * This struct is used to write a pugixml DOM document to a std::string.
37   - * pugiXML is not able to do this on its own, but we use the possibility
38   - * to dump an xml-document to std::cout.
  34 + * \brief xml_string_writer
  35 + * This struct is used to write a pugiXL DOM document to a std::string (QString)
  36 + * pugiXML is not able to this on its own, but we use the possibility to dump
  37 + * an XML-document to std::cout
39 38 */
40 39 struct xml_string_writer : pugi::xml_writer
41 40 {
... ... @@ -44,50 +43,159 @@ struct xml_string_writer : pugi::xml_writer
44 43 };
45 44  
46 45 /*!
47   - * \brief The XmlBase class describes the base class for all xml related classes.
48   - * The basic functionality is implemented here. This class is intrended to
49   - * be inherited an d specialized and not to be used directly. ( Nothing bad
50   - * will happen, just to make life easier. )
  46 + * \brief The XmlBase class describes the base class for all xml related classes
  47 + * The basic functionality is implemented here. This class is intended to
  48 + * be inherited and specialized and not to be used directly. ( Nothing bad
  49 + * will happen, just to make life easier )
  50 + */
  51 +/*
  52 + * ________________________________________
  53 + * / I'm serious about thinking through all \
  54 + * | the possibilities before we settle on |
  55 + * | anything. All things have the |
  56 + * | advantages of their disadvantages, and |
  57 + * | vice versa. |
  58 + * | |
  59 + * | -- Larry Wall in |
  60 + * \ <199709032332.QAA21669@wall.org> /
  61 + * ----------------------------------------
  62 + * \
  63 + * \
  64 + * .--.
  65 + * |o_o |
  66 + * |:_/ |
  67 + * // \ \
  68 + * (| | )
  69 + * /'\_ _/`\
  70 + * \___)=(___/
51 71 */
  72 +
52 73 class XmlBase
53 74 {
54 75 public:
55 76 /*! Default constructor */
56   - explicit XmlBase(const std::string xmlFile = std::string() );
  77 + explicit XmlBase(const QString& xmlFile = QString());
57 78 virtual ~XmlBase();
58 79  
59 80 /*!
60   - * \brief Parses the xml contents of the string.
61   - * \param sxml - String containing the xml-string
62   - * \return true if succesful, false if not...
  81 + * \brief Parses the XML contents of the string.
  82 + * \param qsXml - String containing the contents of the XML-string
  83 + * \return true if successfull, false if not...
63 84 */
64   - bool parseString(const std::string &sxml);
  85 + bool parseString(const QString& qsXml);
65 86  
66 87 /*!
67   - * \brief Parses the contents of the givenm XML-file.
68   - * \param sxml - String with the filepath & -name of the xml file.
69   - * \return true if succesfull, false if not.
  88 + * \brief Parses the contents of the given XML-file.
  89 + * \param qsXml - String with the filepath & -name of the XML file.
  90 + * \return true if successfull, false if not...
70 91 */
71   - bool parseFile(const std::string sxml);
  92 + bool parseFile(const QString& qsXml);
72 93  
73 94 /*!
74   - * \brief Adds and XPath expression to the internal structure.
75   - * \param sName - Name of the XPath expression. This should be descriptive to make life easier.
76   - * \param sXPath - The XPath expression to the specific data we're interested in.
  95 + * \brief Adds an XPath expression to the internal structure.
  96 + * \param qsName - Name of the XPath expression. This should be descriptive to make life easier
  97 + * \param qsXPath - The XPath expression to the specific data we're interested in.
77 98 */
78   - void addXPath(const std::string &sName, const std::string &sXPath);
  99 + void addXPath(const QString& qsName, const QString& qsXPath);
79 100  
80 101 /*!
81   - * \brief Retrieves an XPatrh expression from the internal structure
82   - * \param sXpathSelect - The name of the XPath expression
83   - * \return The XPath expression as stored in the internal Hash.
  102 + * \brief Retrieves an XPath expression from the internal structure
  103 + * \param qsXPathSelect - The name of the XPath expression.
  104 + * \return The XPath expression as stored in the internal Hash
84 105 */
85   - std::string getXPath(const std::string &sXpathSelect);
  106 + QString getXPath(const QString& qsXPathSelect) const;
86 107  
  108 + /*!
  109 + * \brief Interprets the XPath expression and adds values to the variables.
  110 + * \param qsXPathSelect - The XPath expression as given by getXPath.
  111 + * \param arguments - The list of variables to be added to the XPath expression.
  112 + * \return The interpreted XPath expression.
  113 + */
  114 + QString evaluateXPath(const QString& qsXPathSelect, const QList<QVariant>& arguments) const;
87 115  
88   -};
  116 + /*!
  117 + * \brief Set a simple node in the xml-doc.
  118 + * \param qsXPathSelect - The XPath expression of the node we want to set.
  119 + * \param arguments - the list of arguments in the node
  120 + * \param data - The nodetext.
  121 + */
  122 + void setSimpleData(const QString& qsXPathSelect, const QList<QVariant>& arguments, const QVariant& data);
89 123  
  124 + /*!
  125 + * \brief Set a simple node in the xml-doc.
  126 + * \param qsXPathSelect - The XPath expression of the node we want to set.
  127 + * \param data - The nodetext.
  128 + */
  129 + void setSimpleData(const QString& qsXPathSelect, const QVariant& data);
  130 +
  131 + QVariant getSimpleData(const QString& qsXPathSelect, const QList<QVariant>& arguments) const;
  132 +
  133 + /*!
  134 + * \brief Retreive a single node based on the XPath expression
  135 + * \param qsXPath - The XPath expression
  136 + * \return - a single xpath-node
  137 + */
  138 + pugi::xpath_node selectNode(const QString& qsXPath) const;
  139 +
  140 + /*!
  141 + * \brief Retreives a list of nodes based on the given XPath expression
  142 + * \param qsXPath - The XPath expression
  143 + * \return - The list of nodes
  144 + */
  145 + QList<pugi::xpath_node> selectNodes(const QString& qsXPath) const;
  146 +
  147 + /*! Added for convenience. The DOMTree is exported as QString */
  148 + QString asString() const;
  149 +
  150 + /*! Helper method for the setSimpleData */
  151 + void setNodeData(const QString& qsXPath, const QVariant& qsData);
  152 +
  153 + //! Helper method for the getSimpleData. Get data from the node that
  154 + //! is selected with the XPath expression.
  155 + virtual QVariant getNodeData(const QString& qsXPath) const;
  156 +
  157 + /**
  158 + * @brief Turns a value into a boolean.
  159 + * @param value Value to be interpreted.
  160 + * @return boolean representation of value
  161 + *
  162 + * The following (capitalised) items convert to "true" :
  163 + * - Y
  164 + * - YES
  165 + * - TRUE
  166 + * - ON
  167 + * - 1
  168 + *
  169 + * Everything else converts to false.
  170 + */
  171 + static bool getBoolean(const QVariant& value);
  172 +
  173 + /**
  174 + * @param xmlNode The node to query for an attribute value.
  175 + * @param attributeName The name of the attribute to query.
  176 + * @return an attribute value.
  177 + * @retval value as QString
  178 + * @retval null QString when the attribute is not found.
  179 + */
  180 + static QString getAttributeValue(const pugi::xml_node& xmlNode, const char* attributeName);
  181 +
  182 +private:
  183 + /*!
  184 + * \brief Translates the pugiXML status into Human Readable messages
  185 + * \param parseStatus - The pugi::XML status enum from the parser.
  186 + * \return True if there was no error whatsoever. False if not.. 8-|
  187 + */
  188 + bool checkError(pugi::xml_parse_status parseStatus);
  189 +
  190 + /*!
  191 + * \brief The internal representation of the XML document.
  192 + */
  193 + pugi::xml_document m_xmldoc;
  194 +
  195 + //! Storage for the XPath expressions
  196 + QHash<QString, QString> m_xPathHash;
  197 +};
90 198  
91 199 } // End namespace xml
92   -} // End namespace components
93 200 } // End namespace osdev
  201 +} // End namespace components
... ...