MyGUI  3.2.0
MyGUI_XmlDocument.h
Go to the documentation of this file.
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__