1 // XML_as.h:  ActionScript 3 "XMLDocument" class, for Gnash.
2 //
3 //   Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 
20 #ifndef GNASH_ASOBJ3_XMLDOCUMENT_H
21 #define GNASH_ASOBJ3_XMLDOCUMENT_H
22 
23 #include "XMLNode_as.h"
24 #include "dsodefs.h"
25 #include "StringPredicates.h"
26 
27 #include <map>
28 #include <string>
29 
30 
31 namespace gnash {
32 
33 // Forward declarations
34 class fn_call;
35 class URL;
36 
37 /// Implements XML (AS2) and flash.xml.XMLDocument (AS3) class.
38 //
39 /// This class interface is identical in AS3 and AS2; it is probably
40 /// included in AS3 for backward compatibility.
41 //
42 /// The class definition is necessary because XML is encoded differently
43 /// in AMF.
44 class XML_as : public XMLNode_as
45 {
46 public:
47 
48     typedef std::string::const_iterator xml_iterator;
49 
50     enum ParseStatus {
51             XML_OK = 0,
52             XML_UNTERMINATED_CDATA = -2,
53             XML_UNTERMINATED_XML_DECL = -3,
54             XML_UNTERMINATED_DOCTYPE_DECL = -4,
55             XML_UNTERMINATED_COMMENT = -5,
56             XML_UNTERMINATED_ELEMENT = -6,
57             XML_OUT_OF_MEMORY = -7,
58             XML_UNTERMINATED_ATTRIBUTE = -8,
59             XML_MISSING_CLOSE_TAG = -9,
60             XML_MISSING_OPEN_TAG = -10
61     };
62 
63     enum LoadStatus {
64         XML_LOADED_UNDEFINED = -1,
65         XML_LOADED_FALSE = false,
66         XML_LOADED_TRUE = true
67     };
68 
69     /// Create an XML object.
70     //
71     /// An XMLDocument is always user-created, so always starts with an
72     /// associated object.
73     XML_as(as_object& object);
74 
75     XML_as(as_object& object, const std::string& xml);
76 
~XML_as()77     ~XML_as() {};
78 
79     /// Convert the XML object to a string
80     //
81     /// This calls XMLNode::toString after adding an xmlDecl and
82     /// docTypeDecl
83     //
84     /// @param o        The ostream to write the string to.
85     /// @param encode   Whether to URL encode the node values.
86     void toString(std::ostream& o, bool encode) const;
87 
getXMLDecl()88     const std::string& getXMLDecl() const {
89         return _xmlDecl;
90     }
91 
setXMLDecl(const std::string & xml)92     void setXMLDecl(const std::string& xml) {
93         _xmlDecl = xml;
94     }
95 
getDocTypeDecl()96     const std::string& getDocTypeDecl() const {
97         return _docTypeDecl;
98     }
99 
setDocTypeDecl(const std::string & docType)100     void setDocTypeDecl(const std::string& docType) {
101         _docTypeDecl = docType;
102     }
103 
getContentType()104     const std::string& getContentType() const {
105         return _contentType;
106     }
107 
setContentType(const std::string & contentType)108     void setContentType(const std::string& contentType) {
109         _contentType = contentType;
110     }
111 
112     // Methods
113 
114     /// Parses an XML document into the specified XML object tree.
115     //
116     /// This reads in an XML file from disk and parses into into a memory
117     /// resident tree which can be walked through later.
118     ///
119     /// Calls to this function clear any precedently parsed data.
120     ///
121     void parseXML(const std::string& xml);
122 
status()123     int status() const {
124         return _status;
125     }
126 
setStatus(ParseStatus st)127     void setStatus(ParseStatus st) {
128         _status = st;
129     }
130 
loaded()131     LoadStatus loaded() const {
132         return _loaded;
133     }
134 
setLoaded(LoadStatus st)135     void setLoaded(LoadStatus st) {
136         _loaded = st;
137     }
138 
139     /// Return current ignoreWhite property.
ignoreWhite()140     bool ignoreWhite() const {
141         return _ignoreWhite;
142     }
143 
144     /// Set ignoreWhite property.
ignoreWhite(bool ignore)145     void ignoreWhite(bool ignore) {
146         _ignoreWhite = ignore;
147     }
148 
149 private:
150 
151     typedef std::map<std::string, std::string, StringNoCaseLessThan> Attributes;
152 
153     void parseTag(XMLNode_as*& node, xml_iterator& it, xml_iterator end);
154 
155     void parseAttribute(XMLNode_as* node, xml_iterator& it,
156             xml_iterator end, Attributes& attributes);
157 
158     void parseDocTypeDecl( xml_iterator& it, xml_iterator end);
159 
160     void parseText(XMLNode_as* node, xml_iterator& it, xml_iterator end,
161             bool ignoreWhite);
162 
163     void parseXMLDecl(xml_iterator& it, xml_iterator end);
164 
165     void parseComment(XMLNode_as* node, xml_iterator& it, xml_iterator end);
166 
167     void parseCData(XMLNode_as* node, xml_iterator& it, xml_iterator end);
168 
169     /// Clear all properties.
170     //
171     /// This removes all children, resets doctype and xml decls, and
172     /// sets status to XML.
173     void clear();
174 
175     // -1 if never asked to load anything
176     //  0 if asked to load but not yet loaded (or failure)
177     //  1 if successfully loaded
178     LoadStatus _loaded;
179 
180     // Nominally used to store ParseStatus, but can be any int value.
181     int _status;
182 
183     std::string _docTypeDecl;
184 
185     std::string _xmlDecl;
186 
187     std::string _contentType;
188 
189     bool _ignoreWhite;
190 };
191 
192 
193 /// Escape using XML entities.
194 //
195 /// Note this is not the same as a URL escape.
196 void escapeXML(std::string& text);
197 void unescapeXML(std::string& text);
198 
199 /// Register the XML class.
200 void xml_class_init(as_object& where, const ObjectURI& uri);
201 
202 /// Register XML native functions.
203 void registerXMLNative(as_object& where);
204 
205 }	// namespace gnash
206 #endif
207 
208 // local Variables:
209 // mode: C++
210 // indent-tabs-mode: t
211 // End:
212 
213