00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __MYGUI_XML_DOCUMENT_H__
00024 #define __MYGUI_XML_DOCUMENT_H__
00025
00026 #include "MyGUI_Prerequest.h"
00027 #include "MyGUI_Utility.h"
00028 #include "MyGUI_Common.h"
00029 #include "MyGUI_DataStream.h"
00030
00031 #include <vector>
00032 #include <string>
00033 #include <iostream>
00034 #include <fstream>
00035 #include <sstream>
00036 #include <assert.h>
00037 #include <assert.h>
00038
00039 namespace MyGUI
00040 {
00041 namespace xml
00042 {
00043
00044 struct ElementType
00045 {
00046 enum Enum
00047 {
00048 Comment,
00049 Declaration,
00050 Normal,
00051 MAX
00052 };
00053
00054 ElementType(Enum _value = MAX) : value(_value) { }
00055 friend bool operator == (ElementType const& a, ElementType const& b) { return a.value == b.value; }
00056 friend bool operator != (ElementType const& a, ElementType const& b) { return a.value != b.value; }
00057
00058 private:
00059 Enum value;
00060 };
00061
00062 struct ErrorType
00063 {
00064 enum Enum
00065 {
00066 OpenFileFail,
00067 CreateFileFail,
00068 IncorrectContent,
00069 NotClosedElements,
00070 NoXMLDeclaration,
00071 CloseNotOpenedElement,
00072 InconsistentOpenCloseElements,
00073 MoreThanOneXMLDeclaration,
00074 MoreThanOneRootElement,
00075 IncorrectAttribute,
00076 MAX
00077 };
00078
00079 ErrorType(Enum _value = MAX) : value(_value) { }
00080
00081 std::string print() const { return getValueName(value); }
00082
00083 private:
00084 const char * getValueName(int _index) const
00085 {
00086 static const char * values[MAX + 1] =
00087 {
00088 "Failed to open XML file",
00089 "Failed to ceate XML file",
00090 "XML file contain incorrect content",
00091 "XML file contain not closed elements",
00092 "XML file without declaration",
00093 "XML file contain closed but not opened element",
00094 "XML file contain inconsistent elements",
00095 "XML file contain more than one declaration",
00096 "XML file contain more than one root element",
00097 "XML file contain incorrect attribute",
00098 ""
00099 };
00100 return values[(_index < MAX && _index >= 0) ? _index : MAX];
00101 }
00102 private:
00103 Enum value;
00104 };
00105
00106 class Element;
00107 class Document;
00108
00109 typedef Element * ElementPtr;
00110 typedef std::pair<std::string, std::string> PairAttribute;
00111 typedef std::vector<PairAttribute> VectorAttributes;
00112 typedef std::vector<ElementPtr> VectorElement;
00113
00114
00115
00116
00117 class MYGUI_EXPORT ElementEnumerator
00118 {
00119 friend class Element;
00120
00121 private:
00122 ElementEnumerator(VectorElement::iterator _begin, VectorElement::iterator _end);
00123
00124 public:
00125 bool next();
00126 bool next(const std::string& _name);
00127
00128 ElementPtr operator->() const { assert(m_current != m_end); return (*m_current); }
00129 ElementPtr current() { assert(m_current != m_end); return (*m_current); }
00130
00131
00132 #ifndef MYGUI_DONT_USE_OBSOLETE
00133
00134 MYGUI_OBSOLETE("use : bool ElementEnumerator::next()")
00135 bool nextNode() { return next(); }
00136 MYGUI_OBSOLETE("use : bool ElementEnumerator::next(const std::string& _name)")
00137 bool nextNode(const std::string& _name) { return next(_name); }
00138 MYGUI_OBSOLETE("use : ElementPtr ElementEnumerator::current()")
00139 ElementPtr currentNode() { return current(); }
00140
00141 #endif // MYGUI_DONT_USE_OBSOLETE
00142
00143 private:
00144 bool m_first;
00145 VectorElement::iterator m_current, m_end;
00146 };
00147
00148
00149
00150
00151
00152 class MYGUI_EXPORT Element
00153 {
00154 friend class Document;
00155
00156 public:
00157 ~Element();
00158
00159 private:
00160 Element(const std::string &_name, ElementPtr _parent, ElementType _type = ElementType::Normal, const std::string& _content = "");
00161 void save(std::ostream& _stream, size_t _level);
00162
00163 public:
00164 ElementPtr createChild(const std::string& _name, const std::string& _content = "");
00165
00166 template <typename T>
00167 void addAttribute(const std::string &_key, const T& _value)
00168 {
00169 mAttributes.push_back(PairAttribute(_key, utility::toString(_value)));
00170 }
00171
00172 void addAttribute(const std::string& _key, const std::string& _value);
00173
00174 void removeAttribute(const std::string& _key);
00175
00176 void setAttribute(const std::string& _key, const std::string& _value);
00177
00178 template <typename T>
00179 void addContent(const T& _content)
00180 {
00181 mContent.empty() ? mContent = utility::toString(_content) : mContent += utility::toString(" ", _content);
00182 }
00183
00184 void addContent(const std::string& _content);
00185
00186 template <typename T>
00187 void setContent(const T& _content)
00188 {
00189 mContent = utility::toString(_content);
00190 }
00191
00192 void setContent(const std::string& _content) { mContent = _content; }
00193
00194 void clear();
00195
00196 bool findAttribute(const std::string& _name, std::string& _value);
00197 std::string findAttribute(const std::string& _name);
00198
00199 const std::string& getName() { return mName; }
00200 const std::string& getContent() { return mContent; }
00201 const VectorAttributes& getAttributes() { return mAttributes; }
00202 ElementPtr getParent() { return mParent; }
00203
00204 ElementEnumerator getElementEnumerator() { return ElementEnumerator(mChilds.begin(), mChilds.end()); }
00205
00206 ElementType getType() { return mType; }
00207
00208 ElementPtr createCopy();
00209
00210
00211 #ifndef MYGUI_DONT_USE_OBSOLETE
00212
00213 template <typename T>
00214 MYGUI_OBSOLETE("use : template <typename T> void Element::addAttribute(const std::string &_key, const T& _value)")
00215 void addAttributes(const std::string &_key, const T& _value) { addAttribute<T>(_key, _value); }
00216 MYGUI_OBSOLETE("use : void Element::addAttribute(const std::string& _key, const std::string& _value)")
00217 void addAttributes(const std::string& _key, const std::string& _value) { addAttribute(_key, _value); }
00218
00219 template <typename T>
00220 MYGUI_OBSOLETE("use : template <typename T> void Element::addContent(const T& _content)")
00221 void addBody(const T& _content) { addContent<T>(_content); }
00222 MYGUI_OBSOLETE("use : void Element::addContent(const std::string& _content)")
00223 void addBody(const std::string& _content) { addContent(_content); }
00224 template <typename T>
00225 MYGUI_OBSOLETE("use : template <typename T> void Element::setContent(const T& _content)")
00226 void setBody(const T& _content) { setContent<T>(_content); }
00227 MYGUI_OBSOLETE("use : void Element::setContent(const std::string& _content)")
00228 void setBody(const std::string& _content) { setContent(_content); }
00229
00230 MYGUI_OBSOLETE("use : const std::string& Element::getContent()")
00231 const std::string& getBody() { return getContent(); }
00232 MYGUI_OBSOLETE("use : ElementEnumerator Element::getElementEnumerator()")
00233 ElementEnumerator getNodeIterator() { return getElementEnumerator(); }
00234
00235 #endif // MYGUI_DONT_USE_OBSOLETE
00236
00237 private:
00238 std::string mName;
00239 std::string mContent;
00240 VectorAttributes mAttributes;
00241 VectorElement mChilds;
00242 ElementPtr mParent;
00243 ElementType mType;
00244 };
00245
00246
00247
00248
00249 class MYGUI_EXPORT Document
00250 {
00251 public:
00252 Document();
00253 ~Document();
00254
00255
00256 bool open(const std::string& _filename);
00257
00258
00259 bool open(const std::wstring& _filename);
00260
00261
00262 bool open(std::istream& _stream);
00263
00264 bool open(const UString& _filename) { return open(_filename.asWStr()); }
00265
00266 bool open(IDataStream* _data);
00267
00268
00269 bool save(const std::string& _filename);
00270
00271
00272 bool save(const std::wstring& _filename);
00273
00274 bool save(std::ostream& _stream);
00275
00276 bool save(const UString& _filename) { return save(_filename.asWStr()); }
00277
00278 void clear();
00279
00280 std::string getLastError();
00281
00282 void clearLastError() { mLastError = ErrorType::MAX; }
00283
00284 ElementPtr createDeclaration(const std::string& _version = "1.0", const std::string& _encoding = "UTF-8");
00285 ElementPtr createRoot(const std::string& _name);
00286
00287 ElementPtr getRoot() { return mRoot; }
00288
00289
00290 #ifndef MYGUI_DONT_USE_OBSOLETE
00291
00292 MYGUI_OBSOLETE("use : ElementPtr Document::createDeclaration(const std::string& _version, const std::string& _encoding)")
00293 ElementPtr createInfo(const std::string& _version = "1.0", const std::string& _encoding = "UTF-8") { return createDeclaration(_version, _encoding); }
00294
00295 #endif // MYGUI_DONT_USE_OBSOLETE
00296
00297 private:
00298 void setLastFileError(const std::string& _filename) { mLastErrorFile = _filename; }
00299
00300 void setLastFileError(const std::wstring& _filename) { mLastErrorFile = UString(_filename).asUTF8(); }
00301
00302 bool parseTag(ElementPtr &_currentNode, std::string _content);
00303
00304 bool checkPair(std::string &_key, std::string &_value);
00305
00306 bool parseLine(std::string& _line, ElementPtr& _element);
00307
00308
00309 size_t find(const std::string& _text, char _char, size_t _start = 0);
00310
00311 void clearDeclaration();
00312 void clearRoot();
00313
00314 private:
00315 ElementPtr mRoot;
00316 ElementPtr mDeclaration;
00317 ErrorType mLastError;
00318 std::string mLastErrorFile;
00319 size_t mLine;
00320 size_t mCol;
00321
00322 };
00323
00324 MYGUI_OBSOLETE("use : class MyGUI::xml::ElementEnumerator")
00325 typedef ElementEnumerator xmlNodeIterator;
00326 MYGUI_OBSOLETE("use : class MyGUI::xml::ElementPtr")
00327 typedef ElementPtr xmlNodePtr;
00328 MYGUI_OBSOLETE("use : class MyGUI::xml::Document")
00329 typedef Document xmlDocument;
00330
00331 }
00332
00333 }
00334
00335 #endif // __MYGUI_XML_DOCUMENT_H__