MyGUI  3.2.1
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 <assert.h>
21 
22 namespace MyGUI
23 {
24  namespace xml
25  {
26 
27  struct ElementType
28  {
29  enum Enum
30  {
35  };
36 
37  ElementType(Enum _value = MAX) : mValue(_value) { }
38  friend bool operator == (ElementType const& a, ElementType const& b)
39  {
40  return a.mValue == b.mValue;
41  }
42  friend bool operator != (ElementType const& a, ElementType const& b)
43  {
44  return a.mValue != b.mValue;
45  }
46 
47  int getValue() const
48  {
49  return mValue;
50  }
51 
52  private:
53  Enum mValue;
54  };
55 
56  struct ErrorType
57  {
58  enum Enum
59  {
71  };
72 
73  ErrorType(Enum _value = MAX) : mValue(_value) { }
74 
75  std::string print() const
76  {
77  return getValueName(mValue);
78  }
79 
80  private:
81  const char* getValueName(int _index) const
82  {
83  static const char* values[MAX + 1] =
84  {
85  "Failed to open XML file",
86  "Failed to ceate XML file",
87  "XML file contain incorrect content",
88  "XML file contain not closed elements",
89  "XML file without declaration",
90  "XML file contain closed but not opened element",
91  "XML file contain inconsistent elements",
92  "XML file contain more than one declaration",
93  "XML file contain more than one root element",
94  "XML file contain incorrect attribute",
95  ""
96  };
97  return values[(_index < MAX && _index >= 0) ? _index : MAX];
98  }
99  private:
100  Enum mValue;
101  };
102 
103  class Element;
104  class Document;
105 
106  typedef Element* ElementPtr;
107  typedef std::pair<std::string, std::string> PairAttribute;
108  typedef std::vector<PairAttribute> VectorAttributes;
109  typedef std::vector<ElementPtr> VectorElement;
110 
111  //----------------------------------------------------------------------//
112  // class ElementEnumerator
113  //----------------------------------------------------------------------//
115  {
116  friend class Element;
117 
118  private:
119  ElementEnumerator(VectorElement::iterator _begin, VectorElement::iterator _end);
120 
121  public:
122  bool next();
123  bool next(const std::string& _name);
124 
125  ElementPtr operator->() const;
126  ElementPtr current();
127 
128  /*obsolete:*/
129 #ifndef MYGUI_DONT_USE_OBSOLETE
130 
131  MYGUI_OBSOLETE("use : bool ElementEnumerator::next()")
132  bool nextNode()
133  {
134  return next();
135  }
136  MYGUI_OBSOLETE("use : bool ElementEnumerator::next(const std::string& _name)")
137  bool nextNode(const std::string& _name)
138  {
139  return next(_name);
140  }
141  MYGUI_OBSOLETE("use : ElementPtr ElementEnumerator::current()")
142  ElementPtr currentNode()
143  {
144  return current();
145  }
146 
147 #endif // MYGUI_DONT_USE_OBSOLETE
148 
149  private:
150  bool m_first;
151  VectorElement::iterator m_current, m_end;
152  };
153 
154 
155  //----------------------------------------------------------------------//
156  // class Element
157  //----------------------------------------------------------------------//
159  {
160  friend class Document;
161 
162  public:
163  ~Element();
164 
165  private:
166  Element(const std::string& _name, ElementPtr _parent, ElementType _type = ElementType::Normal, const std::string& _content = "");
167  void save(std::ostream& _stream, size_t _level);
168 
169  public:
170  ElementPtr createChild(const std::string& _name, const std::string& _content = "", ElementType _type = ElementType::Normal);
171  void removeChild(ElementPtr _child);
172 
173  template <typename T>
174  void addAttribute(const std::string& _key, const T& _value)
175  {
176  addAttribute(_key, utility::toString(_value));
177  }
178 
179  void addAttribute(const std::string& _key, const std::string& _value);
180 
181  void removeAttribute(const std::string& _key);
182 
183  void setAttribute(const std::string& _key, const std::string& _value);
184 
185  template <typename T>
186  void addContent(const T& _content)
187  {
188  addContent(utility::toString(_content));
189  }
190 
191  void addContent(const std::string& _content);
192 
193  template <typename T>
194  void setContent(const T& _content)
195  {
196  setContent(utility::toString(_content));
197  }
198 
199  void setContent(const std::string& _content);
200 
201  void clear();
202 
203  bool findAttribute(const std::string& _name, std::string& _value);
204  std::string findAttribute(const std::string& _name);
205 
206  const std::string& getName() const;
207 
208  const std::string& getContent() const;
209 
210  const VectorAttributes& getAttributes() const;
211 
212  ElementPtr getParent() const;
213 
214  ElementEnumerator getElementEnumerator();
215 
216  ElementType getType() const;
217 
218  ElementPtr createCopy();
219 
220  /*obsolete:*/
221 #ifndef MYGUI_DONT_USE_OBSOLETE
222 
223  template <typename T>
224  MYGUI_OBSOLETE("use : template <typename T> void Element::addAttribute(const std::string &_key, const T& _value)")
225  void addAttributes(const std::string& _key, const T& _value)
226  {
227  addAttribute<T>(_key, _value);
228  }
229  MYGUI_OBSOLETE("use : void Element::addAttribute(const std::string& _key, const std::string& _value)")
230  void addAttributes(const std::string& _key, const std::string& _value)
231  {
232  addAttribute(_key, _value);
233  }
234 
235  template <typename T>
236  MYGUI_OBSOLETE("use : template <typename T> void Element::addContent(const T& _content)")
237  void addBody(const T& _content)
238  {
239  addContent<T>(_content);
240  }
241  MYGUI_OBSOLETE("use : void Element::addContent(const std::string& _content)")
242  void addBody(const std::string& _content)
243  {
244  addContent(_content);
245  }
246  template <typename T>
247  MYGUI_OBSOLETE("use : template <typename T> void Element::setContent(const T& _content)")
248  void setBody(const T& _content)
249  {
250  setContent<T>(_content);
251  }
252  MYGUI_OBSOLETE("use : void Element::setContent(const std::string& _content)")
253  void setBody(const std::string& _content)
254  {
255  setContent(_content);
256  }
257 
258  MYGUI_OBSOLETE("use : const std::string& Element::getContent()")
259  const std::string& getBody() const
260  {
261  return getContent();
262  }
263  MYGUI_OBSOLETE("use : ElementEnumerator Element::getElementEnumerator()")
264  ElementEnumerator getNodeIterator()
265  {
266  return getElementEnumerator();
267  }
268 
269 #endif // MYGUI_DONT_USE_OBSOLETE
270 
271  private:
272  std::string mName;
273  std::string mContent;
274  VectorAttributes mAttributes;
275  VectorElement mChilds;
276  ElementPtr mParent;
277  ElementType mType;
278  };
279 
280  //----------------------------------------------------------------------//
281  // class Document
282  //----------------------------------------------------------------------//
284  {
285  public:
286  Document();
287  ~Document();
288 
289  // открывает обычным файлом, имя файла в utf8
290  bool open(const std::string& _filename);
291 
292  // открывает обычным файлом, имя файла в utf16 или utf32
293  bool open(const std::wstring& _filename);
294 
295  // открывает обычным потоком
296  bool open(std::istream& _stream);
297 
298  bool open(const UString& _filename);
299 
300  bool open(IDataStream* _data);
301 
302  // сохраняет файл
303  bool save(const std::string& _filename);
304 
305  // сохраняет файл
306  bool save(const std::wstring& _filename);
307 
308  bool save(std::ostream& _stream);
309 
310  bool save(const UString& _filename);
311 
312  void clear();
313 
314  std::string getLastError();
315 
316  void clearLastError();
317 
318  ElementPtr createDeclaration(const std::string& _version = "1.0", const std::string& _encoding = "UTF-8");
319  ElementPtr createRoot(const std::string& _name);
320 
321  ElementPtr getRoot() const;
322 
323  /*obsolete:*/
324 #ifndef MYGUI_DONT_USE_OBSOLETE
325 
326  MYGUI_OBSOLETE("use : ElementPtr Document::createDeclaration(const std::string& _version, const std::string& _encoding)")
327  ElementPtr createInfo(const std::string& _version = "1.0", const std::string& _encoding = "UTF-8")
328  {
329  return createDeclaration(_version, _encoding);
330  }
331 
332 #endif // MYGUI_DONT_USE_OBSOLETE
333 
334  private:
335  void setLastFileError(const std::string& _filename);
336  void setLastFileError(const std::wstring& _filename);
337 
338  bool parseTag(ElementPtr& _currentNode, std::string _content);
339 
340  bool checkPair(std::string& _key, std::string& _value);
341 
342  bool parseLine(std::string& _line, ElementPtr& _element);
343 
344  // ищет символ без учета ковычек
345  size_t find(const std::string& _text, char _char, size_t _start = 0);
346 
347  void clearDeclaration();
348  void clearRoot();
349 
350  private:
351  ElementPtr mRoot;
352  ElementPtr mDeclaration;
353  ErrorType mLastError;
354  std::string mLastErrorFile;
355  size_t mLine;
356  size_t mCol;
357 
358  }; // class Document
359 
360  MYGUI_OBSOLETE("use : class MyGUI::xml::ElementEnumerator")
362  MYGUI_OBSOLETE("use : class MyGUI::xml::ElementPtr")
364  MYGUI_OBSOLETE("use : class MyGUI::xml::Document")
366 
367  } // namespace xml
368 
369 } // namespace MyGUI
370 
371 #endif // __MYGUI_XML_DOCUMENT_H__