From a4a9e2329937da7ce39218f0f87ba4caae7feea0 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Fri, 15 Apr 2016 21:43:08 +0200 Subject: [PATCH] [DEV] rework developement done (API might be good ..) --- exml/AttributeList.cpp | 4 +- exml/AttributeList.h | 2 +- exml/Declaration.h | 2 +- exml/Element.cpp | 67 ++++++++++++--------- exml/Element.h | 84 ++++++++++++++++----------- exml/Node.cpp | 2 +- exml/Node.h | 4 +- exml/internal/AttributeList.cpp | 6 +- exml/internal/Element.cpp | 22 ++++++- exml/internal/Element.h | 5 ++ test/exmlTestAll.cpp | 2 +- test/exmlTestAttribute.cpp | 89 +++++++++++++++++++++++++++- test/exmlTestComment.cpp | 12 +++- test/exmlTestDeclaration.cpp | 3 +- test/exmlTestDeclarationXML.cpp | 3 +- test/exmlTestElement.cpp | 100 +++++++++++++++++++++++++++++++- 16 files changed, 330 insertions(+), 77 deletions(-) diff --git a/exml/AttributeList.cpp b/exml/AttributeList.cpp index ed17617..4d5fe6c 100644 --- a/exml/AttributeList.cpp +++ b/exml/AttributeList.cpp @@ -56,7 +56,7 @@ const exml::Attribute exml::AttributeListData::operator[] (int32_t _id) const { std::pair exml::AttributeListData::getPair(int32_t _id) const { if (m_data->m_data == nullptr) { EXML_ERROR(" can not getAttrPair (nullptr) ..."); - return std::pair(); + return std::pair("",""); } return static_cast(m_data->m_data.get())->getAttrPair(_id); } @@ -69,7 +69,7 @@ void exml::AttributeListData::add(exml::Attribute _attr) { static_cast(m_data->m_data.get())->appendAttribute(_attr.getInternalAttribute()); } -const std::string& exml::AttributeListData::get(const std::string& _name) const { +const std::string& exml::AttributeListData::operator[](const std::string& _name) const { if (m_data->m_data == nullptr) { EXML_ERROR(" can not getAttribute (nullptr) ..."); static std::string errorValue(""); diff --git a/exml/AttributeList.h b/exml/AttributeList.h index 7d89dcb..93b9be6 100644 --- a/exml/AttributeList.h +++ b/exml/AttributeList.h @@ -60,7 +60,7 @@ namespace exml { * @param[in] _name Attribute Name. * @return Value of the attribute or no data in the string */ - const std::string& get(const std::string& _name) const; + const std::string& operator[](const std::string& _name) const; /** * @brief check if an attribute exist or not with his name. * @param[in] _name Attribute Name. diff --git a/exml/Declaration.h b/exml/Declaration.h index 97c885c..58ff1ef 100644 --- a/exml/Declaration.h +++ b/exml/Declaration.h @@ -58,7 +58,7 @@ namespace exml { * @param[in] _format charset of the XML * @param[in] _standalone this document is standalone */ - DeclarationXML(const std::string& _version, const std::string& _format = "UTF-8", bool _standalone = true); + DeclarationXML(const std::string& _version="0.0", const std::string& _format = "UTF-8", bool _standalone = true); /** * @brief Copy constructor * @param[in] _obj Object to copy diff --git a/exml/Element.cpp b/exml/Element.cpp index f93c2ee..5cee4cd 100644 --- a/exml/Element.cpp +++ b/exml/Element.cpp @@ -12,7 +12,8 @@ exml::Element::Element(ememory::SharedPtr _internalNode) : - exml::AttributeList(_internalNode) { + exml::AttributeList(_internalNode), + nodes(this) { if (m_data == nullptr) { return; } @@ -23,12 +24,14 @@ exml::Element::Element(ememory::SharedPtr _internalNode) : } exml::Element::Element(const exml::Element& _obj) : - exml::AttributeList(_obj.m_data) { + exml::AttributeList(_obj.m_data), + nodes(this) { } exml::Element::Element(const std::string& _data) : - exml::AttributeList() { + exml::AttributeList(), + nodes(this) { m_data = exml::internal::Element::create(_data); } @@ -37,61 +40,73 @@ exml::Element& exml::Element::operator= (const exml::Element& _obj) { return *this; } -size_t exml::Element::size() const { - if (m_data == nullptr) { +exml::ElementData::ElementData(exml::Element* _elem) : + m_data(_elem) { + +} + +size_t exml::ElementData::size() const { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not get type ..."); return 0; } - return static_cast(m_data.get())->size(); + return static_cast(m_data->m_data.get())->size(); } - -enum exml::nodeType exml::Element::getType(int32_t _id) const { - if (m_data == nullptr) { +enum exml::nodeType exml::ElementData::getType(int32_t _id) const { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not get type ..."); return exml::nodeType_unknow; } - return static_cast(m_data.get())->getType(_id); + return static_cast(m_data->m_data.get())->getType(_id); } -exml::Node exml::Element::operator[](int32_t _id) { - if (m_data == nullptr) { +exml::Node exml::ElementData::operator[](int32_t _id) { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not get type ..."); return exml::Node(); } - return exml::Node(static_cast(m_data.get())->getNode(_id)); + return exml::Node(static_cast(m_data->m_data.get())->getNode(_id)); } -const exml::Node exml::Element::operator[](int32_t _id) const { - if (m_data == nullptr) { +const exml::Node exml::ElementData::operator[](int32_t _id) const { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not get type ..."); return exml::Node(); } - return exml::Node(static_cast(m_data.get())->getNode(_id)); + return exml::Node(static_cast(m_data->m_data.get())->getNode(_id)); } -exml::Element exml::Element::getNamed(const std::string& _name) { - if (m_data == nullptr) { +exml::Element exml::ElementData::operator[](const std::string& _name) { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not get type ..."); return exml::Element(); } - return exml::Element(static_cast(m_data.get())->getNamed(_name)); + return exml::Element(static_cast(m_data->m_data.get())->getNamed(_name)); } -const exml::Element exml::Element::getNamed(const std::string& _name) const { - if (m_data == nullptr) { +const exml::Element exml::ElementData::operator[] (const std::string& _name) const { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not get type ..."); return exml::Element(); } - return exml::Element(static_cast(m_data.get())->getNamed(_name)); + return exml::Element(static_cast(m_data->m_data.get())->getNamed(_name)); } -void exml::Element::append(const exml::Node& _node) { - if (m_data == nullptr) { +void exml::ElementData::add(const exml::Node& _node) { + if (m_data->m_data == nullptr) { EXML_ERROR(" can not APPEND on null element ..."); return; } - static_cast(m_data.get())->append(_node.m_data); + static_cast(m_data->m_data.get())->append(_node.m_data); +} + +void exml::ElementData::remove(const std::string& _nodeName) { + if (m_data->m_data == nullptr) { + EXML_ERROR(" can not APPEND on null element ..."); + return; + } + static_cast(m_data->m_data.get())->remove(_nodeName); } std::string exml::Element::getText() const { @@ -113,5 +128,5 @@ void exml::Element::clear() { #include -template class exml::iterator; +template class exml::iterator; diff --git a/exml/Element.h b/exml/Element.h index de1a132..f2b6b38 100644 --- a/exml/Element.h +++ b/exml/Element.h @@ -13,31 +13,16 @@ #include namespace exml { + /** * @brief Basic element Node of an XML document <YYYYY> */ - class Element : public exml::AttributeList { + class ElementData { + private: + exml::Element* m_data; + public: + ElementData(exml::Element* _list); public: - /** - * @brief Constructor - * @param[in] _internalNode Internal Node to set data - */ - Element(ememory::SharedPtr _internalNode); - /** - * @brief Copy constructor - * @param[in] _obj Object to copy - */ - Element(const exml::Element& _obj); - /** - * @brief Constructor - * @param[in] _value Element name; - */ - Element(const std::string& _value=""); - /** - * @brief Copy constructor - * @param[in] _obj Object to copy - */ - exml::Element& operator= (const exml::Element& _obj); /** * @brief get the number of sub element in the node (can be exml::Comment ; exml::Element ; exml::Text :exml::Declaration). * @return a number >=0. @@ -45,9 +30,14 @@ namespace exml { size_t size() const; /** * @brief add a node at the element (not exml::Attribute (move in the attribute automaticly). - * @param[in] _node Pointer of the node to add. + * @param[in] _node Node to add. */ - void append(const exml::Node& _node); + void add(const exml::Node& _node); + /** + * @brief Remove a node with his name. + * @param[in] _nodeName Name of the node. + */ + void remove(const std::string& _nodeName); /** * @brief get the type of the element id. * @param[in] _id Id of the element. @@ -71,22 +61,15 @@ namespace exml { * @param[in] _name Name of the element that is requested * @return Pointer on the element or NULL. */ - exml::Element getNamed(const std::string& _name); + exml::Element operator[] (const std::string& _name); /** * @brief get an element with his name (work only with exml::Element) * @param[in] _name Name of the element that is requested * @return Pointer on the element or NULL. */ - const exml::Element getNamed(const std::string& _name) const; - /** - * @brief get the internal data of the element (if the element has some sub node thay are converted in xml string == > like this it is not needed to use - * @return the curent data string. if Only one text node, then we get the parssed data (no & ...) if more than one node, then we transform &,",',<,> in xml normal text... - */ - std::string getText() const; + const exml::Element operator[] (const std::string& _name) const; public: - void clear() override; - public: - using iterator = exml::iterator; + using iterator = exml::iterator; iterator begin() { return iterator(*this, 0); } @@ -94,5 +77,40 @@ namespace exml { return iterator(*this, size()); } }; + /** + * @brief Basic element Node of an XML document <YYYYY> + */ + class Element : public exml::AttributeList { + public: + ElementData nodes; + public: + /** + * @brief Constructor + * @param[in] _internalNode Internal Node to set data + */ + Element(ememory::SharedPtr _internalNode); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + Element(const exml::Element& _obj); + /** + * @brief Constructor + * @param[in] _value Element name; + */ + Element(const std::string& _value=""); + /** + * @brief Copy constructor + * @param[in] _obj Object to copy + */ + exml::Element& operator= (const exml::Element& _obj); + /** + * @brief get the internal data of the element (if the element has some sub node thay are converted in xml string == > like this it is not needed to use + * @return the curent data string. if Only one text node, then we get the parssed data (no & ...) if more than one node, then we transform &,",',<,> in xml normal text... + */ + std::string getText() const; + public: + void clear() override; + }; } diff --git a/exml/Node.cpp b/exml/Node.cpp index 938fdc0..ef803ec 100644 --- a/exml/Node.cpp +++ b/exml/Node.cpp @@ -37,7 +37,7 @@ exml::Node::Node() : } -bool exml::Node::exist() { +bool exml::Node::exist() const { if (m_data == nullptr) { return false; } diff --git a/exml/Node.h b/exml/Node.h index b9a3d0d..9b49934 100644 --- a/exml/Node.h +++ b/exml/Node.h @@ -25,12 +25,14 @@ namespace exml { class Element; class Text; class AttributeListData; + class ElementData; /** * @brief Basic main object of all xml elements. */ class Node { friend class exml::Element; friend class exml::AttributeListData; + friend class exml::ElementData; protected: ememory::SharedPtr m_data; //< internal reference on a node public: @@ -52,7 +54,7 @@ namespace exml { /** * @brief Check if the element exit */ - bool exist(); + bool exist() const; /** * @brief get the current position where the element is in the file * @return The file position reference diff --git a/exml/internal/AttributeList.cpp b/exml/internal/AttributeList.cpp index f3c3af4..a2dc72e 100644 --- a/exml/internal/AttributeList.cpp +++ b/exml/internal/AttributeList.cpp @@ -10,14 +10,16 @@ #include ememory::SharedPtr exml::internal::AttributeList::getAttr(int32_t _id) { - if (_id <0 || (size_t)_id>m_listAttribute.size()) { + if ( _id < 0 + || size_t(_id) >= m_listAttribute.size()) { return nullptr; } return m_listAttribute[_id]; } ememory::SharedPtr exml::internal::AttributeList::getAttr(int32_t _id) const { - if (_id <0 || (size_t)_id>m_listAttribute.size()) { + if ( _id < 0 + || size_t(_id) >= m_listAttribute.size()) { return nullptr; } return m_listAttribute[_id]; diff --git a/exml/internal/Element.cpp b/exml/internal/Element.cpp index 8030e29..6e76dbc 100644 --- a/exml/internal/Element.cpp +++ b/exml/internal/Element.cpp @@ -37,14 +37,16 @@ enum exml::nodeType exml::internal::Element::getType(int32_t _id) const { } ememory::SharedPtr exml::internal::Element::getNode(int32_t _id) { - if (_id <0 || (size_t)_id>m_listSub.size()) { + if ( _id <0 + || (size_t)_id>=m_listSub.size()) { return nullptr; } return m_listSub[_id]; } ememory::SharedPtr exml::internal::Element::getNode(int32_t _id) const { - if (_id <0 || (size_t)_id>m_listSub.size()) { + if ( _id <0 + || (size_t)_id>=m_listSub.size()) { return nullptr; } return m_listSub[_id]; @@ -119,6 +121,22 @@ void exml::internal::Element::append(const ememory::SharedPtrgetValue() == _nodeName) { + it = m_listSub.erase(it); + } else { + ++it; + } + } +} + std::string exml::internal::Element::getText() const { std::string res; if (m_listSub.size() == 1) { diff --git a/exml/internal/Element.h b/exml/internal/Element.h index 68e13ea..55b5c4b 100644 --- a/exml/internal/Element.h +++ b/exml/internal/Element.h @@ -52,6 +52,11 @@ namespace exml { * @param[in] _node Pointer of the node to add. */ void append(const ememory::SharedPtr& _node); + /** + * @brief Remove all element with this name + * @param[in] _nodeName Name of nodes to remove. + */ + void remove(const std::string& _nodeName); /** * @brief get the type of the element id. * @param[in] _id Id of the element. diff --git a/test/exmlTestAll.cpp b/test/exmlTestAll.cpp index e769319..729be43 100644 --- a/test/exmlTestAll.cpp +++ b/test/exmlTestAll.cpp @@ -50,7 +50,7 @@ TEST(TestAll, testCaseSensitive) { " Text example ...\n" " \n" "\n", - 1, + -1, false); } diff --git a/test/exmlTestAttribute.cpp b/test/exmlTestAttribute.cpp index e5bff81..d502b38 100644 --- a/test/exmlTestAttribute.cpp +++ b/test/exmlTestAttribute.cpp @@ -24,8 +24,95 @@ TEST(TestAttribute, createCopy) { TEST(TestAttribute, createAssignement) { exml::Attribute myAttribute("nameAttribute", "valueAttribute"); - exml::Attribute myOtherAttribute = myAttribute; + exml::Attribute myOtherAttribute; + myOtherAttribute = myAttribute; //EXPECT_EQ(myAttribute, myOtherAttribute); } +TEST(TestAttribute, setGetValue) { + exml::Attribute myAttribute("nameAttribute", "valueAttribute"); + EXPECT_EQ(myAttribute.getValue(), "valueAttribute"); + myAttribute.setValue("new value"); + EXPECT_EQ(myAttribute.getValue(), "new value"); +} + + +TEST(TestAttribute, setGetName) { + exml::Attribute myAttribute("nameAttribute", "valueAttribute"); + EXPECT_EQ(myAttribute.getName(), "nameAttribute"); + myAttribute.setName("newName"); + EXPECT_EQ(myAttribute.getName(), "newName"); +} + +TEST(TestAttribute, clear) { + exml::Attribute myAttribute("nameAttribute", "valueAttribute"); + myAttribute.clear(); +} + + +TEST(TestAttribute, nullElement) { + exml::Element myElement("NodeName"); + + exml::Attribute myAttribute = myElement.attributes[65465465]; + EXPECT_EQ(myAttribute.exist(), false); + myAttribute.setName("lkjlkj"); + myAttribute.getName(); + myAttribute.setValue("kljhkljhkjh"); + myAttribute.getValue(); + myAttribute.clear(); +} + +TEST(TestAttribute, moveInAllElement ) { + exml::Document doc; + doc.parse(""); + exml::Element elem = doc.nodes["elem"]; + for (auto it: elem.attributes) { + EXPECT_EQ(it.getName(), "valA"); + EXPECT_EQ(it.getValue(), "plop"); + } +} + +TEST(TestAttribute, setterNew ) { + exml::Element elem("elem"); + elem.attributes.set("valA", "coucou"); + EXPECT_EQ(elem.attributes["valA"], "coucou"); +} +TEST(TestAttribute, setterRewrite ) { + exml::Element elem("elem"); + elem.attributes.set("valA", "coucou"); + EXPECT_EQ(elem.attributes["valA"], "coucou"); + elem.attributes.set("valA", "coucou2"); + EXPECT_EQ(elem.attributes["valA"], "coucou2"); +} +TEST(TestAttribute, getpair ) { + exml::Element elem("elem"); + elem.attributes.set("valA", "coucou"); + EXPECT_EQ(elem.attributes.getPair(0).first, "valA"); + EXPECT_EQ(elem.attributes.getPair(0).second, "coucou"); + EXPECT_EQ(elem.attributes.getPair(1).first, ""); + EXPECT_EQ(elem.attributes.getPair(1).second, ""); +} + +TEST(TestAttribute, get ) { + exml::Element elem("elem"); + elem.attributes.set("valA", "plop"); + EXPECT_EQ(elem.attributes["valA"], "plop"); + EXPECT_EQ(elem.attributes["qsdfsdf"], ""); +} + +TEST(TestAttribute, exist ) { + exml::Element elem("elem"); + elem.attributes.set("valA", "plop"); + EXPECT_EQ(elem.attributes.exist("valA"), true); + EXPECT_EQ(elem.attributes.exist("qsdfsdf"), false); +} + +TEST(TestAttribute, remove ) { + exml::Element elem("elem"); + elem.attributes.set("valA", "plop"); + EXPECT_EQ(elem.attributes.exist("valA"), true); + elem.attributes.remove("valA"); + EXPECT_EQ(elem.attributes.exist("valA"), false); +} + diff --git a/test/exmlTestComment.cpp b/test/exmlTestComment.cpp index d32ed3e..711430b 100644 --- a/test/exmlTestComment.cpp +++ b/test/exmlTestComment.cpp @@ -23,6 +23,14 @@ TEST(TestComment, createCopy) { TEST(TestComment, createAssignement) { exml::Comment myComment("my comment"); - exml::Comment myOtherComment = myComment; + exml::Comment myOtherComment; + myOtherComment = myComment; //EXPECT_EQ(myComment, myOtherComment); -} \ No newline at end of file +} + +TEST(TestComment, transform) { + exml::Comment myComment("my comment"); + exml::Node myNode = myComment; + myComment = myNode.toComment(); + //EXPECT_EQ(myComment, myOtherComment); +} diff --git a/test/exmlTestDeclaration.cpp b/test/exmlTestDeclaration.cpp index 17a0ecf..872b47a 100644 --- a/test/exmlTestDeclaration.cpp +++ b/test/exmlTestDeclaration.cpp @@ -23,7 +23,8 @@ TEST(TestDeclaration, createCopy) { TEST(TestDeclaration, createAssignement) { exml::Declaration myDeclaration("type"); - exml::Declaration myOtherDeclaration = myDeclaration; + exml::Declaration myOtherDeclaration; + myOtherDeclaration = myDeclaration; //EXPECT_EQ(myDeclaration, myOtherDeclaration); } diff --git a/test/exmlTestDeclarationXML.cpp b/test/exmlTestDeclarationXML.cpp index 78892fc..3a027e6 100644 --- a/test/exmlTestDeclarationXML.cpp +++ b/test/exmlTestDeclarationXML.cpp @@ -23,7 +23,8 @@ TEST(TestDeclarationXML, createCopy) { TEST(TestDeclarationXML, createAssignement) { exml::DeclarationXML myDeclarationXML("1.0", "UTF-8", true); - exml::DeclarationXML myOtherDeclarationXML = myDeclarationXML; + exml::DeclarationXML myOtherDeclarationXML; + myOtherDeclarationXML = myDeclarationXML; //EXPECT_EQ(myDeclarationXML, myOtherDeclarationXML); } diff --git a/test/exmlTestElement.cpp b/test/exmlTestElement.cpp index e8bd9c9..c35f389 100644 --- a/test/exmlTestElement.cpp +++ b/test/exmlTestElement.cpp @@ -9,11 +9,12 @@ #include #include #include +#include TEST(TestElement, create) { exml::Element myElement("NodeName"); - //EXPECT_EQ(myElement.getType(), exml::nodeType_element); + EXPECT_EQ(myElement.getType(), exml::nodeType_element); } TEST(TestElement, createCopy) { @@ -24,7 +25,102 @@ TEST(TestElement, createCopy) { TEST(TestElement, createAssignement) { exml::Element myElement("NodeName"); - exml::Element myOtherElement = myElement; + exml::Element myOtherElement; + myOtherElement = myElement; //EXPECT_EQ(myElement, myOtherElement); } +TEST(TestElement, moveInAllElement ) { + exml::Document doc; + doc.parse(""); + for (auto it: doc.nodes) { + EXPECT_EQ(it.getValue(), "elem"); + } + for (const auto it: doc.nodes) { + EXPECT_EQ(it.getValue(), "elem"); + } +} + +TEST(TestElement, getText1 ) { + exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.getText(), ""); +} + +TEST(TestElement, getText2 ) { + exml::Element myElement("NodeName"); + myElement.nodes.add(exml::Element("jkjhkjhkh")); + EXPECT_EQ(myElement.getText(), "\n"); +} + + +TEST(TestElement, getTypeId ) { + exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.nodes.getType(1), exml::nodeType_unknow); +} + +TEST(TestElement, getNamed ) { + exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.nodes["jkjhkjhkh"].exist(), false); +} + +TEST(TestElement, getNamedConst ) { + const exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.nodes["jkjhkjhkh"].exist(), false); +} + +TEST(TestElement, operatorCrochetConst ) { + const exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.nodes[465].exist(), false); +} + +TEST(TestElement, append ) { + exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.nodes.size(), 0); + myElement.nodes.add(exml::Element("jkjhkjhkh")); + EXPECT_EQ(myElement.nodes.size(), 1); + EXPECT_EQ(myElement.nodes["jkjhkjhkh"].exist(), true); + EXPECT_EQ(myElement.nodes.size(), 1); +} + +TEST(TestElement, clear ) { + exml::Element myElement("NodeName"); + EXPECT_EQ(myElement.nodes.size(), 0); + myElement.nodes.add(exml::Element("jkjhkjhkh")); + EXPECT_EQ(myElement.nodes.size(), 1); + EXPECT_EQ(myElement.nodes["jkjhkjhkh"].exist(), true); + EXPECT_EQ(myElement.nodes.size(), 1); + myElement.clear(); + EXPECT_EQ(myElement.nodes.size(), 0); +} + + + +TEST(TestElement, emptyElement ) { + exml::Comment myComment("NodeName"); + exml::Element myElement = myComment.toElement(); + EXPECT_EQ(myElement.exist(), false); + myElement.nodes.size(); + myElement.nodes[55]; + myElement.nodes.add(exml::Comment("kjhlkj")); + myElement.getValue(); + myElement.setValue("lkjhlk"); + myElement.getText(); + myElement.nodes.getType(1); + myElement.nodes["jkjhkjhkh"]; + myElement.clear(); +} + + +TEST(TestElement, emptyElementConst ) { + exml::Comment myComment("NodeName"); + const exml::Element myElement = myComment.toElement(); + EXPECT_EQ(myElement.exist(), false); + myElement.nodes.size(); + myElement.nodes[55]; + myElement.getType(); + myElement.getValue(); + myElement.getText(); + myElement.nodes.getType(1); + myElement.nodes["jkjhkjhkh"]; +} +