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