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