MyGUI 3.4.3
MyGUI_XmlDocument.h
Go to the documentation of this file.
1/*
2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3 * Distributed under the MIT License
4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5 */
6
7#ifndef MYGUI_XML_DOCUMENT_H_
8#define MYGUI_XML_DOCUMENT_H_
9
10#include "MyGUI_Prerequest.h"
11#include "MyGUI_UString.h"
12#include "MyGUI_Diagnostic.h"
13#include "MyGUI_DataStream.h"
14
15#include <vector>
16#include <string>
17#include <iostream>
18#include <fstream>
19#include <sstream>
20#include <cassert>
21#include <type_traits>
22#include <memory>
23
24namespace MyGUI::xml
25{
26
28 {
36
37 ElementType(Enum _value = MAX) :
38 mValue(_value)
39 {
40 }
41 friend bool operator==(ElementType const& a, ElementType const& b)
42 {
43 return a.mValue == b.mValue;
44 }
45 friend bool operator!=(ElementType const& a, ElementType const& b)
46 {
47 return a.mValue != b.mValue;
48 }
49
50 int getValue() const
51 {
52 return mValue;
53 }
54
55 private:
56 Enum mValue;
57 };
58
59 struct ErrorType
60 {
75
76 ErrorType(Enum _value = MAX) :
77 mValue(_value)
78 {
79 }
80
81 std::string_view print() const
82 {
83 return getValueName(mValue);
84 }
85
86 private:
87 std::string_view getValueName(int _index) const
88 {
89 if (_index < 0 || _index >= MAX)
90 return {};
91 static const std::string_view values[MAX] = {
92 "Failed to open XML file",
93 "Failed to create XML file",
94 "XML file contain incorrect content",
95 "XML file contain not closed elements",
96 "XML file without declaration",
97 "XML file contain closed but not opened element",
98 "XML file contain inconsistent elements",
99 "XML file contain more than one declaration",
100 "XML file contain more than one root element",
101 "XML file contain incorrect attribute"};
102 return values[_index];
103 }
104
105 private:
106 Enum mValue;
107 };
108
109 class Element;
110 class Document;
111
113 using PairAttribute = std::pair<std::string, std::string>;
114 using VectorAttributes = std::vector<PairAttribute>;
115 using VectorElement = std::vector<std::unique_ptr<Element>>;
116
117 //----------------------------------------------------------------------//
118 // class ElementEnumerator
119 //----------------------------------------------------------------------//
120 class MYGUI_EXPORT ElementEnumerator
121 {
122 friend class Element;
123
124 private:
125 ElementEnumerator(VectorElement::iterator _begin, VectorElement::iterator _end);
126
127 public:
128 bool next();
129 bool next(std::string_view _name);
130
131 ElementPtr operator->() const;
133
134 /*obsolete:*/
135#ifndef MYGUI_DONT_USE_OBSOLETE
136
137 MYGUI_OBSOLETE("use : bool ElementEnumerator::next()")
138 bool nextNode()
139 {
140 return next();
141 }
142 MYGUI_OBSOLETE("use : bool ElementEnumerator::next(std::string_view _name)")
143 bool nextNode(std::string_view _name)
144 {
145 return next(_name);
146 }
147 MYGUI_OBSOLETE("use : ElementPtr ElementEnumerator::current()")
149 {
150 return current();
151 }
152
153#endif // MYGUI_DONT_USE_OBSOLETE
154
155 private:
156 bool m_first{true};
157 VectorElement::iterator m_current, m_end;
158 };
159
160
161 //----------------------------------------------------------------------//
162 // class Element
163 //----------------------------------------------------------------------//
165 {
166 friend class Document;
167
168 public:
169 Element(
170 std::string_view _name,
171 ElementPtr _parent,
173 std::string_view _content = {});
174 Element(Element&&) = default;
175
176 private:
177 void save(std::ostream& _stream, size_t _level);
178
179 public:
181 std::string_view _name,
182 std::string_view _content = {},
184 void removeChild(ElementPtr _child);
185
186 template<typename T, typename = std::enable_if_t<!std::is_convertible_v<T, std::string_view>>>
187 void addAttribute(std::string_view _key, const T& _value)
188 {
190 }
191
192 void addAttribute(std::string_view _key, std::string_view _value);
193
194 void removeAttribute(std::string_view _key);
195
196 void setAttribute(std::string_view _key, std::string_view _value);
197
198 template<typename T, typename = std::enable_if_t<!std::is_convertible_v<T, std::string_view>>>
199 void addContent(const T& _content)
200 {
202 }
203
204 void addContent(std::string_view _content);
205
206 template<typename T, typename = std::enable_if_t<!std::is_convertible_v<T, std::string_view>>>
207 void setContent(const T& _content)
208 {
210 }
211
212 void setContent(std::string_view _content);
213
214 void clear();
215
216 bool findAttribute(std::string_view _name, std::string& _value);
217 std::string_view findAttribute(std::string_view _name);
218
219 const std::string& getName() const;
220
221 const std::string& getContent() const;
222
223 const VectorAttributes& getAttributes() const;
224
225 ElementPtr getParent() const;
226
227 ElementEnumerator getElementEnumerator();
228
229 ElementType getType() const;
230
231 std::unique_ptr<Element> createCopy();
232
233 /*obsolete:*/
234#ifndef MYGUI_DONT_USE_OBSOLETE
235
236 template<typename T>
238 "use : template <typename T> void Element::addAttribute(const std::string &_key, const T& _value)")
239 void addAttributes(std::string_view _key, const T& _value)
240 {
241 addAttribute<T>(_key, _value);
242 }
243 MYGUI_OBSOLETE("use : void Element::addAttribute(std::string_view _key, std::string_view _value)")
244 void addAttributes(std::string_view _key, std::string_view _value)
245 {
246 addAttribute(_key, _value);
247 }
248
249 template<typename T>
250 MYGUI_OBSOLETE("use : template <typename T> void Element::addContent(const T& _content)")
251 void addBody(const T& _content)
252 {
253 addContent<T>(_content);
254 }
255 MYGUI_OBSOLETE("use : void Element::addContent(std::string_view _content)")
256 void addBody(std::string_view _content)
257 {
258 addContent(_content);
259 }
260 template<typename T>
261 MYGUI_OBSOLETE("use : template <typename T> void Element::setContent(const T& _content)")
262 void setBody(const T& _content)
263 {
264 setContent<T>(_content);
265 }
266 MYGUI_OBSOLETE("use : void Element::setContent(std::string_view _content)")
267 void setBody(std::string_view _content)
268 {
269 setContent(_content);
270 }
271
272 MYGUI_OBSOLETE("use : const std::string& Element::getContent()")
273 const std::string& getBody() const
274 {
275 return getContent();
276 }
277 MYGUI_OBSOLETE("use : ElementEnumerator Element::getElementEnumerator()")
282
283#endif // MYGUI_DONT_USE_OBSOLETE
284
285 private:
286 std::string mName;
287 std::string mContent;
288 VectorAttributes mAttributes;
289 VectorElement mChildren;
290 ElementPtr mParent;
291 ElementType mType;
292 };
293
294 //----------------------------------------------------------------------//
295 // class Document
296 //----------------------------------------------------------------------//
298 {
299 public:
300 // открывает обычным файлом, имя файла в utf8
301 bool open(const std::string& _filename);
302
303 // открывает обычным файлом, имя файла в utf16 или utf32
304 bool open(const std::wstring& _filename);
305
306 // открывает обычным потоком
307 bool open(std::istream& _stream);
308
309 bool open(const UString& _filename);
310
311 bool open(IDataStream* _stream);
312
313 // сохраняет файл
314 bool save(const std::string& _filename);
315
316 // сохраняет файл
317 bool save(const std::wstring& _filename);
318
319 bool save(std::ostream& _stream);
320
321 bool save(const UString& _filename);
322
323 void clear();
324
325 std::string getLastError() const;
326
327 void clearLastError();
328
329 ElementPtr createDeclaration(std::string_view _version = "1.0", std::string_view _encoding = "UTF-8");
330 ElementPtr createRoot(std::string_view _name);
331
332 ElementPtr getRoot() const;
333
334 /*obsolete:*/
335#ifndef MYGUI_DONT_USE_OBSOLETE
336
338 "use : ElementPtr Document::createDeclaration(std::string_view _version, std::string_view _encoding)")
339 ElementPtr createInfo(std::string_view _version = "1.0", std::string_view _encoding = "UTF-8")
340 {
341 return createDeclaration(_version, _encoding);
342 }
343
344#endif // MYGUI_DONT_USE_OBSOLETE
345
346 private:
347 void setLastFileError(std::string_view _filename);
348 void setLastFileError(const std::wstring& _filename);
349
350 bool parseTag(ElementPtr& _currentNode, std::string _content);
351
352 bool checkPair(std::string& _key, std::string& _value);
353
354 bool parseLine(std::string& _line, ElementPtr& _element);
355
356 // ищет символ без учета ковычек
357 size_t find(std::string_view _text, char _char, size_t _start = 0);
358
359 void clearDeclaration();
360 void clearRoot();
361
362 private:
363 std::unique_ptr<Element> mRoot;
364 std::unique_ptr<Element> mDeclaration;
365 ErrorType mLastError;
366 std::string mLastErrorFile;
367 size_t mLine{0};
368 size_t mCol{0};
369
370 }; // class Document
371
372 using xmlNodeIterator MYGUI_OBSOLETE("use : class MyGUI::xml::ElementEnumerator") = ElementEnumerator;
373 using xmlNodePtr MYGUI_OBSOLETE("use : class MyGUI::xml::ElementPtr") = ElementPtr;
374 using xmlDocument MYGUI_OBSOLETE("use : class MyGUI::xml::Document") = Document;
375
376} // namespace MyGUI
377
378#endif // MYGUI_XML_DOCUMENT_H_
#define MYGUI_OBSOLETE(text)
#define MYGUI_EXPORT
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
bool save(const std::string &_filename)
std::string getLastError() const
ElementPtr getRoot() const
ElementPtr createRoot(std::string_view _name)
ElementPtr createDeclaration(std::string_view _version="1.0", std::string_view _encoding="UTF-8")
bool open(const std::string &_filename)
ElementPtr createInfo(std::string_view _version="1.0", std::string_view _encoding="UTF-8")
const std::string & getContent() const
ElementEnumerator getNodeIterator()
ElementEnumerator getElementEnumerator()
Element(Element &&)=default
const std::string & getBody() const
Element(std::string_view _name, ElementPtr _parent, ElementType _type=ElementType::Normal, std::string_view _content={})
void addBody(const T &_content)
void addAttribute(std::string_view _key, const T &_value)
void addAttributes(std::string_view _key, const T &_value)
void setContent(const T &_content)
void setBody(const T &_content)
void addContent(const T &_content)
ElementPtr createChild(std::string_view _name, std::string_view _content={}, ElementType _type=ElementType::Normal)
std::string toString(T _value)
Element * ElementPtr
std::pair< std::string, std::string > PairAttribute
std::vector< PairAttribute > VectorAttributes
std::vector< std::unique_ptr< Element > > VectorElement
friend bool operator==(ElementType const &a, ElementType const &b)
friend bool operator!=(ElementType const &a, ElementType const &b)
ElementType(Enum _value=MAX)
std::string_view print() const
ErrorType(Enum _value=MAX)