1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
//////////////////////////////////////////////////////////////////////// // Copyright (c) Nehmulos 2011-2014 // This file is part of N0 Strain Serialization Library. // // N0Strain-Serialization-Library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // N0Strain-Serialization-Library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with N0Strain-Serialization-Library. If not, see https://gnu.org/licenses/lgpl-3.0 //////////////////////////////////////////////////////////////////////// #ifndef TAG_H_ #define TAG_H_ #include <string> #include <sstream> #include <vector> #include <stack> #include <fstream> #include <iostream> #include "N0SlibConstants.h" #include "N0SlibUtils.h" namespace nw { /// workaround for template type-Overloading /// many thanks to Johannes Schaub /// http://stackoverflow.com/questions/3052579/explicit-specialization-in-non-namespace-scope/3057522#3057522 template<typename T> struct identity { typedef T type; }; /// States for the XmlParser. TODO 1.2 move to XmlReader typedef enum { readTagType, readTagName, searchNewTags, closeTag, searchAttributes, readAttributeName, assignAttribute, readAttributeValue, readXmlVersion, readCommentType, definitionTagName, definitionValue, cDataTagName, cDataValue, xmlComment, } PARSER_STATE; class Tag { public: Tag(); ///< Set's the name to "Unnamed" Tag(const String tagName); ///< Set's the Tag's name virtual ~Tag(); virtual Tag* addNewChild(const String tagName); ///< Adds a new Tag with the given Name and without value. template <class T> Tag* addNewChild(const String tagName, const String tagValue) ///< Adds a new Tag with the given String value. { Tag* newChild = new Tag(tagName); newChild->setValue(tagValue); newChild->setParent(this); newChild->setLevel(this->level+1); children.push_back(newChild); return newChild; } template <class T> Tag* addNewChild(const String tagName, T tagValue) ///< Adds a new Tag with the given String value. { Tag* newChild = new Tag(tagName); newChild->setValue(tagValue); newChild->setParent(this); newChild->setLevel(this->level+1); children.push_back(newChild); return newChild; } void addComment(const String text); ///< Adds a new Tag as a comment void addChild(Tag* child); ///< Add's a childTag to the childrenVector. void removeChild(Tag* child); ///< Removes a childTag form the vector. Does not Delete. bool hasGrandChildren(); ///< scary helper I provided publicly for some reason bool hasChildren(); ///< Returns true if the childrenVector is not empty /// Get the first child-Tag for the given Name. /// Returns NULL if there is no childtag with such a name. Tag* getChildWithName(const String childrenTagName); Tag* getLastChild(); ///< Get the latest added child String getName(); ///< Get the tag's name String getValue(); ///< Get the value String long double getLongDoubleValue(); ///< Converts the value String long long getLongLongValue(); ///< Converts the value String double getDoubleValue(); ///< Converts the value String float getFloatValue(); ///< Converts the value String long getLongValue(); ///< Converts the value String int getIntegerValue(); ///< Converts the value String short getShortValue(); ///< Converts the value String bool getBooleanValue(); ///< Parse "true" and "1" as true, everything else as false void* getPointerValue(); ///< Converts the value String char getCharacterValue(); ///< Converts the value String template<typename T> T getValueAs() { return getValueAs(identity<T>()); } unsigned char getUnsignedCharacterValue(); ///< Converts the value String signed char getSignedCharacterValue(); ///< Converts the value String unsigned short getUnsignedShortValue(); ///< Converts the value String unsigned int getUnsignedIntegerValue(); ///< Converts the value String unsigned long getUnsignedLongValue(); ///< Converts the value String void* getBase64Value(); ///< Converts the value String and creates a pointer to the result void* getHexValue(); ///< Converts the value String and creates a pointer to the result std::stack<Tag*> getCsvTags(); ///< Parse a CsvString into a stack of Tags (specialized for MarkupReder) Tag* getParent(); ///< Returns the Parent Tag. std::vector<Tag*>& getChildren(); ///< Returns a reference to a vector of it's child tags void setParent(Tag* parent); ///< Set's a new Parent Tag. void setName(const String value); ///< Set's the Tag's name void setValue(const String value); ///< Set's the Tag's value String template <class T> void setValue(T value) ///< Set's the Tag's value String { std::stringstream ss; String stringValue; ss << value; ss >> stringValue; setValue(stringValue); } static void writeXmlHeader(std::ostream& file); ///< Writes the Header for a xml File, TODO 1.2 move to xmlWriter // static String valueToHexaDecimalString(String value); void writeAsXmlWithAttributes(std::ostream& file); ///< Writes the current Tag and it's children to a fstream static bool useAttribute; ///< Init value for canBeAttribute void setLevel(int level); ///< Sets the numberOfTabs used bool operator==(Tag& that); ///< Returns true if the values and names are equal bool getIsComent() const; ///< Returns true if the tag is a comment bool getCanBeAttribute() const; ///< Returns ture if canBeAttribute is true void setIsComment(bool isComment); ///< Sets if the Tag is written as Comment void setCanBeAttribute(bool canBe); ///< Sets if the Tag can be written as Attribute void setIsValueArray(bool isVarray);///< Sets if the tag contains anonymous values void setCanBeAttributeRecursive(bool canBe); ///< sets canBeAttribute for itself and it's children protected: std::vector<Tag*> children; ///< All children that this tag holds Tag* parent; ///< The Tag that contains this tag, NULL if this is the motherTag String name; ///< The name of the Tag String value; ///< The value that is saved inside the Tag. int level; ///< Determins the Number of tabs infront of a tag bool isComment; ///< If it's true the Tag will be written as Comment. bool canBeAttribute; ///< If it's false it will never be written as Argument TODO move to XmlWriter bool isValueArray; ///< Does this Tag contain namesless values? This Boolean will tell us. inline void writeAsXmlAttribute(std::ostream& file); ///< Writes this Tag as Xml-Attribute to a fstream /////////////////////////////////////////////////////////////////////////// // // overloaded templates // /////////////////////////////////////////////////////////////////////////// template<typename T> T getValueAs(identity<T>) { std::stringstream ss(value); T ret; ss >> ret; return ret; } bool getValueAs(identity<bool>) { return this->getBooleanValue(); } const char* getValueAs(identity<const char*>) { return this->value.c_str(); } String getValueAs(identity<String>) { return this->value; } char getValueAs(identity<char>) { return this->getValueAs(identity<short>()); } unsigned char getValueAs(identity<unsigned char>) { return this->getValueAs(identity<short>()); } signed char getValueAs(identity<signed char>) { return this->getValueAs(identity<short>()); } }; } // namespace nw #endif /* TAG_H_ */