1 /***********************************************************************
2     created:    Thue May 16 2006
3     author:     Olivier Delannoy
4 *************************************************************************/
5 /***************************************************************************
6  *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
7  *
8  *   Permission is hereby granted, free of charge, to any person obtaining
9  *   a copy of this software and associated documentation files (the
10  *   "Software"), to deal in the Software without restriction, including
11  *   without limitation the rights to use, copy, modify, merge, publish,
12  *   distribute, sublicense, and/or sell copies of the Software, and to
13  *   permit persons to whom the Software is furnished to do so, subject to
14  *   the following conditions:
15  *
16  *   The above copyright notice and this permission notice shall be
17  *   included in all copies or substantial portions of the Software.
18  *
19  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  *   OTHER DEALINGS IN THE SOFTWARE.
26  ***************************************************************************/
27 #ifndef _CEGUIXMLSerializer_h_
28 #define _CEGUIXMLSerializer_h_
29 #include "CEGUI/Base.h"
30 #include "CEGUI/String.h"
31 #include <vector>
32 
33 #if defined(_MSC_VER)
34 #	pragma warning(push)
35 #	pragma warning(disable : 4251)
36 #endif
37 
38 // Start of CEGUI namespace section
39 namespace CEGUI
40 {
41     /*!
42     \brief
43          Class used to create XML Document.
44 
45     This class hides the complexity of formatting valid XML files. The
46     class provides automatic substitution of entities, XML indenting
47     in respect of the spaces. It does not contains any codes specific
48     to CEGUI taking appart the CEGUI::String class. The following
49     example show the code needed to exports parts of an XML document
50     similar to what can be found in a layout.
51 
52     @code
53     #include <iostream>
54     #include <CEGUI/XMLSerializer.h>
55 
56     int main()
57     {
58        // Create an encoder that outputs its result on standard output
59        XMLSerializer xml(std::cout, 4);
60        xml.openTag("Window")
61           .attribute("Type", "TaharezLook/StaticText")
62           .attribute("Name", "Test")
63           .openTag("Property")
64           .attribute("Name", "Text")
65           .text("This is the static text to be displayed")
66           .closeTag()
67           .openTag("Window")
68           .attribute("Name", "Button")
69           .attribute("Type", "Vanilla/Button")
70           .openTag("Property")
71           .attribute("Name", "Text")
72           .attribute("Value", "Push me")
73           .closeTag()
74           .closeTag()
75           .closeTag();
76 
77        if (xml)
78        {
79            std::cout << "XML Exported successfully" << std::endl;
80        }
81        return 0;
82     }
83     @endcode
84     */
85     class CEGUIEXPORT XMLSerializer :
86         public AllocatedObject<XMLSerializer>
87     {
88     public:
89         /*!
90         \brief XMLSerializer constructor
91 
92         \param out The stream to use to export the result
93 
94 
95         \param indentSpace The indentation level (0 to disable indentation)
96         */
97         XMLSerializer(OutStream& out, size_t indentSpace = 4);
98 
99         /*!
100         \brief XMLSerializer destructor
101         */
102         virtual ~XMLSerializer(void);
103 
104         /*!
105         \brief Start a new tag in the xml document.
106 
107         \param name The name of the tag
108 
109         \return
110             A reference to the current object for chaining operation
111         */
112         XMLSerializer& openTag(const String& name);
113         /*!
114         \brief Close the current tag.
115 
116         \return
117             A reference to the current object for chaining operation
118         */
119         XMLSerializer& closeTag(void);
120         /*!
121         \brief After an opening tag you can populate attribute list with this function
122 
123         \param name The name of the attribute
124 
125         \param value The value of the attribute
126 
127         \return
128             A reference to the current object for chaining operation
129         */
130         XMLSerializer& attribute(const String& name, const String& value);
131         /*!
132         \brief Create a text node
133 
134         \param text the content of the node
135 
136         \return
137             A reference to the current object for chaining operation
138         */
139         XMLSerializer& text(const String& text);
140 
141         /*!
142         \brief
143         report the nimber of tags created in the document
144 
145         \return
146             return the number of tag created in the document
147         */
148         unsigned int getTagCount() const;
149         /*!
150         \brief Check wether the XML Serializer status is valid
151 
152         \return
153             True if all previous operations where successfull
154         */
155         operator bool () const
156         {
157             return false == d_error;
158         }
159         /*!
160         \brief Check wether the XML Serializer status is invalid
161 
162         \return
163             True if one operations failed
164         */
165         bool operator!() const
166         {
167             return false != d_error;
168         }
169 
170     protected:
171     private:
172         bool d_error; //!< Store the status of the serializer
173         unsigned int d_tagCount; //!<Return the number of tag in the document
174         size_t d_depth; //!< Store the current depth for indentation purpose
175         size_t d_indentSpace; //!< Store the number of space use for indenting
176         bool d_needClose; //!< Store whether the next operation need to close the tag or not
177         bool d_lastIsText; //!< Store whether the last operation was a text node or not
178         OutStream& d_stream; //!< A reference to the stream object use
179         std::vector<String
180             CEGUI_VECTOR_ALLOC(String)> d_tagStack; //!< Store the tag stack for correct closing of the tags.
181 
182         /*!
183         \brief put padding in the stream before line data
184         */
185         void indentLine();
186         /*!
187         \brief convert special char to there corresponding entity in text data.
188         */
189         static String convertEntityInText(const String& text);
190         /*!
191         \brief convert special char into entities including line ending for use in attributes.
192         */
193         static String convertEntityInAttribute(const String& attributeValue);
194 
195 
196         // Disabled operation
197         XMLSerializer(const XMLSerializer& obj);
198         // Disabled operation
199         XMLSerializer& operator=(const XMLSerializer& obj);
200     };
201 }
202 
203 #if defined(_MSC_VER)
204 #   pragma warning(pop)
205 #endif
206 
207 #endif
208