1 // XMLNode_as.h: ActionScript 3 "XMLNode" class, for Gnash.
3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
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.
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
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
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
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
) {
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,
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();
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 {
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
172 /// The node to insert, moving from its current tree
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
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
204 void setObject(as_object
* o
) {
210 /// Return the object associated with this XMLNode_as.
212 /// The object will be created if it does not already exist.
217 /// Mark reachable elements
219 /// These are: children, attributes object, associated as_object.
220 virtual void setReachable();
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();
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
);
253 as_object
* _attributes
;
255 as_object
* _childNodes
;
263 std::string _namespaceURI
;
265 static void stringify(const XMLNode_as
& xml
, std::ostream
& xmlout
,
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
);
278 // GNASH_ASOBJ3_XMLNODE_H
283 // indent-tabs-mode: t