MyGUI  3.2.0
MyGUI_XmlDocument.h
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #ifndef __MYGUI_XML_DOCUMENT_H__
23 #define __MYGUI_XML_DOCUMENT_H__
24 
25 #include "MyGUI_Prerequest.h"
26 #include "MyGUI_UString.h"
27 #include "MyGUI_Diagnostic.h"
28 #include "MyGUI_DataStream.h"
29 
30 #include <vector>
31 #include <string>
32 #include <iostream>
33 #include <fstream>
34 #include <sstream>
35 #include <assert.h>
36 
37 namespace MyGUI
38 {
39  namespace xml
40  {
41 
42  struct ElementType
43  {
44  enum Enum
45  {
50  };
51 
52  ElementType(Enum _value = MAX) : value(_value) { }
53  friend bool operator == (ElementType const& a, ElementType const& b)
54  {
55  return a.value == b.value;
56  }
57  friend bool operator != (ElementType const& a, ElementType const& b)
58  {
59  return a.value != b.value;
60  }
61 
62  private:
63  Enum value;
64  };
65 
66  struct ErrorType
67  {
68  enum Enum
69  {
81  };
82 
83  ErrorType(Enum _value = MAX) : value(_value) { }
84 
85  std::string print() const
86  {
87  return getValueName(value);
88  }
89 
90  private:
91  const char* getValueName(int _index) const
92  {
93  static const char* values[MAX + 1] =
94  {
95  "Failed to open XML file",
96  "Failed to ceate XML file",
97  "XML file contain incorrect content",
98  "XML file contain not closed elements",
99  "XML file without declaration",
100  "XML file contain closed but not opened element",
101  "XML file contain inconsistent elements",
102  "XML file contain more than one declaration",
103  "XML file contain more than one root element",
104  "XML file contain incorrect attribute",
105  ""
106  };
107  return values[(_index < MAX && _index >= 0) ? _index : MAX];
108  }
109  private:
110  Enum value;
111  };
112 
113  class Element;
114  class Document;
115 
116  typedef Element* ElementPtr;
117  typedef std::pair<std::string, std::string> PairAttribute;
118  typedef std::vector<PairAttribute> VectorAttributes;
119  typedef std::vector<ElementPtr> VectorElement;
120 
121  //----------------------------------------------------------------------//
122  // class ElementEnumerator
123  //----------------------------------------------------------------------//
125  {
126  friend class Element;
127 
128  private:
129  ElementEnumerator(VectorElement::iterator _begin, VectorElement::iterator _end);
130 
131  public:
132  bool next();
133  bool next(const std::string& _name);
134 
135  ElementPtr operator->() const;
136  ElementPtr current();
137 
138  /*obsolete:*/
139 #ifndef MYGUI_DONT_USE_OBSOLETE
140 
141  MYGUI_OBSOLETE("use : bool ElementEnumerator::next()")
142  bool nextNode()
143  {
144  return next();
145  }
146  MYGUI_OBSOLETE("use : bool ElementEnumerator::next(const std::string& _name)")
147  bool nextNode(const std::string& _name)
148  {
149  return next(_name);
150  }
151  MYGUI_OBSOLETE("use : ElementPtr ElementEnumerator::current()")
152  ElementPtr currentNode()
153  {
154  return current();
155  }
156 
157 #endif // MYGUI_DONT_USE_OBSOLETE
158 
159  private:
160  bool m_first;
161  VectorElement::iterator m_current, m_end;
162  };
163 
164 
165  //----------------------------------------------------------------------//
166  // class Element
167  //----------------------------------------------------------------------//
169  {
170  friend class Document;
171 
172  public:
173  ~Element();
174 
175  private:
176  Element(const std::string& _name, ElementPtr _parent, ElementType _type = ElementType::Normal, const std::string& _content = "");
177  void save(std::ostream& _stream, size_t _level);
178 
179  public:
180  ElementPtr createChild(const std::string& _name, const std::string& _content = "", ElementType _type = ElementType::Normal);
181  void removeChild(ElementPtr _child);
182 
183  template <typename T>
184  void addAttribute(const std::string& _key, const T& _value)
185  {
186  addAttribute(_key, utility::toString(_value));
187  }
188 
189  void addAttribute(const std::string& _key, const std::string& _value);
190 
191  void removeAttribute(const std::string& _key);
192 
193  void setAttribute(const std::string& _key, const std::string& _value);
194 
195  template <typename T>
196  void addContent(const T& _content)
197  {
198  addContent(utility::toString(_content));
199  }
200 
201  void addContent(const std::string& _content);
202 
203  template <typename T>
204  void setContent(const T& _content)
205  {
206  setContent(utility::toString(_content));
207  }
208 
209  void setContent(const std::string& _content);
210 
211  void clear();
212 
213  bool findAttribute(const std::string& _name, std::string& _value);
214  std::string findAttribute(const std::string& _name);
215 
216  const std::string& getName() const;
217 
218  const std::string& getContent() const;
219 
220  const VectorAttributes& getAttributes() const;
221 
222  ElementPtr getParent() const;
223 
224  ElementEnumerator getElementEnumerator();
225 
226  ElementType getType() const;
227 
228  ElementPtr createCopy();
229 
230  /*obsolete:*/
231 #ifndef MYGUI_DONT_USE_OBSOLETE
232 
233  template <typename T>
234  MYGUI_OBSOLETE("use : template <typename T> void Element::addAttribute(const std::string &_key, const T& _value)")
235  void addAttributes(const std::string& _key, const T& _value)
236  {
237  addAttribute<T>(_key, _value);
238  }
239  MYGUI_OBSOLETE("use : void Element::addAttribute(const std::string& _key, const std::string& _value)")
240  void addAttributes(const std::string& _key, const std::string& _value)
241  {
242  addAttribute(_key, _value);
243  }
244 
245  template <typename T>
246  MYGUI_OBSOLETE("use : template <typename T> void Element::addContent(const T& _content)")
247  void addBody(const T& _content)
248  {
249  addContent<T>(_content);
250  }
251  MYGUI_OBSOLETE("use : void Element::addContent(const std::string& _content)")
252  void addBody(const std::string& _content)
253  {
254  addContent(_content);
255  }
256  template <typename T>
257  MYGUI_OBSOLETE("use : template <typename T> void Element::setContent(const T& _content)")
258  void setBody(const T& _content)
259  {
260  setContent<T>(_content);
261  }
262  MYGUI_OBSOLETE("use : void Element::setContent(const std::string& _content)")
263  void setBody(const std::string& _content)
264  {
265  setContent(_content);
266  }
267 
268  MYGUI_OBSOLETE("use : const std::string& Element::getContent()")
269  const std::string& getBody() const
270  {
271  return getContent();
272  }
273  MYGUI_OBSOLETE("use : ElementEnumerator Element::getElementEnumerator()")
274  ElementEnumerator getNodeIterator()
275  {
276  return getElementEnumerator();
277  }
278 
279 #endif // MYGUI_DONT_USE_OBSOLETE
280 
281  private:
282  std::string mName;
283  std::string mContent;
284  VectorAttributes mAttributes;
285  VectorElement mChilds;
286  ElementPtr mParent;
287  ElementType mType;
288  };
289 
290  //----------------------------------------------------------------------//
291  // class Document
292  //----------------------------------------------------------------------//
294  {
295  public:
296  Document();
297  ~Document();
298 
299  // открывает обычным файлом, имя файла в utf8
300  bool open(const std::string& _filename);
301 
302  // открывает обычным файлом, имя файла в utf16 или utf32
303  bool open(const std::wstring& _filename);
304 
305  // открывает обычным потоком
306  bool open(std::istream& _stream);
307 
308  bool open(const UString& _filename);
309 
310  bool open(IDataStream* _data);
311 
312  // сохраняет файл
313  bool save(const std::string& _filename);
314 
315  // сохраняет файл
316  bool save(const std::wstring& _filename);
317 
318  bool save(std::ostream& _stream);
319 
320  bool save(const UString& _filename);
321 
322  void clear();
323 
324  std::string getLastError();
325 
326  void clearLastError();
327 
328  ElementPtr createDeclaration(const std::string& _version = "1.0", const std::string& _encoding = "UTF-8");
329  ElementPtr createRoot(const std::string& _name);
330 
331  ElementPtr getRoot() const;
332 
333  /*obsolete:*/
334 #ifndef MYGUI_DONT_USE_OBSOLETE
335 
336  MYGUI_OBSOLETE("use : ElementPtr Document::createDeclaration(const std::string& _version, const std::string& _encoding)")
337  ElementPtr createInfo(const std::string& _version = "1.0", const std::string& _encoding = "UTF-8")
338  {
339  return createDeclaration(_version, _encoding);
340  }
341 
342 #endif // MYGUI_DONT_USE_OBSOLETE
343 
344  private:
345  void setLastFileError(const std::string& _filename);
346  void setLastFileError(const std::wstring& _filename);
347 
348  bool parseTag(ElementPtr& _currentNode, std::string _content);
349 
350  bool checkPair(std::string& _key, std::string& _value);
351 
352  bool parseLine(std::string& _line, ElementPtr& _element);
353 
354  // ищет символ без учета ковычек
355  size_t find(const std::string& _text, char _char, size_t _start = 0);
356 
357  void clearDeclaration();
358  void clearRoot();
359 
360  private:
361  ElementPtr mRoot;
362  ElementPtr mDeclaration;
363  ErrorType mLastError;
364  std::string mLastErrorFile;
365  size_t mLine;
366  size_t mCol;
367 
368  }; // class Document
369 
370  MYGUI_OBSOLETE("use : class MyGUI::xml::ElementEnumerator")
372  MYGUI_OBSOLETE("use : class MyGUI::xml::ElementPtr")
374  MYGUI_OBSOLETE("use : class MyGUI::xml::Document")
376 
377  } // namespace xml
378 
379 } // namespace MyGUI
380 
381 #endif // __MYGUI_XML_DOCUMENT_H__