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_ */