Etterna 0.74.4
Loading...
Searching...
No Matches
XmlFile.h
1/* XmlFile - Simple XML reading and writing. */
2
3#ifndef XML_FILE_H
4#define XML_FILE_H
5
6#include <map>
7#include <string>
8#include <vector>
9
10struct DateTime;
11class RageFileBasic;
12struct lua_State;
13
15{
16 public:
17 virtual ~XNodeValue() = default;
18 [[nodiscard]] virtual auto Copy() const -> XNodeValue* = 0;
19
20 virtual void GetValue(std::string& out) const = 0;
21 virtual void GetValue(int& out) const = 0;
22 virtual void GetValue(float& out) const = 0;
23 virtual void GetValue(bool& out) const = 0;
24 virtual void GetValue(unsigned& out) const = 0;
25 virtual void PushValue(lua_State* L) const = 0;
26
27 template<typename T>
28 auto GetValue() const -> T
29 {
30 T val;
31 GetValue(val);
32 return val;
33 }
34
35 virtual void SetValue(const std::string& v) = 0;
36 virtual void SetValue(int v) = 0;
37 virtual void SetValue(float v) = 0;
38 virtual void SetValue(unsigned v) = 0;
39 virtual void SetValueFromStack(lua_State* L) = 0;
40};
41
43{
44 public:
45 std::string m_sValue;
46
47 [[nodiscard]] auto Copy() const -> XNodeValue* override
48 {
49 return new XNodeStringValue(*this);
50 }
51
52 void GetValue(std::string& out) const override;
53 void GetValue(int& out) const override;
54 void GetValue(float& out) const override;
55 void GetValue(bool& out) const override;
56 void GetValue(unsigned& out) const override;
57 void PushValue(lua_State* L) const override;
58
59 void SetValue(const std::string& v) override;
60 void SetValue(int v) override;
61 void SetValue(float v) override;
62 void SetValue(unsigned v) override;
63 void SetValueFromStack(lua_State* L) override;
64};
65
66using XAttrs = std::map<std::string, XNodeValue*>;
67class XNode;
68using XNodes = std::vector<XNode*>;
70#define FOREACH_Attr(pNode, Var) \
71 for (XAttrs::iterator Var = (pNode)->m_attrs.begin(); \
72 (Var) != (pNode)->m_attrs.end(); \
73 ++(Var))
75#define FOREACH_CONST_Attr(pNode, Var) \
76 for (XAttrs::const_iterator Var = (pNode)->m_attrs.begin(); \
77 (Var) != (pNode)->m_attrs.end(); \
78 ++(Var))
80#define FOREACH_Child(pNode, Var) \
81 XNode* Var = NULL; \
82 for (XNodes::iterator Var##Iter = (pNode)->GetChildrenBegin(); \
83 (Var) = (Var##Iter != (pNode)->GetChildrenEnd()) ? *Var##Iter : NULL, \
84 Var##Iter != (pNode)->GetChildrenEnd(); \
85 ++Var##Iter)
87#define FOREACH_CONST_Child(pNode, Var) \
88 const XNode* Var = NULL; \
89 for (XNodes::const_iterator Var##Iter = (pNode)->GetChildrenBegin(); \
90 (Var) = (Var##Iter != (pNode)->GetChildrenEnd()) ? *Var##Iter : NULL, \
91 Var##Iter != (pNode)->GetChildrenEnd(); \
92 ++Var##Iter)
93
94class XNode
95{
96 private:
97 XNodes m_childs; // child nodes
98 std::multimap<std::string, XNode*> m_children_by_name;
99
100 public:
101 std::string m_sName;
102 XAttrs m_attrs; // attributes
103
104 void SetName(const std::string& sName) { m_sName = sName; }
105 [[nodiscard]] auto GetName() const -> const std::string& { return m_sName; }
106
107 static const std::string TEXT_ATTRIBUTE;
108 template<typename T>
109 void GetTextValue(T& out) const
110 {
111 GetAttrValue(TEXT_ATTRIBUTE, out);
112 }
113
114 // in own attribute list
115 [[nodiscard]] auto GetAttr(const std::string& sAttrName) const
116 -> const XNodeValue*;
117 auto GetAttr(const std::string& sAttrName) -> XNodeValue*;
118 template<typename T>
119 auto GetAttrValue(const std::string& sName, T& out) const -> bool
120 {
121 const XNodeValue* pAttr = GetAttr(sName);
122 if (pAttr == nullptr) {
123 return false;
124 }
125 pAttr->GetValue(out);
126 return true;
127 }
128 auto PushAttrValue(lua_State* L, const std::string& sName) const -> bool;
129
130 auto GetChildrenBegin() -> XNodes::iterator { return m_childs.begin(); }
131 [[nodiscard]] auto GetChildrenBegin() const -> XNodes::const_iterator
132 {
133 return m_childs.begin();
134 }
135 auto GetChildrenEnd() -> XNodes::iterator { return m_childs.end(); }
136 [[nodiscard]] auto GetChildrenEnd() const -> XNodes::const_iterator
137 {
138 return m_childs.end();
139 }
140 [[nodiscard]] auto ChildrenEmpty() const -> bool
141 {
142 return m_childs.empty();
143 }
144
145 // in one level child nodes
146 [[nodiscard]] auto GetChild(const std::string& sName) const -> const XNode*;
147 auto GetChild(const std::string& sName) -> XNode*;
148 template<typename T>
149 auto GetChildValue(const std::string& sName, T& out) const -> bool
150 {
151 const XNode* pChild = GetChild(sName);
152 if (pChild == nullptr) {
153 return false;
154 }
155 pChild->GetTextValue(out);
156 return true;
157 }
158 auto PushChildValue(lua_State* L, const std::string& sName) const -> bool;
159
160 // modify DOM
161 template<typename T>
162 auto AppendChild(const std::string& sName, T value) -> XNode*
163 {
164 XNode* p = AppendChild(sName);
165 p->AppendAttr(XNode::TEXT_ATTRIBUTE, value);
166 return p;
167 }
168 auto AppendChild(const std::string& sName) -> XNode*
169 {
170 auto* p = new XNode(sName);
171 return AppendChild(p);
172 }
173 auto AppendChild(XNode* node) -> XNode*;
174 auto RemoveChild(XNode* node, bool bDelete = true) -> bool;
175 void RemoveChildFromByName(XNode* node);
176 void RenameChildInByName(XNode* node);
177
178 auto AppendAttrFrom(const std::string& sName,
179 XNodeValue* pValue,
180 bool bOverwrite = true) -> XNodeValue*;
181 auto AppendAttr(const std::string& sName) -> XNodeValue*;
182 template<typename T>
183 auto AppendAttr(const std::string& sName, T value) -> XNodeValue*
184 {
185 XNodeValue* pVal = AppendAttr(sName);
186 pVal->SetValue(value);
187 return pVal;
188 }
189 auto RemoveAttr(const std::string& sName) -> bool;
190
191 XNode();
192 explicit XNode(const std::string& sName);
193 XNode(const XNode& cpy);
194 ~XNode() { Free(); }
195
196 void Clear();
197
198 private:
199 void Free();
200 auto operator=(const XNode& cpy) -> XNode& = delete; // don't use
201};
202
203#endif
Definition RageFileBasic.h:10
Definition XmlFile.h:43
Definition XmlFile.h:15
Definition XmlFile.h:95
A standard way of determining the date and the time.
Definition DateTime.h:81