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