gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/Makefile.am server/asobj...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/Makefile.am server/asobj...
Date: Fri, 24 Nov 2006 09:19:51 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  06/11/24 09:19:50

Modified files:
        .              : ChangeLog 
        server         : Makefile.am 
        server/asobj   : Makefile.am 
Added files:
        server/asobj   : xml.cpp xml.h xmlattrs.cpp xmlattrs.h 
                         xmlnode.cpp xmlnode.h xmlsocket.cpp xmlsocket.h 
Removed files:
        server         : xml.cpp xml.h xmlattrs.cpp xmlattrs.h 
                         xmlnode.cpp xmlnode.h xmlsocket.cpp xmlsocket.h 

Log message:
                * server: {xmlattres,xmlnode,xmlsocket}.{h,cpp} => asobj

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.1736&r2=1.1737
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.89&r2=1.90
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xml.cpp?cvsroot=gnash&r1=1.34&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xml.h?cvsroot=gnash&r1=1.21&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlattrs.cpp?cvsroot=gnash&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlattrs.h?cvsroot=gnash&r1=1.10&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlnode.cpp?cvsroot=gnash&r1=1.22&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlnode.h?cvsroot=gnash&r1=1.11&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlsocket.cpp?cvsroot=gnash&r1=1.28&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/xmlsocket.h?cvsroot=gnash&r1=1.13&r2=0
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Makefile.am?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xml.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xml.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlattrs.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlattrs.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlnode.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlnode.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlsocket.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlsocket.h?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.1736
retrieving revision 1.1737
diff -u -b -r1.1736 -r1.1737
--- ChangeLog   24 Nov 2006 09:17:49 -0000      1.1736
+++ ChangeLog   24 Nov 2006 09:19:50 -0000      1.1737
@@ -1,7 +1,7 @@
 2006-11-24 Sandro Santilli <address@hidden>
 
        * server/gnash.h: ok, include as_value, but document what's needed
-         from it (as_c_function_ptr typedef, in this case)
+       * server: {xmlattres,xmlnode,xmlsocket}.{h,cpp} => asobj
 
 2006-11-24 Sandro Santilli <address@hidden>
 

Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -b -r1.89 -r1.90
--- server/Makefile.am  24 Nov 2006 09:04:24 -0000      1.89
+++ server/Makefile.am  24 Nov 2006 09:19:50 -0000      1.90
@@ -18,7 +18,7 @@
 # 
 #
 
-# $Id: Makefile.am,v 1.89 2006/11/24 09:04:24 strk Exp $
+# $Id: Makefile.am,v 1.90 2006/11/24 09:19:50 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -46,104 +46,96 @@
        $(NULL)
 
 libgnashserver_la_SOURCES = \
-       as_object.cpp   \
-       as_value.cpp     \
+       GetterSetter.cpp \
+       PropertyList.cpp \
+       URLAccessManager.cpp    \
        as_environment.cpp       \
        as_function.cpp         \
-       swf_function.cpp        \
+       as_object.cpp   \
+       as_value.cpp     \
        character.cpp \
+       edit_text_character.cpp \
        generic_character.cpp \
-        textformat.cpp \
-        timers.cpp \
-        xml.cpp \
-        xmlattrs.cpp \
-        xmlnode.cpp \
+       matrix.cpp      \
+       movie_instance.cpp \
        movie_root.cpp \
-        xmlsocket.cpp \
+       rect.cpp \
+       shm.cpp \
+       sprite_instance.cpp \
+       swf/TagLoadersTable.cpp \
+       swf/tag_loaders.cpp     \
+       swf_function.cpp        \
+       video_stream_instance.cpp \
+       video_yuv.cpp   \
+        StreamProvider.cpp \
+        array.cpp \
         button_character_instance.cpp \
         dlist.cpp \
-       edit_text_character.cpp \
         font.cpp \
         fontlib.cpp \
-       GetterSetter.cpp \
         impl.cpp \
-       rect.cpp \
         render.cpp \
         shape.cpp \
-       shm.cpp \
         sound.cpp \
-       sprite_instance.cpp \
-       matrix.cpp      \
-       movie_instance.cpp \
-       PropertyList.cpp \
         stream.cpp \
-        StreamProvider.cpp \
-       URLAccessManager.cpp    \
         styles.cpp \
         tesselate.cpp \
         text.cpp \
-        array.cpp \
-       swf/TagLoadersTable.cpp \
-       swf/tag_loaders.cpp     \
+        textformat.cpp \
+        timers.cpp \
         types.cpp      \
-       video_yuv.cpp   \
-       video_stream_instance.cpp \
        $(NULL)
 
 noinst_HEADERS = \
+       GetterSetter.h \
+       Global.h \
+       Property.h \
+       PropertyList.h \
+       Sprite.h \
+       StreamProvider.h        \
+       StringPredicates.h \
+       URLAccessManager.h      \
        array.h \
-       as_value.h \
        as_environment.h \
        as_function.h           \
-       builtin_function.h      \
-       swf_function.h          \
-       as_prop_flags.h \
        as_object.h \
+       as_prop_flags.h \
+       as_value.h \
+       builtin_function.h      \
        button_character_instance.h \
-       matrix.h \
-       mouse_button_state.h \
-       dlist.h \
        character.h \
-       generic_character.h \
+       dlist.h \
        edit_text_character.h \
        event_id.h \
        execute_tag.h \
        font.h \
        fontlib.h \
-       GetterSetter.h \
-       Global.h \
+       generic_character.h \
        gnash.h \
        impl.h \
+       matrix.h \
+       mouse_button_state.h \
+       movie_instance.h \
        movie_root.h \
-       Property.h \
-       PropertyList.h \
        rect.h \
-       resource.h \
        render.h \
+       resource.h \
        shape.h \
        shm.h \
        sound.h \
-       Sprite.h \
        sprite_instance.h \
-       StringPredicates.h \
-       movie_instance.h \
        stream.h \
-       StreamProvider.h        \
-       URLAccessManager.h      \
        styles.h \
        swf.h \
+       swf/TagLoadersTable.h \
+       swf/tag_loaders.h \
        swf_event.h \
+       swf_function.h          \
        tesselate.h \
-       textformat.h \
        text.h \
+       textformat.h \
        timers.h \
        types.h \
-        xmlattrs.h \
-       xml.h \
-        xmlnode.h \
-       swf/TagLoadersTable.h \
-       swf/tag_loaders.h \
-       xmlsocket.h \
        $(NULL)
 
 libgnashserver_la_LIBADD = \

Index: server/asobj/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Makefile.am,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/asobj/Makefile.am    24 Nov 2006 09:04:24 -0000      1.19
+++ server/asobj/Makefile.am    24 Nov 2006 09:19:50 -0000      1.20
@@ -18,7 +18,7 @@
 # 
 #
 
-# $Id: Makefile.am,v 1.19 2006/11/24 09:04:24 strk Exp $
+# $Id: Makefile.am,v 1.20 2006/11/24 09:19:50 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -43,6 +43,7 @@
        $(NULL)
 
 libgnashasobjs_la_SOURCES = \
+       ASSound.cpp     \
        Boolean.cpp     \
        Camera.cpp      \
        Color.cpp       \
@@ -50,27 +51,31 @@
        CustomActions.cpp\
        Date.cpp        \
        Error.cpp       \
-       Math.cpp        \
        Global.cpp      \
        Key.cpp         \
        LoadVars.cpp    \
        LocalConnection.cpp\
+       Math.cpp        \
        Microphone.cpp  \
        Mouse.cpp       \
        MovieClip.cpp   \
-        MovieClipLoader.cpp\
        NetConnection.cpp\
        NetStream.cpp   \
        Number.cpp      \
        Object.cpp      \
        Selection.cpp   \
        SharedObject.cpp\
-       ASSound.cpp     \
-        string.cpp \
        Stage.cpp       \
        System.cpp      \
        TextSnapshot.cpp\
-       Video.cpp
+       Video.cpp       \
+        MovieClipLoader.cpp\
+        string.cpp \
+        xml.cpp \
+        xmlattrs.cpp \
+        xmlnode.cpp \
+        xmlsocket.cpp \
+       $(NULL)
 
 noinst_HEADERS = \
        ASSound.h       \
@@ -81,12 +86,11 @@
        CustomActions.h \
        Date.h          \
        Error.h         \
+       GMath.h         \
        Key.h \
        LoadVars.h      \
        LocalConnection.h\
        Microphone.h    \
-       GMath.h         \
-       gstring.h \
        Mouse.h         \
        MovieClip.h     \
        MovieClipLoader.h \
@@ -99,7 +103,13 @@
        Stage.h         \
        System.h        \
        TextSnapshot.h  \
-       Video.h
+       Video.h         \
+       gstring.h       \
+       xml.h           \
+       xmlsocket.h \
+        xmlattrs.h     \
+        xmlnode.h      \
+       $(NULL)
 
 libgnashasobjs_la_LIBADD = \
        $(top_builddir)/libamf/libgnashamf.la \

Index: server/asobj/xml.cpp
===================================================================
RCS file: server/asobj/xml.cpp
diff -N server/asobj/xml.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xml.cpp        24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,1328 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// 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.1 2006/11/24 09:19:50 strk Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string>
+#include <vector>
+
+#include "log.h"
+#include "tu_config.h"
+#include "as_function.h" // for as_function
+#include "fn_call.h"
+
+#ifdef HAVE_LIBXML
+
+#include <unistd.h>
+#include "xmlattrs.h"
+#include "xmlnode.h"
+#include "xml.h"
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlreader.h>
+
+using namespace std;
+
+namespace gnash {
+  
+//#define DEBUG_MEMORY_ALLOCATION 1
+  
+XML::XML() 
+    :_loaded(false),  _nodename(0), _nodes(0), _bytes_loaded(0), 
_bytes_total(0)
+{
+    GNASH_REPORT_FUNCTION;
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("Creating XML data at %p \n", this);
+#endif
+    //log_msg("%s: %p \n", __FUNCTION__, this);
+}
+
+
+// Parse the ASCII XML string into memory
+XML::XML(tu_string xml_in)
+{
+    GNASH_REPORT_FUNCTION;
+#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 */)
+{
+    GNASH_REPORT_FUNCTION;
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("\tCreating XML data at %p \n", this);
+#endif
+    //log_msg("%s: %p \n", __FUNCTION__, this);
+}
+
+
+XML::~XML()
+{
+    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);
+    }
+#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(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(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);
+}
+
+// Dispatch event handler(s), if any.
+bool
+XML::on_event(const event_id& /* id */)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    // Keep m_as_environment alive during any method calls!
+    //  boost::intrusive_ptr<as_object_interface>      this_ptr(this);
+  
+#if 0
+    // First, check for built-in event handler.
+    as_value   method;
+    if (get_event_handler(event_id(id), &method)) {
+        call_method0(method, &m_as_environment, this);
+        return true;
+    }
+  
+    // Check for member function.
+    // In ActionScript 2.0, event method names are CASE SENSITIVE.
+    // In ActionScript 1.0, event method names are CASE INSENSITIVE.
+    const tu_string&   method_name = id.get_function_name();
+    if (method_name.length() > 0) {
+        as_value       method;
+        if (get_member(method_name, &method)) {
+            call_method0(method, &m_as_environment, this);
+            return true;
+        }
+    }
+#endif
+    return false;
+}
+
+void
+XML::on_event_load()
+{
+    // Do the events that (appear to) happen as the movie
+    // loads.  frame1 tags and actions are executed (even
+    // before advance() is called).  Then the onLoad event
+    // is triggered.
+    on_event(event_id::LOAD);
+}
+
+XMLNode*
+XML::extractNode(xmlNodePtr node, bool mem)
+{
+    xmlAttrPtr attr;
+    xmlNodePtr childnode;
+    xmlChar *ptr = NULL;
+    XMLNode *element, *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) {
+        //log_msg("extractNode %s has property %s, value is %s\n",
+        //          node->name, attr->name, attr->children->content);
+        XMLAttr *attrib = new XMLAttr;
+        len = memadjust(strlen(reinterpret_cast<const char *>(attr->name))+1);
+        attrib->_name = (char *)new char[len];
+        memset(attrib->_name, 0, len);
+        strcpy(attrib->_name, reinterpret_cast<const char *>(attr->name));
+        len = memadjust(strlen(reinterpret_cast<const char 
*>(attr->children->content))+1);
+        attrib->_value = (char *)new char[len];
+        memset(attrib->_value, 0, len);
+        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);
+        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);
+    if (node->children) {
+        //ptr = node->children->content;
+        ptr = xmlNodeGetContent(node->children);
+        if (ptr != NULL) {
+            if ((strchr((const char *)ptr, '\n') == 0) && (ptr[0] != 0)) {
+                if (node->children->content == NULL) {
+                    //log_msg("Node %s has no contents\n", node->name);
+                } 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 = reinterpret_cast<const char *>(ptr);
+                }
+            }
+            xmlFree(ptr);
+        }
+    }
+    
+    // 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 %p\n", 
child->_name.c_str(), child->_value.to_string(), element);
+            } else {
+                //log_msg("\tPushing childNode %s on element %p\n", 
child->_name.c_str(), element);
+            }
+            element->_children.push_back(child);
+        }
+        childnode = childnode->next;
+    }
+
+    return element;
+}
+
+// Read in an XML document from the specified source
+bool
+XML::parseDoc(xmlDocPtr document, bool mem)
+{
+    GNASH_REPORT_FUNCTION;
+    
+    XMLNode *top;
+    xmlNodePtr cur;
+
+    if (document == 0) {
+        log_error("Can't load XML file!\n");
+        return false;
+    }
+
+    cur = xmlDocGetRootElement(document);
+  
+    if (cur != NULL) {
+        top = extractNode(cur, mem);
+        //_nodes->_name = reinterpret_cast<const char *>(cur->name);
+        _nodes = top;
+        //_node_data.push_back(top);
+        //cur = cur->next;
+    }  
+
+    _loaded = true;
+    return true;
+}
+
+// This reads in an XML file from disk and parses into into a memory resident
+// tree which can be walked through later.
+bool
+XML::parseXML(tu_string xml_in)
+{
+    GNASH_REPORT_FUNCTION;
+
+    log_msg("Parse XML from memory: %s\n", xml_in.c_str());
+
+    if (xml_in.size() == 0) {
+        log_error("XML data is empty!\n");
+        return false;
+    }
+
+#ifndef USE_DMALLOC
+    //dump_memory_stats(__FUNCTION__, __LINE__, "before xmlParseMemory");
+#endif
+
+    _bytes_total = _bytes_loaded = xml_in.size();
+    
+#ifdef USE_XMLREADER
+    XMLNode *node = 0;
+    xmlTextReaderPtr reader;
+
+    reader = xmlReaderForMemory(xml_in.c_str(), xml_in.size(), NULL, NULL, 0);
+    if (reader != NULL) {
+       bool ret = true;
+        while (ret) {
+            ret = xmlTextReaderRead(reader);
+            node = processNode(reader, node);
+        }
+        xmlFreeTextReader(reader);
+        if (ret != false) {
+            log_error("%s : couldn't parse\n", xml_in.c_str());
+            return false;
+        }
+    } else {
+        log_error("Unable to open %s\n", xml_in.c_str());
+        return false;
+    }
+    xmlCleanupParser();
+    return true;
+#else
+
+bool ret = true;
+
+#ifdef USE_DOM
+    xmlInitParser();
+  
+    _doc = xmlParseMemory(xml_in.c_str(), xml_in.size());
+    if (_doc == 0) {
+        log_error("Can't parse XML data!\n");
+        return false;
+    }
+    ret = parseDoc(_doc, true);
+    xmlCleanupParser();
+    xmlFreeDoc(_doc);
+    xmlMemoryDump();
+#endif
+#ifndef USE_DMALLOC
+    //dump_memory_stats(__FUNCTION__, __LINE__, "after xmlParseMemory");
+#endif
+    return ret;
+#endif
+  
+}
+
+//     XML_READER_TYPE_NONE = 0
+//     XML_READER_TYPE_ELEMENT = 1,
+//     XML_READER_TYPE_ATTRIBUTE = 2,
+//     XML_READER_TYPE_TEXT = 3,
+//     XML_READER_TYPE_COMMENT = 8,
+//     XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14,
+//     XML_READER_TYPE_END_ELEMENT = 15,
+//
+// processNode:
+// 2 1 IP 0// processNode:
+// 3 3 #text 0 192.168.2.50
+// processNode:
+// 2 15 IP 0
+// processNode:
+// 2 14 #text 0
+const char *tabs[] = {
+    "",
+    "\t",
+    "\t\t",
+    "\t\t\t",
+    "\t\t\t",
+    "\t\t\t\t",
+};
+
+#ifdef USE_XMLREADER
+// This is an xmlReader (SAX) based parser. For some reason it core dumps
+// when compiled with GCC 3.x, but works just fine with GCC 4.x.
+XMLNode*
+XML::processNode(xmlTextReaderPtr reader, XMLNode *node)
+{
+    log_msg("%s: node is %p\n", __PRETTY_FUNCTION__, node);
+    static XMLNode *parent[10];
+    xmlChar *name, *value;
+    int   depth;
+    XMLNode *element;
+    //static int previous_depth = 0;
+    xmlReaderTypes type;
+
+    if (node == 0) {
+        memset(parent, 0, sizeof(XMLNode *));
+    }
+    type = (xmlReaderTypes)xmlTextReaderNodeType(reader);
+    depth = xmlTextReaderDepth(reader);
+    value = xmlTextReaderValue(reader);
+    name = xmlTextReaderName(reader);
+  
+    if (name == NULL)
+        name = xmlStrdup(BAD_CAST "--");
+
+#if 0
+    printf("%d %d %s %d\n",
+           depth,
+           (int)type,
+           name,
+           xmlTextReaderIsEmptyElement(reader));  
+#endif
+
+  
+    //child = node->_children[0];
+    switch(xmlTextReaderNodeType(reader)) {
+      case XML_READER_TYPE_NONE:
+          break;
+      case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: // This is an empty text 
node
+          //log_msg("\tWhitespace at depth %d\n", depth);
+          break;
+      case XML_READER_TYPE_END_ELEMENT:
+          if (depth == 0) {          // This is the last node in the file
+              element = node;
+              break;
+          }
+          parent[depth]->_children.push_back(element);
+//       log_msg("Pushing element %s on node %s\n", node->_name, 
parent[depth]->_name);
+//       log_msg("End element at depth %d is %s for parent %s %p\n", depth, 
name,
+//               parent[depth]->_name, parent[depth]);
+          element = parent[depth];
+          break;
+      case XML_READER_TYPE_ELEMENT:
+          element = new XMLNode;
+//      log_msg("%sElement at depth %d is %s for node at %p\n", tabs[depth], 
depth, name, element);
+          element->_name = (char *)new char[strlen(reinterpret_cast<const char 
*>(name))+1];
+          memset(element->_name, 0, strlen(reinterpret_cast<const char 
*>(name))+1);
+          strcpy(element->_name, reinterpret_cast<const char *>(name));
+          if (node == 0) {
+              _nodes = element;
+              parent[0] = element;
+          } else {
+              parent[depth] = node;
+              parent[depth+1] = node;
+          }
+          //  xmlTextReaderAttributeCount(reader);
+          if (xmlTextReaderHasAttributes(reader)) {
+              // log_msg("Has Attributes!\n");
+              xmlTextReaderMoveToFirstAttribute(reader);
+              processNode(reader, element);
+              while(xmlTextReaderMoveToNextAttribute(reader)) {
+                  processNode(reader, element);
+              }
+          }
+          break;
+      case XML_READER_TYPE_TEXT:
+          element = node;
+//      log_msg("%sValue at depth %d is \"%s\" for node at %p\n", tabs[depth], 
depth, value, element);
+          element->_value = (char *)new char[strlen(reinterpret_cast<const 
char *>(value))+1];
+          memset(element->_value, 0, strlen(reinterpret_cast<const char 
*>(value))+1);
+          strcpy(element->_value, reinterpret_cast<const char *>(value));
+          break;
+      case XML_READER_TYPE_ATTRIBUTE:
+          element = node;
+          XMLAttr *attrib = new XMLAttr;
+          attrib->_name = (char *)new char[strlen(reinterpret_cast<const char 
*>(name))+1];
+          memset(attrib->_name, 0, strlen(reinterpret_cast<const char 
*>(name))+1);
+          strcpy(attrib->_name, reinterpret_cast<const char *>(name));
+          attrib->_value = (char *)new char[strlen(reinterpret_cast<const char 
*>(value))+1];
+          memset(attrib->_value, 0, strlen(reinterpret_cast<const char 
*>(value))+1);
+          strcpy(attrib->_value, reinterpret_cast<const char *>(value));
+//     log_msg("%sPushing attribute %s, value \"%s\" for node %s\n", 
tabs[depth], name, value, element->_name);
+          element->_attributes.push_back(attrib);
+          break;
+      default:   // FIXME: why does this break GCC 3.3.3 but not 3.4.3 ?
+          log_error("Unsupported XML type %d\n!", type);
+          break;
+    };
+
+    xmlFree(name);
+    if (value != NULL) {
+        xmlFree(value);
+    }
+    //previous_depth = depth;
+    return element;
+}
+#endif
+
+// This reads in an XML file from disk and parses into into a memory resident
+// tree which can be walked through later.
+bool
+XML::load(const char *filespec)
+{
+    GNASH_REPORT_FUNCTION;
+    struct stat stats;
+    log_msg("Load disk XML file: %s\n", filespec);
+  
+    //log_msg("%s: mem is %d\n", __FUNCTION__, mem);
+
+    // See if the file exists
+    if (stat(filespec, &stats) == 0) {
+        _bytes_total = stats.st_size;
+        _bytes_loaded = stats.st_size; // FIXME: this should probably
+                                       // be set later on after the
+                                       // file is loaded
+    }
+#ifdef USE_XMLREADER
+    XMLNode *node = 0;
+    xmlTextReaderPtr reader;  
+  
+    reader = xmlNewTextReaderFilename(filespec);
+    if (reader != NULL) {
+        bool ret = true;
+        while (ret) {
+            ret = xmlTextReaderRead(reader);
+            node = processNode(reader, node);
+        }
+        xmlFreeTextReader(reader);
+        if (ret != false) {
+            log_error("%s : couldn't parse\n", filespec);
+            return false;
+        }
+    } else {
+        log_error("Unable to open %s\n", filespec);
+        return false;
+    }
+    xmlCleanupParser();
+    return true;
+#else
+#ifdef USE_DOM
+    xmlInitParser();
+    _doc = xmlParseFile(filespec);
+    if (_doc == 0) {
+        log_error("Can't load XML file: %s!\n", filespec);
+        return false;
+    }
+    parseDoc(_doc, false);
+    xmlCleanupParser();
+    xmlFreeDoc(_doc);
+    xmlMemoryDump();
+    return true;
+#else
+#error "You have to enable either a DOM or an xmlReader XML parser"
+#endif
+#endif
+}
+
+
+vector<XMLNode *>
+XML::childNodes() 
+{
+  if (_nodes) {
+    return _nodes->_children;
+  } else {
+    return static_cast< vector<XMLNode*> >(0);
+  }
+}
+
+bool
+XML::onLoad()
+{
+    log_msg("%s: FIXME: onLoad Default event handler\n", __FUNCTION__);
+
+    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 *
+XML::setupFrame(as_object *obj, XMLNode *xml, bool mem)
+{
+//    GNASH_REPORT_FUNCTION;
+    
+    int                 child;
+    unsigned int i;
+    const char    *nodename;
+    //const char    *nodevalue;
+    //AS_value      nodevalue;
+    int           length;
+    as_value      inum;
+    XMLNode       *childnode;
+    xmlnode_as_object *xmlchildnode_obj;
+    xmlattr_as_object* attr_obj;
+
+    //log_msg("\t%s: processing node %s for object %p, mem is %d\n", 
__FUNCTION__, xml->_name, obj, mem);
+  
+    // 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
+    // primarily by the disk based XML parser, where at least in all my current
+    // test cases this is referenced with firstChild first, then nodeName and
+    // childNodes.
+    obj->set_member("nodeName",           nodename);
+    obj->set_member("length",             length);
+    if (xml->_value != 0) {
+        obj->set_member("nodeValue",        xml->_value);
+        log_msg("\tnodevalue for %s is: %s\n", nodename, xml->_value);
+    } else {
+        obj->set_member("nodeValue", as_value::UNDEFINED);
+    }
+
+//   if (nodevalue.get_type() != as_value::UNDEFINED) {
+//     obj->set_member("nodeValue",        nodevalue.to_string());
+//     log_msg("\tnodevalue for %s is: %s\n", nodename, nodevalue.to_string());
+//   } else {
+//     // If there is no value, we want to define it as an empty
+//     // string.
+//     obj->set_member("nodeValue", "");
+//   }
+
+  
+    // Process the attributes, if any
+    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 {
+        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);
+    }
+
+    //xml->_attributes.resize(0);
+    //obj->set_member("attributes", attr_obj);
+
+    // Process the children, if there are any
+    if (length) {
+        //log_msg("\tProcessing %d children nodes for %s\n", length, nodename);
+        inum = 0;
+        for (child=0; child<length; child++) {
+            // Create a new AS object for this node's children
+            xmlchildnode_obj = new xmlnode_as_object;
+            // When parsing XML from memory, the test movies I have expect the 
firstChild
+            // to be the first element of the array instead.
+            if (mem) {
+                childnode = xml;
+                //obj->set_member(inum.to_string(), obj);
+                //inum += 1;
+                //childnode = xml->_children[child];
+            } else {
+                childnode = xml->_children[child];
+            }
+            setupFrame(xmlchildnode_obj, childnode, false); // setup child node
+            obj->set_member(inum.to_string(), xmlchildnode_obj);
+            inum += 1;
+        }
+    } else {
+        //log_msg("\tNode %s has no children\n", nodename);
+    }  
+
+    return obj;
+}
+
+
+/// \brief add or change the HTTP Request header
+///
+/// Method; adds or changes HTTP request headers (such as Content-Type
+/// or SOAPAction) sent with POST actions. In the first usage, you pass
+/// two strings to the method: headerName and headerValue. In the
+/// second usage, you pass an array of strings, alternating header
+/// names and header values.
+///
+/// If multiple calls are made to set the same header name, each
+/// successive value replaces the value set in the previous call.
+void
+XML::addRequestHeader(const char */* name */, const char */* value */)
+{
+    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)
+{
+    if (!_nodes) {
+      _nodes = new XMLNode;
+    }
+    _nodes->_children.push_back(node);
+    //    log_msg("%s: %p at _nodes at %p\n", __PRETTY_FUNCTION__, this, 
_nodes);
+}
+
+/// \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)
+{
+    log_msg("%s: deep is %d\n", __PRETTY_FUNCTION__, deep);
+
+    if (deep) {
+       newnode = _nodes;
+//     } else {
+//     newnode.nodeNameSet((char *)_nodes->nodeName());
+//     newnode.nodeValueSet((char *)_nodes->nodeValue());    
+    }
+
+    return newnode;
+  
+    log_msg("%s:partially unimplemented \n", __PRETTY_FUNCTION__);
+}
+
+/// \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;
+}
+
+/// \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()
+{
+    log_msg("%s:unimplemented \n", __FUNCTION__);
+}
+
+void
+XML::parseXML()
+{
+    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()
+{
+    log_msg("%s:unimplemented \n", __FUNCTION__);
+}
+
+void
+XML::sendAndLoad()
+{
+    log_msg("%s:unimplemented \n", __FUNCTION__);
+}
+
+const char *
+XML::toString()
+{
+    if (_nodes) {
+       return stringify(_nodes);
+    }
+    return NULL;
+}
+
+// 
+const char *
+XML::stringify(XMLNode *xml)
+{
+    int           child;
+    unsigned int  i;
+    const char    *nodename = xml->nodeName();
+    int           length;
+    string       str;
+    
+    log_msg("%s: processing for object %p\n", __PRETTY_FUNCTION__, 
(void*)this);
+  
+    // Process the attributes, if any
+    if (_nodes->_attributes.size() == 0) {
+        log_msg("\t\tNo attributes for node\n");
+    } else {
+        for (i=0; i<xml->_attributes.size(); i++) {
+            log_msg("\t\tAdding attribute as member %s, value is %s to node 
%s\n",
+                    xml->_attributes[i]->_name,
+                    xml->_attributes[i]->_value, nodename);
+        }
+    }
+
+    vector<XMLNode *>::iterator it;
+    for (it = _nodes->_children.begin(); it != _nodes->_children.end(); ++it) {
+       log_msg("Found One!!!! %p\n", (void*)*it);
+    }
+    
+    // Process the children, if there are any
+    length = xml->_children.size();
+
+    if (length) {
+        log_msg("\tProcessing %d children nodes\n", length);
+        for (child=0; child<length; child++) {
+           log_msg("Name %p\n", (void*)(xml->_children[child]));
+           if (xml->_children[child]->_name) {
+//             log_msg("Name %p", xml->_children[child]);
+           }
+           if (xml->_children[child]->_value) {
+//             log_msg("Value %s", xml->_children[child]->_value);
+           }
+       
+//         str += stringify(xml->_children[child]);
+        }
+    } else {
+        log_msg("\tNode %s has no children\n", nodename);
+    }
+    return str.c_str();
+}
+
+//
+// Callbacks. These are the wrappers for the C++ functions so they'll work as
+// callbacks from within gnash.
+//
+void
+xml_load(const fn_call& fn)
+{
+    as_value   method;
+    as_value   val;
+    bool          ret;
+    struct stat   stats;
+
+    //GNASH_REPORT_FUNCTION;
+  
+    xml_as_object *xml_obj = (xml_as_object*)fn.this_ptr;
+  
+    const std::string filespec = 
fn.env->bottom(fn.first_arg_bottom_index).to_string();
+
+    // If the file doesn't exist, don't try to do anything.
+    if (stat(filespec.c_str(), &stats) < 0) {
+        fprintf(stderr, "ERROR: doesn't exist.%s\n", filespec.c_str());
+        fn.result->set_bool(false);
+        return;
+    }
+  
+    // Set the argument to the function event handler based on whether the load
+    // was successful or failed.
+    ret = xml_obj->obj.load(filespec.c_str());
+    fn.result->set_bool(ret);
+
+    if (ret == false) {
+        return;
+    }
+    
+    //env->bottom(first_arg) = ret;
+    //  struct node *first_node = ptr->obj.firstChildGet();
+  
+    //const char *name = ptr->obj.nodeNameGet();
+
+    if (xml_obj->obj.hasChildNodes() == false) {
+        log_error("%s: No child nodes!\n", __FUNCTION__);
+    }  
+    xml_obj->obj.setupFrame(xml_obj, xml_obj->obj.firstChild(), false);
+  
+#if 1
+    if (fn.this_ptr->get_member("onLoad", &method)) {
+        //    log_msg("FIXME: Found onLoad!\n");
+        fn.env->set_variable("success", true);
+        fn.env->bottom(fn.first_arg_bottom_index) = true;
+        as_c_function_ptr      func = method.to_c_function();
+        if (func) {
+           // It's a C function.  Call it.
+           log_msg("Calling C function for onLoad\n");
+           (*func)(fn_call(&val, xml_obj, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
+       } else if (as_function* as_func = method.to_as_function()) {
+           // It's an ActionScript function.  Call it.
+           log_msg("Calling ActionScript function for onLoad\n");
+           (*as_func)(fn_call(&val, xml_obj, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
+       } else {
+           log_error("error in call_method(): method is not a function\n");
+       }
+    } else {
+        log_msg("Couldn't find onLoad event handler, setting up callback\n");
+        // ptr->set_event_handler(event_id::XML_LOAD, 
(as_c_function_ptr)&xml_onload);
+    }
+#else
+    xml_obj->set_event_handler(event_id::XML_LOAD, &xml_onload);
+
+#endif
+
+    fn.result->set_bool(true);
+}
+
+// This executes the event handler for XML::XML_LOAD if it's been defined,
+// and the XML file has loaded sucessfully.
+void
+xml_onload(const fn_call& fn)
+{
+    //log_msg("%s:\n", __FUNCTION__);
+    
+    as_value   method;
+    as_value      val;
+    static bool first = true;     // This event handler should only be 
executed once.
+    xml_as_object*     ptr = (xml_as_object*) (as_object*) fn.this_ptr;
+    assert(ptr);
+  
+    if ((ptr->obj.loaded()) && (first)) {
+        // env->set_variable("success", true, 0);
+        //as_value bo(true);
+        //env->push_val(bo);
+
+        first = false;
+        log_msg("The XML file has been loaded successfully!\n");
+        // ptr->on_event(event_id::XML_LOAD);
+        //env->set_variable("success", true, 0);
+        //env->bottom(0) = true;
+    
+        if (fn.this_ptr->get_member("onLoad", &method)) {
+            // log_msg("FIXME: Found onLoad!\n");
+            as_c_function_ptr  func = method.to_c_function();
+            if (func)
+                {
+                    // It's a C function.  Call it.
+                    log_msg("Calling C function for onLoad\n");
+                    (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+                }
+            else if (as_function* as_func = method.to_as_function())
+                {
+                    // It's an ActionScript function.  Call it.
+                    log_msg("Calling ActionScript function for onLoad\n");
+                    (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+                }
+            else
+                {
+                    log_error("error in call_method(): method is not a 
function\n");
+                }    
+        } else {
+            log_msg("FIXME: Couldn't find onLoad!\n");
+        }
+    }
+      
+    fn.result->set_bool(val.to_bool());
+}
+
+// This is the default event handler, and is usually redefined in the SWF 
script
+void
+xml_ondata(const fn_call& fn)
+{
+    log_msg("%s:\n", __FUNCTION__);
+    
+    as_value   method;
+    as_value   val;
+    static bool first = true;     // FIXME: ugly hack!
+  
+    xml_as_object*     ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+  
+    if ((ptr->obj.loaded()) && (first)) {
+        if (fn.this_ptr->get_member("onData", &method)) {
+            log_msg("FIXME: Found onData!\n");
+            as_c_function_ptr  func = method.to_c_function();
+            fn.env->set_variable("success", true);
+            if (func)
+                {
+                    // It's a C function.  Call it.
+                    log_msg("Calling C function for onData\n");
+                    (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+                }
+            else if (as_function* as_func = method.to_as_function())
+                {
+                    // It's an ActionScript function.  Call it.
+                    log_msg("Calling ActionScript function for onData\n");
+                    (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+                }
+            else
+                {
+                    log_error("error in call_method(): method is not a 
function\n");
+                }    
+        } else {
+            log_msg("FIXME: Couldn't find onData!\n");
+        }
+    }
+
+    //fn.result->set(&val);
+    fn.result->set_bool(val.to_bool());
+}
+
+void
+xml_new(const fn_call& fn)
+{
+    as_value      inum;
+    xml_as_object *xml_obj;
+    //const char    *data;
+  
+    // log_msg("%s: nargs=%d\n", __FUNCTION__, fn.nargs);
+  
+    if (fn.nargs > 0) {
+        if (fn.env->top(0).get_type() == as_value::STRING) {
+            xml_obj = new xml_as_object;
+            //log_msg("\tCreated New XML object at %p\n", xml_obj);
+            tu_string datain = fn.env->top(0).to_tu_string();
+            xml_obj->obj.parseXML(datain);
+            //log_msg("*** Start setting up the stack frames ***\n");
+            xml_obj->obj.setupFrame(xml_obj, xml_obj->obj.firstChild(), true);
+            //xml_obj->obj.clear();
+            //delete xml_obj->obj.firstChild();
+        } else {
+            xml_as_object*     xml_obj = 
(xml_as_object*)fn.env->top(0).to_object();
+            //log_msg("\tCloned the XML object at %p\n", xml_obj);
+            //result->set(xml_obj);
+            fn.result->set_as_object(xml_obj);
+            return;
+        }
+    } else {
+        xml_obj = new xml_as_object;
+        //log_msg("\tCreated New XML object at %p\n", xml_obj);
+       // FIXME: this doesn't appear to exist in the MM player, should it ?
+       xml_obj->set_member("loaded", &xml_loaded);
+       
+        xml_obj->set_member("addRequestHeader", &xml_addrequestheader);
+        xml_obj->set_member("appendChild", &xml_appendchild);
+        xml_obj->set_member("cloneNode", &xml_clonenode);
+        xml_obj->set_member("createElement", &xml_createelement);
+        xml_obj->set_member("createTextNode", &xml_createtextnode);
+        xml_obj->set_member("getBytesLoaded", &xml_getbytesloaded);
+        xml_obj->set_member("getBytesTotal", &xml_getbytestotal);
+        xml_obj->set_member("hasChildNodes", &xml_haschildnodes);
+        xml_obj->set_member("insertBefore", &xml_insertbefore);
+        xml_obj->set_member("load", &xml_load);
+        xml_obj->set_member("parseXML", &xml_parsexml);
+        xml_obj->set_member("removeNode", &xml_removenode);
+        xml_obj->set_member("send", &xml_send);
+        xml_obj->set_member("sendAndLoad", &xml_sendandload);
+        xml_obj->set_member("toString", &xml_tostring);
+       // Properties
+        xml_obj->set_member("nodeName", as_value(""));
+        xml_obj->set_member("nodevalue", as_value(""));
+
+    }
+
+    fn.result->set_as_object(xml_obj);
+}
+
+//
+// SWF Property of this class. These are "accessors" into the private data
+// of the class.
+//
+
+// determines whether the document-loading process initiated by the XML.load()
+// call has completed. If the process completes successfully, the method
+// returns true; otherwise, it returns false.
+void
+xml_loaded(const fn_call& fn)
+{
+    as_value   method;
+    as_value   val;
+
+    log_msg("%s:\n", __FUNCTION__);
+    
+    xml_as_object*     ptr = (xml_as_object*) (as_object*) fn.this_ptr;
+    assert(ptr);
+    std::string filespec = 
fn.env->bottom(fn.first_arg_bottom_index).to_string();
+    //fn.result->set(ptr->obj.loaded());
+    fn.result->set_bool(ptr->obj.loaded());
+}
+
+
+void xml_addrequestheader(const fn_call& fn)
+{
+    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+//    ptr->obj.addRequestHeader();
+    log_msg("%s:unimplemented \n", __FUNCTION__);
+}
+void xml_appendchild(const fn_call& fn)
+{
+  //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    xmlnode_as_object *xml_obj = 
(xmlnode_as_object*)fn.env->top(0).to_object();
+    
+    ptr->obj.appendChild(&(xml_obj->obj));
+}
+
+void xml_clonenode(const fn_call& fn)
+{
+    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
+    xml_as_object      *ptr = (xml_as_object*)fn.this_ptr;
+    xmlnode_as_object   *xml_obj;
+    assert(ptr);
+
+    if (fn.nargs > 0) {
+      bool deep = fn.env->bottom(fn.first_arg_bottom_index).to_bool();
+      xml_obj = new xmlnode_as_object;
+      xml_obj->set_member("nodeName", as_value(""));
+      xml_obj->set_member("nodeValue", as_value(""));
+      xml_obj->set_member("appendChild", &xmlnode_appendchild);
+      ptr->obj.cloneNode(xml_obj->obj, deep);
+      fn.result->set_as_object(xml_obj);
+   } else {
+        log_msg("ERROR: no Depth paramater!\n");
+    }
+
+}
+void xml_createelement(const fn_call& fn)
+{
+  //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    xmlnode_as_object *xml_obj;
+    const char *text;
+
+    if (fn.nargs > 0) {
+        text = fn.env->bottom(fn.first_arg_bottom_index).to_string();
+       xml_obj = new xmlnode_as_object;
+       xml_obj->set_member("nodeName", as_value(text));
+       xml_obj->set_member("nodeValue", as_value(""));
+       xml_obj->set_member("appendChild", &xmlnode_appendchild);
+//     xml_obj->obj.nodeNameSet((char *)text);
+       xml_obj->obj._type = XML_ELEMENT_NODE; 
+       fn.result->set_as_object(xml_obj);
+   } else {
+        log_msg("ERROR: no text for element creation!\n");
+    }
+}
+
+
+void xml_createtextnode(const fn_call& fn)
+{
+  //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    xmlnode_as_object *xml_obj;
+    const char *text;
+
+    if (fn.nargs > 0) {
+        text = fn.env->bottom(fn.first_arg_bottom_index).to_string();
+       xml_obj = new xmlnode_as_object;
+       xml_obj->set_member("nodeName", as_value(""));
+       xml_obj->set_member("nodeValue", as_value(text));       
+       xml_obj->set_member("appendChild", &xmlnode_appendchild);
+//     xml_obj->obj.nodeValueSet((char *)text);
+       xml_obj->obj._type = XML_TEXT_NODE;
+       fn.result->set_as_object(xml_obj);
+//     log_msg("%s: xml obj is %p\n", __PRETTY_FUNCTION__, xml_obj);
+    } else {
+        log_msg("ERROR: no text for text node creation!\n");
+    }
+}
+
+void xml_getbytesloaded(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    fn.result->set_int(ptr->obj.getBytesLoaded());
+}
+
+void xml_getbytestotal(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    fn.result->set_int(ptr->obj.getBytesTotal());
+}
+
+void xml_haschildnodes(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    fn.result->set_bool(ptr->obj.hasChildNodes());
+}
+void xml_insertbefore(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+//    ptr->obj.insertBefore();
+    log_msg("%s:unimplemented \n", __FUNCTION__);
+}
+void xml_parsexml(const fn_call& fn)
+{
+    const char *text;
+    as_value   method;
+    as_value   val;    
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+
+    if (fn.nargs > 0) {
+        text = fn.env->bottom(fn.first_arg_bottom_index).to_string();
+       ptr->obj.parseXML(text);
+       ptr->obj.setupFrame(ptr, ptr->obj.firstChild(), false);  
+    }
+    
+#if 1
+    if (fn.this_ptr->get_member("onLoad", &method)) {
+        //    log_msg("FIXME: Found onLoad!\n");
+        fn.env->set_variable("success", true);
+        fn.env->bottom(fn.first_arg_bottom_index) = true;
+        as_c_function_ptr      func = method.to_c_function();
+        if (func) {
+           // It's a C function.  Call it.
+           log_msg("Calling C function for onLoad\n");
+           (*func)(fn_call(&val, ptr, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
+       } else if (as_function* as_func = method.to_as_function()) {
+           // It's an ActionScript function.  Call it.
+           log_msg("Calling ActionScript function for onLoad\n");
+           (*as_func)(fn_call(&val, ptr, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
+       } else {
+           log_error("error in call_method(): method is not a function\n");
+       }
+    } else {
+        log_msg("Couldn't find onLoad event handler, setting up callback\n");
+        // ptr->set_event_handler(event_id::XML_LOAD, 
(as_c_function_ptr)&xml_onload);
+    }
+#else
+    
+#endif
+//    fn.result->set_int(ptr->obj.getAllocated());
+}
+    
+void xml_removenode(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+    ptr->obj.removeNode();
+}
+void xml_send(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+    ptr->obj.send();
+}
+void xml_sendandload(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+    ptr->obj.sendAndLoad();
+}
+void xml_tostring(const fn_call& fn)
+{
+    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+    fn.result->set_string(ptr->obj.toString());
+}
+
+int
+memadjust(int x)
+{
+    return (x + (4 - x % 4));
+}
+
+
+} // end of gnash namespace
+
+// HAVE_LIBXML
+#endif
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/asobj/xml.h
===================================================================
RCS file: server/asobj/xml.h
diff -N server/asobj/xml.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xml.h  24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,266 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+//
+
+#ifndef __XML_H__
+#define __XML_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tu_config.h"
+
+#include "event_id.h"
+#include "action.h"
+
+//#define DEBUG_MEMORY_ALLOCATION 1
+#include <vector>
+
+#ifdef HAVE_LIBXML
+
+#include "xmlattrs.h"
+#include "xmlnode.h"
+
+#ifdef DEBUG_MEMORY_ALLOCATION
+       #include "log.h"
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xmlreader.h>
+
+// Forward declarations
+namespace gnash {
+       class fn_call;
+}
+
+namespace gnash {
+  
+/// XML class
+class DSOLOCAL XML {
+public:
+    XML();
+    XML(tu_string xml_in);
+    XML(struct node * childNode);
+    virtual ~XML();
+  
+    // 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);
+    // Loads a document (specified by
+    bool load(const char *filespec);
+    // the XML object) from a 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);
+    
+    virtual bool on_event(const gnash::event_id& id);
+    virtual void       on_event_load();
+    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);
+    //  Returns true if the specified node has child nodes; otherwise, returns 
false.
+  bool hasChildNodes() {
+    if (_nodes) {
+      if (_nodes->_children.size()) {
+        return true;
+      } 
+    }
+    return false;
+  }
+    
+    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(char *name);
+    void nodeValueSet(char *value);
+    int length()                 { return _nodes->length(); }
+  
+    // 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; };
+
+    virtual void       on_xml_event(const gnash::event_id& id)
+    {
+       on_event(id);
+    }
+  
+    // Special event handler; 
+    void       on_event_close()
+    {
+       on_event(gnash::event_id::SOCK_CLOSE);
+    }
+  
+    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;
+    
+    bool        _contentType;
+    bool        _attributes;
+    bool        _childNodes;
+    bool        _xmlDecl;
+    bool        _docTypeDecl;
+    bool        _ignoreWhite;
+    bool        _lastChild;
+    bool        _nextSibling;
+    bool        _nodeType;
+    bool        _nodeValue;
+    bool        _parentNode;
+    bool        _status;
+    bool        _previousSibling;
+
+};
+
+/// XML ActionScript object
+class DSOLOCAL xml_as_object : public gnash::as_object
+{
+public:
+    XML obj;
+#ifdef DEBUG_MEMORY_ALLOCATION
+    xml_as_object() {
+        log_msg("\tCreating xml_as_object at %p\n", this);
+    };
+    ~xml_as_object() {
+        log_msg("\tDeleting xml_as_object at %p\n", this);
+    };
+#endif
+
+    virtual bool get_member(const tu_stringi& name, as_value* val) {
+        //printf("GET XML MEMBER: %s at %p for object %p\n", name.c_str(), 
val, this);
+        
+        if ((name == "firstChild") || (name == "childNodes")) {
+//             printf("Returning a self reference for %s for object at %p\n",
+//                    name.c_str(), this);
+            val->set_as_object(this);
+            return true;
+        }
+
+       return get_member_default(name, val);
+        
+    }
+};
+
+
+DSOEXPORT void xml_load(const fn_call& fn);
+DSOEXPORT void xml_set_current(const fn_call& fn);
+DSOEXPORT void xml_new(const fn_call& fn);
+
+DSOEXPORT void xml_addrequestheader(const fn_call& fn);
+DSOEXPORT void xml_appendchild(const fn_call& fn);
+DSOEXPORT void xml_clonenode(const fn_call& fn);
+DSOEXPORT void xml_createelement(const fn_call& fn);
+DSOEXPORT void xml_createtextnode(const fn_call& fn);
+DSOEXPORT void xml_getbytesloaded(const fn_call& fn);
+DSOEXPORT void xml_getbytestotal(const fn_call& fn);
+DSOEXPORT void xml_haschildnodes(const fn_call& fn);
+DSOEXPORT void xml_insertbefore(const fn_call& fn);
+DSOEXPORT void xml_parsexml(const fn_call& fn);
+DSOEXPORT void xml_removenode(const fn_call& fn);
+DSOEXPORT void xml_send(const fn_call& fn);
+DSOEXPORT void xml_sendandload(const fn_call& fn);
+DSOEXPORT void xml_tostring(const fn_call& fn);
+
+// These are the event handlers called for this object
+DSOEXPORT void xml_onload(const fn_call& fn);
+DSOEXPORT void xml_ondata(const fn_call& fn);
+DSOEXPORT void xml_loaded(const fn_call& fn);
+
+// Properties
+DSOEXPORT void xml_nodename(const fn_call& fn);
+DSOEXPORT void xml_nodevalue(const fn_call& fn);
+
+
+DSOEXPORT int memadjust(int x);
+
+
+}      // end namespace gnash
+
+
+#endif // HAVE_LIBXML
+
+#endif // __XML_H__
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/asobj/xmlattrs.cpp
===================================================================
RCS file: server/asobj/xmlattrs.cpp
diff -N server/asobj/xmlattrs.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xmlattrs.cpp   24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,90 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+//
+
+/* $Id: xmlattrs.cpp,v 1.1 2006/11/24 09:19:50 strk Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <vector>
+
+#include "action.h"
+#include "impl.h"
+#include "tu_config.h"
+#include "as_function.h"
+
+#ifdef HAVE_LIBXML
+
+#include "xmlattrs.h"
+
+#ifdef DEBUG_MEMORY_ALLOCATION
+       #include "log.h"
+#endif
+
+#include <unistd.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlreader.h>
+
+using namespace std;
+
+namespace gnash {
+  
+//#define DEBUG_MEMORY_ALLOCATION 1
+  
+//std::vector<as_object *> _xmlobjs;    // FIXME: hack alert
+
+XMLAttr::XMLAttr()
+{
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("\t\tCreating XMLAttr data at %p \n", this);
+#endif
+    _name = 0;
+    _value = 0;
+}
+
+XMLAttr::~XMLAttr()
+{
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("\t\tDeleting XMLAttr data %s at %p \n", this->_name, this);
+#endif
+    //log_msg("%s: %p \n", __FUNCTION__, this);
+    if (_name) {
+        delete _name;
+    }
+    if (_value) {
+        delete _value;
+    }  
+}  
+
+} // end of gnash namespace
+
+// HAVE_LIBXML
+#endif
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/asobj/xmlattrs.h
===================================================================
RCS file: server/asobj/xmlattrs.h
diff -N server/asobj/xmlattrs.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xmlattrs.h     24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,102 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+//
+
+#ifndef __XML_ATTRS_H__
+#define __XML_ATTRS_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_LIBXML
+
+#include "tu_config.h"
+
+//#define DEBUG_MEMORY_ALLOCATION 1
+#include "as_object.h" // for inheritance
+
+#include "log.h"
+
+#include <vector>
+
+#ifdef DEBUG_MEMORY_ALLOCATION
+       #include "log.h"
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xmlreader.h>
+
+namespace gnash {
+  
+/// XML Attribute class
+class DSOLOCAL XMLAttr {
+public:
+    XMLAttr();
+    ~XMLAttr();
+  
+    // why don't we use std::strings here ?
+    // code would be much simpler and safer!
+    char                *_name;
+    char                *_value;
+    xmlAttributeType    _type;
+    
+    XMLAttr *operator = (XMLAttr node) {
+        log_msg("\t\tCopying XMLAttr object at %p\n", (void*)this);
+    
+        _name = new char[strlen(node._name)+2];
+        memset(_name, 0, strlen(node._name)+2);
+        strcpy(_name, node._name);
+
+        _value = new char[strlen(node._value)+2];
+        memset(_value, 0, strlen(node._value)+2);
+        strcpy(_value, node._value);
+
+        return this;
+    }
+};
+
+/// XML Attribute ActionScript Object
+class DSOLOCAL xmlattr_as_object : public as_object
+{
+public:
+    //XMLAttr obj;
+    int   padding;
+#ifdef DEBUG_MEMORY_ALLOCATION
+    xmlattr_as_object() {
+        log_msg("\t\tCreating xmlattr_as_object at %p\n", this);
+    };
+    ~xmlattr_as_object() {
+        log_msg("\tDeleting xmlattr_as_object at %p \n", this);
+    };
+#endif
+};
+ 
+} // end of gnash namespace
+
+#endif // HAVE_LIBXML
+
+#endif // __XML_ATTRS_H__
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/asobj/xmlnode.cpp
===================================================================
RCS file: server/asobj/xmlnode.cpp
diff -N server/asobj/xmlnode.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xmlnode.cpp    24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,449 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// 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.1 2006/11/24 09:19:50 strk Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <vector>
+#include "tu_config.h"
+#include "fn_call.h"
+
+#ifdef HAVE_LIBXML
+
+//#define DEBUG_MEMORY_ALLOCATION 1
+
+#include "xmlnode.h"
+
+#ifdef DEBUG_MEMORY_ALLOCATION
+       #include "log.h"
+#endif
+
+#include <unistd.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlreader.h>
+
+using namespace std;
+
+namespace gnash {
+    
+//std::vector<as_object *> _xmlobjs;    // FIXME: hack alert
+
+XMLNode::XMLNode() :_name(0), _value(0), _type(XML_ELEMENT_NODE)
+{
+    //log_msg("%s: %p \n", __PRETTY_FUNCTION__, this);
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("\tCreating XMLNode data at %p \n", this);
+#endif
+    _name = 0;
+    _value = 0;
+}
+
+XMLNode::~XMLNode()
+{
+    unsigned int i;
+    //log_msg("%s: %p \n", __PRETTY_FUNCTION__, this);
+#ifdef DEBUG_MEMORY_ALLOCATION
+    log_msg("\tDeleting XMLNode data %s at %p\n", this->_name, this);
+#endif
+  
+    for (i=0; i<_children.size(); i++) {
+     if (_children[i]->_name) {
+       delete [] _children[i]->_name;
+     }
+     if (_children[i]->_value) {
+       delete [] _children[i]->_value;
+     }
+    }
+
+    for (i=0; i<_attributes.size(); i++) {
+       if (_attributes[i]->_name) {
+           delete [] _attributes[i]->_name;
+       }
+       if (_attributes[i]->_value) {
+           delete [] _attributes[i]->_value;
+       }
+    }
+
+    _children.clear();
+    _attributes.clear();
+
+    if (_name) {
+        delete [] _name;
+    }
+    if (_value) {
+        delete [] _value;
+    }
+    //  _value.set_undefined();
+}
+
+void
+XMLNode::nodeNameSet(char *name)
+{
+  int len = strlen(name) + 1;
+ 
+  if (!_name) {
+    _name = (char *)new char[len];
+    memset(_name, 0, len);
+    strcpy(_name, reinterpret_cast<const char *>(name));
+  }
+}
+
+void
+XMLNode::nodeValueSet(char *value)
+{
+  int len = strlen(value) + 1;
+ 
+  if (!_value) {
+    _value = (char *)new char[len];
+    memset(_value, 0, len);
+    strcpy(_value, reinterpret_cast<const char *>(value));
+  }
+}
+
+/// \brief Get the type of an XML Node.
+///
+
+/// Read-only property; a nodeType value, either 1 for an XML element
+/// or 3 for a text node. The nodeType is a numeric value from the
+/// NodeType enumeration in the W3C DOM Level 1 recommendation:
+/// www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core.html.
+/// The following table lists the values.
+int
+XMLNode::nodeType() 
+{
+    switch (_type) {
+      case XML_TEXT_NODE:
+         return 3;
+         break;
+      case XML_ELEMENT_NODE:
+         return 1;
+         break;
+      default:
+         return 0;
+    }
+    // you should never get here
+    return -1;
+}
+
+const char *
+XMLNode::nodeName() 
+{
+  if (_name) {
+    return _name;
+  }
+  return "unknown";
+}
+
+const char *
+XMLNode::nodeValue() 
+{  
+  if (_value) {
+    return _value;
+  }
+  return "unknown";
+}
+
+/// \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.
+void
+XMLNode::appendChild(as_object *as, XMLNode *node)
+{
+//     log_msg("%s: %p, as is %d, node is %d\n",
+//         __PRETTY_FUNCTION__, this, _objects.size(), _children.size());
+
+    if (node) {
+       _children.push_back(node);
+    }
+
+    if (as) {
+       _objects.push_back(as);
+    }
+
+//    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)
+{
+    log_msg("%s: deep is %d\n", __PRETTY_FUNCTION__, deep);
+
+    if (deep) {
+//     newnode = _nodes;
+    } else {
+       newnode.nodeNameSet(_name);
+       newnode.nodeValueSet(_value);
+    }
+
+    return newnode;
+  
+    log_msg("%s: partially unimplemented \n", __PRETTY_FUNCTION__);
+}
+
+/// \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
+XMLNode::insertBefore(XMLNode */* newnode */, XMLNode */* node */)
+{
+    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
+}
+/// \brief removes the specified XML object from its parent. Also
+/// deletes all descendants of the node.
+void
+XMLNode::removeNode()
+{
+    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
+}
+const char *
+XMLNode::toString()
+{
+    XMLNode *node;
+    
+    vector<XMLNode *>::const_iterator it;
+    for (it = _children.begin(); it != _children.end(); it++) {
+       node = *it;
+//     log_msg("Got something\n");
+       if (node->_name) {
+           log_msg("Node name is %s", node->_name);
+       }
+       if (node->_value) {
+           log_msg("Node value is %s", node->_name);
+       }       
+    }
+    
+    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
+    return "Hello World!";
+}
+
+as_object *
+XMLNode::previousSibling(int x)
+{
+    log_msg("%s: partially implemented. " SIZET_FMT " objects\n",
+           __PRETTY_FUNCTION__,  _objects.size());
+    if (_objects.size() > 0) {
+       return _objects[x-1];
+    }
+
+    return NULL;
+}
+
+as_object *
+XMLNode::nextSibling(int x)
+{
+    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
+    if (x < (int) _objects.size()) {
+       return _objects[x];
+    }
+    return NULL;
+}
+
+void
+xmlnode_new(const fn_call& fn)
+{
+    xmlnode_as_object *xml_obj;
+    //const char    *data;
+  
+//    log_msg("%s\n", __PRETTY_FUNCTION__);
+  
+    xml_obj = new xmlnode_as_object;
+    // Methods
+    xml_obj->set_member("appendChild", &xmlnode_appendchild);
+    xml_obj->set_member("cloneNode", &xmlnode_clonenode);
+    xml_obj->set_member("hasChildNodes", &xmlnode_haschildnodes);
+    xml_obj->set_member("insertBefore", &xmlnode_insertbefore);
+    xml_obj->set_member("removeNode", &xmlnode_removenode);
+    xml_obj->set_member("toString", &xmlnode_tostring);
+
+    // Properties
+    xml_obj->set_member("nodeName",  as_value(""));
+    xml_obj->set_member("nodeValue", as_value(""));
+    xml_obj->set_member("nodeType", as_value(""));
+
+    // FIXME: these need real values
+    // These two return an array of objects
+    xml_obj->set_member("attributes", as_value(""));
+    xml_obj->set_member("childNodes", as_value(""));
+
+    //These return a reference to an object
+
+    /// \fn MLNode::firstChild
+    /// \brief XMLNode::firstChild property
+    ///
+    /// Read-only property; evaluates the specified XML object and
+    /// references the first child in the parent node\ufffds child
+    /// list. This property is null if the node does not have
+    /// children. This property is undefined if the node is a text
+    /// node. This is a read-only property and cannot be used to
+    /// manipulate child nodes; use the appendChild(), insertBefore(),
+    /// and removeNode() methods to manipulate child nodes. 
+
+    xml_obj->set_member("firstChild", as_value(""));
+    /// \fn MLNode::lastChild
+    /// \brief XMLNode::lastChild property 
+    ///
+    /// Read-only property; an XMLNode value that references the last
+    /// child in the node's child list. The XML.lastChild property
+    /// is null if the node does not have children. This property cannot
+    /// be used to manipulate child nodes; use the appendChild(),
+    /// insertBefore(), and removeNode() methods to manipulate child
+    /// nodes.
+    xml_obj->set_member("lastChild",   as_value(""));
+    xml_obj->set_member("nextSibling", as_value(""));
+    xml_obj->set_member("parentNode",  as_value(""));
+    xml_obj->set_member("previousSibling", as_value(""));
+
+    fn.result->set_as_object(xml_obj);
+}
+
+void xmlnode_appendchild(const fn_call& fn)
+{
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+//    log_msg("%s: %p, %d args\n", __PRETTY_FUNCTION__, ptr, fn.nargs);
+    
+    xmlnode_as_object *xml_obj = 
(xmlnode_as_object*)fn.env->bottom(fn.first_arg_bottom_index).to_object();
+    
+//    log_msg("%s: %p \n", __PRETTY_FUNCTION__, xml_obj);
+    XMLNode *node = &(xml_obj->obj);
+    if (ptr->obj.hasChildNodes() == false) {
+       ptr->set_member("firstChild", xml_obj);
+    }
+    int length = ptr->obj.length();
+    if (length > 0) {
+       as_object *ass = xml_obj->obj.previousSibling(length);
+// FIXME: This shouldn't always be NULL
+//     log_msg("%s: ASS is %p, length is %d\n", __PRETTY_FUNCTION__,
+//             ass, length);
+       ptr->set_member("previousSibling", ass);
+//     ptr->set_member("nextSibling", 
xml_obj->obj.nextSibling(ptr->obj.length()));
+    }
+    ptr->obj.appendChild((as_object *)xml_obj, node);
+    // The last child in the list is always the one we just appended
+    ptr->set_member("lastChild", xml_obj);
+   
+//    ptr->obj.appendChild(&(xml_obj->obj));
+//    ptr->obj.nodeValueSet((char *)xmlnode_obj->obj.nodeValue());
+}
+
+void xmlnode_clonenode(const fn_call& fn)
+{
+    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
+    xmlnode_as_object  *ptr = (xmlnode_as_object*)fn.this_ptr;
+    xmlnode_as_object   *xmlnode_obj;
+    assert(ptr);
+
+    if (fn.nargs > 0) {
+      bool deep = fn.env->bottom(fn.first_arg_bottom_index).to_bool();
+      xmlnode_obj = new xmlnode_as_object;
+      ptr->obj.cloneNode(xmlnode_obj->obj, deep);
+      fn.result->set_as_object(xmlnode_obj);
+   } else {
+        log_msg("ERROR: no Depth paramater!\n");
+    }
+
+}
+
+void xmlnode_insertbefore(const fn_call& fn)
+{
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+//    ptr->obj.insertBefore();
+    log_msg("%s:unimplemented \n", __PRETTY_FUNCTION__);
+}
+void xmlnode_removenode(const fn_call& fn)
+{
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+//    fn.result->set_int(ptr->obj.getAllocated());
+    ptr->obj.removeNode();
+}
+void xmlnode_tostring(const fn_call& fn)
+{
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+    fn.result->set_string(ptr->obj.toString());
+}
+
+void xmlnode_haschildnodes(const fn_call& fn)
+{
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+    fn.result->set_bool(ptr->obj.hasChildNodes());
+}
+
+#ifdef ENABLE_TESTING
+void xmlnode_nodevalue(const fn_call& fn)
+{
+    log_msg("%s: \n", __PRETTY_FUNCTION__);
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+    fn.result->set_string(ptr->obj.nodeValue());
+}
+void xmlnode_nodename(const fn_call& fn)
+{
+    log_msg("%s: \n", __PRETTY_FUNCTION__);
+    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
+    assert(ptr);
+    
+    fn.result->set_string(ptr->obj.nodeName());
+}
+#endif
+
+} // end of gnash namespace
+
+// HAVE_LIBXML
+#endif
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/asobj/xmlnode.h
===================================================================
RCS file: server/asobj/xmlnode.h
diff -N server/asobj/xmlnode.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xmlnode.h      24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,167 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+//
+
+#ifndef __XML_NODE_H__
+#define __XML_NODE_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tu_config.h"
+
+//#define DEBUG_MEMORY_ALLOCATION 1
+#include <vector>
+#include "action.h"
+#include "impl.h"
+
+#ifdef HAVE_LIBXML
+
+#include "xmlattrs.h"
+
+#ifdef DEBUG_MEMORY_ALLOCATION
+       #include "log.h"
+#endif
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xmlreader.h>
+
+namespace gnash {  
+ 
+/// XML Node 
+class DSOLOCAL XMLNode
+{
+public:
+    XMLNode();
+    ~XMLNode();
+    
+    int length()                 { return _children.size(); }
+    const char *nodeName();
+    const char *nodeValue();
+    int nodeType();
+
+    //    char *valueGet();
+  
+    void nodeNameSet(char *name);
+    void nodeValueSet(char *value);
+    //  nodeType       XML.nodeType
+
+    bool hasChildNodes() {
+      if (_children.size()) {
+        return true;
+      }
+      return false;
+    }
+  
+    XMLNode *firstChild()              { return _children[0]; }
+  
+    std::vector<XMLNode *>childNodes()  { return _children; }  
+    
+    XMLNode *operator [] (int x) {
+        gnash::log_msg("%s: get element %d\n", __PRETTY_FUNCTION__, x);
+        
+        return _children[x];
+    }
+    
+    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) {
+        gnash::log_msg("%s: \n", __PRETTY_FUNCTION__);
+        _name = node->_name;
+        _value = node->_value;
+       _children = node->_children;
+        _attributes = node->_attributes;
+        return this;
+    }
+
+    as_object *previousSibling(int x);
+    as_object *nextSibling(int x);
+    XMLNode &cloneNode(XMLNode &newnode, bool deep);
+    void appendChild(as_object *as,XMLNode *node);
+    void insertBefore(XMLNode *newnode, XMLNode *node);
+    void removeNode();
+    const char *toString();
+
+    void  change_stack_frame(int frame, gnash::as_object *xml, 
gnash::as_environment *env);
+
+
+    // why don't we use std::strings here ?
+    // code would be much simpler and safer!
+    char                *_name;
+    char                *_value;
+
+    xmlElementType      _type;
+    std::vector<as_object *>  _objects;
+    std::vector<XMLNode *>    _children;
+    std::vector<XMLAttr *>    _attributes;
+};
+
+/// XML Node ActionScript object
+class DSOLOCAL xmlnode_as_object : public gnash::as_object
+{
+public:
+    XMLNode            obj;
+//    int                      _padding;
+    
+#ifdef DEBUG_MEMORY_ALLOCATION
+    xmlnode_as_object() {
+       //      obj  = new XMLNode;
+        log_msg("\tCreating xmlnode_as_object at %p \n", this);
+    };
+    ~xmlnode_as_object() {
+        log_msg("\tDeleting xmlnode_as_object at %p \n", this);
+    };
+#endif
+};
+
+DSOEXPORT void xmlnode_new(const fn_call& fn);
+
+DSOEXPORT void xmlnode_haschildren(const fn_call& fn);
+DSOEXPORT void xmlnode_nodename(const fn_call& fn);
+DSOEXPORT void xmlnode_nodevalue(const fn_call& fn);
+DSOEXPORT void xmlnode_nodetype(const fn_call& fn);
+
+DSOEXPORT void xmlnode_appendchild(const fn_call& fn);
+DSOEXPORT void xmlnode_clonenode(const fn_call& fn);
+DSOEXPORT void xmlnode_haschildnodes(const fn_call& fn);
+DSOEXPORT void xmlnode_insertbefore(const fn_call& fn);
+DSOEXPORT void xmlnode_removenode(const fn_call& fn);
+DSOEXPORT void xmlnode_tostring(const fn_call& fn);
+
+} // end of gnash namespace
+
+
+#endif // HAVE_LIBXML
+
+#endif // __XMLNODE_NODE_H__
+
+
+// Local Variables:
+// mode: C++
+// indent-tabs-mode: t
+// End:

Index: server/asobj/xmlsocket.cpp
===================================================================
RCS file: server/asobj/xmlsocket.cpp
diff -N server/asobj/xmlsocket.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xmlsocket.cpp  24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,811 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "utility.h"
+#include "xml.h"
+#include "xmlsocket.h"
+#include "timers.h"
+#include "as_function.h"
+#include "fn_call.h"
+#include "sprite_instance.h"
+
+#ifdef HAVE_LIBXML
+
+#include "log.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#ifdef HAVE_WINSOCK
+# include <WinSock2.h>
+# include <windows.h>
+# include <sys/stat.h>
+# include <io.h>
+#else
+# include <sys/time.h>
+# include <unistd.h>
+# include <sys/select.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <cerrno>
+# include <sys/param.h>
+# include <sys/select.h>
+#endif
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+int xml_fd = 0;                 // FIXME: This file descriptor is used by
+                                // XML::checkSocket() when called from the main
+                                // processing loop. 
+
+namespace gnash {
+const int SOCKET_DATA = 1;
+  
+const int INBUF = 10000;
+  
+XMLSocket::XMLSocket() {
+  //log_msg("%s: \n", __FUNCTION__);
+  _data = false;
+  _xmldata = false;
+  _closed = false;
+  _connect = false;
+  _processing = false;
+  _port = 0;
+  _sockfd = 0;
+  xml_fd = 0;
+}
+
+XMLSocket::~XMLSocket()
+{
+  //log_msg("%s: \n", __FUNCTION__);
+}
+
+bool
+XMLSocket::connect(const char *host, int port)
+{
+  struct sockaddr_in  sock_in;
+  fd_set              fdset;
+  struct timeval      tval;
+  int                 ret;
+  int                 retries;
+  char                thishostname[MAXHOSTNAMELEN];
+  struct protoent     *proto;
+
+  if (port < 1024) {
+    log_error("Can't connect to priviledged port #%d!\n", port);
+    _connect = false;
+    return false;
+  }
+
+  log_msg("%s: to host %s at port %d\n", __FUNCTION__, host, port);
+  
+  memset(&sock_in, 0, sizeof(struct sockaddr_in));
+  memset(&thishostname, 0, MAXHOSTNAMELEN);
+  if (strlen(host) == 0) {
+    if (gethostname(thishostname, MAXHOSTNAMELEN) == 0) {
+      log_msg("The hostname for this machine is %s.\n", thishostname);
+    } else {
+      log_msg("Couldn't get the hostname for this machine!\n");
+      return false;
+    }   
+  }
+  const struct hostent *hent = ::gethostbyname(host);
+  if (hent > 0) {
+    ::memcpy(&sock_in.sin_addr, hent->h_addr, hent->h_length);
+  }
+  sock_in.sin_family = AF_INET;
+  sock_in.sin_port = ntohs(static_cast<short>(port));
+
+#if 0
+    char ascip[32];
+    inet_ntop(AF_INET, &sock_in.sin_addr.s_addr, ascip, INET_ADDRSTRLEN);
+      log_msg("The IP address for this client socket is %s\n", ascip);
+#endif
+
+  proto = ::getprotobyname("TCP");
+
+  _sockfd = ::socket(PF_INET, SOCK_STREAM, proto->p_proto);
+  if (_sockfd < 0)
+    {
+      log_error("unable to create socket : %s\n", strerror(errno));
+      _sockfd = -1;
+      return false;
+    }
+
+  retries = 2;
+  while (retries-- > 0) {
+    // We use select to wait for the read file descriptor to be
+    // active, which means there is a client waiting to connect.
+    FD_ZERO(&fdset);
+    FD_SET(_sockfd, &fdset);
+    
+    // Reset the timeout value, since select modifies it on return. To
+    // block, set the timeout to zero.
+    tval.tv_sec = 5;
+    tval.tv_usec = 0;
+    
+    ret = ::select(_sockfd+1, &fdset, NULL, NULL, &tval);
+
+    // If interupted by a system call, try again
+    if (ret == -1 && errno == EINTR)
+      {
+        log_msg("The connect() socket for fd #%d was interupted by a system 
call!\n",
+                _sockfd);
+        continue;
+      }
+    
+    if (ret == -1)
+      {
+        log_msg("The connect() socket for fd #%d never was available for 
writing!\n",
+                _sockfd);
+#ifdef HAVE_WINSOCK
+        ::shutdown(_sockfd, SHUT_BOTH);
+#else
+        ::shutdown(_sockfd, SHUT_RDWR);
+#endif
+        _sockfd = -1;      
+        return false;
+      }
+    if (ret == 0) {
+      log_error("The connect() socket for fd #%d timed out waiting to 
write!\n",
+                _sockfd);
+      continue;
+    }
+
+    if (ret > 0) {
+      ret = ::connect(_sockfd, reinterpret_cast<struct sockaddr *>(&sock_in), 
sizeof(sock_in));
+      if (ret == 0) {
+        log_msg("\tport %d at IP %s for fd #%d\n", port,
+                ::inet_ntoa(sock_in.sin_addr), _sockfd);
+        _connect = true;
+        xml_fd = _sockfd;               // FIXME: This file descriptor is used 
by
+                                        // XML::checkSocket() when called from
+                                        // the main processing loop.
+        return true;
+      }
+      if (ret == -1) {
+        log_msg("The connect() socket for fd #%d never was available for 
writing!\n",
+                _sockfd);
+        _sockfd = -1;      
+        return false;
+      }
+    }
+  }
+  //  ::close(_sockfd);
+  //  return false;
+
+  printf("\tConnected at port %d on IP %s for fd #%d\n", port,
+          ::inet_ntoa(sock_in.sin_addr), _sockfd);
+  
+#ifndef HAVE_WINSOCK
+  fcntl(_sockfd, F_SETFL, O_NONBLOCK);
+#endif
+
+  _connect = true;
+  return true;
+}
+
+void
+XMLSocket::close()
+{
+  log_msg("%s: \n", __FUNCTION__);
+  // Since the return code from close() doesn't get used by Shockwave,
+  // we don't care either.
+  if (_sockfd > 0) {
+    ::close(_sockfd);
+  }
+}
+
+// Return true if there is data in the socket, otherwise return false.
+bool
+XMLSocket::anydata(char **msgs)
+{
+  //printf("%s: \n", __FUNCTION__);
+  return anydata(_sockfd, msgs);
+}
+
+bool XMLSocket::processingData()
+{
+  //printf("%s: processing flags is is %d\n", __FUNCTION__, _processing);
+  return _processing;
+}
+
+void XMLSocket::processing(bool x)
+{
+  //printf("%s: set processing flag to %d\n", __FUNCTION__, x);
+  _processing = x;
+}
+
+bool
+XMLSocket::anydata(int fd, char **msgs)
+{
+  fd_set                fdset;
+  struct timeval        tval;
+  int                   ret = 0;
+  char                  buf[INBUF];
+  char                  *packet;
+  int                   retries = 10;
+  char                  *ptr, *eom;
+  int                   cr, index = 0;
+  static char           *leftover = 0;
+  int                   adjusted_size;
+
+  //log_msg("%s: \n", __FUNCTION__);
+
+  if (fd <= 0) {
+    return false;
+  }
+
+  //msgs = (char **)realloc(msgs, sizeof(char *));
+
+  while (retries-- > 0) {
+    FD_ZERO(&fdset);
+    FD_SET(fd, &fdset);
+    
+    tval.tv_sec = 0;
+    tval.tv_usec = 103;
+    
+    ret = ::select(fd+1, &fdset, NULL, NULL, &tval);
+
+    // If interupted by a system call, try again
+    if (ret == -1 && errno == EINTR) {
+      log_msg("The socket for fd #%d was interupted by a system call!\n",
+              fd);
+      continue;
+    }
+    if (ret == -1) {
+      log_error("The socket for fd #%d never was available!\n", fd);
+      return false;
+    }
+    if (ret == 0) {
+      //log_msg("There is no data in the socket for fd #%d!\n", fd);
+      return false;
+    }
+    if (ret > 0) {
+      //log_msg("There is data in the socket for fd #%d!\n", fd);        
+      //break;
+    }
+    memset(buf, 0, INBUF);
+    ret = ::read(_sockfd, buf, INBUF-2);
+    cr = strlen(buf);
+    //log_msg("%s: read %d bytes, first msg terminates at %d\n", __FUNCTION__, 
ret, cr);
+    //log_msg("%s: read (%d,%d) %s\n", __FUNCTION__, buf[0], buf[1], buf);
+    ptr = buf;
+    // If we get a single XML message, do less work
+    if (ret == cr + 1) {
+      adjusted_size = memadjust(ret + 1);
+      packet = new char[adjusted_size];
+      //printf("Packet size is %d at %p\n", ret + 1, packet);
+      memset(packet, 0, adjusted_size);
+      strcpy(packet, ptr);
+      eom = strrchr(packet, '\n'); // drop the CR off the end if there is one
+      if (eom) {
+        *eom = 0;
+      }
+      //data.push_back(packet);
+      msgs[index] = packet;
+      msgs[index+1] = 0;
+      //printf("%d: Pushing Packet of size %d at %p\n", __LINE__, 
strlen(packet), packet);
+      processing(false);
+      return true;
+    }
+
+    // If we get multiple messages in a single transmission, break the buffer
+    // into separate messages.
+    while (strchr(ptr, '\n') > 0) {
+      if (leftover) {
+        processing(false);
+        //printf("%s: The remainder is: \"%s\"\n", __FUNCTION__, leftover);
+        //printf("%s: The rest of the message is: \"%s\"\n", __FUNCTION__, 
ptr);
+        adjusted_size = memadjust(cr + strlen(leftover) + 1);
+        packet = new char[adjusted_size];
+        memset(packet, 0, adjusted_size);
+        strcpy(packet, leftover);
+        strcat(packet, ptr);
+        eom = strrchr(packet, '\n'); // drop the CR off the end there is one
+        if (eom) {
+          *eom = 0;
+        }
+        //printf("%s: The whole message is: \"%s\"\n", __FUNCTION__, packet);
+        ptr = strchr(ptr, '\n') + 2; // messages are delimited by a "\n\0"
+        delete leftover;
+        leftover = 0;
+      } else {
+        adjusted_size = memadjust(cr + 1);
+        packet = new char[adjusted_size];
+        memset(packet, 0, adjusted_size);
+        strcpy(packet, ptr);
+        ptr += cr + 1;
+      } // end of if remainder
+      if (*packet == '<') {
+        //printf("%d: Pushing Packet #%d of size %d at %p: %s\n", __LINE__,
+        //       data.size(), strlen(packet), packet, packet);
+        eom = strrchr(packet, '\n'); // drop the CR off the end there is one
+        if (eom) {
+          *eom = 0;
+        }
+        //printf("Allocating new packet at %p\n", packet);
+        //data.push_back(packet);
+        msgs[index++] = packet;
+      } else {
+        log_error("Throwing out partial packet %s\n", packet);
+      }
+      
+      //log_msg("%d messages in array now\n", data.size());
+      cr = strlen(ptr);
+    } // end of while (cr)
+    
+    if (strlen(ptr) > 0) {
+      leftover = new char[strlen(ptr) + 1];
+      strcpy(leftover, ptr);
+      processing(true);
+      //printf("%s: Adding remainder: \"%s\"\n", __FUNCTION__, leftover);
+    }
+    
+    processing(false);
+    printf("Returning %d messages\n", index);
+    return true;
+    
+  } // end of while (retires)
+
+  return true;
+}
+
+bool
+XMLSocket::send(std::string str)
+{
+  //GNASH_REPORT_FUNCTION;
+  
+  str += '\0';
+  int ret = write(_sockfd, str.c_str(), str.size());
+
+  //log_msg("%s: sent %d bytes, data was %s\n", __FUNCTION__, ret, 
str.c_str());
+  if (ret == static_cast<signed int>(str.size())) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+// Callbacks
+
+void
+XMLSocket::onClose(std::string /* str */)
+{
+  log_msg("%s: \n", __FUNCTION__);
+}
+
+void
+XMLSocket::onConnect(std::string /* str */)
+{
+  log_msg("%s: \n", __FUNCTION__);
+}
+
+void
+XMLSocket::onData(std::string /* str */)
+{
+  log_msg("%s: \n", __FUNCTION__);
+}
+
+void
+XMLSocket::onXML(std::string /* str */)
+{
+  log_msg("%s: \n", __FUNCTION__);
+}
+
+void
+XMLSocket::push(as_object *obj)
+{
+  _nodes.push_back(obj);
+}
+
+void
+XMLSocket::clear()
+{
+  unsigned int i;
+  for (i=0; i< _nodes.size(); i++) {
+    delete _nodes[i];
+  }
+}
+
+int
+XMLSocket::count()
+{
+  return _nodes.size();
+}
+
+int
+XMLSocket::checkSockets(void)
+{
+  return checkSockets(_sockfd);
+}
+
+int
+XMLSocket::checkSockets(int fd)
+{
+  fd_set                fdset;
+  int                   ret = 0;
+  struct timeval        tval;
+
+  //log_msg("%s:\n", __FUNCTION__);
+
+  FD_ZERO(&fdset);
+  FD_SET(fd, &fdset);
+  
+  tval.tv_sec = 2;
+  tval.tv_usec = 10;
+  
+  ret = ::select(fd+1, &fdset, NULL, NULL, &tval); // &tval
+  
+  // If interupted by a system call, try again
+  if (ret == -1 && errno == EINTR) {
+    log_msg("The socket for fd #%d was interupted by a system call in this 
thread!\n",
+            fd);
+  }
+  if (ret == -1) {
+    log_error("The socket for fd #%d never was available!\n", fd);
+  }
+  if (ret == 0) {
+    printf("There is no data in the socket for fd #%d!\n", fd);
+  }
+  if (ret > 0) {
+    //printf("There is data in the socket for fd #%d!\n", fd);        
+  }
+  
+  return ret;
+}
+
+void
+xmlsocket_connect(const fn_call& fn)
+{
+  as_value     method;
+  as_value     val;
+  static bool first = true;     // This event handler should only be executed 
once.
+
+  if (!first) {
+    fn.result->set_bool(true);
+    return;
+  }
+  
+  log_msg("%s: nargs=%d\n", __FUNCTION__, fn.nargs);
+  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
+  assert(ptr);
+  const std::string host = 
fn.env->bottom(fn.first_arg_bottom_index).to_string();
+  std::string port_str = 
fn.env->bottom(fn.first_arg_bottom_index-1).to_string();
+  double port = atof(port_str.c_str());
+
+  ptr->obj.connect(host.c_str(), static_cast<int>(port));
+
+#if 0 // use connect return as result
+  // Push result onto stack for onConnect
+  if (ret) {
+    fn.env->push(as_value(true));
+  }
+  else {
+    fn.env->push(as_value(false));
+  }
+#endif
+  fn.env->push(as_value(true));
+  if (fn.this_ptr->get_member("onConnect", &method)) {
+    //    log_msg("FIXME: Found onConnect!\n");
+    as_c_function_ptr  func = method.to_c_function();
+    first = false;
+    //env->set_variable("success", true, 0);
+
+    if (func) {
+      // It's a C function.  Call it.
+      log_msg("Calling C function for onConnect\n");
+      (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+    }
+    else if (as_function* as_func = method.to_as_function()) {
+      // It's an ActionScript function.  Call it.
+      log_msg("Calling ActionScript function for onConnect\n");
+      (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 2, 2));
+    } else {
+      log_error("error in call_method(): method is not a function\n");
+    }    
+  } else {
+    //ptr->set_event_handler(event_id::SOCK_CONNECT, 
(as_c_function_ptr)&xmlsocket_event_connect);
+  }
+
+#if 1
+  sprite_instance* mov = fn.env->get_target()->get_root_movie();
+  Timer *timer = new Timer;
+  as_c_function_ptr ondata_handler =
+    (as_c_function_ptr)&xmlsocket_event_ondata;
+  timer->setInterval(ondata_handler, 50, ptr, fn.env);
+  timer->setObject(ptr);
+  mov->add_interval_timer(timer);
+#endif
+
+  fn.env->pop();
+  
+  fn.result->set_bool(true);
+}
+
+
+void
+xmlsocket_send(const fn_call& fn)
+{
+  as_value     method;
+  as_value     val;
+  
+  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
+  assert(ptr);
+  const std::string object = fn.env->bottom( 
fn.first_arg_bottom_index).to_string();
+  //  log_msg("%s: host=%s, port=%g\n", __FUNCTION__, host, port);
+  fn.result->set_bool(ptr->obj.send(object));
+}
+
+void
+xmlsocket_close(const fn_call& fn)
+{
+  as_value     method;
+  as_value     val;
+  
+  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
+  assert(ptr);
+  // Since the return code from close() doesn't get used by Shockwave,
+  // we don't care either.
+  ptr->obj.close();
+}
+
+void
+xmlsocket_xml_new(const fn_call& fn)
+{
+  //log_msg("%s: nargs=%d\n", __FUNCTION__, nargs);
+  
+  xml_new(fn);
+}
+
+void
+xmlsocket_new(const fn_call& fn)
+{
+  //log_msg("%s: nargs=%d\n", __FUNCTION__, nargs);
+  
+  as_object*   xmlsock_obj = new xmlsocket_as_object;
+  //log_msg("\tCreated New XMLSocket object at 0x%X\n", (unsigned 
int)xmlsock_obj);
+  xmlsock_obj->set_member("connect", &xmlsocket_connect);
+  xmlsock_obj->set_member("send", &xmlsocket_send);
+  xmlsock_obj->set_member("close", &xmlsocket_close);
+  xmlsock_obj->set_member("Connected", true);
+  // swf_event*        ev = new swf_event;
+  // m_event_handlers.push_back(ev);
+  // Setup event handlers
+#if 0
+  xmlsock_obj->set_event_handler(event_id::SOCK_DATA,
+                                 (as_c_function_ptr)&xmlsocket_event_ondata);
+  xmlsock_obj->set_event_handler(event_id::SOCK_CLOSE,
+                                 (as_c_function_ptr)&xmlsocket_event_close);
+  //                                                   
xmlsock_obj->set_event_handler(event_id::SOCK_CONNECT,
+  //                                                                          
(as_c_function_ptr)&xmlsocket_event_connect);
+  xmlsock_obj->set_event_handler(event_id::SOCK_XML,
+                                 (as_c_function_ptr)&xmlsocket_event_xml);
+#endif
+  //periodic_events.set_event_handler(xmlsock_obj);
+  
+  
+#if 1
+  //as_c_function_ptr int_handler = (as_c_function_ptr)&timer_setinterval;
+  //env->set_member("setInterval", int_handler);
+  fn.env->set_member("setInterval", timer_setinterval);
+  
+  //as_c_function_ptr clr_handler = timer_clearinterval;
+  fn.env->set_member("clearInterval", timer_clearinterval);
+  //env->set_variable("setInterval", int_handler, 0);
+  //xmlsock_obj->set_event_handler(event_id::TIMER,
+  //       (as_c_function_ptr)&timer_expire);
+#if 0
+  Timer *timer = new Timer;
+  as_c_function_ptr ondata_handler =
+    (as_c_function_ptr)&xmlsocket_event_ondata;
+  timer->setInterval(ondata_handler, 10);
+  timer->setObject(xmlsock_obj);
+  current_movie->add_interval_timer(timer);
+#endif
+  
+  fn.result->set_bool(xmlsock_obj);
+
+  // Tune malloc for the best performance
+  //mallopt(M_MMAP_MAX,0);
+  //mallopt(M_TRIM_THRESHOLD,-1);
+  //mallopt(M_MMAP_THRESHOLD,16);
+
+#endif
+}
+
+
+void
+xmlsocket_event_ondata(const fn_call& fn)
+{
+  //log_msg("%s: nargs is %d\n", __FUNCTION__, nargs);
+    
+  as_value     method;
+  as_value     val;
+  as_value      datain;
+  std::vector<const char *> msgs;
+  char          *messages[200];
+  int           i;
+  as_c_function_ptr    func;
+  as_function*       as_func;
+
+  xmlsocket_as_object* ptr = (xmlsocket_as_object*)fn.this_ptr;
+  assert(ptr);
+  if (ptr->obj.processingData()) {
+    log_msg("Still processing data!\n");
+    fn.result->set_bool(false);
+    return;
+  }
+  
+  memset(messages, 0, sizeof(char *)*200);
+  
+#ifndef USE_DMALLOC
+  //dump_memory_stats(__FUNCTION__, __LINE__, "memory checkpoint");
+#endif
+  
+  if (ptr->obj.anydata(messages)) {
+    if (fn.this_ptr->get_member("onData", &method)) {
+      func = method.to_c_function();
+      as_func = method.to_as_function();
+      //log_msg("Got %d messages from XMLsocket\n", msgs.size());
+      //      for (i=0; i<msgs.size(); i++) {
+      for (i=0; messages[i] != 0; i++) {
+//          log_msg("Got message #%d, %d bytes long at %p: %s: \n", i,
+//                  strlen(messages[i]), messages[i], messages[i]);
+        datain = messages[i];
+        //fn.env->push(datain);
+#ifndef USE_DMALLOC
+        //dump_memory_stats(__FUNCTION__, __LINE__, "start");
+#endif
+        as_environment *env = new as_environment;
+        env->push(datain);
+        if (func) {
+          // It's a C function.  Call it.
+          //log_msg("Calling C function for onData\n");
+          (*func)(fn_call(&val, fn.this_ptr, env, 1, 0));
+        } else if (as_func) {
+          // It's an ActionScript function.  Call it.
+          //log_msg("Calling ActionScript function for onData, processing msg 
%d\n", i);
+          (*as_func)(fn_call(&val, fn.this_ptr, env, 1, 0));
+        } else {
+          log_error("error in call_method(): method is not a function\n");
+        }
+        env->pop();
+        delete env;
+#ifndef USE_DMALLOC
+        //dump_memory_stats(__FUNCTION__, __LINE__, "end");
+#endif  
+        //log_msg("Deleting message #%d at %p\n", i, messages[i]);
+        //delete messages[i];
+        //fn.env->pop();
+        datain.set_undefined();
+      }
+      ptr->obj.processing(false);
+    } else {
+      log_error("Couldn't find onData!\n");
+    }
+    // Delete this in a batch for now so we can track memory allocation
+    for (i=0; messages[i] != 0; i++) {
+      //log_msg("Deleting message #%d at %p\n", i, messages[i]);
+      delete messages[i];
+    }
+  }
+
+  //malloc_trim(0);
+  
+  //result->set(&data);
+  fn.result->set_bool(true);
+}
+
+void
+xmlsocket_event_close(const fn_call& /* fn */)
+{
+#if 0
+  as_value* result = fn.result;
+  as_object* this_ptr = fn.this_ptr;
+  int nargs = fn.nargs;
+  int first_arg = fn.first_arg_bottom_index;
+#else
+  log_error("%s: unimplemented!\n", __FUNCTION__);
+#endif
+}
+
+void
+xmlsocket_event_connect(const fn_call& fn)
+{
+  as_value     method;
+  as_value     val;
+  static bool first = true;     // This event handler should only be executed 
once.
+
+  if (!first) {
+    fn.result->set_bool(true);
+    return;
+  }
+  
+  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
+  assert(ptr);
+
+  log_msg("%s: connected = %d\n", __FUNCTION__, ptr->obj.connected());
+  if ((ptr->obj.connected()) && (first)) {
+    first = false;
+    //env->set_variable("success", true, 0);
+    //env->bottom(0) = true;
+
+    if (fn.this_ptr->get_member("onConnect", &method)) {
+      as_c_function_ptr        func = method.to_c_function();
+      if (func)
+        {
+          // It's a C function.  Call it.
+          //log_msg("Calling C function for onConnect\n");
+          (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+      }
+      else if (as_function* as_func = method.to_as_function())
+        {
+          // It's an ActionScript function.  Call it.
+          //log_msg("Calling ActionScript function for onConnect\n");
+          (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
+        }
+      else
+        {
+          log_error("error in call_method(): method is not a function\n");
+        }    
+    } else {
+      log_msg("FIXME: Couldn't find onConnect!\n");
+    }
+  }
+
+  fn.result->set_bool(val.to_bool()); 
+}
+void
+xmlsocket_event_xml(const fn_call& /* fn */)
+{
+#if 0
+  as_value* result = fn.result;
+  as_object* this_ptr = fn.this_ptr;
+  int nargs = fn.nargs;
+  int first_arg = fn.first_arg_bottom_index;
+#else
+  log_error("%s: unimplemented!\n", __FUNCTION__);
+#endif  
+}
+
+static XMLSocket xs;
+
+int
+check_sockets(int x)
+{
+  if (xml_fd == 0) {
+    return -1;
+  }
+  
+  return xs.checkSockets(x);
+}
+
+} // end of gnaash namespace
+
+// HAVE_LIBXML
+#endif

Index: server/asobj/xmlsocket.h
===================================================================
RCS file: server/asobj/xmlsocket.h
diff -N server/asobj/xmlsocket.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asobj/xmlsocket.h    24 Nov 2006 09:19:50 -0000      1.1
@@ -0,0 +1,119 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+//
+
+#ifndef __XMLSOCKET_H__
+#define __XMLSOCKET_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tu_config.h"
+#include "xml.h"
+#include "impl.h"
+
+#include <string>
+
+#ifdef HAVE_LIBXML
+
+namespace gnash {
+
+extern const int SOCKET_DATA;
+  
+class DSOLOCAL XMLSocket {
+ public:
+  XMLSocket();
+  ~XMLSocket();
+  
+  bool connect(const char *host, int port);
+  bool send(std::string str);
+  void close();
+
+  
+  bool anydata(char **msgs);
+  bool anydata(int sockfd, char **msgs);
+  bool connected() { return _connect; };
+  bool fdclosed() { return _closed; }
+  bool xmlmsg() { return _xmldata; }
+  
+  void messagesClear()      { _messages.clear(); }
+  void messageRemove(int x) { _messages.erase(_messages.begin() + x); }
+  int messagesCount()       { return _messages.size(); }
+  std::string operator [] (int x)  { return _messages[x]; }
+  
+  bool processingData();
+  void processing(bool x);
+ 
+  // Event Handlers
+  void onClose(std::string);
+  void onConnect(std::string);
+  void onData(std::string);
+  void onXML(std::string);
+
+  // These handle the array of XML nodes
+  void push(as_object *obj);
+  void clear();
+  int  count();
+
+  int checkSockets(void);
+  int checkSockets(int x);
+
+ private:
+  std::string  _host;
+  short         _port;
+  int           _sockfd;
+  bool          _data;
+  bool          _xmldata;
+  bool          _closed;
+  bool          _connect;
+  bool          _processing;
+  std::vector<std::string> _messages;
+  std::vector<as_object *>  _nodes;
+};
+
+
+class DSOLOCAL xmlsocket_as_object : public gnash::as_object
+{
+public:
+  XMLSocket obj;
+};
+
+DSOEXPORT void xmlsocket_connect(const fn_call& fn);
+DSOEXPORT void xmlsocket_send(const fn_call& fn);
+DSOEXPORT void xmlsocket_xml_new(const fn_call& fn);
+DSOEXPORT void xmlsocket_new(const fn_call& fn);
+DSOEXPORT void xmlsocket_close(const fn_call& fn);
+
+// These are the event handlers called for this object
+DSOEXPORT void xmlsocket_event_ondata(const fn_call& fn);
+DSOEXPORT void xmlsocket_event_close(const fn_call& fn);
+DSOEXPORT void xmlsocket_event_connect(const fn_call& fn);
+DSOEXPORT void xmlsocket_event_xml(const fn_call& fn);
+
+DSOEXPORT int check_sockets(int fd);
+ 
+} // end of gnash namespace
+
+// HAVE_LIBXML
+#endif
+
+// __XMLSOCKETSOCKET_H__
+#endif
+

Index: server/xml.cpp
===================================================================
RCS file: server/xml.cpp
diff -N server/xml.cpp
--- server/xml.cpp      20 Nov 2006 22:06:38 -0000      1.34
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,1328 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// 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.34 2006/11/20 22:06:38 strk Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string>
-#include <vector>
-
-#include "log.h"
-#include "tu_config.h"
-#include "as_function.h" // for as_function
-#include "fn_call.h"
-
-#ifdef HAVE_LIBXML
-
-#include <unistd.h>
-#include "xmlattrs.h"
-#include "xmlnode.h"
-#include "xml.h"
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlreader.h>
-
-using namespace std;
-
-namespace gnash {
-  
-//#define DEBUG_MEMORY_ALLOCATION 1
-  
-XML::XML() 
-    :_loaded(false),  _nodename(0), _nodes(0), _bytes_loaded(0), 
_bytes_total(0)
-{
-    GNASH_REPORT_FUNCTION;
-#ifdef DEBUG_MEMORY_ALLOCATION
-    log_msg("Creating XML data at %p \n", this);
-#endif
-    //log_msg("%s: %p \n", __FUNCTION__, this);
-}
-
-
-// Parse the ASCII XML string into memory
-XML::XML(tu_string xml_in)
-{
-    GNASH_REPORT_FUNCTION;
-#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 */)
-{
-    GNASH_REPORT_FUNCTION;
-#ifdef DEBUG_MEMORY_ALLOCATION
-    log_msg("\tCreating XML data at %p \n", this);
-#endif
-    //log_msg("%s: %p \n", __FUNCTION__, this);
-}
-
-
-XML::~XML()
-{
-    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);
-    }
-#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(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(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);
-}
-
-// Dispatch event handler(s), if any.
-bool
-XML::on_event(const event_id& /* id */)
-{
-    GNASH_REPORT_FUNCTION;
-    
-    // Keep m_as_environment alive during any method calls!
-    //  boost::intrusive_ptr<as_object_interface>      this_ptr(this);
-  
-#if 0
-    // First, check for built-in event handler.
-    as_value   method;
-    if (get_event_handler(event_id(id), &method)) {
-        call_method0(method, &m_as_environment, this);
-        return true;
-    }
-  
-    // Check for member function.
-    // In ActionScript 2.0, event method names are CASE SENSITIVE.
-    // In ActionScript 1.0, event method names are CASE INSENSITIVE.
-    const tu_string&   method_name = id.get_function_name();
-    if (method_name.length() > 0) {
-        as_value       method;
-        if (get_member(method_name, &method)) {
-            call_method0(method, &m_as_environment, this);
-            return true;
-        }
-    }
-#endif
-    return false;
-}
-
-void
-XML::on_event_load()
-{
-    // Do the events that (appear to) happen as the movie
-    // loads.  frame1 tags and actions are executed (even
-    // before advance() is called).  Then the onLoad event
-    // is triggered.
-    on_event(event_id::LOAD);
-}
-
-XMLNode*
-XML::extractNode(xmlNodePtr node, bool mem)
-{
-    xmlAttrPtr attr;
-    xmlNodePtr childnode;
-    xmlChar *ptr = NULL;
-    XMLNode *element, *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) {
-        //log_msg("extractNode %s has property %s, value is %s\n",
-        //          node->name, attr->name, attr->children->content);
-        XMLAttr *attrib = new XMLAttr;
-        len = memadjust(strlen(reinterpret_cast<const char *>(attr->name))+1);
-        attrib->_name = (char *)new char[len];
-        memset(attrib->_name, 0, len);
-        strcpy(attrib->_name, reinterpret_cast<const char *>(attr->name));
-        len = memadjust(strlen(reinterpret_cast<const char 
*>(attr->children->content))+1);
-        attrib->_value = (char *)new char[len];
-        memset(attrib->_value, 0, len);
-        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);
-        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);
-    if (node->children) {
-        //ptr = node->children->content;
-        ptr = xmlNodeGetContent(node->children);
-        if (ptr != NULL) {
-            if ((strchr((const char *)ptr, '\n') == 0) && (ptr[0] != 0)) {
-                if (node->children->content == NULL) {
-                    //log_msg("Node %s has no contents\n", node->name);
-                } 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 = reinterpret_cast<const char *>(ptr);
-                }
-            }
-            xmlFree(ptr);
-        }
-    }
-    
-    // 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 %p\n", 
child->_name.c_str(), child->_value.to_string(), element);
-            } else {
-                //log_msg("\tPushing childNode %s on element %p\n", 
child->_name.c_str(), element);
-            }
-            element->_children.push_back(child);
-        }
-        childnode = childnode->next;
-    }
-
-    return element;
-}
-
-// Read in an XML document from the specified source
-bool
-XML::parseDoc(xmlDocPtr document, bool mem)
-{
-    GNASH_REPORT_FUNCTION;
-    
-    XMLNode *top;
-    xmlNodePtr cur;
-
-    if (document == 0) {
-        log_error("Can't load XML file!\n");
-        return false;
-    }
-
-    cur = xmlDocGetRootElement(document);
-  
-    if (cur != NULL) {
-        top = extractNode(cur, mem);
-        //_nodes->_name = reinterpret_cast<const char *>(cur->name);
-        _nodes = top;
-        //_node_data.push_back(top);
-        //cur = cur->next;
-    }  
-
-    _loaded = true;
-    return true;
-}
-
-// This reads in an XML file from disk and parses into into a memory resident
-// tree which can be walked through later.
-bool
-XML::parseXML(tu_string xml_in)
-{
-    GNASH_REPORT_FUNCTION;
-
-    log_msg("Parse XML from memory: %s\n", xml_in.c_str());
-
-    if (xml_in.size() == 0) {
-        log_error("XML data is empty!\n");
-        return false;
-    }
-
-#ifndef USE_DMALLOC
-    //dump_memory_stats(__FUNCTION__, __LINE__, "before xmlParseMemory");
-#endif
-
-    _bytes_total = _bytes_loaded = xml_in.size();
-    
-#ifdef USE_XMLREADER
-    XMLNode *node = 0;
-    xmlTextReaderPtr reader;
-
-    reader = xmlReaderForMemory(xml_in.c_str(), xml_in.size(), NULL, NULL, 0);
-    if (reader != NULL) {
-       bool ret = true;
-        while (ret) {
-            ret = xmlTextReaderRead(reader);
-            node = processNode(reader, node);
-        }
-        xmlFreeTextReader(reader);
-        if (ret != false) {
-            log_error("%s : couldn't parse\n", xml_in.c_str());
-            return false;
-        }
-    } else {
-        log_error("Unable to open %s\n", xml_in.c_str());
-        return false;
-    }
-    xmlCleanupParser();
-    return true;
-#else
-
-bool ret = true;
-
-#ifdef USE_DOM
-    xmlInitParser();
-  
-    _doc = xmlParseMemory(xml_in.c_str(), xml_in.size());
-    if (_doc == 0) {
-        log_error("Can't parse XML data!\n");
-        return false;
-    }
-    ret = parseDoc(_doc, true);
-    xmlCleanupParser();
-    xmlFreeDoc(_doc);
-    xmlMemoryDump();
-#endif
-#ifndef USE_DMALLOC
-    //dump_memory_stats(__FUNCTION__, __LINE__, "after xmlParseMemory");
-#endif
-    return ret;
-#endif
-  
-}
-
-//     XML_READER_TYPE_NONE = 0
-//     XML_READER_TYPE_ELEMENT = 1,
-//     XML_READER_TYPE_ATTRIBUTE = 2,
-//     XML_READER_TYPE_TEXT = 3,
-//     XML_READER_TYPE_COMMENT = 8,
-//     XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14,
-//     XML_READER_TYPE_END_ELEMENT = 15,
-//
-// processNode:
-// 2 1 IP 0// processNode:
-// 3 3 #text 0 192.168.2.50
-// processNode:
-// 2 15 IP 0
-// processNode:
-// 2 14 #text 0
-const char *tabs[] = {
-    "",
-    "\t",
-    "\t\t",
-    "\t\t\t",
-    "\t\t\t",
-    "\t\t\t\t",
-};
-
-#ifdef USE_XMLREADER
-// This is an xmlReader (SAX) based parser. For some reason it core dumps
-// when compiled with GCC 3.x, but works just fine with GCC 4.x.
-XMLNode*
-XML::processNode(xmlTextReaderPtr reader, XMLNode *node)
-{
-    log_msg("%s: node is %p\n", __PRETTY_FUNCTION__, node);
-    static XMLNode *parent[10];
-    xmlChar *name, *value;
-    int   depth;
-    XMLNode *element;
-    //static int previous_depth = 0;
-    xmlReaderTypes type;
-
-    if (node == 0) {
-        memset(parent, 0, sizeof(XMLNode *));
-    }
-    type = (xmlReaderTypes)xmlTextReaderNodeType(reader);
-    depth = xmlTextReaderDepth(reader);
-    value = xmlTextReaderValue(reader);
-    name = xmlTextReaderName(reader);
-  
-    if (name == NULL)
-        name = xmlStrdup(BAD_CAST "--");
-
-#if 0
-    printf("%d %d %s %d\n",
-           depth,
-           (int)type,
-           name,
-           xmlTextReaderIsEmptyElement(reader));  
-#endif
-
-  
-    //child = node->_children[0];
-    switch(xmlTextReaderNodeType(reader)) {
-      case XML_READER_TYPE_NONE:
-          break;
-      case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: // This is an empty text 
node
-          //log_msg("\tWhitespace at depth %d\n", depth);
-          break;
-      case XML_READER_TYPE_END_ELEMENT:
-          if (depth == 0) {          // This is the last node in the file
-              element = node;
-              break;
-          }
-          parent[depth]->_children.push_back(element);
-//       log_msg("Pushing element %s on node %s\n", node->_name, 
parent[depth]->_name);
-//       log_msg("End element at depth %d is %s for parent %s %p\n", depth, 
name,
-//               parent[depth]->_name, parent[depth]);
-          element = parent[depth];
-          break;
-      case XML_READER_TYPE_ELEMENT:
-          element = new XMLNode;
-//      log_msg("%sElement at depth %d is %s for node at %p\n", tabs[depth], 
depth, name, element);
-          element->_name = (char *)new char[strlen(reinterpret_cast<const char 
*>(name))+1];
-          memset(element->_name, 0, strlen(reinterpret_cast<const char 
*>(name))+1);
-          strcpy(element->_name, reinterpret_cast<const char *>(name));
-          if (node == 0) {
-              _nodes = element;
-              parent[0] = element;
-          } else {
-              parent[depth] = node;
-              parent[depth+1] = node;
-          }
-          //  xmlTextReaderAttributeCount(reader);
-          if (xmlTextReaderHasAttributes(reader)) {
-              // log_msg("Has Attributes!\n");
-              xmlTextReaderMoveToFirstAttribute(reader);
-              processNode(reader, element);
-              while(xmlTextReaderMoveToNextAttribute(reader)) {
-                  processNode(reader, element);
-              }
-          }
-          break;
-      case XML_READER_TYPE_TEXT:
-          element = node;
-//      log_msg("%sValue at depth %d is \"%s\" for node at %p\n", tabs[depth], 
depth, value, element);
-          element->_value = (char *)new char[strlen(reinterpret_cast<const 
char *>(value))+1];
-          memset(element->_value, 0, strlen(reinterpret_cast<const char 
*>(value))+1);
-          strcpy(element->_value, reinterpret_cast<const char *>(value));
-          break;
-      case XML_READER_TYPE_ATTRIBUTE:
-          element = node;
-          XMLAttr *attrib = new XMLAttr;
-          attrib->_name = (char *)new char[strlen(reinterpret_cast<const char 
*>(name))+1];
-          memset(attrib->_name, 0, strlen(reinterpret_cast<const char 
*>(name))+1);
-          strcpy(attrib->_name, reinterpret_cast<const char *>(name));
-          attrib->_value = (char *)new char[strlen(reinterpret_cast<const char 
*>(value))+1];
-          memset(attrib->_value, 0, strlen(reinterpret_cast<const char 
*>(value))+1);
-          strcpy(attrib->_value, reinterpret_cast<const char *>(value));
-//     log_msg("%sPushing attribute %s, value \"%s\" for node %s\n", 
tabs[depth], name, value, element->_name);
-          element->_attributes.push_back(attrib);
-          break;
-      default:   // FIXME: why does this break GCC 3.3.3 but not 3.4.3 ?
-          log_error("Unsupported XML type %d\n!", type);
-          break;
-    };
-
-    xmlFree(name);
-    if (value != NULL) {
-        xmlFree(value);
-    }
-    //previous_depth = depth;
-    return element;
-}
-#endif
-
-// This reads in an XML file from disk and parses into into a memory resident
-// tree which can be walked through later.
-bool
-XML::load(const char *filespec)
-{
-    GNASH_REPORT_FUNCTION;
-    struct stat stats;
-    log_msg("Load disk XML file: %s\n", filespec);
-  
-    //log_msg("%s: mem is %d\n", __FUNCTION__, mem);
-
-    // See if the file exists
-    if (stat(filespec, &stats) == 0) {
-        _bytes_total = stats.st_size;
-        _bytes_loaded = stats.st_size; // FIXME: this should probably
-                                       // be set later on after the
-                                       // file is loaded
-    }
-#ifdef USE_XMLREADER
-    XMLNode *node = 0;
-    xmlTextReaderPtr reader;  
-  
-    reader = xmlNewTextReaderFilename(filespec);
-    if (reader != NULL) {
-        bool ret = true;
-        while (ret) {
-            ret = xmlTextReaderRead(reader);
-            node = processNode(reader, node);
-        }
-        xmlFreeTextReader(reader);
-        if (ret != false) {
-            log_error("%s : couldn't parse\n", filespec);
-            return false;
-        }
-    } else {
-        log_error("Unable to open %s\n", filespec);
-        return false;
-    }
-    xmlCleanupParser();
-    return true;
-#else
-#ifdef USE_DOM
-    xmlInitParser();
-    _doc = xmlParseFile(filespec);
-    if (_doc == 0) {
-        log_error("Can't load XML file: %s!\n", filespec);
-        return false;
-    }
-    parseDoc(_doc, false);
-    xmlCleanupParser();
-    xmlFreeDoc(_doc);
-    xmlMemoryDump();
-    return true;
-#else
-#error "You have to enable either a DOM or an xmlReader XML parser"
-#endif
-#endif
-}
-
-
-vector<XMLNode *>
-XML::childNodes() 
-{
-  if (_nodes) {
-    return _nodes->_children;
-  } else {
-    return static_cast< vector<XMLNode*> >(0);
-  }
-}
-
-bool
-XML::onLoad()
-{
-    log_msg("%s: FIXME: onLoad Default event handler\n", __FUNCTION__);
-
-    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 *
-XML::setupFrame(as_object *obj, XMLNode *xml, bool mem)
-{
-//    GNASH_REPORT_FUNCTION;
-    
-    int                 child;
-    unsigned int i;
-    const char    *nodename;
-    //const char    *nodevalue;
-    //AS_value      nodevalue;
-    int           length;
-    as_value      inum;
-    XMLNode       *childnode;
-    xmlnode_as_object *xmlchildnode_obj;
-    xmlattr_as_object* attr_obj;
-
-    //log_msg("\t%s: processing node %s for object %p, mem is %d\n", 
__FUNCTION__, xml->_name, obj, mem);
-  
-    // 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
-    // primarily by the disk based XML parser, where at least in all my current
-    // test cases this is referenced with firstChild first, then nodeName and
-    // childNodes.
-    obj->set_member("nodeName",           nodename);
-    obj->set_member("length",             length);
-    if (xml->_value != 0) {
-        obj->set_member("nodeValue",        xml->_value);
-        log_msg("\tnodevalue for %s is: %s\n", nodename, xml->_value);
-    } else {
-        obj->set_member("nodeValue", as_value::UNDEFINED);
-    }
-
-//   if (nodevalue.get_type() != as_value::UNDEFINED) {
-//     obj->set_member("nodeValue",        nodevalue.to_string());
-//     log_msg("\tnodevalue for %s is: %s\n", nodename, nodevalue.to_string());
-//   } else {
-//     // If there is no value, we want to define it as an empty
-//     // string.
-//     obj->set_member("nodeValue", "");
-//   }
-
-  
-    // Process the attributes, if any
-    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 {
-        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);
-    }
-
-    //xml->_attributes.resize(0);
-    //obj->set_member("attributes", attr_obj);
-
-    // Process the children, if there are any
-    if (length) {
-        //log_msg("\tProcessing %d children nodes for %s\n", length, nodename);
-        inum = 0;
-        for (child=0; child<length; child++) {
-            // Create a new AS object for this node's children
-            xmlchildnode_obj = new xmlnode_as_object;
-            // When parsing XML from memory, the test movies I have expect the 
firstChild
-            // to be the first element of the array instead.
-            if (mem) {
-                childnode = xml;
-                //obj->set_member(inum.to_string(), obj);
-                //inum += 1;
-                //childnode = xml->_children[child];
-            } else {
-                childnode = xml->_children[child];
-            }
-            setupFrame(xmlchildnode_obj, childnode, false); // setup child node
-            obj->set_member(inum.to_string(), xmlchildnode_obj);
-            inum += 1;
-        }
-    } else {
-        //log_msg("\tNode %s has no children\n", nodename);
-    }  
-
-    return obj;
-}
-
-
-/// \brief add or change the HTTP Request header
-///
-/// Method; adds or changes HTTP request headers (such as Content-Type
-/// or SOAPAction) sent with POST actions. In the first usage, you pass
-/// two strings to the method: headerName and headerValue. In the
-/// second usage, you pass an array of strings, alternating header
-/// names and header values.
-///
-/// If multiple calls are made to set the same header name, each
-/// successive value replaces the value set in the previous call.
-void
-XML::addRequestHeader(const char */* name */, const char */* value */)
-{
-    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)
-{
-    if (!_nodes) {
-      _nodes = new XMLNode;
-    }
-    _nodes->_children.push_back(node);
-    //    log_msg("%s: %p at _nodes at %p\n", __PRETTY_FUNCTION__, this, 
_nodes);
-}
-
-/// \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)
-{
-    log_msg("%s: deep is %d\n", __PRETTY_FUNCTION__, deep);
-
-    if (deep) {
-       newnode = _nodes;
-//     } else {
-//     newnode.nodeNameSet((char *)_nodes->nodeName());
-//     newnode.nodeValueSet((char *)_nodes->nodeValue());    
-    }
-
-    return newnode;
-  
-    log_msg("%s:partially unimplemented \n", __PRETTY_FUNCTION__);
-}
-
-/// \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;
-}
-
-/// \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()
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
-
-void
-XML::parseXML()
-{
-    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()
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
-
-void
-XML::sendAndLoad()
-{
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
-
-const char *
-XML::toString()
-{
-    if (_nodes) {
-       return stringify(_nodes);
-    }
-    return NULL;
-}
-
-// 
-const char *
-XML::stringify(XMLNode *xml)
-{
-    int           child;
-    unsigned int  i;
-    const char    *nodename = xml->nodeName();
-    int           length;
-    string       str;
-    
-    log_msg("%s: processing for object %p\n", __PRETTY_FUNCTION__, 
(void*)this);
-  
-    // Process the attributes, if any
-    if (_nodes->_attributes.size() == 0) {
-        log_msg("\t\tNo attributes for node\n");
-    } else {
-        for (i=0; i<xml->_attributes.size(); i++) {
-            log_msg("\t\tAdding attribute as member %s, value is %s to node 
%s\n",
-                    xml->_attributes[i]->_name,
-                    xml->_attributes[i]->_value, nodename);
-        }
-    }
-
-    vector<XMLNode *>::iterator it;
-    for (it = _nodes->_children.begin(); it != _nodes->_children.end(); ++it) {
-       log_msg("Found One!!!! %p\n", (void*)*it);
-    }
-    
-    // Process the children, if there are any
-    length = xml->_children.size();
-
-    if (length) {
-        log_msg("\tProcessing %d children nodes\n", length);
-        for (child=0; child<length; child++) {
-           log_msg("Name %p\n", (void*)(xml->_children[child]));
-           if (xml->_children[child]->_name) {
-//             log_msg("Name %p", xml->_children[child]);
-           }
-           if (xml->_children[child]->_value) {
-//             log_msg("Value %s", xml->_children[child]->_value);
-           }
-       
-//         str += stringify(xml->_children[child]);
-        }
-    } else {
-        log_msg("\tNode %s has no children\n", nodename);
-    }
-    return str.c_str();
-}
-
-//
-// Callbacks. These are the wrappers for the C++ functions so they'll work as
-// callbacks from within gnash.
-//
-void
-xml_load(const fn_call& fn)
-{
-    as_value   method;
-    as_value   val;
-    bool          ret;
-    struct stat   stats;
-
-    //GNASH_REPORT_FUNCTION;
-  
-    xml_as_object *xml_obj = (xml_as_object*)fn.this_ptr;
-  
-    const std::string filespec = 
fn.env->bottom(fn.first_arg_bottom_index).to_string();
-
-    // If the file doesn't exist, don't try to do anything.
-    if (stat(filespec.c_str(), &stats) < 0) {
-        fprintf(stderr, "ERROR: doesn't exist.%s\n", filespec.c_str());
-        fn.result->set_bool(false);
-        return;
-    }
-  
-    // Set the argument to the function event handler based on whether the load
-    // was successful or failed.
-    ret = xml_obj->obj.load(filespec.c_str());
-    fn.result->set_bool(ret);
-
-    if (ret == false) {
-        return;
-    }
-    
-    //env->bottom(first_arg) = ret;
-    //  struct node *first_node = ptr->obj.firstChildGet();
-  
-    //const char *name = ptr->obj.nodeNameGet();
-
-    if (xml_obj->obj.hasChildNodes() == false) {
-        log_error("%s: No child nodes!\n", __FUNCTION__);
-    }  
-    xml_obj->obj.setupFrame(xml_obj, xml_obj->obj.firstChild(), false);
-  
-#if 1
-    if (fn.this_ptr->get_member("onLoad", &method)) {
-        //    log_msg("FIXME: Found onLoad!\n");
-        fn.env->set_variable("success", true);
-        fn.env->bottom(fn.first_arg_bottom_index) = true;
-        as_c_function_ptr      func = method.to_c_function();
-        if (func) {
-           // It's a C function.  Call it.
-           log_msg("Calling C function for onLoad\n");
-           (*func)(fn_call(&val, xml_obj, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
-       } else if (as_function* as_func = method.to_as_function()) {
-           // It's an ActionScript function.  Call it.
-           log_msg("Calling ActionScript function for onLoad\n");
-           (*as_func)(fn_call(&val, xml_obj, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
-       } else {
-           log_error("error in call_method(): method is not a function\n");
-       }
-    } else {
-        log_msg("Couldn't find onLoad event handler, setting up callback\n");
-        // ptr->set_event_handler(event_id::XML_LOAD, 
(as_c_function_ptr)&xml_onload);
-    }
-#else
-    xml_obj->set_event_handler(event_id::XML_LOAD, &xml_onload);
-
-#endif
-
-    fn.result->set_bool(true);
-}
-
-// This executes the event handler for XML::XML_LOAD if it's been defined,
-// and the XML file has loaded sucessfully.
-void
-xml_onload(const fn_call& fn)
-{
-    //log_msg("%s:\n", __FUNCTION__);
-    
-    as_value   method;
-    as_value      val;
-    static bool first = true;     // This event handler should only be 
executed once.
-    xml_as_object*     ptr = (xml_as_object*) (as_object*) fn.this_ptr;
-    assert(ptr);
-  
-    if ((ptr->obj.loaded()) && (first)) {
-        // env->set_variable("success", true, 0);
-        //as_value bo(true);
-        //env->push_val(bo);
-
-        first = false;
-        log_msg("The XML file has been loaded successfully!\n");
-        // ptr->on_event(event_id::XML_LOAD);
-        //env->set_variable("success", true, 0);
-        //env->bottom(0) = true;
-    
-        if (fn.this_ptr->get_member("onLoad", &method)) {
-            // log_msg("FIXME: Found onLoad!\n");
-            as_c_function_ptr  func = method.to_c_function();
-            if (func)
-                {
-                    // It's a C function.  Call it.
-                    log_msg("Calling C function for onLoad\n");
-                    (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-                }
-            else if (as_function* as_func = method.to_as_function())
-                {
-                    // It's an ActionScript function.  Call it.
-                    log_msg("Calling ActionScript function for onLoad\n");
-                    (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-                }
-            else
-                {
-                    log_error("error in call_method(): method is not a 
function\n");
-                }    
-        } else {
-            log_msg("FIXME: Couldn't find onLoad!\n");
-        }
-    }
-      
-    fn.result->set_bool(val.to_bool());
-}
-
-// This is the default event handler, and is usually redefined in the SWF 
script
-void
-xml_ondata(const fn_call& fn)
-{
-    log_msg("%s:\n", __FUNCTION__);
-    
-    as_value   method;
-    as_value   val;
-    static bool first = true;     // FIXME: ugly hack!
-  
-    xml_as_object*     ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-  
-    if ((ptr->obj.loaded()) && (first)) {
-        if (fn.this_ptr->get_member("onData", &method)) {
-            log_msg("FIXME: Found onData!\n");
-            as_c_function_ptr  func = method.to_c_function();
-            fn.env->set_variable("success", true);
-            if (func)
-                {
-                    // It's a C function.  Call it.
-                    log_msg("Calling C function for onData\n");
-                    (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-                }
-            else if (as_function* as_func = method.to_as_function())
-                {
-                    // It's an ActionScript function.  Call it.
-                    log_msg("Calling ActionScript function for onData\n");
-                    (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-                }
-            else
-                {
-                    log_error("error in call_method(): method is not a 
function\n");
-                }    
-        } else {
-            log_msg("FIXME: Couldn't find onData!\n");
-        }
-    }
-
-    //fn.result->set(&val);
-    fn.result->set_bool(val.to_bool());
-}
-
-void
-xml_new(const fn_call& fn)
-{
-    as_value      inum;
-    xml_as_object *xml_obj;
-    //const char    *data;
-  
-    // log_msg("%s: nargs=%d\n", __FUNCTION__, fn.nargs);
-  
-    if (fn.nargs > 0) {
-        if (fn.env->top(0).get_type() == as_value::STRING) {
-            xml_obj = new xml_as_object;
-            //log_msg("\tCreated New XML object at %p\n", xml_obj);
-            tu_string datain = fn.env->top(0).to_tu_string();
-            xml_obj->obj.parseXML(datain);
-            //log_msg("*** Start setting up the stack frames ***\n");
-            xml_obj->obj.setupFrame(xml_obj, xml_obj->obj.firstChild(), true);
-            //xml_obj->obj.clear();
-            //delete xml_obj->obj.firstChild();
-        } else {
-            xml_as_object*     xml_obj = 
(xml_as_object*)fn.env->top(0).to_object();
-            //log_msg("\tCloned the XML object at %p\n", xml_obj);
-            //result->set(xml_obj);
-            fn.result->set_as_object(xml_obj);
-            return;
-        }
-    } else {
-        xml_obj = new xml_as_object;
-        //log_msg("\tCreated New XML object at %p\n", xml_obj);
-       // FIXME: this doesn't appear to exist in the MM player, should it ?
-       xml_obj->set_member("loaded", &xml_loaded);
-       
-        xml_obj->set_member("addRequestHeader", &xml_addrequestheader);
-        xml_obj->set_member("appendChild", &xml_appendchild);
-        xml_obj->set_member("cloneNode", &xml_clonenode);
-        xml_obj->set_member("createElement", &xml_createelement);
-        xml_obj->set_member("createTextNode", &xml_createtextnode);
-        xml_obj->set_member("getBytesLoaded", &xml_getbytesloaded);
-        xml_obj->set_member("getBytesTotal", &xml_getbytestotal);
-        xml_obj->set_member("hasChildNodes", &xml_haschildnodes);
-        xml_obj->set_member("insertBefore", &xml_insertbefore);
-        xml_obj->set_member("load", &xml_load);
-        xml_obj->set_member("parseXML", &xml_parsexml);
-        xml_obj->set_member("removeNode", &xml_removenode);
-        xml_obj->set_member("send", &xml_send);
-        xml_obj->set_member("sendAndLoad", &xml_sendandload);
-        xml_obj->set_member("toString", &xml_tostring);
-       // Properties
-        xml_obj->set_member("nodeName", as_value(""));
-        xml_obj->set_member("nodevalue", as_value(""));
-
-    }
-
-    fn.result->set_as_object(xml_obj);
-}
-
-//
-// SWF Property of this class. These are "accessors" into the private data
-// of the class.
-//
-
-// determines whether the document-loading process initiated by the XML.load()
-// call has completed. If the process completes successfully, the method
-// returns true; otherwise, it returns false.
-void
-xml_loaded(const fn_call& fn)
-{
-    as_value   method;
-    as_value   val;
-
-    log_msg("%s:\n", __FUNCTION__);
-    
-    xml_as_object*     ptr = (xml_as_object*) (as_object*) fn.this_ptr;
-    assert(ptr);
-    std::string filespec = 
fn.env->bottom(fn.first_arg_bottom_index).to_string();
-    //fn.result->set(ptr->obj.loaded());
-    fn.result->set_bool(ptr->obj.loaded());
-}
-
-
-void xml_addrequestheader(const fn_call& fn)
-{
-    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-//    ptr->obj.addRequestHeader();
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
-void xml_appendchild(const fn_call& fn)
-{
-  //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    xmlnode_as_object *xml_obj = 
(xmlnode_as_object*)fn.env->top(0).to_object();
-    
-    ptr->obj.appendChild(&(xml_obj->obj));
-}
-
-void xml_clonenode(const fn_call& fn)
-{
-    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    xml_as_object      *ptr = (xml_as_object*)fn.this_ptr;
-    xmlnode_as_object   *xml_obj;
-    assert(ptr);
-
-    if (fn.nargs > 0) {
-      bool deep = fn.env->bottom(fn.first_arg_bottom_index).to_bool();
-      xml_obj = new xmlnode_as_object;
-      xml_obj->set_member("nodeName", as_value(""));
-      xml_obj->set_member("nodeValue", as_value(""));
-      xml_obj->set_member("appendChild", &xmlnode_appendchild);
-      ptr->obj.cloneNode(xml_obj->obj, deep);
-      fn.result->set_as_object(xml_obj);
-   } else {
-        log_msg("ERROR: no Depth paramater!\n");
-    }
-
-}
-void xml_createelement(const fn_call& fn)
-{
-  //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    xmlnode_as_object *xml_obj;
-    const char *text;
-
-    if (fn.nargs > 0) {
-        text = fn.env->bottom(fn.first_arg_bottom_index).to_string();
-       xml_obj = new xmlnode_as_object;
-       xml_obj->set_member("nodeName", as_value(text));
-       xml_obj->set_member("nodeValue", as_value(""));
-       xml_obj->set_member("appendChild", &xmlnode_appendchild);
-//     xml_obj->obj.nodeNameSet((char *)text);
-       xml_obj->obj._type = XML_ELEMENT_NODE; 
-       fn.result->set_as_object(xml_obj);
-   } else {
-        log_msg("ERROR: no text for element creation!\n");
-    }
-}
-
-
-void xml_createtextnode(const fn_call& fn)
-{
-  //    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    xmlnode_as_object *xml_obj;
-    const char *text;
-
-    if (fn.nargs > 0) {
-        text = fn.env->bottom(fn.first_arg_bottom_index).to_string();
-       xml_obj = new xmlnode_as_object;
-       xml_obj->set_member("nodeName", as_value(""));
-       xml_obj->set_member("nodeValue", as_value(text));       
-       xml_obj->set_member("appendChild", &xmlnode_appendchild);
-//     xml_obj->obj.nodeValueSet((char *)text);
-       xml_obj->obj._type = XML_TEXT_NODE;
-       fn.result->set_as_object(xml_obj);
-//     log_msg("%s: xml obj is %p\n", __PRETTY_FUNCTION__, xml_obj);
-    } else {
-        log_msg("ERROR: no text for text node creation!\n");
-    }
-}
-
-void xml_getbytesloaded(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    fn.result->set_int(ptr->obj.getBytesLoaded());
-}
-
-void xml_getbytestotal(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    fn.result->set_int(ptr->obj.getBytesTotal());
-}
-
-void xml_haschildnodes(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    fn.result->set_bool(ptr->obj.hasChildNodes());
-}
-void xml_insertbefore(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-//    ptr->obj.insertBefore();
-    log_msg("%s:unimplemented \n", __FUNCTION__);
-}
-void xml_parsexml(const fn_call& fn)
-{
-    const char *text;
-    as_value   method;
-    as_value   val;    
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-
-    if (fn.nargs > 0) {
-        text = fn.env->bottom(fn.first_arg_bottom_index).to_string();
-       ptr->obj.parseXML(text);
-       ptr->obj.setupFrame(ptr, ptr->obj.firstChild(), false);  
-    }
-    
-#if 1
-    if (fn.this_ptr->get_member("onLoad", &method)) {
-        //    log_msg("FIXME: Found onLoad!\n");
-        fn.env->set_variable("success", true);
-        fn.env->bottom(fn.first_arg_bottom_index) = true;
-        as_c_function_ptr      func = method.to_c_function();
-        if (func) {
-           // It's a C function.  Call it.
-           log_msg("Calling C function for onLoad\n");
-           (*func)(fn_call(&val, ptr, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
-       } else if (as_function* as_func = method.to_as_function()) {
-           // It's an ActionScript function.  Call it.
-           log_msg("Calling ActionScript function for onLoad\n");
-           (*as_func)(fn_call(&val, ptr, fn.env, fn.nargs, 
fn.first_arg_bottom_index)); // was this_ptr instead of node
-       } else {
-           log_error("error in call_method(): method is not a function\n");
-       }
-    } else {
-        log_msg("Couldn't find onLoad event handler, setting up callback\n");
-        // ptr->set_event_handler(event_id::XML_LOAD, 
(as_c_function_ptr)&xml_onload);
-    }
-#else
-    
-#endif
-//    fn.result->set_int(ptr->obj.getAllocated());
-}
-    
-void xml_removenode(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-    ptr->obj.removeNode();
-}
-void xml_send(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-    ptr->obj.send();
-}
-void xml_sendandload(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-    ptr->obj.sendAndLoad();
-}
-void xml_tostring(const fn_call& fn)
-{
-    xml_as_object *ptr = (xml_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-    fn.result->set_string(ptr->obj.toString());
-}
-
-int
-memadjust(int x)
-{
-    return (x + (4 - x % 4));
-}
-
-
-} // end of gnash namespace
-
-// HAVE_LIBXML
-#endif
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/xml.h
===================================================================
RCS file: server/xml.h
diff -N server/xml.h
--- server/xml.h        20 Nov 2006 22:06:38 -0000      1.21
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,266 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// 
-//
-//
-
-#ifndef __XML_H__
-#define __XML_H__
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tu_config.h"
-
-#include "event_id.h"
-#include "action.h"
-
-//#define DEBUG_MEMORY_ALLOCATION 1
-#include <vector>
-
-#ifdef HAVE_LIBXML
-
-#include "xmlattrs.h"
-#include "xmlnode.h"
-
-#ifdef DEBUG_MEMORY_ALLOCATION
-       #include "log.h"
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xmlreader.h>
-
-// Forward declarations
-namespace gnash {
-       class fn_call;
-}
-
-namespace gnash {
-  
-/// XML class
-class DSOLOCAL XML {
-public:
-    XML();
-    XML(tu_string xml_in);
-    XML(struct node * childNode);
-    virtual ~XML();
-  
-    // 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);
-    // Loads a document (specified by
-    bool load(const char *filespec);
-    // the XML object) from a 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);
-    
-    virtual bool on_event(const gnash::event_id& id);
-    virtual void       on_event_load();
-    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);
-    //  Returns true if the specified node has child nodes; otherwise, returns 
false.
-  bool hasChildNodes() {
-    if (_nodes) {
-      if (_nodes->_children.size()) {
-        return true;
-      } 
-    }
-    return false;
-  }
-    
-    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(char *name);
-    void nodeValueSet(char *value);
-    int length()                 { return _nodes->length(); }
-  
-    // 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; };
-
-    virtual void       on_xml_event(const gnash::event_id& id)
-    {
-       on_event(id);
-    }
-  
-    // Special event handler; 
-    void       on_event_close()
-    {
-       on_event(gnash::event_id::SOCK_CLOSE);
-    }
-  
-    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;
-    
-    bool        _contentType;
-    bool        _attributes;
-    bool        _childNodes;
-    bool        _xmlDecl;
-    bool        _docTypeDecl;
-    bool        _ignoreWhite;
-    bool        _lastChild;
-    bool        _nextSibling;
-    bool        _nodeType;
-    bool        _nodeValue;
-    bool        _parentNode;
-    bool        _status;
-    bool        _previousSibling;
-
-};
-
-/// XML ActionScript object
-class DSOLOCAL xml_as_object : public gnash::as_object
-{
-public:
-    XML obj;
-#ifdef DEBUG_MEMORY_ALLOCATION
-    xml_as_object() {
-        log_msg("\tCreating xml_as_object at %p\n", this);
-    };
-    ~xml_as_object() {
-        log_msg("\tDeleting xml_as_object at %p\n", this);
-    };
-#endif
-
-    virtual bool get_member(const tu_stringi& name, as_value* val) {
-        //printf("GET XML MEMBER: %s at %p for object %p\n", name.c_str(), 
val, this);
-        
-        if ((name == "firstChild") || (name == "childNodes")) {
-//             printf("Returning a self reference for %s for object at %p\n",
-//                    name.c_str(), this);
-            val->set_as_object(this);
-            return true;
-        }
-
-       return get_member_default(name, val);
-        
-    }
-};
-
-
-DSOEXPORT void xml_load(const fn_call& fn);
-DSOEXPORT void xml_set_current(const fn_call& fn);
-DSOEXPORT void xml_new(const fn_call& fn);
-
-DSOEXPORT void xml_addrequestheader(const fn_call& fn);
-DSOEXPORT void xml_appendchild(const fn_call& fn);
-DSOEXPORT void xml_clonenode(const fn_call& fn);
-DSOEXPORT void xml_createelement(const fn_call& fn);
-DSOEXPORT void xml_createtextnode(const fn_call& fn);
-DSOEXPORT void xml_getbytesloaded(const fn_call& fn);
-DSOEXPORT void xml_getbytestotal(const fn_call& fn);
-DSOEXPORT void xml_haschildnodes(const fn_call& fn);
-DSOEXPORT void xml_insertbefore(const fn_call& fn);
-DSOEXPORT void xml_parsexml(const fn_call& fn);
-DSOEXPORT void xml_removenode(const fn_call& fn);
-DSOEXPORT void xml_send(const fn_call& fn);
-DSOEXPORT void xml_sendandload(const fn_call& fn);
-DSOEXPORT void xml_tostring(const fn_call& fn);
-
-// These are the event handlers called for this object
-DSOEXPORT void xml_onload(const fn_call& fn);
-DSOEXPORT void xml_ondata(const fn_call& fn);
-DSOEXPORT void xml_loaded(const fn_call& fn);
-
-// Properties
-DSOEXPORT void xml_nodename(const fn_call& fn);
-DSOEXPORT void xml_nodevalue(const fn_call& fn);
-
-
-DSOEXPORT int memadjust(int x);
-
-
-}      // end namespace gnash
-
-
-#endif // HAVE_LIBXML
-
-#endif // __XML_H__
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/xmlattrs.cpp
===================================================================
RCS file: server/xmlattrs.cpp
diff -N server/xmlattrs.cpp
--- server/xmlattrs.cpp 29 Oct 2006 18:34:11 -0000      1.7
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,90 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// 
-//
-//
-
-/* $Id: xmlattrs.cpp,v 1.7 2006/10/29 18:34:11 rsavoye Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <vector>
-
-#include "action.h"
-#include "impl.h"
-#include "tu_config.h"
-#include "as_function.h"
-
-#ifdef HAVE_LIBXML
-
-#include "xmlattrs.h"
-
-#ifdef DEBUG_MEMORY_ALLOCATION
-       #include "log.h"
-#endif
-
-#include <unistd.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlreader.h>
-
-using namespace std;
-
-namespace gnash {
-  
-//#define DEBUG_MEMORY_ALLOCATION 1
-  
-//std::vector<as_object *> _xmlobjs;    // FIXME: hack alert
-
-XMLAttr::XMLAttr()
-{
-#ifdef DEBUG_MEMORY_ALLOCATION
-    log_msg("\t\tCreating XMLAttr data at %p \n", this);
-#endif
-    _name = 0;
-    _value = 0;
-}
-
-XMLAttr::~XMLAttr()
-{
-#ifdef DEBUG_MEMORY_ALLOCATION
-    log_msg("\t\tDeleting XMLAttr data %s at %p \n", this->_name, this);
-#endif
-    //log_msg("%s: %p \n", __FUNCTION__, this);
-    if (_name) {
-        delete _name;
-    }
-    if (_value) {
-        delete _value;
-    }  
-}  
-
-} // end of gnash namespace
-
-// HAVE_LIBXML
-#endif
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/xmlattrs.h
===================================================================
RCS file: server/xmlattrs.h
diff -N server/xmlattrs.h
--- server/xmlattrs.h   22 Nov 2006 15:19:51 -0000      1.10
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,102 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// 
-//
-//
-
-#ifndef __XML_ATTRS_H__
-#define __XML_ATTRS_H__
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_LIBXML
-
-#include "tu_config.h"
-
-//#define DEBUG_MEMORY_ALLOCATION 1
-#include "as_object.h" // for inheritance
-
-#include "log.h"
-
-#include <vector>
-
-#ifdef DEBUG_MEMORY_ALLOCATION
-       #include "log.h"
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xmlreader.h>
-
-namespace gnash {
-  
-/// XML Attribute class
-class DSOLOCAL XMLAttr {
-public:
-    XMLAttr();
-    ~XMLAttr();
-  
-    // why don't we use std::strings here ?
-    // code would be much simpler and safer!
-    char                *_name;
-    char                *_value;
-    xmlAttributeType    _type;
-    
-    XMLAttr *operator = (XMLAttr node) {
-        log_msg("\t\tCopying XMLAttr object at %p\n", (void*)this);
-    
-        _name = new char[strlen(node._name)+2];
-        memset(_name, 0, strlen(node._name)+2);
-        strcpy(_name, node._name);
-
-        _value = new char[strlen(node._value)+2];
-        memset(_value, 0, strlen(node._value)+2);
-        strcpy(_value, node._value);
-
-        return this;
-    }
-};
-
-/// XML Attribute ActionScript Object
-class DSOLOCAL xmlattr_as_object : public as_object
-{
-public:
-    //XMLAttr obj;
-    int   padding;
-#ifdef DEBUG_MEMORY_ALLOCATION
-    xmlattr_as_object() {
-        log_msg("\t\tCreating xmlattr_as_object at %p\n", this);
-    };
-    ~xmlattr_as_object() {
-        log_msg("\tDeleting xmlattr_as_object at %p \n", this);
-    };
-#endif
-};
- 
-} // end of gnash namespace
-
-#endif // HAVE_LIBXML
-
-#endif // __XML_ATTRS_H__
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/xmlnode.cpp
===================================================================
RCS file: server/xmlnode.cpp
diff -N server/xmlnode.cpp
--- server/xmlnode.cpp  22 Nov 2006 15:19:51 -0000      1.22
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,449 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// 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.22 2006/11/22 15:19:51 strk Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <vector>
-#include "tu_config.h"
-#include "fn_call.h"
-
-#ifdef HAVE_LIBXML
-
-//#define DEBUG_MEMORY_ALLOCATION 1
-
-#include "xmlnode.h"
-
-#ifdef DEBUG_MEMORY_ALLOCATION
-       #include "log.h"
-#endif
-
-#include <unistd.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlreader.h>
-
-using namespace std;
-
-namespace gnash {
-    
-//std::vector<as_object *> _xmlobjs;    // FIXME: hack alert
-
-XMLNode::XMLNode() :_name(0), _value(0), _type(XML_ELEMENT_NODE)
-{
-    //log_msg("%s: %p \n", __PRETTY_FUNCTION__, this);
-#ifdef DEBUG_MEMORY_ALLOCATION
-    log_msg("\tCreating XMLNode data at %p \n", this);
-#endif
-    _name = 0;
-    _value = 0;
-}
-
-XMLNode::~XMLNode()
-{
-    unsigned int i;
-    //log_msg("%s: %p \n", __PRETTY_FUNCTION__, this);
-#ifdef DEBUG_MEMORY_ALLOCATION
-    log_msg("\tDeleting XMLNode data %s at %p\n", this->_name, this);
-#endif
-  
-    for (i=0; i<_children.size(); i++) {
-     if (_children[i]->_name) {
-       delete [] _children[i]->_name;
-     }
-     if (_children[i]->_value) {
-       delete [] _children[i]->_value;
-     }
-    }
-
-    for (i=0; i<_attributes.size(); i++) {
-       if (_attributes[i]->_name) {
-           delete [] _attributes[i]->_name;
-       }
-       if (_attributes[i]->_value) {
-           delete [] _attributes[i]->_value;
-       }
-    }
-
-    _children.clear();
-    _attributes.clear();
-
-    if (_name) {
-        delete [] _name;
-    }
-    if (_value) {
-        delete [] _value;
-    }
-    //  _value.set_undefined();
-}
-
-void
-XMLNode::nodeNameSet(char *name)
-{
-  int len = strlen(name) + 1;
- 
-  if (!_name) {
-    _name = (char *)new char[len];
-    memset(_name, 0, len);
-    strcpy(_name, reinterpret_cast<const char *>(name));
-  }
-}
-
-void
-XMLNode::nodeValueSet(char *value)
-{
-  int len = strlen(value) + 1;
- 
-  if (!_value) {
-    _value = (char *)new char[len];
-    memset(_value, 0, len);
-    strcpy(_value, reinterpret_cast<const char *>(value));
-  }
-}
-
-/// \brief Get the type of an XML Node.
-///
-
-/// Read-only property; a nodeType value, either 1 for an XML element
-/// or 3 for a text node. The nodeType is a numeric value from the
-/// NodeType enumeration in the W3C DOM Level 1 recommendation:
-/// www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core.html.
-/// The following table lists the values.
-int
-XMLNode::nodeType() 
-{
-    switch (_type) {
-      case XML_TEXT_NODE:
-         return 3;
-         break;
-      case XML_ELEMENT_NODE:
-         return 1;
-         break;
-      default:
-         return 0;
-    }
-    // you should never get here
-    return -1;
-}
-
-const char *
-XMLNode::nodeName() 
-{
-  if (_name) {
-    return _name;
-  }
-  return "unknown";
-}
-
-const char *
-XMLNode::nodeValue() 
-{  
-  if (_value) {
-    return _value;
-  }
-  return "unknown";
-}
-
-/// \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.
-void
-XMLNode::appendChild(as_object *as, XMLNode *node)
-{
-//     log_msg("%s: %p, as is %d, node is %d\n",
-//         __PRETTY_FUNCTION__, this, _objects.size(), _children.size());
-
-    if (node) {
-       _children.push_back(node);
-    }
-
-    if (as) {
-       _objects.push_back(as);
-    }
-
-//    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)
-{
-    log_msg("%s: deep is %d\n", __PRETTY_FUNCTION__, deep);
-
-    if (deep) {
-//     newnode = _nodes;
-    } else {
-       newnode.nodeNameSet(_name);
-       newnode.nodeValueSet(_value);
-    }
-
-    return newnode;
-  
-    log_msg("%s: partially unimplemented \n", __PRETTY_FUNCTION__);
-}
-
-/// \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
-XMLNode::insertBefore(XMLNode */* newnode */, XMLNode */* node */)
-{
-    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
-}
-/// \brief removes the specified XML object from its parent. Also
-/// deletes all descendants of the node.
-void
-XMLNode::removeNode()
-{
-    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
-}
-const char *
-XMLNode::toString()
-{
-    XMLNode *node;
-    
-    vector<XMLNode *>::const_iterator it;
-    for (it = _children.begin(); it != _children.end(); it++) {
-       node = *it;
-//     log_msg("Got something\n");
-       if (node->_name) {
-           log_msg("Node name is %s", node->_name);
-       }
-       if (node->_value) {
-           log_msg("Node value is %s", node->_name);
-       }       
-    }
-    
-    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
-    return "Hello World!";
-}
-
-as_object *
-XMLNode::previousSibling(int x)
-{
-    log_msg("%s: partially implemented. " SIZET_FMT " objects\n",
-           __PRETTY_FUNCTION__,  _objects.size());
-    if (_objects.size() > 0) {
-       return _objects[x-1];
-    }
-
-    return NULL;
-}
-
-as_object *
-XMLNode::nextSibling(int x)
-{
-    log_msg("%s: unimplemented \n", __PRETTY_FUNCTION__);
-    if (x < (int) _objects.size()) {
-       return _objects[x];
-    }
-    return NULL;
-}
-
-void
-xmlnode_new(const fn_call& fn)
-{
-    xmlnode_as_object *xml_obj;
-    //const char    *data;
-  
-//    log_msg("%s\n", __PRETTY_FUNCTION__);
-  
-    xml_obj = new xmlnode_as_object;
-    // Methods
-    xml_obj->set_member("appendChild", &xmlnode_appendchild);
-    xml_obj->set_member("cloneNode", &xmlnode_clonenode);
-    xml_obj->set_member("hasChildNodes", &xmlnode_haschildnodes);
-    xml_obj->set_member("insertBefore", &xmlnode_insertbefore);
-    xml_obj->set_member("removeNode", &xmlnode_removenode);
-    xml_obj->set_member("toString", &xmlnode_tostring);
-
-    // Properties
-    xml_obj->set_member("nodeName",  as_value(""));
-    xml_obj->set_member("nodeValue", as_value(""));
-    xml_obj->set_member("nodeType", as_value(""));
-
-    // FIXME: these need real values
-    // These two return an array of objects
-    xml_obj->set_member("attributes", as_value(""));
-    xml_obj->set_member("childNodes", as_value(""));
-
-    //These return a reference to an object
-
-    /// \fn MLNode::firstChild
-    /// \brief XMLNode::firstChild property
-    ///
-    /// Read-only property; evaluates the specified XML object and
-    /// references the first child in the parent node\ufffds child
-    /// list. This property is null if the node does not have
-    /// children. This property is undefined if the node is a text
-    /// node. This is a read-only property and cannot be used to
-    /// manipulate child nodes; use the appendChild(), insertBefore(),
-    /// and removeNode() methods to manipulate child nodes. 
-
-    xml_obj->set_member("firstChild", as_value(""));
-    /// \fn MLNode::lastChild
-    /// \brief XMLNode::lastChild property 
-    ///
-    /// Read-only property; an XMLNode value that references the last
-    /// child in the node's child list. The XML.lastChild property
-    /// is null if the node does not have children. This property cannot
-    /// be used to manipulate child nodes; use the appendChild(),
-    /// insertBefore(), and removeNode() methods to manipulate child
-    /// nodes.
-    xml_obj->set_member("lastChild",   as_value(""));
-    xml_obj->set_member("nextSibling", as_value(""));
-    xml_obj->set_member("parentNode",  as_value(""));
-    xml_obj->set_member("previousSibling", as_value(""));
-
-    fn.result->set_as_object(xml_obj);
-}
-
-void xmlnode_appendchild(const fn_call& fn)
-{
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-//    log_msg("%s: %p, %d args\n", __PRETTY_FUNCTION__, ptr, fn.nargs);
-    
-    xmlnode_as_object *xml_obj = 
(xmlnode_as_object*)fn.env->bottom(fn.first_arg_bottom_index).to_object();
-    
-//    log_msg("%s: %p \n", __PRETTY_FUNCTION__, xml_obj);
-    XMLNode *node = &(xml_obj->obj);
-    if (ptr->obj.hasChildNodes() == false) {
-       ptr->set_member("firstChild", xml_obj);
-    }
-    int length = ptr->obj.length();
-    if (length > 0) {
-       as_object *ass = xml_obj->obj.previousSibling(length);
-// FIXME: This shouldn't always be NULL
-//     log_msg("%s: ASS is %p, length is %d\n", __PRETTY_FUNCTION__,
-//             ass, length);
-       ptr->set_member("previousSibling", ass);
-//     ptr->set_member("nextSibling", 
xml_obj->obj.nextSibling(ptr->obj.length()));
-    }
-    ptr->obj.appendChild((as_object *)xml_obj, node);
-    // The last child in the list is always the one we just appended
-    ptr->set_member("lastChild", xml_obj);
-   
-//    ptr->obj.appendChild(&(xml_obj->obj));
-//    ptr->obj.nodeValueSet((char *)xmlnode_obj->obj.nodeValue());
-}
-
-void xmlnode_clonenode(const fn_call& fn)
-{
-    log_msg("%s: %d args\n", __PRETTY_FUNCTION__, fn.nargs);
-    xmlnode_as_object  *ptr = (xmlnode_as_object*)fn.this_ptr;
-    xmlnode_as_object   *xmlnode_obj;
-    assert(ptr);
-
-    if (fn.nargs > 0) {
-      bool deep = fn.env->bottom(fn.first_arg_bottom_index).to_bool();
-      xmlnode_obj = new xmlnode_as_object;
-      ptr->obj.cloneNode(xmlnode_obj->obj, deep);
-      fn.result->set_as_object(xmlnode_obj);
-   } else {
-        log_msg("ERROR: no Depth paramater!\n");
-    }
-
-}
-
-void xmlnode_insertbefore(const fn_call& fn)
-{
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-//    ptr->obj.insertBefore();
-    log_msg("%s:unimplemented \n", __PRETTY_FUNCTION__);
-}
-void xmlnode_removenode(const fn_call& fn)
-{
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-//    fn.result->set_int(ptr->obj.getAllocated());
-    ptr->obj.removeNode();
-}
-void xmlnode_tostring(const fn_call& fn)
-{
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-    fn.result->set_string(ptr->obj.toString());
-}
-
-void xmlnode_haschildnodes(const fn_call& fn)
-{
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-    fn.result->set_bool(ptr->obj.hasChildNodes());
-}
-
-#ifdef ENABLE_TESTING
-void xmlnode_nodevalue(const fn_call& fn)
-{
-    log_msg("%s: \n", __PRETTY_FUNCTION__);
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-    fn.result->set_string(ptr->obj.nodeValue());
-}
-void xmlnode_nodename(const fn_call& fn)
-{
-    log_msg("%s: \n", __PRETTY_FUNCTION__);
-    xmlnode_as_object *ptr = (xmlnode_as_object*)fn.this_ptr;
-    assert(ptr);
-    
-    fn.result->set_string(ptr->obj.nodeName());
-}
-#endif
-
-} // end of gnash namespace
-
-// HAVE_LIBXML
-#endif
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/xmlnode.h
===================================================================
RCS file: server/xmlnode.h
diff -N server/xmlnode.h
--- server/xmlnode.h    22 Nov 2006 15:19:51 -0000      1.11
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,167 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// 
-//
-//
-
-#ifndef __XML_NODE_H__
-#define __XML_NODE_H__
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tu_config.h"
-
-//#define DEBUG_MEMORY_ALLOCATION 1
-#include <vector>
-#include "action.h"
-#include "impl.h"
-
-#ifdef HAVE_LIBXML
-
-#include "xmlattrs.h"
-
-#ifdef DEBUG_MEMORY_ALLOCATION
-       #include "log.h"
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xmlreader.h>
-
-namespace gnash {  
- 
-/// XML Node 
-class DSOLOCAL XMLNode
-{
-public:
-    XMLNode();
-    ~XMLNode();
-    
-    int length()                 { return _children.size(); }
-    const char *nodeName();
-    const char *nodeValue();
-    int nodeType();
-
-    //    char *valueGet();
-  
-    void nodeNameSet(char *name);
-    void nodeValueSet(char *value);
-    //  nodeType       XML.nodeType
-
-    bool hasChildNodes() {
-      if (_children.size()) {
-        return true;
-      }
-      return false;
-    }
-  
-    XMLNode *firstChild()              { return _children[0]; }
-  
-    std::vector<XMLNode *>childNodes()  { return _children; }  
-    
-    XMLNode *operator [] (int x) {
-        gnash::log_msg("%s: get element %d\n", __PRETTY_FUNCTION__, x);
-        
-        return _children[x];
-    }
-    
-    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) {
-        gnash::log_msg("%s: \n", __PRETTY_FUNCTION__);
-        _name = node->_name;
-        _value = node->_value;
-       _children = node->_children;
-        _attributes = node->_attributes;
-        return this;
-    }
-
-    as_object *previousSibling(int x);
-    as_object *nextSibling(int x);
-    XMLNode &cloneNode(XMLNode &newnode, bool deep);
-    void appendChild(as_object *as,XMLNode *node);
-    void insertBefore(XMLNode *newnode, XMLNode *node);
-    void removeNode();
-    const char *toString();
-
-    void  change_stack_frame(int frame, gnash::as_object *xml, 
gnash::as_environment *env);
-
-
-    // why don't we use std::strings here ?
-    // code would be much simpler and safer!
-    char                *_name;
-    char                *_value;
-
-    xmlElementType      _type;
-    std::vector<as_object *>  _objects;
-    std::vector<XMLNode *>    _children;
-    std::vector<XMLAttr *>    _attributes;
-};
-
-/// XML Node ActionScript object
-class DSOLOCAL xmlnode_as_object : public gnash::as_object
-{
-public:
-    XMLNode            obj;
-//    int                      _padding;
-    
-#ifdef DEBUG_MEMORY_ALLOCATION
-    xmlnode_as_object() {
-       //      obj  = new XMLNode;
-        log_msg("\tCreating xmlnode_as_object at %p \n", this);
-    };
-    ~xmlnode_as_object() {
-        log_msg("\tDeleting xmlnode_as_object at %p \n", this);
-    };
-#endif
-};
-
-DSOEXPORT void xmlnode_new(const fn_call& fn);
-
-DSOEXPORT void xmlnode_haschildren(const fn_call& fn);
-DSOEXPORT void xmlnode_nodename(const fn_call& fn);
-DSOEXPORT void xmlnode_nodevalue(const fn_call& fn);
-DSOEXPORT void xmlnode_nodetype(const fn_call& fn);
-
-DSOEXPORT void xmlnode_appendchild(const fn_call& fn);
-DSOEXPORT void xmlnode_clonenode(const fn_call& fn);
-DSOEXPORT void xmlnode_haschildnodes(const fn_call& fn);
-DSOEXPORT void xmlnode_insertbefore(const fn_call& fn);
-DSOEXPORT void xmlnode_removenode(const fn_call& fn);
-DSOEXPORT void xmlnode_tostring(const fn_call& fn);
-
-} // end of gnash namespace
-
-
-#endif // HAVE_LIBXML
-
-#endif // __XMLNODE_NODE_H__
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:

Index: server/xmlsocket.cpp
===================================================================
RCS file: server/xmlsocket.cpp
diff -N server/xmlsocket.cpp
--- server/xmlsocket.cpp        21 Nov 2006 00:25:46 -0000      1.28
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,811 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// 
-//
-//
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "utility.h"
-#include "xml.h"
-#include "xmlsocket.h"
-#include "timers.h"
-#include "as_function.h"
-#include "fn_call.h"
-#include "sprite_instance.h"
-
-#ifdef HAVE_LIBXML
-
-#include "log.h"
-
-#include <sys/types.h>
-#include <fcntl.h>
-#ifdef HAVE_WINSOCK
-# include <WinSock2.h>
-# include <windows.h>
-# include <sys/stat.h>
-# include <io.h>
-#else
-# include <sys/time.h>
-# include <unistd.h>
-# include <sys/select.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# include <sys/socket.h>
-# include <netdb.h>
-# include <cerrno>
-# include <sys/param.h>
-# include <sys/select.h>
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-int xml_fd = 0;                 // FIXME: This file descriptor is used by
-                                // XML::checkSocket() when called from the main
-                                // processing loop. 
-
-namespace gnash {
-const int SOCKET_DATA = 1;
-  
-const int INBUF = 10000;
-  
-XMLSocket::XMLSocket() {
-  //log_msg("%s: \n", __FUNCTION__);
-  _data = false;
-  _xmldata = false;
-  _closed = false;
-  _connect = false;
-  _processing = false;
-  _port = 0;
-  _sockfd = 0;
-  xml_fd = 0;
-}
-
-XMLSocket::~XMLSocket()
-{
-  //log_msg("%s: \n", __FUNCTION__);
-}
-
-bool
-XMLSocket::connect(const char *host, int port)
-{
-  struct sockaddr_in  sock_in;
-  fd_set              fdset;
-  struct timeval      tval;
-  int                 ret;
-  int                 retries;
-  char                thishostname[MAXHOSTNAMELEN];
-  struct protoent     *proto;
-
-  if (port < 1024) {
-    log_error("Can't connect to priviledged port #%d!\n", port);
-    _connect = false;
-    return false;
-  }
-
-  log_msg("%s: to host %s at port %d\n", __FUNCTION__, host, port);
-  
-  memset(&sock_in, 0, sizeof(struct sockaddr_in));
-  memset(&thishostname, 0, MAXHOSTNAMELEN);
-  if (strlen(host) == 0) {
-    if (gethostname(thishostname, MAXHOSTNAMELEN) == 0) {
-      log_msg("The hostname for this machine is %s.\n", thishostname);
-    } else {
-      log_msg("Couldn't get the hostname for this machine!\n");
-      return false;
-    }   
-  }
-  const struct hostent *hent = ::gethostbyname(host);
-  if (hent > 0) {
-    ::memcpy(&sock_in.sin_addr, hent->h_addr, hent->h_length);
-  }
-  sock_in.sin_family = AF_INET;
-  sock_in.sin_port = ntohs(static_cast<short>(port));
-
-#if 0
-    char ascip[32];
-    inet_ntop(AF_INET, &sock_in.sin_addr.s_addr, ascip, INET_ADDRSTRLEN);
-      log_msg("The IP address for this client socket is %s\n", ascip);
-#endif
-
-  proto = ::getprotobyname("TCP");
-
-  _sockfd = ::socket(PF_INET, SOCK_STREAM, proto->p_proto);
-  if (_sockfd < 0)
-    {
-      log_error("unable to create socket : %s\n", strerror(errno));
-      _sockfd = -1;
-      return false;
-    }
-
-  retries = 2;
-  while (retries-- > 0) {
-    // We use select to wait for the read file descriptor to be
-    // active, which means there is a client waiting to connect.
-    FD_ZERO(&fdset);
-    FD_SET(_sockfd, &fdset);
-    
-    // Reset the timeout value, since select modifies it on return. To
-    // block, set the timeout to zero.
-    tval.tv_sec = 5;
-    tval.tv_usec = 0;
-    
-    ret = ::select(_sockfd+1, &fdset, NULL, NULL, &tval);
-
-    // If interupted by a system call, try again
-    if (ret == -1 && errno == EINTR)
-      {
-        log_msg("The connect() socket for fd #%d was interupted by a system 
call!\n",
-                _sockfd);
-        continue;
-      }
-    
-    if (ret == -1)
-      {
-        log_msg("The connect() socket for fd #%d never was available for 
writing!\n",
-                _sockfd);
-#ifdef HAVE_WINSOCK
-        ::shutdown(_sockfd, SHUT_BOTH);
-#else
-        ::shutdown(_sockfd, SHUT_RDWR);
-#endif
-        _sockfd = -1;      
-        return false;
-      }
-    if (ret == 0) {
-      log_error("The connect() socket for fd #%d timed out waiting to 
write!\n",
-                _sockfd);
-      continue;
-    }
-
-    if (ret > 0) {
-      ret = ::connect(_sockfd, reinterpret_cast<struct sockaddr *>(&sock_in), 
sizeof(sock_in));
-      if (ret == 0) {
-        log_msg("\tport %d at IP %s for fd #%d\n", port,
-                ::inet_ntoa(sock_in.sin_addr), _sockfd);
-        _connect = true;
-        xml_fd = _sockfd;               // FIXME: This file descriptor is used 
by
-                                        // XML::checkSocket() when called from
-                                        // the main processing loop.
-        return true;
-      }
-      if (ret == -1) {
-        log_msg("The connect() socket for fd #%d never was available for 
writing!\n",
-                _sockfd);
-        _sockfd = -1;      
-        return false;
-      }
-    }
-  }
-  //  ::close(_sockfd);
-  //  return false;
-
-  printf("\tConnected at port %d on IP %s for fd #%d\n", port,
-          ::inet_ntoa(sock_in.sin_addr), _sockfd);
-  
-#ifndef HAVE_WINSOCK
-  fcntl(_sockfd, F_SETFL, O_NONBLOCK);
-#endif
-
-  _connect = true;
-  return true;
-}
-
-void
-XMLSocket::close()
-{
-  log_msg("%s: \n", __FUNCTION__);
-  // Since the return code from close() doesn't get used by Shockwave,
-  // we don't care either.
-  if (_sockfd > 0) {
-    ::close(_sockfd);
-  }
-}
-
-// Return true if there is data in the socket, otherwise return false.
-bool
-XMLSocket::anydata(char **msgs)
-{
-  //printf("%s: \n", __FUNCTION__);
-  return anydata(_sockfd, msgs);
-}
-
-bool XMLSocket::processingData()
-{
-  //printf("%s: processing flags is is %d\n", __FUNCTION__, _processing);
-  return _processing;
-}
-
-void XMLSocket::processing(bool x)
-{
-  //printf("%s: set processing flag to %d\n", __FUNCTION__, x);
-  _processing = x;
-}
-
-bool
-XMLSocket::anydata(int fd, char **msgs)
-{
-  fd_set                fdset;
-  struct timeval        tval;
-  int                   ret = 0;
-  char                  buf[INBUF];
-  char                  *packet;
-  int                   retries = 10;
-  char                  *ptr, *eom;
-  int                   cr, index = 0;
-  static char           *leftover = 0;
-  int                   adjusted_size;
-
-  //log_msg("%s: \n", __FUNCTION__);
-
-  if (fd <= 0) {
-    return false;
-  }
-
-  //msgs = (char **)realloc(msgs, sizeof(char *));
-
-  while (retries-- > 0) {
-    FD_ZERO(&fdset);
-    FD_SET(fd, &fdset);
-    
-    tval.tv_sec = 0;
-    tval.tv_usec = 103;
-    
-    ret = ::select(fd+1, &fdset, NULL, NULL, &tval);
-
-    // If interupted by a system call, try again
-    if (ret == -1 && errno == EINTR) {
-      log_msg("The socket for fd #%d was interupted by a system call!\n",
-              fd);
-      continue;
-    }
-    if (ret == -1) {
-      log_error("The socket for fd #%d never was available!\n", fd);
-      return false;
-    }
-    if (ret == 0) {
-      //log_msg("There is no data in the socket for fd #%d!\n", fd);
-      return false;
-    }
-    if (ret > 0) {
-      //log_msg("There is data in the socket for fd #%d!\n", fd);        
-      //break;
-    }
-    memset(buf, 0, INBUF);
-    ret = ::read(_sockfd, buf, INBUF-2);
-    cr = strlen(buf);
-    //log_msg("%s: read %d bytes, first msg terminates at %d\n", __FUNCTION__, 
ret, cr);
-    //log_msg("%s: read (%d,%d) %s\n", __FUNCTION__, buf[0], buf[1], buf);
-    ptr = buf;
-    // If we get a single XML message, do less work
-    if (ret == cr + 1) {
-      adjusted_size = memadjust(ret + 1);
-      packet = new char[adjusted_size];
-      //printf("Packet size is %d at %p\n", ret + 1, packet);
-      memset(packet, 0, adjusted_size);
-      strcpy(packet, ptr);
-      eom = strrchr(packet, '\n'); // drop the CR off the end if there is one
-      if (eom) {
-        *eom = 0;
-      }
-      //data.push_back(packet);
-      msgs[index] = packet;
-      msgs[index+1] = 0;
-      //printf("%d: Pushing Packet of size %d at %p\n", __LINE__, 
strlen(packet), packet);
-      processing(false);
-      return true;
-    }
-
-    // If we get multiple messages in a single transmission, break the buffer
-    // into separate messages.
-    while (strchr(ptr, '\n') > 0) {
-      if (leftover) {
-        processing(false);
-        //printf("%s: The remainder is: \"%s\"\n", __FUNCTION__, leftover);
-        //printf("%s: The rest of the message is: \"%s\"\n", __FUNCTION__, 
ptr);
-        adjusted_size = memadjust(cr + strlen(leftover) + 1);
-        packet = new char[adjusted_size];
-        memset(packet, 0, adjusted_size);
-        strcpy(packet, leftover);
-        strcat(packet, ptr);
-        eom = strrchr(packet, '\n'); // drop the CR off the end there is one
-        if (eom) {
-          *eom = 0;
-        }
-        //printf("%s: The whole message is: \"%s\"\n", __FUNCTION__, packet);
-        ptr = strchr(ptr, '\n') + 2; // messages are delimited by a "\n\0"
-        delete leftover;
-        leftover = 0;
-      } else {
-        adjusted_size = memadjust(cr + 1);
-        packet = new char[adjusted_size];
-        memset(packet, 0, adjusted_size);
-        strcpy(packet, ptr);
-        ptr += cr + 1;
-      } // end of if remainder
-      if (*packet == '<') {
-        //printf("%d: Pushing Packet #%d of size %d at %p: %s\n", __LINE__,
-        //       data.size(), strlen(packet), packet, packet);
-        eom = strrchr(packet, '\n'); // drop the CR off the end there is one
-        if (eom) {
-          *eom = 0;
-        }
-        //printf("Allocating new packet at %p\n", packet);
-        //data.push_back(packet);
-        msgs[index++] = packet;
-      } else {
-        log_error("Throwing out partial packet %s\n", packet);
-      }
-      
-      //log_msg("%d messages in array now\n", data.size());
-      cr = strlen(ptr);
-    } // end of while (cr)
-    
-    if (strlen(ptr) > 0) {
-      leftover = new char[strlen(ptr) + 1];
-      strcpy(leftover, ptr);
-      processing(true);
-      //printf("%s: Adding remainder: \"%s\"\n", __FUNCTION__, leftover);
-    }
-    
-    processing(false);
-    printf("Returning %d messages\n", index);
-    return true;
-    
-  } // end of while (retires)
-
-  return true;
-}
-
-bool
-XMLSocket::send(std::string str)
-{
-  //GNASH_REPORT_FUNCTION;
-  
-  str += '\0';
-  int ret = write(_sockfd, str.c_str(), str.size());
-
-  //log_msg("%s: sent %d bytes, data was %s\n", __FUNCTION__, ret, 
str.c_str());
-  if (ret == static_cast<signed int>(str.size())) {
-    return true;
-  } else {
-    return false;
-  }
-}
-
-// Callbacks
-
-void
-XMLSocket::onClose(std::string /* str */)
-{
-  log_msg("%s: \n", __FUNCTION__);
-}
-
-void
-XMLSocket::onConnect(std::string /* str */)
-{
-  log_msg("%s: \n", __FUNCTION__);
-}
-
-void
-XMLSocket::onData(std::string /* str */)
-{
-  log_msg("%s: \n", __FUNCTION__);
-}
-
-void
-XMLSocket::onXML(std::string /* str */)
-{
-  log_msg("%s: \n", __FUNCTION__);
-}
-
-void
-XMLSocket::push(as_object *obj)
-{
-  _nodes.push_back(obj);
-}
-
-void
-XMLSocket::clear()
-{
-  unsigned int i;
-  for (i=0; i< _nodes.size(); i++) {
-    delete _nodes[i];
-  }
-}
-
-int
-XMLSocket::count()
-{
-  return _nodes.size();
-}
-
-int
-XMLSocket::checkSockets(void)
-{
-  return checkSockets(_sockfd);
-}
-
-int
-XMLSocket::checkSockets(int fd)
-{
-  fd_set                fdset;
-  int                   ret = 0;
-  struct timeval        tval;
-
-  //log_msg("%s:\n", __FUNCTION__);
-
-  FD_ZERO(&fdset);
-  FD_SET(fd, &fdset);
-  
-  tval.tv_sec = 2;
-  tval.tv_usec = 10;
-  
-  ret = ::select(fd+1, &fdset, NULL, NULL, &tval); // &tval
-  
-  // If interupted by a system call, try again
-  if (ret == -1 && errno == EINTR) {
-    log_msg("The socket for fd #%d was interupted by a system call in this 
thread!\n",
-            fd);
-  }
-  if (ret == -1) {
-    log_error("The socket for fd #%d never was available!\n", fd);
-  }
-  if (ret == 0) {
-    printf("There is no data in the socket for fd #%d!\n", fd);
-  }
-  if (ret > 0) {
-    //printf("There is data in the socket for fd #%d!\n", fd);        
-  }
-  
-  return ret;
-}
-
-void
-xmlsocket_connect(const fn_call& fn)
-{
-  as_value     method;
-  as_value     val;
-  static bool first = true;     // This event handler should only be executed 
once.
-
-  if (!first) {
-    fn.result->set_bool(true);
-    return;
-  }
-  
-  log_msg("%s: nargs=%d\n", __FUNCTION__, fn.nargs);
-  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
-  assert(ptr);
-  const std::string host = 
fn.env->bottom(fn.first_arg_bottom_index).to_string();
-  std::string port_str = 
fn.env->bottom(fn.first_arg_bottom_index-1).to_string();
-  double port = atof(port_str.c_str());
-
-  ptr->obj.connect(host.c_str(), static_cast<int>(port));
-
-#if 0 // use connect return as result
-  // Push result onto stack for onConnect
-  if (ret) {
-    fn.env->push(as_value(true));
-  }
-  else {
-    fn.env->push(as_value(false));
-  }
-#endif
-  fn.env->push(as_value(true));
-  if (fn.this_ptr->get_member("onConnect", &method)) {
-    //    log_msg("FIXME: Found onConnect!\n");
-    as_c_function_ptr  func = method.to_c_function();
-    first = false;
-    //env->set_variable("success", true, 0);
-
-    if (func) {
-      // It's a C function.  Call it.
-      log_msg("Calling C function for onConnect\n");
-      (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-    }
-    else if (as_function* as_func = method.to_as_function()) {
-      // It's an ActionScript function.  Call it.
-      log_msg("Calling ActionScript function for onConnect\n");
-      (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 2, 2));
-    } else {
-      log_error("error in call_method(): method is not a function\n");
-    }    
-  } else {
-    //ptr->set_event_handler(event_id::SOCK_CONNECT, 
(as_c_function_ptr)&xmlsocket_event_connect);
-  }
-
-#if 1
-  sprite_instance* mov = fn.env->get_target()->get_root_movie();
-  Timer *timer = new Timer;
-  as_c_function_ptr ondata_handler =
-    (as_c_function_ptr)&xmlsocket_event_ondata;
-  timer->setInterval(ondata_handler, 50, ptr, fn.env);
-  timer->setObject(ptr);
-  mov->add_interval_timer(timer);
-#endif
-
-  fn.env->pop();
-  
-  fn.result->set_bool(true);
-}
-
-
-void
-xmlsocket_send(const fn_call& fn)
-{
-  as_value     method;
-  as_value     val;
-  
-  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
-  assert(ptr);
-  const std::string object = fn.env->bottom( 
fn.first_arg_bottom_index).to_string();
-  //  log_msg("%s: host=%s, port=%g\n", __FUNCTION__, host, port);
-  fn.result->set_bool(ptr->obj.send(object));
-}
-
-void
-xmlsocket_close(const fn_call& fn)
-{
-  as_value     method;
-  as_value     val;
-  
-  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
-  assert(ptr);
-  // Since the return code from close() doesn't get used by Shockwave,
-  // we don't care either.
-  ptr->obj.close();
-}
-
-void
-xmlsocket_xml_new(const fn_call& fn)
-{
-  //log_msg("%s: nargs=%d\n", __FUNCTION__, nargs);
-  
-  xml_new(fn);
-}
-
-void
-xmlsocket_new(const fn_call& fn)
-{
-  //log_msg("%s: nargs=%d\n", __FUNCTION__, nargs);
-  
-  as_object*   xmlsock_obj = new xmlsocket_as_object;
-  //log_msg("\tCreated New XMLSocket object at 0x%X\n", (unsigned 
int)xmlsock_obj);
-  xmlsock_obj->set_member("connect", &xmlsocket_connect);
-  xmlsock_obj->set_member("send", &xmlsocket_send);
-  xmlsock_obj->set_member("close", &xmlsocket_close);
-  xmlsock_obj->set_member("Connected", true);
-  // swf_event*        ev = new swf_event;
-  // m_event_handlers.push_back(ev);
-  // Setup event handlers
-#if 0
-  xmlsock_obj->set_event_handler(event_id::SOCK_DATA,
-                                 (as_c_function_ptr)&xmlsocket_event_ondata);
-  xmlsock_obj->set_event_handler(event_id::SOCK_CLOSE,
-                                 (as_c_function_ptr)&xmlsocket_event_close);
-  //                                                   
xmlsock_obj->set_event_handler(event_id::SOCK_CONNECT,
-  //                                                                          
(as_c_function_ptr)&xmlsocket_event_connect);
-  xmlsock_obj->set_event_handler(event_id::SOCK_XML,
-                                 (as_c_function_ptr)&xmlsocket_event_xml);
-#endif
-  //periodic_events.set_event_handler(xmlsock_obj);
-  
-  
-#if 1
-  //as_c_function_ptr int_handler = (as_c_function_ptr)&timer_setinterval;
-  //env->set_member("setInterval", int_handler);
-  fn.env->set_member("setInterval", timer_setinterval);
-  
-  //as_c_function_ptr clr_handler = timer_clearinterval;
-  fn.env->set_member("clearInterval", timer_clearinterval);
-  //env->set_variable("setInterval", int_handler, 0);
-  //xmlsock_obj->set_event_handler(event_id::TIMER,
-  //       (as_c_function_ptr)&timer_expire);
-#if 0
-  Timer *timer = new Timer;
-  as_c_function_ptr ondata_handler =
-    (as_c_function_ptr)&xmlsocket_event_ondata;
-  timer->setInterval(ondata_handler, 10);
-  timer->setObject(xmlsock_obj);
-  current_movie->add_interval_timer(timer);
-#endif
-  
-  fn.result->set_bool(xmlsock_obj);
-
-  // Tune malloc for the best performance
-  //mallopt(M_MMAP_MAX,0);
-  //mallopt(M_TRIM_THRESHOLD,-1);
-  //mallopt(M_MMAP_THRESHOLD,16);
-
-#endif
-}
-
-
-void
-xmlsocket_event_ondata(const fn_call& fn)
-{
-  //log_msg("%s: nargs is %d\n", __FUNCTION__, nargs);
-    
-  as_value     method;
-  as_value     val;
-  as_value      datain;
-  std::vector<const char *> msgs;
-  char          *messages[200];
-  int           i;
-  as_c_function_ptr    func;
-  as_function*       as_func;
-
-  xmlsocket_as_object* ptr = (xmlsocket_as_object*)fn.this_ptr;
-  assert(ptr);
-  if (ptr->obj.processingData()) {
-    log_msg("Still processing data!\n");
-    fn.result->set_bool(false);
-    return;
-  }
-  
-  memset(messages, 0, sizeof(char *)*200);
-  
-#ifndef USE_DMALLOC
-  //dump_memory_stats(__FUNCTION__, __LINE__, "memory checkpoint");
-#endif
-  
-  if (ptr->obj.anydata(messages)) {
-    if (fn.this_ptr->get_member("onData", &method)) {
-      func = method.to_c_function();
-      as_func = method.to_as_function();
-      //log_msg("Got %d messages from XMLsocket\n", msgs.size());
-      //      for (i=0; i<msgs.size(); i++) {
-      for (i=0; messages[i] != 0; i++) {
-//          log_msg("Got message #%d, %d bytes long at %p: %s: \n", i,
-//                  strlen(messages[i]), messages[i], messages[i]);
-        datain = messages[i];
-        //fn.env->push(datain);
-#ifndef USE_DMALLOC
-        //dump_memory_stats(__FUNCTION__, __LINE__, "start");
-#endif
-        as_environment *env = new as_environment;
-        env->push(datain);
-        if (func) {
-          // It's a C function.  Call it.
-          //log_msg("Calling C function for onData\n");
-          (*func)(fn_call(&val, fn.this_ptr, env, 1, 0));
-        } else if (as_func) {
-          // It's an ActionScript function.  Call it.
-          //log_msg("Calling ActionScript function for onData, processing msg 
%d\n", i);
-          (*as_func)(fn_call(&val, fn.this_ptr, env, 1, 0));
-        } else {
-          log_error("error in call_method(): method is not a function\n");
-        }
-        env->pop();
-        delete env;
-#ifndef USE_DMALLOC
-        //dump_memory_stats(__FUNCTION__, __LINE__, "end");
-#endif  
-        //log_msg("Deleting message #%d at %p\n", i, messages[i]);
-        //delete messages[i];
-        //fn.env->pop();
-        datain.set_undefined();
-      }
-      ptr->obj.processing(false);
-    } else {
-      log_error("Couldn't find onData!\n");
-    }
-    // Delete this in a batch for now so we can track memory allocation
-    for (i=0; messages[i] != 0; i++) {
-      //log_msg("Deleting message #%d at %p\n", i, messages[i]);
-      delete messages[i];
-    }
-  }
-
-  //malloc_trim(0);
-  
-  //result->set(&data);
-  fn.result->set_bool(true);
-}
-
-void
-xmlsocket_event_close(const fn_call& /* fn */)
-{
-#if 0
-  as_value* result = fn.result;
-  as_object* this_ptr = fn.this_ptr;
-  int nargs = fn.nargs;
-  int first_arg = fn.first_arg_bottom_index;
-#else
-  log_error("%s: unimplemented!\n", __FUNCTION__);
-#endif
-}
-
-void
-xmlsocket_event_connect(const fn_call& fn)
-{
-  as_value     method;
-  as_value     val;
-  static bool first = true;     // This event handler should only be executed 
once.
-
-  if (!first) {
-    fn.result->set_bool(true);
-    return;
-  }
-  
-  xmlsocket_as_object* ptr = (xmlsocket_as_object*) (as_object*) fn.this_ptr;
-  assert(ptr);
-
-  log_msg("%s: connected = %d\n", __FUNCTION__, ptr->obj.connected());
-  if ((ptr->obj.connected()) && (first)) {
-    first = false;
-    //env->set_variable("success", true, 0);
-    //env->bottom(0) = true;
-
-    if (fn.this_ptr->get_member("onConnect", &method)) {
-      as_c_function_ptr        func = method.to_c_function();
-      if (func)
-        {
-          // It's a C function.  Call it.
-          //log_msg("Calling C function for onConnect\n");
-          (*func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-      }
-      else if (as_function* as_func = method.to_as_function())
-        {
-          // It's an ActionScript function.  Call it.
-          //log_msg("Calling ActionScript function for onConnect\n");
-          (*as_func)(fn_call(&val, fn.this_ptr, fn.env, 0, 0));
-        }
-      else
-        {
-          log_error("error in call_method(): method is not a function\n");
-        }    
-    } else {
-      log_msg("FIXME: Couldn't find onConnect!\n");
-    }
-  }
-
-  fn.result->set_bool(val.to_bool()); 
-}
-void
-xmlsocket_event_xml(const fn_call& /* fn */)
-{
-#if 0
-  as_value* result = fn.result;
-  as_object* this_ptr = fn.this_ptr;
-  int nargs = fn.nargs;
-  int first_arg = fn.first_arg_bottom_index;
-#else
-  log_error("%s: unimplemented!\n", __FUNCTION__);
-#endif  
-}
-
-static XMLSocket xs;
-
-int
-check_sockets(int x)
-{
-  if (xml_fd == 0) {
-    return -1;
-  }
-  
-  return xs.checkSockets(x);
-}
-
-} // end of gnaash namespace
-
-// HAVE_LIBXML
-#endif

Index: server/xmlsocket.h
===================================================================
RCS file: server/xmlsocket.h
diff -N server/xmlsocket.h
--- server/xmlsocket.h  3 Nov 2006 14:03:37 -0000       1.13
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,119 +0,0 @@
-// 
-//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
-// 
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-// 
-//
-//
-
-#ifndef __XMLSOCKET_H__
-#define __XMLSOCKET_H__
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "tu_config.h"
-#include "xml.h"
-#include "impl.h"
-
-#include <string>
-
-#ifdef HAVE_LIBXML
-
-namespace gnash {
-
-extern const int SOCKET_DATA;
-  
-class DSOLOCAL XMLSocket {
- public:
-  XMLSocket();
-  ~XMLSocket();
-  
-  bool connect(const char *host, int port);
-  bool send(std::string str);
-  void close();
-
-  
-  bool anydata(char **msgs);
-  bool anydata(int sockfd, char **msgs);
-  bool connected() { return _connect; };
-  bool fdclosed() { return _closed; }
-  bool xmlmsg() { return _xmldata; }
-  
-  void messagesClear()      { _messages.clear(); }
-  void messageRemove(int x) { _messages.erase(_messages.begin() + x); }
-  int messagesCount()       { return _messages.size(); }
-  std::string operator [] (int x)  { return _messages[x]; }
-  
-  bool processingData();
-  void processing(bool x);
- 
-  // Event Handlers
-  void onClose(std::string);
-  void onConnect(std::string);
-  void onData(std::string);
-  void onXML(std::string);
-
-  // These handle the array of XML nodes
-  void push(as_object *obj);
-  void clear();
-  int  count();
-
-  int checkSockets(void);
-  int checkSockets(int x);
-
- private:
-  std::string  _host;
-  short         _port;
-  int           _sockfd;
-  bool          _data;
-  bool          _xmldata;
-  bool          _closed;
-  bool          _connect;
-  bool          _processing;
-  std::vector<std::string> _messages;
-  std::vector<as_object *>  _nodes;
-};
-
-
-class DSOLOCAL xmlsocket_as_object : public gnash::as_object
-{
-public:
-  XMLSocket obj;
-};
-
-DSOEXPORT void xmlsocket_connect(const fn_call& fn);
-DSOEXPORT void xmlsocket_send(const fn_call& fn);
-DSOEXPORT void xmlsocket_xml_new(const fn_call& fn);
-DSOEXPORT void xmlsocket_new(const fn_call& fn);
-DSOEXPORT void xmlsocket_close(const fn_call& fn);
-
-// These are the event handlers called for this object
-DSOEXPORT void xmlsocket_event_ondata(const fn_call& fn);
-DSOEXPORT void xmlsocket_event_close(const fn_call& fn);
-DSOEXPORT void xmlsocket_event_connect(const fn_call& fn);
-DSOEXPORT void xmlsocket_event_xml(const fn_call& fn);
-
-DSOEXPORT int check_sockets(int fd);
- 
-} // end of gnash namespace
-
-// HAVE_LIBXML
-#endif
-
-// __XMLSOCKETSOCKET_H__
-#endif
-




reply via email to

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