gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/asobj/xml.cpp server/aso...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/asobj/xml.cpp server/aso...
Date: Tue, 03 Apr 2007 12:34:44 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/04/03 12:34:43

Modified files:
        .              : ChangeLog 
        server/asobj   : xml.cpp xml.h xmlnode.cpp xmlnode.h 
        testsuite/actionscript.all: XML.as XMLNode.as 

Log message:
                * server/asobj/xml.{cpp,h}: have XML be a subclass
                  of XMLNode. Many cleanups.
                * server/asobj/xmlnode.{cpp,h}: many cleanups.
                * testsuite/actionscript.all/XML.as: add more tests.
                * testsuite/actionscript.all/XMLNode.as: fix some bogus
                  existing tests.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2759&r2=1.2760
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xml.cpp?cvsroot=gnash&r1=1.26&r2=1.27
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xml.h?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlnode.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlnode.h?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/XML.as?cvsroot=gnash&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/XMLNode.as?cvsroot=gnash&r1=1.9&r2=1.10

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2759
retrieving revision 1.2760
diff -u -b -r1.2759 -r1.2760
--- ChangeLog   3 Apr 2007 10:37:14 -0000       1.2759
+++ ChangeLog   3 Apr 2007 12:34:43 -0000       1.2760
@@ -1,5 +1,14 @@
 2007-04-03 Sandro Santilli <address@hidden>
 
+       * server/asobj/xml.{cpp,h}: have XML be a subclass
+         of XMLNode. Many cleanups.
+       * server/asobj/xmlnode.{cpp,h}: many cleanups.
+       * testsuite/actionscript.all/XML.as: add more tests.
+       * testsuite/actionscript.all/XMLNode.as: fix some bogus
+         existing tests.
+
+2007-04-03 Sandro Santilli <address@hidden>
+
        * server/parser/movie_def_impl.h (add_init_action): fix typo.
        * testsuite/actionscript.all/XML.as: a few more tests.
        * testsuite/media/gnash.xml: new data file for testing.

Index: server/asobj/xml.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xml.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -b -r1.26 -r1.27
--- server/asobj/xml.cpp        3 Apr 2007 08:04:46 -0000       1.26
+++ server/asobj/xml.cpp        3 Apr 2007 12:34:43 -0000       1.27
@@ -14,7 +14,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: xml.cpp,v 1.26 2007/04/03 08:04:46 strk Exp $ */
+/* $Id: xml.cpp,v 1.27 2007/04/03 12:34:43 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -59,40 +59,24 @@
 
 static as_object* getXMLInterface();
 
-// Callback function for xmlReadIO
+// Callback functions for xmlReadIO
 static int closeTuFile (void * context);
-// Callback function for xmlReadIO
 static int readFromTuFile (void * context, char * buffer, int len);
 
 DSOEXPORT as_value xml_new(const fn_call& fn);
 static as_value xml_load(const fn_call& fn);
-//static as_value xml_set_current(const fn_call& fn); // UNDEFINED
-
 static as_value xml_addrequestheader(const fn_call& fn);
-static as_value xml_appendchild(const fn_call& fn);
-static as_value xml_clonenode(const fn_call& fn);
 static as_value xml_createelement(const fn_call& fn);
 static as_value xml_createtextnode(const fn_call& fn);
 static as_value xml_getbytesloaded(const fn_call& fn);
 static as_value xml_getbytestotal(const fn_call& fn);
-static as_value xml_haschildnodes(const fn_call& fn);
-static as_value xml_insertbefore(const fn_call& fn);
 static as_value xml_parsexml(const fn_call& fn);
-static as_value xml_removenode(const fn_call& fn);
 static as_value xml_send(const fn_call& fn);
 static as_value xml_sendandload(const fn_call& fn);
-static as_value xml_tostring(const fn_call& fn);
-static as_value xml_firstchild(const fn_call& fn);
-static as_value xml_childnodes(const fn_call& fn);
 
 // These are the event handlers called for this object
-//static as_value xml_ondata(const fn_call& fn); // UNUSED
 static as_value xml_loaded(const fn_call& fn);
 
-// Properties
-static as_value xml_nodename(const fn_call& fn);
-static as_value xml_nodevalue(const fn_call& fn);
-
 static LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
 #ifdef USE_DEBUGGER
 static Debugger& debugger = Debugger::getDefaultInstance();
@@ -100,10 +84,8 @@
 
 XML::XML() 
     :
-    as_object(getXMLInterface()),
+    XMLNode(getXMLInterface()),
     _loaded(false), 
-    _nodename(0),
-    _nodes(0),
     _bytes_loaded(0),
     _bytes_total(0)
 {
@@ -118,10 +100,8 @@
 // Parse the ASCII XML string into memory
 XML::XML(tu_string xml_in)
     :
-    as_object(getXMLInterface()),
+    XMLNode(getXMLInterface()),
     _loaded(false), 
-    _nodename(0),
-    _nodes(0),
     _bytes_loaded(0),
     _bytes_total(0)
 {
@@ -129,17 +109,13 @@
 #ifdef DEBUG_MEMORY_ALLOCATION
     log_msg("Creating XML data at %p \n", this);
 #endif
-    //log_msg("%s: %p \n", __FUNCTION__, this);
-    //memset(&_nodes, 0, sizeof(XMLNode));
     parseXML(xml_in);
 }
 
 XML::XML(struct node * /* childNode */)
     :
-    as_object(getXMLInterface()),
+    XMLNode(getXMLInterface()),
     _loaded(false), 
-    _nodename(0),
-    _nodes(0),
     _bytes_loaded(0),
     _bytes_total(0)
 {
@@ -156,59 +132,9 @@
     GNASH_REPORT_FUNCTION;
     
 #ifdef DEBUG_MEMORY_ALLOCATION
-    if (this->_nodes) {
-        log_msg("\tDeleting XML top level node %s at %p \n", 
this->_nodes->_name, this);
-    } else {
-        log_msg("\tDeleting XML top level node at %p \n", this);
-    }
+    log_msg("\tDeleting XML top level node at %p", this);
 #endif
   
-    //log_msg("%s: %p \n", __FUNCTION__, this);
-    delete _nodes;
-}
-
-const char *
-XML::nodeName()
-{
-    printf("%s: XML %p _nodes at %p\n", __PRETTY_FUNCTION__, (void*)this, 
(void*)_nodes);
-    if (_nodes) {
-       return _nodes->nodeName();
-    }
-    return "undefined";
-}
-
-const char *
-XML::nodeValue()
-{
-    printf("%s: XML _nodes at %p\n", __PRETTY_FUNCTION__, (void*)_nodes);
-    if (_nodes) {
-       return _nodes->nodeValue();
-    }
-    return "undefined";
-}
-
-void
-XML::nodeNameSet(const char * /*name */)
-{
-    if (!_nodes) {
-       _nodes = new XMLNode;
-       printf("%s: New XML %p _nodes at %p\n", __PRETTY_FUNCTION__, 
(void*)this, (void*)_nodes);
-    }
-    //  _nodes->nodeNameSet(name);
-    printf("%s: XML %p _name at %p, %s\n", __PRETTY_FUNCTION__, (void*)this,
-          _nodes->nodeName(), _nodes->nodeName() );
-}
-
-void
-XML::nodeValueSet(const char * /* value */)
-{
-    if (!_nodes) {
-       _nodes = new XMLNode;
-       printf("%s: New XML _nodes at %p\n", __PRETTY_FUNCTION__, 
(void*)_nodes);
-    }
-  
-    //  _nodes->nodeValueSet(value);
-    printf("%s: XML _nodes at %p\n", __PRETTY_FUNCTION__, (void*)_nodes);
 }
 
 void
@@ -264,25 +190,23 @@
     call_method(method, &env, this, 0, 0);
 }
 
-XMLNode*
-XML::extractNode(xmlNodePtr node, bool mem)
+void
+XML::extractNode(XMLNode& element, xmlNodePtr node, bool mem)
 {
     xmlAttrPtr attr;
     xmlNodePtr childnode;
     xmlChar *ptr = NULL;
-    XMLNode *element, *child;
+    boost::intrusive_ptr<XMLNode> child;
     int len;
 
-    element = new XMLNode;
-            
 //    log_msg("Created new element for %s at %p\n", node->name, element);
-    memset(element, 0, sizeof (XMLNode));
 
 //    log_msg("%s: extracting node %s\n", __FUNCTION__, node->name);
 
     // See if we have any Attributes (properties)
     attr = node->properties;
-    while (attr != NULL) {
+    while (attr != NULL)
+    {
         //log_msg("extractNode %s has property %s, value is %s\n",
         //          node->name, attr->name, attr->children->content);
         XMLAttr *attrib = new XMLAttr;
@@ -296,15 +220,15 @@
         strcpy(attrib->_value, reinterpret_cast<const char 
*>(attr->children->content));
         //log_msg("\tPushing attribute %s for element %s has value %s\n",
         //        attr->name, node->name, attr->children->content);
-        element->_attributes.push_back(attrib);
+        element._attributes.push_back(attrib);
         attr = attr->next;
     }
 
     len = memadjust(strlen(reinterpret_cast<const char *>(node->name))+1);
-    element->_name = (char *)new char[len];
-    memset(element->_name, 0, len);
-    strcpy(element->_name, reinterpret_cast<const char *>(node->name));
-    //element->_name = reinterpret_cast<const char *>(node->name);
+    element._name = (char *)new char[len];
+    memset(element._name, 0, len);
+    strcpy(element._name, reinterpret_cast<const char *>(node->name));
+    //element._name = reinterpret_cast<const char *>(node->name);
     if (node->children) {
         //ptr = node->children->content;
         ptr = xmlNodeGetContent(node->children);
@@ -315,9 +239,9 @@
                 } else {
                     //log_msg("extractChildNode from text for %s has contents 
%s\n", node->name, ptr);
                     len = memadjust(strlen(reinterpret_cast<const char 
*>(ptr))+1);
-                    element->_value = (char *)new char[len];
-                    memset(element->_value, 0, len);
-                    strcpy(element->_value, reinterpret_cast<const char 
*>(ptr));
+                    element._value = (char *)new char[len];
+                    memset(element._value, 0, len);
+                    strcpy(element._value, reinterpret_cast<const char 
*>(ptr));
                     //element->_value = reinterpret_cast<const char *>(ptr);
                 }
             }
@@ -328,22 +252,17 @@
     // See if we have any data (content)
     childnode = node->children;
 
-    while (childnode != NULL) {
-        if (childnode->type == XML_ELEMENT_NODE) {
-//            log_msg("\t\t extracting node %s\n", childnode->name);
-            child = extractNode(childnode, mem);
-            //if (child->_value.get_type() != as_value::UNDEFINED) {
-//             if (child->_value != 0) {
-//                 log_msg("\tPushing childNode %s, value %s on element %s\n", 
child->_name, child->_value, element->_name);
-//             } else {
-//                 log_msg("\tPushing childNode %s on element %s\n", 
child->_name, element->_name);
-//             }
-            element->_children.push_back(child);
+    while (childnode != NULL)
+    {
+        if (childnode->type == XML_ELEMENT_NODE)
+        {
+            child = new XMLNode();
+            extractNode(*child, childnode, mem);
+            element._children.push_back(child);
         }
         childnode = childnode->next;
     }
 
-    return element;
 }
 
 // Read in an XML document from the specified source
@@ -360,8 +279,11 @@
 
     cur = xmlDocGetRootElement(document);
   
-    if (cur != NULL) {
-        _nodes = extractNode(cur, mem);
+    if (cur != NULL)
+    {
+        boost::intrusive_ptr<XMLNode> child = new XMLNode();
+        extractNode(*child, cur, mem);
+        _children.push_back(child);
     }  
 
     _loaded = true;
@@ -452,16 +374,6 @@
 }
 
 
-vector<XMLNode *>
-XML::childNodes() 
-{
-    if (_nodes) {
-       return _nodes->_children;
-    } else {
-       return static_cast< vector<XMLNode*> >(0);
-    }
-}
-
 bool
 XML::onLoad()
 {
@@ -470,20 +382,14 @@
     return(_loaded);
 }
 
-XMLNode *
-XML::operator [] (int x) {
-    log_msg("%s:\n", __FUNCTION__);
-
-    return _nodes->_children[x];
-}
-
 void
 XML::cleanupStackFrames(XMLNode * /* xml */)
 {
     GNASH_REPORT_FUNCTION;
 }
 
-as_object *
+#if 0
+void
 XML::setupFrame(as_object *obj, XMLNode *xml, bool mem)
 {
 //    GNASH_REPORT_FUNCTION;
@@ -502,8 +408,6 @@
   
     // Get the data for this node
     nodename   = xml->_name;
-    //nodename   = xml->_name.c_str();
-    //nodevalue  = xml->_value;
     length     = xml->length();
 
     // Set these members in the top level object passed in. This are used
@@ -512,24 +416,17 @@
     // childNodes.
     //obj->set_member("nodeName", nodename); // use the getter/setter !
     obj->set_member("length", length); // FIXME: use a getter/setter !
-    if (xml->_value != 0) {
-        //obj->set_member("nodeValue", xml->_value); // use the getter/setter !
-        //log_msg("\tnodevalue for %s is: %s\n", nodename, xml->_value);
-    } else {
-        // obj->set_member("nodeValue", as_value::UNDEFINED); // use the 
getter/setter !
-    }
 
     // Process the attributes, if any
-    if (xml->_attributes.size() == 0) {
+    if (xml->_attributes.size() == 0)
+    {
         //log_msg("\t\tNo attributes for node %s, created empty object at 
%p\n", nodename, attr_obj);
-//     log_msg("\t\tNo attributes for node %s\n", nodename);
-    } else {
+    }
+    else
+    {
         attr_obj = new xmlattr_as_object;
         for (i=0; i<xml->_attributes.size(); i++) {
             attr_obj->set_member(xml->_attributes[i]->_name, 
xml->_attributes[i]->_value);
-//         log_msg("\t\tAdding attribute as member %s, value is %s to node %s 
(%p)\n",
-//                 xml->_attributes[i]->_name,
-//                 xml->_attributes[i]->_value, nodename, 
static_cast<void*>(obj) );
         }
         obj->set_member("attributes", attr_obj);
     }
@@ -538,7 +435,8 @@
     //obj->set_member("attributes", attr_obj);
 
     // Process the children, if there are any
-    if (length) {
+    if (length)
+    {
         //log_msg("\tProcessing %d children nodes for %s\n", length, nodename);
        int inum;
         inum = 0;
@@ -557,12 +455,14 @@
             obj->set_member(boost::lexical_cast<std::string>(inum), 
xmlchildnode_obj);
             ++inum;
         }
-    } else {
+    }
+    else
+    {
         //log_msg("\tNode %s has no children\n", nodename);
     }  
 
-    return obj;
 }
+#endif
 
 
 /// \brief add or change the HTTP Request header
@@ -581,98 +481,6 @@
     log_msg("%s:unimplemented \n", __FUNCTION__);
 }
 
-/// \brief append a node the the XML object
-///
-/// Method; appends the specified node to the XML object's child
-/// list. This method operates directly on the node referenced by the
-/// childNode parameter; it does not append a copy of the node. If the
-/// node to be appended already exists in another tree structure,
-/// appending the node to the new location will remove it from its
-/// current location. If the childNode parameter refers to a node that
-/// already exists in another XML tree structure, the appended child
-/// node is placed in the new tree structure after it is removed from
-/// its existing parent node. 
-void
-XML::appendChild(XMLNode *node)
-{
-    GNASH_REPORT_FUNCTION;
-    
-    if (!_nodes) {
-       _nodes = new XMLNode;
-    }
-    _nodes->_children.push_back(node);
-//    log_msg("%s: %p at _nodes at %p\n", __PRETTY_FUNCTION__, this, _nodes);
-//    dbglogfile << node->_name << endl;
-}
-
-/// \brief copy a node
-///
-/// Method; constructs and returns a new XML node of the same type,
-/// name, value, and attributes as the specified XML object. If deep
-/// is set to true, all child nodes are recursively cloned, resulting
-/// in an exact copy of the original object's document tree. 
-XMLNode &
-XML::cloneNode(XMLNode &newnode, bool deep)
-{
-    GNASH_REPORT_FUNCTION;
-    log_msg("%s: deep is %d\n", __PRETTY_FUNCTION__, deep);
-
-    if (_nodes && deep) {
-       newnode = _nodes;
-//     } else {
-//     newnode.nodeNameSet((char *)_nodes->nodeName());
-//     newnode.nodeValueSet((char *)_nodes->nodeValue());    
-    }
-
-    log_msg("%s:partially unimplemented \n", __PRETTY_FUNCTION__);
-
-    return newnode;
-}
-
-# if 0
-/// \brief create a new XML element
-///
-/// Method; creates a new XML element with the name specified in the
-/// parameter. The new element initially has no parent, no children,
-/// and no siblings. The method returns a reference to the newly
-/// created XML object that represents the element. This method and
-/// the XML.createTextNode() method are the constructor methods for
-/// creating nodes for an XML object. 
-XMLNode *
-XML::createElement(const char * /* name */)
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-    return (XMLNode*)0;
-}
-
-/// \brief Create a new XML node
-/// 
-/// Method; creates a new XML text node with the specified text. The
-/// new node initially has no parent, and text nodes cannot have
-/// children or siblings. This method returns a reference to the XML
-/// object that represents the new text node. This method and the
-/// XML.createElement() method are the constructor methods for
-/// creating nodes for an XML object.
-XMLNode *
-XML::createTextNode(const char * /* name */)
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-    return (XMLNode*)0;
-}
-#endif
-
-/// \brief insert a node before a node
-///
-/// Method; inserts a new child node into the XML object's child
-/// list, before the beforeNode node. If the beforeNode parameter is
-/// undefined or null, the node is added using the appendChild()
-/// method. If beforeNode is not a child of my_xml, the insertion
-/// fails.
-void
-XML::insertBefore(XMLNode * /* newnode */, XMLNode * /* node */)
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
 
 void
 XML::load()
@@ -686,14 +494,6 @@
     log_msg("%s: unimplemented \n", __FUNCTION__);
 }
 
-/// \brief removes the specified XML object from its parent. Also
-/// deletes all descendants of the node.
-void
-XML::removeNode()
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
-
 void
 XML::send()
 {
@@ -706,85 +506,6 @@
     log_msg("%s:unimplemented \n", __FUNCTION__);
 }
 
-const char *
-XML::toString()
-{
-    GNASH_REPORT_FUNCTION;
-    if (_nodes) {
-       stringstream xmlout;
-       return stringify(_nodes, &xmlout);
-    }
-    return NULL;
-}
-
-const char *
-XML::stringify(XMLNode *xml, stringstream *xmlout)
-{
-//    GNASH_REPORT_FUNCTION;
-    const char    *nodename = xml->nodeName();
-    const char    *nodevalue = xml->nodeValue();
-//    stringstream xmlout;
-//     string str;
-
-//    log_msg("%s: processing for object %s <%p>\n", __PRETTY_FUNCTION__, 
nodename, (void*)xml);
-  
-    if (nodename) {
-       *xmlout << "<" << nodename;
-//       str = "<";
-//       str += nodename;
-     }
-    
-    if (nodevalue) {
-       *xmlout << nodevalue;
-//     str += nodevalue;
-    }
-
-    // Process the attributes, if any
-    vector<XMLAttr *>::iterator ita;
-    for (ita = xml->_attributes.begin(); ita != xml->_attributes.end(); ita++) 
{
-//     log_msg("Found One child !!!! %p\n", (void*)*ita);
-//     cerr << "<" << (*it)->nodeName() << ">" << endl;
-       XMLAttr *xa = *ita;
-//     log_msg("\t\tAdding attribute as member %s, value is %s to node %s",
-//             nodename, xa->_name, xa->_value);
-       *xmlout << " " << xa->_name << "=\"" << xa->_value << "\"";
-//     str += " ";
-//     str += xa->_name;
-//     str += "=\"";
-//     str += xa->_value;
-//     str += "\"";
-    }
-    
-    if (nodename) {
-       *xmlout << ">";         // closing symbol for this tag
-//     str += ">";
-    }
-
-//    int length = xml->_children.size();
-//    log_msg("\tProcessing %d children nodes for %s", length, nodename);
-    
-    vector<XMLNode *>::iterator itx;
-    for (itx = _nodes->_children.begin(); itx != _nodes->_children.end(); 
++itx) {
-//     log_msg("Found One XML child !!!! %s <%p>\n", (*itx)->nodeName(), 
(void*)*itx);
-//     cerr << "<" << (*it)->nodeName() << ">" << endl;
-       XMLNode *x = *itx;
-       *xmlout << x->toString();
-//     str +=  x->stringify(x);
-    }
-    
-    if (nodename) {
-       *xmlout << "</" << nodename << ">";
-//      str += "</";
-//      str += nodename;
-
-//      str += ">";
-    }
-
-//    const char *xxx = xmlout->str().c_str();
-//    cerr << "XMLOUT XML= " << xxx << endl;
-    return xmlout->str().c_str();
-//    return str.c_str();
-}
 
 //
 // Callbacks. These are the wrappers for the C++ functions so they'll work as
@@ -826,23 +547,18 @@
     o.init_member("loaded", new builtin_function(xml_loaded));
        
     o.init_member("addRequestHeader", new 
builtin_function(xml_addrequestheader));
-    o.init_member("appendChild", new builtin_function(xml_appendchild));
-    o.init_member("cloneNode", new builtin_function(xml_clonenode));
     o.init_member("createElement", new builtin_function(xml_createelement));
     o.init_member("createTextNode", new builtin_function(xml_createtextnode));
     o.init_member("getBytesLoaded", new builtin_function(xml_getbytesloaded));
     o.init_member("getBytesTotal", new builtin_function(xml_getbytestotal));
-    o.init_member("hasChildNodes", new builtin_function(xml_haschildnodes));
-    o.init_member("insertBefore", new builtin_function(xml_insertbefore));
     o.init_member("load", new builtin_function(xml_load));
     o.init_member("parseXML", new builtin_function(xml_parsexml));
-    o.init_member("removeNode", new builtin_function(xml_removenode));
     o.init_member("send", new builtin_function(xml_send));
     o.init_member("sendAndLoad", new builtin_function(xml_sendandload));
-    o.init_member("toString", new builtin_function(xml_tostring));
 
     // Properties
 
+#if 0
     boost::intrusive_ptr<builtin_function> gettersetter;
 
     gettersetter = new builtin_function(&xml_nodename, NULL);
@@ -854,16 +570,22 @@
     gettersetter = new builtin_function(&xml_firstchild, NULL);
     o.init_property("firstChild", *gettersetter, *gettersetter);
 
+    gettersetter = new builtin_function(&xml_lastchild, NULL);
+    o.init_property("lastChild", *gettersetter, *gettersetter);
+
     gettersetter = new builtin_function(&xml_childnodes, NULL);
     o.init_property("childNodes", *gettersetter, *gettersetter);
+#endif
+
 }
 
 static as_object*
 getXMLInterface()
 {
     static boost::intrusive_ptr<as_object> o;
-    if ( o == NULL ) {
-       o = new as_object();
+    if ( o == NULL )
+    {
+        o = new as_object(getXMLNodeInterface());
        attachXMLInterface(*o);
     }
     return o.get();
@@ -878,28 +600,19 @@
   
     // log_msg("%s: nargs=%d\n", __FUNCTION__, fn.nargs);
   
-    if (fn.nargs > 0) {
+    if (fn.nargs > 0 && fn.arg(0).is_object() )
+    {
            boost::intrusive_ptr<as_object> obj = fn.env().top(0).to_object();
-
-        if (! obj ) {
-            xml_obj = new XML;
-            //log_msg("\tCreated New XML object at %p\n", xml_obj);
-            tu_string datain = fn.env().top(0).to_tu_string();
-            xml_obj->parseXML(datain);
-            //log_msg("*** Start setting up the stack frames ***\n");
-            xml_obj->setupFrame(xml_obj.get(), xml_obj->firstChild(), true);
-            //xml_obj->clear();
-            //delete xml_obj->firstChild();
-        } else {
                xml_obj = boost::dynamic_pointer_cast<XML>(obj);
-            //log_msg("\tCloned the XML object at %p\n", xml_obj);
-            //result->set(xml_obj);
-            return as_value(xml_obj.get());
+        if ( xml_obj )
+        {
+            log_msg("\tCloned the XML object at %p\n", xml_obj.get());
+            return as_value(xml_obj->cloneNode(true).get());
         }
-    } else {
+    }
+
         xml_obj = new XML;
         //log_msg("\tCreated New XML object at %p\n", xml_obj);
-    }
 
     return as_value(xml_obj.get());
 }
@@ -938,52 +651,6 @@
     log_msg("%s:unimplemented \n", __FUNCTION__);
     return as_value();
 }
-as_value xml_appendchild(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-    //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    if (fn.nargs > 0) {
-
-       boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr); 
-       boost::intrusive_ptr<XMLNode> xml_obj = 
boost::dynamic_pointer_cast<XMLNode>(fn.arg(0).to_object());
-       if ( ! xml_obj )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               log_aserror("First argument to XML::appendChild() is not an 
XMLNode");
-               );
-               return as_value();
-       }
-
-       if (xml_obj->nodeType() == XML_ELEMENT_NODE) {
-           ptr->appendChild(xml_obj.get());
-       } else {
-           ptr->nodeValueSet(xml_obj->nodeValue());
-       }
-
-    } else {
-        log_msg("ERROR: no child XMLNode paramaters!\\n");
-    }
-    return as_value();
-}
-
-as_value xml_clonenode(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-//    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-    XMLNode   *xml_obj;
-
-    if (fn.nargs > 0) {
-       bool deep = fn.arg(0).to_bool(); 
-       xml_obj = new XMLNode;
-       ptr->cloneNode(*xml_obj, deep);
-       return as_value(xml_obj);
-    } else {
-        log_msg("ERROR: no Depth paramater!\n");
-    }
-
-    return as_value();
-}
 
 /// \brief create a new XML element
 ///
@@ -1055,33 +722,6 @@
     return as_value(ptr->getBytesTotal());
 }
 
-as_value xml_haschildnodes(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-    return as_value(ptr->hasChildNodes());
-}
-
-/// \brief insert a node before a node
-///
-/// Method; inserts a new child node into the XML object's child
-/// list, before the beforeNode node. If the beforeNode parameter is
-/// undefined or null, the node is added using the appendChild()
-/// method. If beforeNode is not a child of my_xml, the insertion
-/// fails.
-
-as_value xml_insertbefore(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-    UNUSED(ptr);
-    
-//    return as_value(ptr->getAllocated());
-//    ptr->insertBefore();
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-    return as_value();
-}
-
 as_value xml_parsexml(const fn_call& fn)
 {
 //    GNASH_REPORT_FUNCTION;
@@ -1090,10 +730,12 @@
     as_value   val;    
     boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
 
-    if (fn.nargs > 0) {
+    if (fn.nargs > 0)
+    {
         text = fn.arg(0).to_string(); 
-       if (ptr->parseXML(text)) {
-           ptr->setupFrame(ptr.get(), ptr->firstChild(), false);  
+           if (ptr->parseXML(text))
+        {
+               //ptr->setupFrame(ptr.get(), ptr->firstChild().get(), false);
        }
     }
     
@@ -1103,15 +745,6 @@
 /// \brief removes the specified XML object from its parent. Also
 /// deletes all descendants of the node.
     
-as_value xml_removenode(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-    
-//    return as_value(ptr->getAllocated());
-    ptr->removeNode();
-    return as_value();
-}
 as_value xml_send(const fn_call& fn)
 {
     GNASH_REPORT_FUNCTION;
@@ -1121,105 +754,15 @@
     ptr->send();
     return as_value();
 }
-as_value xml_sendandload(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
     
-//    return as_value(ptr->getAllocated());
-    ptr->sendAndLoad();
-    return as_value();
-}
-as_value xml_tostring(const fn_call& fn)
-{
-//    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-
-    // TODO: There is also the "stringify" function to be used here.
-    // See above. Wot does FlashPlayer return for this call?
-
-    string str = ptr->toString();
-//     cerr << "AAAAHHHHH: " << str << endl;
-    return as_value(str.c_str());
-}
-
-// Both a getter and a setter for nodeName
 static as_value
-xml_nodename(const fn_call& fn)
-{
-//    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) {
-       const char* val = ptr->nodeName();
-       if ( val ) {
-           return as_value(val);
-       } else {
-           return as_value();
-       }
-    } else {
-       ptr->nodeNameSet(fn.arg(0).to_string());
-    }
-    return as_value();
-}
-
-// Both a getter and a setter for nodeValue
-static as_value
-xml_nodevalue(const fn_call& fn)
-{
-//    GNASH_REPORT_FUNCTION;
-
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-    
-    //log_msg("xml_nodevalue called with %d args against 'this' = %p", 
fn.nargs, ptr);
-    if ( fn.nargs == 0 ) {
-       //log_msg("  nodeValue() returns '%s'", ptr->nodeValue());
-       const char* val = ptr->nodeValue();
-       if ( val ) {
-           return as_value(val);
-       } else {
-           return as_value();
-       }
-    } else {
-       //log_msg(" arg(0) == '%s'", fn.arg(0).to_string());
-       ptr->nodeValueSet(fn.arg(0).to_string());
-    }
-    return as_value();
-}
-
-// Both a getter and a (do-nothing) setter for firstChild
-static as_value
-xml_firstchild(const fn_call& fn)
+xml_sendandload(const fn_call& fn)
 {
     GNASH_REPORT_FUNCTION;
     boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
 
-    if ( fn.nargs == 0 ) {
-       //return as_value(ptr->firstChild());
-       return as_value(ptr.get());
-    } else {
-       IF_VERBOSE_ASCODING_ERRORS(
-           log_aserror("Tried to set read-only property XML.firstChild");
-           );
-    }
-    return as_value();
-}
-
-// Both a getter and a (do-nothing) setter for childNodes
-static as_value
-xml_childnodes(const fn_call& fn)
-{
-    GNASH_REPORT_FUNCTION;
-    boost::intrusive_ptr<XML> ptr = ensureType<XML>(fn.this_ptr);
-
-    if ( fn.nargs == 0 ) {
-       //return as_value(ptr->childNodes());
-       return as_value(ptr.get());
-    } else {
-       IF_VERBOSE_ASCODING_ERRORS(
-           log_aserror("Tried to set read-only property XML.childNodes");
-           );
-    }
+//    return as_value(ptr->getAllocated());
+    ptr->sendAndLoad();
     return as_value();
 }
 

Index: server/asobj/xml.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xml.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/asobj/xml.h  3 Apr 2007 08:04:46 -0000       1.10
+++ server/asobj/xml.h  3 Apr 2007 12:34:43 -0000       1.11
@@ -50,7 +50,7 @@
 class URL;
 
 /// XML class and ActionScript object
-class DSOLOCAL XML : public as_object
+class DSOLOCAL XML : public XMLNode
 {
 public:
 
@@ -62,6 +62,7 @@
     // Methods
     // This is the base method used by both parseXML() and load().
     bool parseDoc(xmlDocPtr document, bool mem);
+
     // Parses an XML document into the specified XML object tree.
     bool parseXML(tu_string xml_in);
 
@@ -69,111 +70,55 @@
     // the XML object) from a URL.
     bool load(const URL& url);
 
-
     // An event handler that returns a
     bool onLoad();
+
     // Boolean value indicating whether
     // the XML object was successfully
     // loaded with XML.load() or
     // XML.sendAndLoad().
 
-    // Appends a node to the end of the specified object's child list.
-    void appendChild(XMLNode *node);
-    
     bool loaded()    { return _loaded; }
     
-    XMLNode *firstChild() {
-        return _nodes;
-        //return _node_data[0];
-    }
-    
-    void clear() {
-        delete _nodes;
-    }
-  
-    std::vector<XMLNode *> childNodes();
-  
-    const char *stringify(XMLNode *xml, std::stringstream *str);
-    //  Returns true if the specified node has child nodes; otherwise, returns 
false.
-    bool hasChildNodes() {
-       if (_nodes) {
-           if (_nodes->_children.size()) {
-               return true;
-           } 
-       }
-       return false;
-    }
+    void clear() {}
     
-    XMLNode *extractNode(xmlNodePtr node, bool mem);
     XMLNode *processNode(xmlTextReaderPtr reader, XMLNode *node);
 
     void  change_stack_frame(int frame, gnash::as_object *xml, 
gnash::as_environment *env);
 //    void  setupStackFrames(gnash::as_object *xml, gnash::as_environment 
*env);
-    void  cleanupStackFrames( XMLNode *data);
-    as_object *setupFrame(gnash::as_object *xml, XMLNode *data, bool src);
   
-    const char *nodeNameGet()    { return _nodename; }
-    const char *nodeName();
-    const char *nodeValue();
-    void nodeNameSet(const char *name);
-    void nodeValueSet(const char *value);
-    int length()                 { return _nodes->length(); }
+    void  cleanupStackFrames( XMLNode *data);
   
     // These 6 have to 
     void addRequestHeader(const char *name, const char *value);
-    XMLNode &cloneNode(XMLNode &newnode, bool deep);
+
     XMLNode *createElement(const char *name);
+
     XMLNode *createTextNode(const char *name);
-    void insertBefore(XMLNode *newnode, XMLNode *node);
 
     void load();
+
     void parseXML();
-    void removeNode();
+
     void send();
+
     void sendAndLoad();
-    const char *toString();
 
     int getBytesLoaded()         { return _bytes_loaded; };
     int getBytesTotal()          { return _bytes_total; };
 
-    XMLNode *operator [] (int x);
-#if 0
-    XMLNode *operator = (XMLNode &node) {
-        gnash::log_msg("%s: copy element %s\n", __PRETTY_FUNCTION__, 
node._name);
-       //        _nodes = node.;
-    }
-
-#endif
-    XML *operator = (XMLNode *node) {
-        _nodes = node;    
-        return this;
-    }
-
 private:
     xmlDocPtr _doc;
     xmlNodePtr _firstChild;
     
     // Properties
     bool _loaded;
-    const char  *_nodename;
-    XMLNode     *_nodes;
 
-    int         _bytes_loaded;
-    int         _bytes_total;
+    size_t      _bytes_loaded;
+ 
+    size_t      _bytes_total;
     
-    bool        _contentType;  // TODO Should be String
-    bool        _attributes;
-    bool        _childNodes;
-    bool        _xmlDecl;      // TODO Should be String
-    bool        _docTypeDecl;  // TODO Should be String
-    bool        _ignoreWhite;
-    bool        _lastChild;
-    bool        _nextSibling;
-    bool        _nodeType;
-    bool        _nodeValue;
-    bool        _parentNode;
     bool        _status;       // TODO Should be Number
-    bool        _previousSibling;
 
     /// Trigger the onLoad event, if any
     void onLoadEvent(bool success);
@@ -181,6 +126,16 @@
     /// Trigger the onClose event, if any
     void onCloseEvent();
   
+    /// Initialize an XMLNode from an xmlNodePtr
+    //
+    /// @param element
+    ///     The XMLNode to initialize.
+    ///
+    void extractNode(XMLNode& element, xmlNodePtr node, bool mem);
+
+    void setupFrame(gnash::as_object *xml, XMLNode *data, bool src);
+  
+
 };
 
 

Index: server/asobj/xmlnode.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xmlnode.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/asobj/xmlnode.cpp    20 Mar 2007 15:01:20 -0000      1.19
+++ server/asobj/xmlnode.cpp    3 Apr 2007 12:34:43 -0000       1.20
@@ -14,7 +14,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: xmlnode.cpp,v 1.19 2007/03/20 15:01:20 strk Exp $ */
+/* $Id: xmlnode.cpp,v 1.20 2007/04/03 12:34:43 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -52,18 +52,18 @@
 static as_value xmlnode_nodename(const fn_call& fn);
 static as_value xmlnode_nodevalue(const fn_call& fn);
 static as_value xmlnode_nodetype(const fn_call& fn);
+static as_value xmlnode_attributes(const fn_call& fn);
 static as_value xmlnode_appendchild(const fn_call& fn);
 static as_value xmlnode_clonenode(const fn_call& fn);
 static as_value xmlnode_haschildnodes(const fn_call& fn);
 static as_value xmlnode_insertbefore(const fn_call& fn);
 static as_value xmlnode_removenode(const fn_call& fn);
 static as_value xmlnode_tostring(const fn_call& fn);
-static as_value xmlnode_nodename(const fn_call& fn);
 static as_value xmlnode_firstchild(const fn_call& fn);
 static as_value xmlnode_lastchild(const fn_call& fn);
 static as_value xmlnode_nextsibling(const fn_call& fn);
 static as_value xmlnode_previoussibling(const fn_call& fn);
-static as_object* getXMLNodeInterface();
+as_object* getXMLNodeInterface();
 
 static LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
 
@@ -82,8 +82,43 @@
 #ifdef DEBUG_MEMORY_ALLOCATION
     log_msg("\tCreating XMLNode data at %p \n", this);
 #endif
-    _name = 0;
-    _value = 0;
+}
+
+XMLNode::XMLNode(as_object* overridden_interface)
+    :
+    as_object(overridden_interface),
+    _name(0),
+    _value(0),
+    _type(XML_ELEMENT_NODE),
+    _parent(0)
+{
+    //log_msg("%s: %p \n", __PRETTY_FUNCTION__, this);
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("\tCreating XMLNode data at %p \n", this);
+#endif
+}
+
+XMLNode::XMLNode(const XMLNode& tpl, bool deep)
+    :
+    as_object(getXMLNodeInterface()),
+    _name(tpl._name),
+    _value(tpl._value),
+    _type(tpl._type),
+    _parent(tpl._parent)
+{
+    if ( ! deep )
+    {
+            _children = tpl._children;
+    }
+    else // deep copy
+    {
+        const ChildList& from=tpl._children;
+        for (ChildList::const_iterator it=from.begin(), itEnd=from.end();
+                        it != itEnd; ++it)
+        {
+                _children.push_back(new XMLNode(*(*it), deep));
+        }
+    }
 }
 
 XMLNode::~XMLNode()
@@ -134,25 +169,24 @@
     return false;
 }
 
-XMLNode *
+boost::intrusive_ptr<XMLNode>
 XMLNode::firstChild()
 {
     GNASH_REPORT_FUNCTION;
-    if (_children.size() > 0) {
+       if ( _children.empty() ) return NULL;
        return _children.front();
-    }
-    return NULL;
 }
 
-XMLNode *
+boost::intrusive_ptr<XMLNode>
 XMLNode::lastChild()
 {
     GNASH_REPORT_FUNCTION;
-    
-    if (_children.size() > 0) {
-       return _children.back();
-    }
+       if ( _children.empty() )
+       {
+                       log_msg("XMLNode %p has no childrens", (void*)this);
     return NULL;
+       }
+       return _children.back();
 }
 
 void
@@ -204,51 +238,11 @@
     return -1;
 }
 
-const char *
-XMLNode::nodeName() 
-{
-    if (_name) {
-       return _name;
-    }
-    return NULL;
-}
-
-const char *
-XMLNode::nodeValue() 
-{  
-    if (_value) {
-       return _value;
-    }
-    return NULL;
-}
-
-/// \brief append a node the the XMLNode object
-///
-/// Method; appends the specified node to the XMLNode object's child
-/// list. This method operates directly on the node referenced by the
-/// childNode parameter; it does not append a copy of the node. If the
-/// node to be appended already exists in another tree structure,
-/// appending the node to the new location will remove it from its
-/// current location. If the childNode parameter refers to a node that
-/// already exists in another XMLNode tree structure, the appended child
-/// node is placed in the new tree structure after it is removed from
-/// its existing parent node.
-///
-/// @param as
-///    The XMLNode ?
-///
-/// @param node
-///    same as XMLNode::obj ?
-///
 void
-XMLNode::appendChild(XMLNode *node)
+XMLNode::appendChild(boost::intrusive_ptr<XMLNode> node)
 {
-//    GNASH_REPORT_FUNCTION;
-//     log_msg("%s: %p, as is %d, node is %d\n",
-//         __PRETTY_FUNCTION__, this, _children.size(), _children.size());
-//
-
-    if (node) {
+    if (node)
+       {
        node->setParent(this);
        _children.push_back(node);
     }
@@ -256,26 +250,14 @@
 //    log_msg("%s: partially unimplemented\n", __PRETTY_FUNCTION__);
 }
 
-/// \brief copy a node
-///
-/// Method; constructs and returns a new XML node of the same type,
-/// name, value, and attributes as the specified XML object. If deep
-/// is set to true, all child nodes are recursively cloned, resulting
-/// in an exact copy of the original object's document tree. 
-XMLNode &
-XMLNode::cloneNode(XMLNode &newnode, bool deep)
+boost::intrusive_ptr<XMLNode> 
+XMLNode::cloneNode(bool deep)
 {
     GNASH_REPORT_FUNCTION;
     log_msg("%s: deep is %d\n", __PRETTY_FUNCTION__, deep);
 
-    if (deep) {
-//     newnode = _nodes;
-    } else {
-       newnode.nodeNameSet(_name);
-       newnode.nodeValueSet(_value);
-    }
+    boost::intrusive_ptr<XMLNode> newnode = new XMLNode(*this, deep);
 
-    log_msg("%s: partially unimplemented \n", __PRETTY_FUNCTION__);
     return newnode;
 }
 
@@ -304,18 +286,19 @@
 {
     GNASH_REPORT_FUNCTION;
 
-    vector<XMLNode *>::iterator itx;
+    if ( ! _parent) return NULL;
+       if (_parent->_children.size() <= 1) return NULL;
+
     XMLNode *previous_node = NULL;
-    if (_parent) {
-       if (_parent->_children.size() > 1) {
-           for (itx = _parent->_children.begin(); itx != 
_parent->_children.end(); itx++) {
-               if ((*itx) == this) {
+    ChildList::iterator itx;
+    for (itx = _parent->_children.begin(); itx != _parent->_children.end(); 
itx++)
+    {
+        if (itx->get() == this)
+        {
                    // log_msg("Found the previous XMLNode child !!!! %s 
<%p>\n", (*itx)->nodeName(), (void*)*itx);
                    return previous_node;
                }
-               previous_node = *itx;
-           }
-       }
+               previous_node = itx->get();
     }
 
     return NULL;
@@ -325,77 +308,79 @@
 XMLNode::nextSibling()
 {
     GNASH_REPORT_FUNCTION;
-    vector<XMLNode *>::iterator itx;
-    if (_parent) {
-       if (_parent->_children.size() > 1) {
-           for (itx = _parent->_children.begin(); itx != 
_parent->_children.end(); itx++) {
-               if ((*itx) == this) {
-                   // We've found ourselves; now find next sibling if any
-                   XMLNode *sibling = *++itx;
-                   if (itx == _parent->_children.end()) return NULL;
-                   else {
+
+    if ( ! _parent) return NULL;
+       if (_parent->_children.size() <= 1) return NULL;
+
+    XMLNode *previous_node = NULL;
+    ChildList::reverse_iterator itx;
+    for (itx = _parent->_children.rbegin(); itx != _parent->_children.rend(); 
itx++)
+    {
+        if (itx->get() == this)
+        {
                        // log_msg("Found the next XMLNode child !!!! %s 
<%p>\n", (*itx)->nodeName(), (void*)*itx);
-                       return sibling;
-                   }
-               }
-           }
+                   return previous_node;
        }
+               previous_node = itx->get();
     }
+
     return NULL;
 }
 
-const char *
-XMLNode::toString()
+void
+XMLNode::toString(std::ostream& xmlout) const
 {
 //    GNASH_REPORT_FUNCTION;
-    stringstream xmlout;
-    return stringify(this, &xmlout);
+    stringify(*this, xmlout);
 }
 
-const char *
-XMLNode::stringify(XMLNode *xml, stringstream *xmlout)
+/* static private */
+void
+XMLNode::stringify(const XMLNode& xml, std::ostream& xmlout) 
 {
 //    GNASH_REPORT_FUNCTION;
-    const char    *nodevalue = xml->nodeValue();
-    const char    *nodename = xml->nodeName();
+    const char    *nodevalue = xml.nodeValue();
+    const char    *nodename = xml.nodeName();
     
 //    log_msg("%s: processing for object %s <%p>\n", __PRETTY_FUNCTION__, 
nodename, xml);
 
     // Create the beginning of the tag
-    *xmlout << "<" << nodename;
+    xmlout << "<" << nodename;
     
     // Process the attributes, if any
-    vector<XMLAttr *>::iterator ita;
-    for (ita = xml->_attributes.begin(); ita != xml->_attributes.end(); ita++) 
{
-       XMLAttr *xa = *ita;
+    vector<XMLAttr *>::const_iterator ita;
+    for (ita = xml._attributes.begin(); ita != xml._attributes.end(); ita++)
+    {
+           const XMLAttr *xa = *ita;
 //     log_msg("\t\tAdding attribute as member %s, value is %s to node %s",
 //             nodename, xa->_name, xa->_value);
-       *xmlout << " " << xa->_name << "=\"" << xa->_value << "\"";
+        xmlout << " " << xa->_name << "=\"" << xa->_value << "\"";
     }
 
-    *xmlout << ">";            // closing symbol for this tag
+    xmlout << ">";             // closing symbol for this tag
     
     if (nodevalue) {
-       *xmlout << nodevalue;
-       *xmlout << "</" << nodename << ">";
+       xmlout << nodevalue;
+       xmlout << "</" << nodename << ">";
     }
 
 //    int length = xml->_children.size();
 //    log_msg("\tProcessing %d children nodes for %s", length, nodename);
     
-    vector<XMLNode *>::iterator itx;
-    for (itx = xml->_children.begin(); itx != xml->_children.end(); itx++) {
+    ChildList::const_iterator itx;
+    for (itx = xml._children.begin(); itx != xml._children.end(); itx++)
+    {
 //     log_msg("Found One XMLNode child !!!! %s <%p>\n", (*itx)->nodeName(), 
(void*)*itx);
 //     cerr << "<" << (*it)->nodeName() << ">" << endl;
-       XMLNode *x = *itx;
-       *xmlout << x->toString();
+        (*itx)->toString(xmlout);
+        //x->toString(xmlout);
     }
 
-    if (!nodevalue) {
-       *xmlout << "</" << nodename << ">";
+    if (!nodevalue)
+    {
+           xmlout << "</" << nodename << ">";
     }
 
-    return xmlout->str().c_str();;
 }
 
 void
@@ -421,8 +406,10 @@
     gettersetter = new builtin_function(&xmlnode_nodetype, NULL);
     o.init_property("nodeType", *gettersetter, *gettersetter);
 
+    gettersetter = new builtin_function(&xmlnode_attributes, NULL);
+    o.init_property("attributes", *gettersetter, *gettersetter);
+
     // These two return an array of objects
-    o.init_member("attributes", as_value(""));
     o.init_member("childNodes", as_value(""));
 
     /// \fn MLNode::firstChild
@@ -460,7 +447,8 @@
 
 }
 
-static as_object*
+// External, used by getXMLInterface() !
+as_object*
 getXMLNodeInterface()
 {
     static boost::intrusive_ptr<as_object> o;
@@ -492,9 +480,16 @@
 xmlnode_appendchild(const fn_call& fn)
 {
 //    GNASH_REPORT_FUNCTION;
-    if (fn.nargs > 0) {
+
       boost::intrusive_ptr<XMLNode> ptr = ensureType<XMLNode>(fn.this_ptr);
-//    log_msg("%s: %p, %d args\n", __PRETTY_FUNCTION__, ptr, fn.nargs);
+
+       if ( ! fn.nargs )
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+               log_aserror("XMLNode::appendChild() needs at least one 
argument");
+               );
+               return as_value();
+       }
        
        boost::intrusive_ptr<XMLNode> xml_obj = 
boost::dynamic_pointer_cast<XMLNode>(fn.arg(0).to_object());    
        if ( ! xml_obj )
@@ -505,6 +500,10 @@
                return as_value();
        }
 
+       ptr->appendChild(xml_obj);
+       return as_value(); // undefined
+
+#if 0
        if (xml_obj->nodeType() == XML_ELEMENT_NODE) {
            ptr->appendChild(xml_obj.get());
        } else {
@@ -527,6 +526,7 @@
         log_msg("ERROR: no child XMLNode paramaters!\\n");
     }
     return as_value();
+#endif
 }
 
 static as_value
@@ -535,18 +535,12 @@
     GNASH_REPORT_FUNCTION;
 //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
     boost::intrusive_ptr<XMLNode> ptr = ensureType<XMLNode>(fn.this_ptr);
-    XMLNode   *xmlnode_obj;
 
-    if (fn.nargs > 0) {
-       bool deep = fn.arg(0).to_bool();
-       xmlnode_obj = new XMLNode;
-       ptr->cloneNode(*xmlnode_obj, deep);
-       return as_value(xmlnode_obj);
-    } else {
-        log_msg("ERROR: no Depth paramater!\n");
-    }
-    return as_value();
+    bool deep = false;
+    if (fn.nargs > 0) deep = fn.arg(0).to_bool();
 
+    boost::intrusive_ptr<XMLNode> newnode = ptr->cloneNode(deep);
+    return as_value(newnode.get());
 }
 
 static as_value
@@ -580,7 +574,10 @@
     
     boost::intrusive_ptr<XMLNode> ptr = ensureType<XMLNode>(fn.this_ptr);
     
-    return as_value(ptr->toString());
+    std::stringstream ss;
+    ptr->toString(ss);
+
+    return as_value(ss.str());
 }
 
 static as_value
@@ -602,13 +599,14 @@
     rv.set_null();
     
     //log_msg("xmlnode_nodevalue called with %d args against 'this' = %p", 
fn.nargs, ptr);
-    if ( fn.nargs == 0 ) {
+    if ( fn.nargs == 0 )
+    {
        //log_msg("  nodeValue() returns '%s'", ptr->nodeValue());
        const char* val = ptr->nodeValue();
-       if ( val ) {
-           rv = val;
+        if ( val ) rv = val;
        }
-    } else {
+    else
+    {
        //log_msg(" arg(0) == '%s'", fn.arg(0).to_string());
        ptr->nodeValueSet(fn.arg(0).to_string());
     }
@@ -626,10 +624,10 @@
 
     if ( fn.nargs == 0 ) {
        const char* val = ptr->nodeName();
-       if ( val ) {
-           rv = val;
+        if ( val ) rv = val;
        }
-    } else {
+    else
+    {
        ptr->nodeNameSet(fn.arg(0).to_string());
     }
     return rv;
@@ -653,6 +651,28 @@
     return as_value();
 }
 
+// Both a getter and a (do-nothing) setter for attributes
+static as_value
+xmlnode_attributes(const fn_call& fn)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    boost::intrusive_ptr<XMLNode> ptr = ensureType<XMLNode>(fn.this_ptr);
+
+    if ( fn.nargs == 0 )
+       {
+               log_error("FIXME: XMLNode.attributes not implemented yet");
+               return as_value(); 
+    }
+       else
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+           log_aserror("Tried to set read-only property XMLNode.attributes");
+           );
+    }
+    return as_value();
+}
+
 // Both a getter and a (do-nothing) setter for firstChild
 static as_value
 xmlnode_firstchild(const fn_call& fn)
@@ -664,9 +684,9 @@
 
     if ( fn.nargs == 0 )
     {
-           XMLNode *node = ptr->firstChild();
+        boost::intrusive_ptr<XMLNode> node = ptr->firstChild();
            if (node) {
-               rv = node;
+                   rv = node.get();
            }
     }
     else
@@ -683,7 +703,7 @@
 static as_value
 xmlnode_lastchild(const fn_call& fn)
 {
-//    GNASH_REPORT_FUNCTION;
+    GNASH_REPORT_FUNCTION;
     boost::intrusive_ptr<XMLNode> ptr = ensureType<XMLNode>(fn.this_ptr);
     as_value rv;
     rv.set_null();
@@ -696,10 +716,9 @@
        return rv;
     } 
 
-    XMLNode *node = ptr->lastChild();
-    if (node) {
-       rv = node;
-    }
+    boost::intrusive_ptr<XMLNode> node = ptr->lastChild();
+    if (node) rv = node.get();
+
     return rv;
 }
 

Index: server/asobj/xmlnode.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xmlnode.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/asobj/xmlnode.h      15 Feb 2007 04:05:41 -0000      1.7
+++ server/asobj/xmlnode.h      3 Apr 2007 12:34:43 -0000       1.8
@@ -52,10 +52,19 @@
 {
 public:
     XMLNode();
+
+    // This constructor is used by the XML class
+    XMLNode(as_object* overridden_interface);
+
+    XMLNode(const XMLNode &node, bool deep);
     ~XMLNode();
-    int length()                 { return _children.size(); }
-    const char *nodeName();
-    const char *nodeValue();
+
+    size_t length() const { return _children.size(); }
+
+    const char* nodeName() const { return _name; }
+
+    const char* nodeValue() const { return _value; }
+
     int nodeType();
     void nodeTypeSet(xmlElementType type) {
            _type = type;
@@ -73,47 +82,94 @@
     void nodeValueSet(const char *value);
     //  nodeType       XML.nodeType
 
-    const char *stringify(XMLNode *xml, std::stringstream *xmlout);
+    ///  Returns true if the specified node has child nodes; otherwise, 
returns false.
     bool hasChildNodes();
-    XMLNode *firstChild();
-    XMLNode *lastChild();
     
-    std::vector<XMLNode *>& childNodes() { return _children; }
+    boost::intrusive_ptr<XMLNode> firstChild();
+    boost::intrusive_ptr<XMLNode> lastChild();
+    
+    typedef std::vector< boost::intrusive_ptr<XMLNode> > ChildList;
     
-    XMLNode *operator [] (int x) {
-        gnash::log_msg("%s: get element %d\n", __PRETTY_FUNCTION__, x);
+    // Change this !! We want a managed thing, maybe also shared ?
+    typedef std::vector< XMLAttr* > AttribList;
+
+    ChildList& childNodes() { return _children; }
+
+    AttribList& attributes() { return _attributes; }
+    
+    boost::intrusive_ptr<XMLNode> operator [] (int x)
+    {
+        log_msg("%s: get element %d", __PRETTY_FUNCTION__, x);
         
         return _children[x];
     }
     
-    XMLNode *operator = (XMLNode &node) {
+    XMLNode& operator = (XMLNode &node) {
         gnash::log_msg("%s: \n", __PRETTY_FUNCTION__);
+        if (this == &node) return *this;
         _name = node._name;
         _value = node._value;
        _children = node._children;
         _attributes = node._attributes;
-        return this;
+        return *this;
     }
     
-    XMLNode *operator = (XMLNode *node) {
-        gnash::log_msg("%s: \n", __PRETTY_FUNCTION__);
-        _name = node->_name;
-        _value = node->_value;
-       _children = node->_children;
-        _attributes = node->_attributes;
-        return this;
+    XMLNode& operator = (XMLNode *node)
+    {
+           assert(node);
+           return (*this = *node);
     }
 
     XMLNode* previousSibling();
     XMLNode* nextSibling();
-    XMLNode &cloneNode(XMLNode &newnode, bool deep);
-    void appendChild(XMLNode *node);
+
+    /// Copy a node
+    //
+    /// Method; constructs and returns a new XML node of the same type,
+    /// name, value, and attributes as the specified XML object. If deep
+    /// is set to true, all child nodes are recursively cloned, resulting
+    /// in an exact copy of the original object's document tree. 
+    ///
+    boost::intrusive_ptr<XMLNode> cloneNode(bool deep);
+
+    /// Append a child node the the XML object
+    //
+    /// Appends the specified node to the XML object's child
+    /// list. This method operates directly on the node referenced by the
+    /// childNode parameter; it does not append a copy of the node. If the
+    /// node to be appended already exists in another tree structure,
+    /// appending the node to the new location will remove it from its
+    /// current location. If the childNode parameter refers to a node that
+    /// already exists in another XML tree structure, the appended child
+    /// node is placed in the new tree structure after it is removed from
+    /// its existing parent node. 
+    ///
+    /// @param as
+    ///           The XMLNode ?
+    ///
+    /// @param node
+    ///           same as XMLNode::obj ?
+    ///
+    void appendChild(boost::intrusive_ptr<XMLNode> childNode);
+
     void setParent(XMLNode *node) { _parent = node; };
     XMLNode *getParent() { return _parent; };
 
+    /// Insert a node before a node
+    //
+    /// Method; inserts a new child node into the XML object's child
+    /// list, before the beforeNode node. If the beforeNode parameter is
+    /// undefined or null, the node is added using the appendChild()
+    /// method. If beforeNode is not a child of my_xml, the insertion
+    /// fails.
     void insertBefore(XMLNode *newnode, XMLNode *node);
+
+    /// Removes the specified XML object from its parent.
+    //
+    /// Also deletes all descendants of the node.
     void removeNode();
-    const char *toString();
+
+    void toString(std::ostream& str) const;
 
     void  change_stack_frame(int frame, gnash::as_object *xml, 
gnash::as_environment *env);
 
@@ -125,14 +181,23 @@
 
     xmlElementType      _type;
     XMLNode            *_parent;
-    std::vector<XMLNode *>    _children;
-    std::vector<XMLAttr *>    _attributes;
+    ChildList          _children;
+    AttribList      _attributes;
+
+private:
+
+    // TODO: make a lot more things private !
+
+    static void stringify(const XMLNode& xml, std::ostream& xmlout);
 
 };
 
 // Initialize the global XMLNode class
 void xmlnode_class_init(as_object& global);
 
+// External, used by getXMLInterface() !
+as_object* getXMLNodeInterface();
+
 } // end of gnash namespace
 
 

Index: testsuite/actionscript.all/XML.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/XML.as,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- testsuite/actionscript.all/XML.as   3 Apr 2007 08:04:46 -0000       1.18
+++ testsuite/actionscript.all/XML.as   3 Apr 2007 12:34:43 -0000       1.19
@@ -20,7 +20,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: XML.as,v 1.18 2007/04/03 08:04:46 strk Exp $";
+rcsid="$Id: XML.as,v 1.19 2007/04/03 12:34:43 strk Exp $";
 
 #include "dejagnu.as"
 #include "utils.as"
@@ -28,7 +28,47 @@
 var existtests = true;
 
 check(XML);
+
+#if OUTPUT_VERSION >= 6
+check(! XML.prototype.hasOwnProperty("appendChild") );
+check(! XML.prototype.hasOwnProperty("cloneNode") );
+check(! XML.prototype.hasOwnProperty("hasChildNodes") );
+check(! XML.prototype.hasOwnProperty("insertBefore") );
+check(! XML.prototype.hasOwnProperty("removeNode") );
+check(! XML.prototype.hasOwnProperty("cloneNode") );
+check(! XML.prototype.hasOwnProperty("toString") );
+check(! XML.prototype.hasOwnProperty("length") );
+check(XML.prototype.hasOwnProperty("createElement") );
+check(XML.prototype.hasOwnProperty("addRequestHeader") );
+check(XML.prototype.hasOwnProperty("createTextNode") );
+check(XML.prototype.hasOwnProperty("getBytesLoaded") );
+check(XML.prototype.hasOwnProperty("getBytesTotal") );
+check(XML.prototype.hasOwnProperty("load") );
+check(XML.prototype.hasOwnProperty("parseXML") );
+check(XML.prototype.hasOwnProperty("send") );
+check(XML.prototype.hasOwnProperty("sendAndLoad") );
+
+check(XMLNode.prototype.hasOwnProperty("appendChild") );
+check(XMLNode.prototype.hasOwnProperty("cloneNode") );
+check(XMLNode.prototype.hasOwnProperty("hasChildNodes") );
+check(XMLNode.prototype.hasOwnProperty("insertBefore") );
+check(XMLNode.prototype.hasOwnProperty("removeNode") );
+check(XMLNode.prototype.hasOwnProperty("toString") );
+check(XMLNode.prototype.hasOwnProperty("cloneNode") );
+check(! XMLNode.prototype.hasOwnProperty("length") );
+check(! XMLNode.prototype.hasOwnProperty("createElement") );
+check(! XMLNode.prototype.hasOwnProperty("addRequestHeader") );
+check(! XMLNode.prototype.hasOwnProperty("createTextNode") );
+check(! XMLNode.prototype.hasOwnProperty("getBytesLoaded") );
+check(! XMLNode.prototype.hasOwnProperty("getBytesTotal") );
+check(! XMLNode.prototype.hasOwnProperty("load") );
+check(! XMLNode.prototype.hasOwnProperty("parseXML") );
+check(! XMLNode.prototype.hasOwnProperty("send") );
+check(! XMLNode.prototype.hasOwnProperty("sendAndLoad") );
+#endif
+
 var tmp = new XML();
+check(! tmp.hasOwnProperty("length"));
 
 // test the XML constuctor
 if (tmp) {
@@ -202,12 +242,17 @@
 check_equals( typeof(tmp.parseXML), 'function');
 // parseXML doesn't return anything
 tmp.parseXML(xml_in);
-
-if (tmp.firstChild.nodeName == "TOPNODE") {
-    pass("XML::parseXML() works");
-} else {
-    fail("XML::parseXML() doesn't work");
-}
+check_equals(typeof(tmp.firstChild), 'object');
+note("Parsed XML: "+tmp.toString());
+check(XML.prototype instanceof XMLNode);
+check(tmp instanceof XML);
+check(tmp instanceof XMLNode);
+check(tmp.firstChild instanceof XMLNode);
+check_equals(typeof(tmp.nodeName), 'null');
+check_equals(typeof(tmp.nodeValue), 'null');
+check_equals(typeof(tmp.length), 'undefined');
+check_equals(tmp.firstChild.nodeName, "TOPNODE");
+check_equals(typeof(tmp.firstChild.length), 'undefined');
 
 if (tmp.hasChildNodes() == true) {
     pass("XML::hasChildNodes() works");
@@ -241,10 +286,10 @@
 check(element1.nodeName == "element1");
 
 var element2 = myXML.createElement("element2");
-check(element2.nodeName == "element2");
+check_equals(element2.nodeName, "element2");
 
 var element3 = myXML.createElement("element3");
-check(element3.nodeName == "element3");
+check_equals(element3.nodeName, "element3");
 
 check(myXML.createTextNode);
 
@@ -256,13 +301,21 @@
 check(textNode2.nodeValue == "textNode2 String value");
 
 // place the new nodes into the XML tree
-element2.appendChild(textNode1);
-xcheck_equals(element2.nodeValue, null);
-xcheck_equals(element2.lastChild.nodeValue, "textNode1 String value");
+check(!element2.hasChildNodes());
+ret = element2.appendChild(textNode1);
+check_equals(typeof(ret), 'undefined');
+check(element2.hasChildNodes());
+
+check_equals(element2.nodeValue, null);
+check_equals(typeof(element2.lastChild), 'object');
+check_equals(element2.lastChild.nodeValue, "textNode1 String value");
+element2.lastChild = 4;
+check_equals(typeof(element2.lastChild), 'object');
 
 element3.appendChild(textNode2);
-xcheck_equals(element3.nodeValue, null); 
-xcheck_equals(element3.lastChild.nodeValue, "textNode2 String value");
+check_equals(element3.nodeValue, null); 
+check_equals(typeof(element3.lastChild), 'object');
+check_equals(element3.lastChild.nodeValue, "textNode2 String value");
 
 // place the new nodes into the XML tree
 doc.appendChild(element1);
@@ -322,7 +375,7 @@
        note("myxml.toString(): "+myxml.toString());
        xcheck_equals(typeof(myxml.attributes), 'object');
        check(myxml.hasChildNodes());
-       xcheck_equals(myxml.nodeName, null);
+       check_equals(myxml.nodeName, null);
 };
 myxml.load( MEDIA(gnash.xml) );
 

Index: testsuite/actionscript.all/XMLNode.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/XMLNode.as,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- testsuite/actionscript.all/XMLNode.as       15 Feb 2007 04:05:41 -0000      
1.9
+++ testsuite/actionscript.all/XMLNode.as       3 Apr 2007 12:34:43 -0000       
1.10
@@ -20,7 +20,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: XMLNode.as,v 1.9 2007/02/15 04:05:41 rsavoye Exp $";
+rcsid="$Id: XMLNode.as,v 1.10 2007/04/03 12:34:43 strk Exp $";
 
 #include "dejagnu.as"
 
@@ -77,9 +77,9 @@
 node1.appendChild(node2);
 check_equals(node1.hasChildNodes(), true);
 
-check_equals(node1.firstChild.nodeValue, "second text node");
-check_equals(node1.lastChild.nodeValue, "second text node");
-xcheck_equals(node2.lastChild, "null"); // FIXME
+check_equals(node1.firstChild.nodeValue, "first text node");
+check_equals(typeof(node1.lastChild.nodeValue), 'null');
+xcheck_equals(node2.lastChild.toString(), "second text node"); 
 
 var node3 = doc.createElement("node3");
 var textnode3 = doc.createTextNode("third text node");
@@ -91,16 +91,16 @@
 
 // trace(node1.firstChild.nodeValue);
 // trace(node1.lastChild.nodeValue);
-check_equals(node1.firstChild.nodeValue, "second text node");
-check_equals(node1.lastChild.nodeValue, "third text node");
+check_equals(node1.firstChild.nodeValue, "first text node");
+check_equals(typeof(node1.lastChild.nodeValue), 'null');
 
 trace(node1.lastChild.previousSibling);
 trace(node1.firstChild.nextSibling);
 
-check_equals(node1.firstChild.nodeName, "node2");
+check_equals(typeof(node1.firstChild.nodeName), "null");
 check_equals(node1.lastChild.nodeName, "node3");
 
-xcheck_equals(node2.previousSibling.nodeValue, "second text node");
+check_equals(node2.previousSibling.nodeValue, "first text node");
 
 // TODO: test removeNode, insertNode
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]