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