Merge branch 'master' of git.sv.gnu.org:/srv/git/gnash
[gnash.git] / libcore / asobj / XMLNode_as.h
blob29eb1c525bf00027c4137bdd06dcff1f9281c281
1 // XMLNode_as.h: ActionScript 3 "XMLNode" class, for Gnash.
2 //
3 // Copyright (C) 2009, 2010 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.
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
20 #ifndef GNASH_ASOBJ3_XMLNODE_H
21 #define GNASH_ASOBJ3_XMLNODE_H
23 #include <list>
24 #include <string>
25 #include <sstream>
26 #include <cassert>
28 #include "Relay.h"
30 namespace gnash {
31 class as_object;
32 class Global_as;
33 struct ObjectURI;
36 namespace gnash {
39 /// A node in an XML tree.
41 /// This class has various complications to reduce memory usage when parsing
42 /// very large XML documents.
44 /// 1. It is a Relay class that can be attached to an as_object.
45 /// 2. It does not have to have an associated object. This is only created
46 /// once the XMLNode is accessed in ActionScript.
47 /// 3. The top node of an XML tree is always accessible in ActionScript, either
48 /// as an XML_as or a user-created XMLNode_as.
49 /// 4. XMLNodes consequently mark their children as reachable, but not their
50 /// parent.
51 /// 5. When an XMLNode is destroyed, any children without an associated object
52 /// are also deleted. Children with an associated object will be destroyed
53 /// when the GC destroys the object.
54 class XMLNode_as : public Relay
56 public:
58 enum NodeType {
59 Element = 1,
60 Attribute = 2,
61 Text = 3,
62 Cdata = 4,
63 EntityRef = 5,
64 Entity = 6,
65 ProcInstr = 7,
66 Comment = 8,
67 Document = 9,
68 DocType = 10,
69 DocFragment = 11,
70 Notation = 12
73 XMLNode_as(Global_as& gl);
75 virtual ~XMLNode_as();
77 size_t length() const { return _children.size(); }
79 const std::string& nodeName() const { return _name; }
81 const std::string& nodeValue() const { return _value; }
83 /// Get the type of an XML Node.
84 NodeType nodeType() const { return _type; }
86 /// Set the type of an XML Node.
87 void nodeTypeSet(NodeType type) {
88 _type = type;
91 /// Set name of this node
92 void nodeNameSet(const std::string& name) { _name = name; }
94 bool extractPrefix(std::string& prefix);
96 /// Set value of this node
97 void nodeValueSet(const std::string& value) { _value = value; }
99 /// Performs a recursive search of node attributes to find a match
100 void getNamespaceForPrefix(const std::string& prefix, std::string& ns);
102 /// Performs a recursive search of node attributes to find a match
104 /// @return false if no match found.
105 bool getPrefixForNamespace(const std::string& ns, std::string& prefix);
107 void setNamespaceURI(const std::string& value) {
108 _namespaceURI = value;
111 const std::string& getNamespaceURI() const {
112 return _namespaceURI;
115 /// Returns true if the specified node has child nodes; otherwise,
116 /// returns false.
117 bool hasChildNodes();
119 XMLNode_as* firstChild();
120 XMLNode_as* lastChild();
122 // Use a list for quick erasing
123 typedef std::list<XMLNode_as*> Children;
125 as_object* childNodes();
127 XMLNode_as* previousSibling();
128 XMLNode_as* nextSibling();
130 /// Copy a node
132 /// Method; constructs and returns a new XML node of the same type,
133 /// name, value, and attributes as the specified XML object. If deep
134 /// is set to true, all child nodes are recursively cloned, resulting
135 /// in an exact copy of the original object's document tree.
136 XMLNode_as* cloneNode(bool deep);
138 /// Append a child node to this XML object
140 /// The child node's parent is set to this object, the node is added to
141 /// this object's children.
143 /// The childNodes array will be updated if it exists.
145 /// @param node The node to add as a child
146 void appendChild(XMLNode_as* node);
148 /// Remove a child node from this XML object
150 /// The child node's parent is set to 0, the node is removed from
151 /// this object's children.
153 /// The childNodes array will be updated if it exists.
155 /// @param node The node to remove.
156 void removeChild(XMLNode_as* node);
158 /// Get the parent XMLNode_as of this node. Can be 0.
159 XMLNode_as* getParent() const {
160 return _parent;
163 /// Insert a node before a node
165 /// Method; inserts a new child node into the XML object's child
166 /// list, before the beforeNode node. If the beforeNode parameter is
167 /// undefined or null, the node is added using the appendChild()
168 /// method. If beforeNode is not a child of my_xml, the insertion
169 /// fails.
171 /// @param newnode
172 /// The node to insert, moving from its current tree
174 /// @param pos
175 /// The node before which to insert the new one.
176 /// Must be a child of this XMLNode or the operation will fail.
178 void insertBefore(XMLNode_as* newnode, XMLNode_as* pos);
180 /// Convert the XMLNode to a string
182 /// @param o The ostream to write the string to.
183 /// @param encode Whether to URL encode the node values. This
184 /// is false by default, as it is only necessary
185 /// for XML.sendAndLoad.
186 virtual void toString(std::ostream& str, bool encode = false) const;
188 /// Return the attributes object associated with this node.
189 as_object* getAttributes() const { return _attributes; }
191 /// Set a named attribute to a value.
193 /// @param name The name of the attribute to set. If already present,
194 /// the value is changed. If not present, the attribute is
195 /// added.
196 /// @param value The value to set the named attribute to.
197 void setAttribute(const std::string& name, const std::string& value);
199 /// Associate an as_object with this XMLNode_as.
201 /// An XMLNode_as with an associated object is regarded as being owned
202 /// by that object, so make sure it is! Using as_object::setRelay will
203 /// achieve that.
204 void setObject(as_object* o) {
205 assert(!_object);
206 assert(o);
207 _object = o;
210 /// Return the object associated with this XMLNode_as.
212 /// The object will be created if it does not already exist.
213 as_object* object();
215 protected:
217 /// Mark reachable elements
219 /// These are: children, attributes object, associated as_object.
220 virtual void setReachable();
222 Global_as& _global;
224 /// Clear all children, making sure unreferenced children are deleted.
226 /// AS-referenced child nodes will no longer be marked as reachable, so
227 /// the GC will remove them on the next run.
228 void clearChildren();
230 private:
232 /// Set the parent XMLNode_as of this node.
234 /// @param node The new parent of this node. May be 0.
235 void setParent(XMLNode_as* node) { _parent = node; }
237 /// Reset the array of childNodes to match the actual children.
239 /// Only called when the XML structure changes, and only once the
240 /// childNodes array has been created. Before this point it is not
241 /// referenceable, so we don't need to do anything.
242 void updateChildNodes();
244 /// A non-trivial copy-constructor for cloning nodes.
245 XMLNode_as(const XMLNode_as &node, bool deep);
247 Children _children;
249 as_object* _object;
251 XMLNode_as* _parent;
253 as_object* _attributes;
255 as_object* _childNodes;
257 std::string _name;
259 std::string _value;
261 NodeType _type;
263 std::string _namespaceURI;
265 static void stringify(const XMLNode_as& xml, std::ostream& xmlout,
266 bool encode);
270 // Initialize the global XMLNode class
271 void xmlnode_class_init(as_object& where, const ObjectURI& uri);
273 /// Register ASnative methods
274 void registerXMLNodeNative(as_object& where);
276 } // gnash namespace
278 // GNASH_ASOBJ3_XMLNODE_H
279 #endif
281 // local Variables:
282 // mode: C++
283 // indent-tabs-mode: t
284 // End: