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