[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11036: migrated the XML document to
From: |
Ben Limmer |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11036: migrated the XML document to new namespace (still working on bug in testcase) |
Date: |
Mon, 08 Jun 2009 10:10:02 -0600 |
User-agent: |
Bazaar (1.13.1) |
------------------------------------------------------------
revno: 11036
committer: Ben Limmer <address@hidden>
branch nick: trunk
timestamp: Mon 2009-06-08 10:10:02 -0600
message:
migrated the XML document to new namespace (still working on bug in testcase)
removed:
libcore/asobj/XML_as.cpp
libcore/asobj/XML_as.h
modified:
libcore/ClassHierarchy.cpp
libcore/asobj/Global.cpp
libcore/asobj/Makefile.am
libcore/asobj/XMLSocket_as.cpp
libcore/asobj/flash/xml/XMLDocument_as.cpp
libcore/asobj/flash/xml/XMLDocument_as.h
libcore/asobj/flash/xml/XMLNode_as.cpp
testsuite/actionscript.all/XML.as
------------------------------------------------------------
revno: 11004.2.1
committer: Ben Limmer <address@hidden>
branch nick: branch_4
timestamp: Mon 2009-06-08 10:08:56 -0600
message:
migrated the XML document to new namespace (still working on bug in
testcase)
removed:
libcore/asobj/XML_as.cpp
libcore/asobj/XML_as.h
modified:
libcore/ClassHierarchy.cpp
libcore/asobj/Global.cpp
libcore/asobj/Makefile.am
libcore/asobj/XMLSocket_as.cpp
libcore/asobj/flash/xml/XMLDocument_as.cpp
libcore/asobj/flash/xml/XMLDocument_as.h
libcore/asobj/flash/xml/XMLNode_as.cpp
testsuite/actionscript.all/XML.as
=== modified file 'libcore/ClassHierarchy.cpp'
--- a/libcore/ClassHierarchy.cpp 2009-06-05 20:31:43 +0000
+++ b/libcore/ClassHierarchy.cpp 2009-06-08 16:10:02 +0000
@@ -63,7 +63,7 @@
#include "ClassHierarchy.h"
#include "builtin_function.h"
#include "XMLSocket_as.h"
-#include "XML_as.h"
+#include "xml/XMLDocument_as.h"
#include "xml/XMLNode_as.h"
#include "asClass.h"
#include "flash/text/TextFieldAutoSize_as.h"
@@ -304,7 +304,7 @@
{ xmlsocket_class_init, NSV::CLASS_XMLSOCKET, NSV::CLASS_OBJECT,
NSV::NS_FLASH_NET, 5 },
{ Date_as::init, NSV::CLASS_DATE, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
- { XML_as::init, NSV::CLASS_XML, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
+ { XMLDocument_as::init, NSV::CLASS_XML, NSV::CLASS_OBJECT, NS_GLOBAL, 5
},
{ XMLNode_as::init, NSV::CLASS_XMLNODE, NSV::CLASS_OBJECT,
NSV::NS_FLASH_XML, 5 },
{ mouse_class_init, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT,
NSV::NS_FLASH_UI,
=== modified file 'libcore/asobj/Global.cpp'
--- a/libcore/asobj/Global.cpp 2009-05-26 14:42:44 +0000
+++ b/libcore/asobj/Global.cpp 2009-06-08 16:08:56 +0000
@@ -43,7 +43,7 @@
#include "Number_as.h"
#include "Object.h"
#include "Math_as.h"
-#include "XML_as.h"
+#include "flash/xml/XMLDocument_as.h"
#include "XMLSocket_as.h"
#include "flash/ui/Mouse_as.h"
#include "MovieClipLoader.h"
@@ -899,7 +899,7 @@
// LoadableObject has natives shared between LoadVars and XML, so
// should be registered first.
LoadableObject::registerNative(global);
- XML_as::registerNative(global);
+ XMLDocument_as::registerNative(global);
XMLNode_as::registerNative(global);
}
=== modified file 'libcore/asobj/Makefile.am'
--- a/libcore/asobj/Makefile.am 2009-06-06 07:02:01 +0000
+++ b/libcore/asobj/Makefile.am 2009-06-08 16:10:02 +0000
@@ -82,7 +82,6 @@
TextSnapshot_as.cpp \
MovieClipLoader.cpp\
String_as.cpp \
- XML_as.cpp \
XMLSocket_as.cpp \
LoadableObject.cpp \
Object.cpp
@@ -116,7 +115,6 @@
TextFormat_as.h \
TextSnapshot_as.h \
String_as.h \
- XML_as.h \
XMLSocket_as.h \
LoadableObject.h \
Namespace_as.h \
=== modified file 'libcore/asobj/XMLSocket_as.cpp'
--- a/libcore/asobj/XMLSocket_as.cpp 2009-06-03 16:05:40 +0000
+++ b/libcore/asobj/XMLSocket_as.cpp 2009-06-08 16:08:56 +0000
@@ -24,7 +24,7 @@
#include "GnashSystemFDHeaders.h"
#include "network.h"
#include "utility.h"
-#include "XML_as.h"
+#include "xml/XMLDocument_as.h"
#include "XMLSocket_as.h"
#include "as_function.h"
#include "movie_root.h"
@@ -547,7 +547,7 @@
return as_value();
}
- boost::intrusive_ptr<as_object> xml = new XML_as(xmlin);
+ boost::intrusive_ptr<as_object> xml = new XMLDocument_as(xmlin);
as_value arg(xml.get());
ptr->callMethod(NSV::PROP_ON_XML, arg);
=== removed file 'libcore/asobj/XML_as.cpp'
--- a/libcore/asobj/XML_as.cpp 2009-06-04 21:48:41 +0000
+++ b/libcore/asobj/XML_as.cpp 1970-01-01 00:00:00 +0000
@@ -1,985 +0,0 @@
-// xml.cpp: XML markup language support, for Gnash.
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 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 3 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
-//
-
-// The XML parsing algorithms are based on swfdec's parsing model.
-
-#ifdef HAVE_CONFIG_H
-#include "gnashconfig.h"
-#endif
-
-#include "log.h"
-#include "as_function.h" // for as_function
-#include "fn_call.h"
-
-#include "LoadableObject.h"
-#include "xml/XMLNode_as.h"
-#include "XML_as.h"
-#include "builtin_function.h"
-#include "VM.h"
-#include "namedStrings.h"
-#include "StringPredicates.h"
-
-#include <string>
-#include <sstream>
-#include <vector>
-#include <algorithm>
-#include <boost/assign/list_of.hpp>
-#include <boost/algorithm/string/compare.hpp>
-#include <boost/algorithm/string/replace.hpp>
-
-
-namespace gnash {
-
-//#define DEBUG_MEMORY_ALLOCATION 1
-
-// Define this to enable verbosity of XML loads
-//#define DEBUG_XML_LOADS 1
-
-// Define this to enable verbosity of XML parsing
-//#define DEBUG_XML_PARSE 1
-// Forward declarations.
-namespace {
- as_object* getXMLInterface();
- void attachXMLInterface(as_object& o);
- void attachXMLProperties(as_object& o);
-
- as_value xml_new(const fn_call& fn);
- as_value xml_createElement(const fn_call& fn);
- as_value xml_createTextNode(const fn_call& fn);
- as_value xml_getBytesLoaded(const fn_call& fn);
- as_value xml_getBytesTotal(const fn_call& fn);
- as_value xml_parseXML(const fn_call& fn);
- as_value xml_ondata(const fn_call& fn);
- as_value xml_xmlDecl(const fn_call& fn);
- as_value xml_docTypeDecl(const fn_call& fn);
- as_value xml_escape(const fn_call& fn);
-
- bool textAfterWhitespace(const std::string& xml,
- std::string::const_iterator& it);
- bool textMatch(const std::string& xml, std::string::const_iterator& it,
- const std::string& match, bool advance = true);
- bool parseNodeWithTerminator(const std::string& xml,
- std::string::const_iterator& it, const std::string& terminator,
- std::string& content);
-}
-
-XML_as::XML_as()
- :
- as_object(getXMLInterface()),
- _loaded(-1),
- _status(XML_OK)
-{
-#ifdef DEBUG_MEMORY_ALLOCATION
- log_debug(_("Creating XML data at %p"), this);
-#endif
-
- attachXMLProperties(*this);
-}
-
-
-// Parse the ASCII XML string into an XMLNode tree
-XML_as::XML_as(const std::string& xml)
- :
- as_object(getXMLInterface()),
- _loaded(-1),
- _status(XML_OK)
-{
-#ifdef DEBUG_MEMORY_ALLOCATION
- log_debug(_("Creating XML data at %p"), this);
-#endif
-
- parseXML(xml);
-}
-
-const XML_as::Entities&
-XML_as::getEntities()
-{
-
- static Entities entities = boost::assign::map_list_of
- ("&", "&")
- (""", "\"")
- ("<", "<")
- (">", ">")
- ("'", "'");
-
- return entities;
-
-}
-
-void
-XML_as::escape(std::string& text)
-{
- const Entities& ent = getEntities();
-
- for (Entities::const_iterator i = ent.begin(), e = ent.end();
- i != e; ++i)
- {
- boost::replace_all(text, i->second, i->first);
- }
-}
-
-void
-XML_as::unescape(std::string& text)
-{
- const Entities& ent = getEntities();
-
- for (Entities::const_iterator i = ent.begin(), e = ent.end();
- i != e; ++i)
- {
- boost::replace_all(text, i->first, i->second);
- }
-
-}
-
-void
-XML_as::toString(std::ostream& o, bool encode) const
-{
- if (!_xmlDecl.empty()) o << _xmlDecl;
- if (!_docTypeDecl.empty()) o << _docTypeDecl;
-
- XMLNode_as::toString(o, encode);
-}
-
-bool
-XML_as::get_member(string_table::key name, as_value *val,
- string_table::key nsname)
-{
- if (name == NSV::PROP_STATUS)
- {
- val->set_int(_status);
- return true;
- }
- else if (name == NSV::PROP_LOADED)
- {
- if ( _loaded < 0 ) val->set_undefined();
- else val->set_bool(_loaded);
- return true;
- }
-
- return as_object::get_member(name, val, nsname);
-}
-
-bool
-XML_as::set_member(string_table::key name, const as_value& val,
- string_table::key nsname, bool ifFound)
-{
- if (name == NSV::PROP_STATUS)
- {
- // TODO: this should really be a proper property (see XML.as)
- if ( ! val.is_number() )
- {
- _status = static_cast<ParseStatus>(
- std::numeric_limits<boost::int32_t>::min());
- }
- else
- {
- unsigned int statusNumber = static_cast<int>(val.to_number());
- _status = static_cast<ParseStatus>(statusNumber);
- }
- return true;
- }
- else if (name == NSV::PROP_LOADED)
- {
- // TODO: this should really be a proper property
- bool b = val.to_bool();
- if ( b ) _loaded = 1;
- else _loaded = 0;
- return true;
- }
-
- return as_object::set_member(name, val, nsname, ifFound);
-}
-
-void
-XML_as::parseAttribute(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it, Attributes& attributes)
-{
-
- const std::string terminators("\r\t\n >=");
-
- std::string::const_iterator end = std::find_first_of(it, xml.end(),
- terminators.begin(), terminators.end());
-
- if (end == xml.end()) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
- std::string name(it, end);
-
- if (name.empty()) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
-
- // Point iterator to the DisplayObject after the name.
- it = end;
-
- // Skip any whitespace before the '='. If we reach the end of the string
- // or don't find an '=', it's a parser error.
- if (!textAfterWhitespace(xml, it) || *it != '=') {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
-
- // Point to the DisplayObject after the '='
- ++it;
-
- // Skip any whitespace. If we reach the end of the string, or don't find
- // a " or ', it's a parser error.
- if (!textAfterWhitespace(xml, it) || (*it != '"' && *it != '\'')) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
-
- // Find the end of the attribute, looking for the opening DisplayObject,
- // as long as it's not escaped. We begin one after the present position,
- // which should be the opening DisplayObject. We want to remember what the
- // iterator is pointing to for a while, so don't advance it.
- end = it;
- do {
- ++end;
- end = std::find(end, xml.end(), *it);
- } while (end != xml.end() && *(end - 1) == '\\');
-
- if (end == xml.end()) {
- _status = XML_UNTERMINATED_ATTRIBUTE;
- return;
- }
- ++it;
-
- std::string value(it, end);
-
- // Replace entities in the value.
- unescape(value);
-
- //log_debug("adding attribute to node %s: %s, %s", node->nodeName(),
- // name, value);
-
- // We've already checked that end != xml.end(), so we can advance at
- // least once.
- it = end;
- // Advance past the last attribute DisplayObject
- ++it;
-
- // Handle namespace. This is set once only for each node, and is also
- // pushed to the attributes list once.
- StringNoCaseEqual noCaseCompare;
- if (noCaseCompare(name, "xmlns") || noCaseCompare(name, "xmlns:")) {
- if (!node->getNamespaceURI().empty()) return;
- node->setNamespaceURI(value);
- }
-
- // This ensures values are not inserted twice, which is expected
- // behaviour
- attributes.insert(std::make_pair(name, value));
-
-}
-
-/// Parse and set the docTypeDecl. This is stored without any validation and
-/// with the same case as in the parsed XML.
-void
-XML_as::parseDocTypeDecl(const std::string& xml,
- std::string::const_iterator& it)
-{
-
- std::string::const_iterator end;
- std::string::const_iterator current = it;
-
- std::string::size_type count = 1;
-
- // Look for angle brackets in the doctype declaration.
- while (count) {
-
- // Find the next closing bracket after the current position.
- end = std::find(current, xml.end(), '>');
- if (end == xml.end()) {
- _status = XML_UNTERMINATED_DOCTYPE_DECL;
- return;
- }
- --count;
-
- // Count any opening brackets in between.
- count += std::count(current, end, '<');
- current = end;
- ++current;
- }
-
- const std::string content(it, end);
- std::ostringstream os;
- os << '<' << content << '>';
- _docTypeDecl = os.str();
- it = end + 1;
-}
-
-
-void
-XML_as::parseXMLDecl(const std::string& xml, std::string::const_iterator& it)
-{
- std::string content;
- if (!parseNodeWithTerminator(xml, it, "?>", content))
- {
- _status = XML_UNTERMINATED_XML_DECL;
- return;
- }
-
- std::ostringstream os;
- os << "<" << content << "?>";
-
- // This is appended to any xmlDecl already there.
- _xmlDecl += os.str();
-
-}
-
-// The iterator should be pointing to the first char after the '<'
-void
-XML_as::parseTag(XMLNode_as*& node, const std::string& xml,
- std::string::const_iterator& it)
-{
- //log_debug("Processing node: %s", node->nodeName());
-
- bool closing = (*it == '/');
- if (closing) ++it;
-
- // These are for terminating the tag name, not (necessarily) the tag.
- const std::string terminators("\r\n\t >");
-
- std::string::const_iterator endName = std::find_first_of(it, xml.end(),
- terminators.begin(), terminators.end());
-
- // Check that one of the terminators was found; otherwise it's malformed.
- if (endName == xml.end()) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
-
- // Knock off the "/>" of a self-closing tag.
- if (std::equal(endName - 1, endName + 1, "/>")) {
- // This can leave endName before it, e.g when a self-closing tag is
- // empty ("</>"). This must be checked before trying to construct
- // a string!
- --endName;
- }
-
- // If the tag is empty, the XML counts as malformed.
- if (it >= endName) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
-
- std::string tagName(it, endName);
-
- if (!closing) {
-
- XMLNode_as* childNode = new XMLNode_as;
- childNode->nodeNameSet(tagName);
- childNode->nodeTypeSet(Element);
-
- //log_debug("created childNode with name %s", childNode->nodeName());
- // Skip to the end of any whitespace after the tag name
- it = endName;
-
- if (!textAfterWhitespace(xml, it)) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
-
- // Parse any attributes in an opening tag only, stopping at "/>" or
- // '>'
- // Attributes are added in reverse order and without any duplicates.
- Attributes attributes;
- while (it != xml.end() && *it != '>' && _status == XML_OK)
- {
- if (xml.end() - it > 1 && std::equal(it, it + 2, "/>")) break;
-
- // This advances the iterator
- parseAttribute(childNode, xml, it, attributes);
-
- // Skip any whitespace. If we reach the end of the string,
- // it's malformed.
- if (!textAfterWhitespace(xml, it)) {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
- }
-
- // Do nothing more if there was an error in attributes parsing.
- if (_status != XML_OK) return;
-
- for (Attributes::const_reverse_iterator i = attributes.rbegin(),
- e = attributes.rend(); i != e; ++i) {
- childNode->setAttribute(i->first, i->second);
- }
-
- node->appendChild(childNode);
- if (*it == '/') ++it;
- else node = childNode;
-
- if (*it == '>') ++it;
-
- return;
- }
-
- // If we reach here, this is a closing tag.
-
- it = std::find(endName, xml.end(), '>');
-
- if (it == xml.end())
- {
- _status = XML_UNTERMINATED_ELEMENT;
- return;
- }
- ++it;
-
- StringNoCaseEqual noCaseCompare;
-
- if (node->getParent() && noCaseCompare(node->nodeName(), tagName)) {
- node = node->getParent();
- }
- else {
- // Malformed. Search for the parent node.
- XMLNode_as* s = node;
- while (s && !noCaseCompare(s->nodeName(), tagName)) {
- //log_debug("parent: %s, this: %s", s->nodeName(), tagName);
- s = s->getParent();
- }
- if (s) {
- // If there's a parent, the open tag is orphaned.
- _status = XML_MISSING_CLOSE_TAG;
- }
- else {
- // If no parent, the close tag is orphaned.
- _status = XML_MISSING_OPEN_TAG;
- }
- }
-
-}
-
-void
-XML_as::parseText(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it)
-{
- std::string::const_iterator end = std::find(it, xml.end(), '<');
- std::string content(it, end);
-
- it = end;
-
- if (ignoreWhite() &&
- content.find_first_not_of("\t\r\n ") == std::string::npos) return;
-
- XMLNode_as* childNode = new XMLNode_as;
-
- childNode->nodeTypeSet(XMLNode_as::Text);
-
- // Replace any entitites.
- unescape(content);
-
- childNode->nodeValueSet(content);
- node->appendChild(childNode);
-
- //log_debug("appended text node: %s", content);
-}
-
-
-
-void
-XML_as::parseComment(XMLNode_as* /*node*/, const std::string& xml,
- std::string::const_iterator& it)
-{
- //log_debug("discarding comment node");
-
- std::string content;
-
- if (!parseNodeWithTerminator(xml, it, "-->", content)) {
- _status = XML_UNTERMINATED_COMMENT;
- return;
- }
- // Comments are discarded at least up to SWF8
-
-}
-
-void
-XML_as::parseCData(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it)
-{
- std::string content;
-
- if (!parseNodeWithTerminator(xml, it, "]]>", content)) {
- _status = XML_UNTERMINATED_CDATA;
- return;
- }
-
- XMLNode_as* childNode = new XMLNode_as;
- childNode->nodeValueSet(content);
- childNode->nodeTypeSet(Text);
- node->appendChild(childNode);
-
-}
-
-
-// This parses an XML string into a tree of XMLNodes.
-void
-XML_as::parseXML(const std::string& xml)
-{
- GNASH_REPORT_FUNCTION;
- if (xml.empty())
- {
- log_error(_("XML data is empty"));
- return;
- }
-
- // Clear current data
- clear();
- _status = XML_OK;
-
- std::string::const_iterator it = xml.begin();
- XMLNode_as* node = this;
-
- while (it != xml.end() && _status == XML_OK)
- {
- if (*it == '<')
- {
- ++it;
- if (textMatch(xml, it, "!DOCTYPE", false))
- {
- // We should not advance past the DOCTYPE label, as
- // the case is preserved.
- parseDocTypeDecl(xml, it);
- }
- else if (textMatch(xml, it, "?xml", false))
- {
- // We should not advance past the xml label, as
- // the case is preserved.
- parseXMLDecl(xml, it);
- }
- else if (textMatch(xml, it, "!--"))
- {
- parseComment(node, xml, it);
- }
- else if (textMatch(xml, it, "![CDATA["))
- {
- parseCData(node, xml, it);
- }
- else parseTag(node, xml, it);
- }
- else parseText(node, xml, it);
- }
-
- // If everything parsed correctly, check that we've got back to the
- // parent node. If not, there is a missing closing tag.
- if (_status == XML_OK && node != this) {
- _status = XML_MISSING_CLOSE_TAG;
- }
-
-}
-
-bool
-XML_as::onLoad()
-{
- log_debug(_("%s: FIXME: onLoad Default event handler"), __FUNCTION__);
-
- return(_loaded);
-}
-
-
-void
-XML_as::clear()
-{
- // TODO: should set childs's parent to NULL ?
- _children.clear();
- _docTypeDecl.clear();
- _xmlDecl.clear();
-}
-
-bool
-XML_as::ignoreWhite() const
-{
-
- string_table::key propnamekey = _vm.getStringTable().find("ignoreWhite");
- as_value val;
- if (!const_cast<XML_as*>(this)->get_member(propnamekey, &val)) {
- return false;
- }
- return val.to_bool();
-}
-
-
-// extern (used by Global.cpp)
-void
-XML_as::init(as_object& global)
-{
-
- static boost::intrusive_ptr<builtin_function> cl;
-
- if ( cl == NULL )
- {
- cl=new builtin_function(&xml_new, getXMLInterface());
- }
-
- global.init_member("XML", cl.get());
-
-}
-
-void
-XML_as::registerNative(as_object& global)
-{
- VM& vm = global.getVM();
- vm.registerNative(xml_escape, 100, 5);
- vm.registerNative(xml_createElement, 253, 8);
- vm.registerNative(xml_createTextNode, 253, 9);
- vm.registerNative(xml_parseXML, 253, 10);
-}
-
-///
-/// XML object AS interface.
-///
-
-namespace {
-
-void
-attachXMLProperties(as_object& /*o*/)
-{
- // if we use a proper member here hasOwnProperty() would return true
- // but we want it to return false instead. See XML.as
- //o.init_member("status", as_value(XML::sOK));
-}
-
-
-void
-attachXMLInterface(as_object& o)
-{
-
- VM& vm = o.getVM();
-
- const int flags = 0;
-
- // No flags:
- o.init_member("addRequestHeader", new builtin_function(
- LoadableObject::loadableobject_addRequestHeader), flags);
- o.init_member("createElement", vm.getNative(253, 8), flags);
- o.init_member("createTextNode", vm.getNative(253, 9), flags);
- o.init_member("getBytesLoaded",
- new builtin_function(xml_getBytesLoaded), flags);
- o.init_member("getBytesTotal",
- new builtin_function(xml_getBytesTotal), flags);
- o.init_member("load", vm.getNative(301, 0), flags);
- o.init_member("parseXML", vm.getNative(253, 10), flags);
- o.init_member("send", vm.getNative(301, 1), flags);
- o.init_member("sendAndLoad", vm.getNative(301, 2), flags);
- o.init_member("onData", new builtin_function(xml_ondata), flags);
-
- o.init_property("xmlDecl", &xml_xmlDecl, &xml_xmlDecl, flags);
- o.init_property("docTypeDecl", &xml_docTypeDecl, &xml_docTypeDecl, flags);
-}
-
-as_object*
-getXMLInterface()
-{
- static boost::intrusive_ptr<as_object> o;
- if ( o == NULL )
- {
- o = new as_object(XMLNode_as::getXMLNodeInterface());
- VM::get().addStatic(o.get());
- attachXMLInterface(*o);
- }
- return o.get();
-}
-
-as_value
-xml_new(const fn_call& fn)
-{
- boost::intrusive_ptr<XML_as> xml_obj;
-
- if ( fn.nargs > 0 )
- {
- if ( fn.arg(0).is_object() )
- {
- boost::intrusive_ptr<as_object> obj = fn.arg(0).to_object();
- xml_obj = dynamic_cast<XML_as*>(obj.get());
- if ( xml_obj )
- {
- log_debug(_("Cloned the XML object at %p"),
- (void *)xml_obj.get());
- return as_value(xml_obj->cloneNode(true).get());
- }
- }
-
- const std::string& xml_in = fn.arg(0).to_string();
- if ( xml_in.empty() )
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror(_("First arg given to XML constructor (%s) "
- "evaluates to the empty string"), fn.arg(0));
- );
- }
- else
- {
- xml_obj = new XML_as(xml_in);
- return as_value(xml_obj.get());
- }
- }
-
- xml_obj = new XML_as;
-
- return as_value(xml_obj.get());
-}
-
-
-/// Only available as ASnative.
-as_value
-xml_escape(const fn_call& fn)
-{
- if (!fn.nargs) return as_value();
-
- std::string escaped = fn.arg(0).to_string();
- XML_as::escape(escaped);
- return as_value(escaped);
-}
-
-/// \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.
-as_value
-xml_createElement(const fn_call& fn)
-{
-
- if (fn.nargs > 0)
- {
- const std::string& text = fn.arg(0).to_string();
- XMLNode_as *xml_obj = new XMLNode_as;
- xml_obj->nodeNameSet(text);
- xml_obj->nodeTypeSet(XMLNode_as::Text);
-
- return as_value(xml_obj);
-
- }
- else {
- log_error(_("no text for element creation"));
- }
- return as_value();
-}
-
-
-/// \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.
-as_value
-xml_createTextNode(const fn_call& fn)
-{
-
- if (fn.nargs > 0) {
- const std::string& text = fn.arg(0).to_string();
- XMLNode_as* xml_obj = new XMLNode_as;
- xml_obj->nodeValueSet(text);
- xml_obj->nodeTypeSet(XMLNode_as::Text);
- return as_value(xml_obj);
- }
- else {
- log_error(_("no text for text node creation"));
- }
- return as_value();
-}
-
-
-as_value
-xml_getBytesLoaded(const fn_call& fn)
-{
- boost::intrusive_ptr<XML_as> ptr = ensureType<XML_as>(fn.this_ptr);
- long int ret = ptr->getBytesLoaded();
- if ( ret < 0 ) return as_value();
- else return as_value(ret);
-}
-
-
-as_value
-xml_getBytesTotal(const fn_call& fn)
-{
- boost::intrusive_ptr<XML_as> ptr = ensureType<XML_as>(fn.this_ptr);
- long int ret = ptr->getBytesTotal();
- if ( ret < 0 ) return as_value();
- else return as_value(ret);
-}
-
-
-as_value
-xml_parseXML(const fn_call& fn)
-{
-
- boost::intrusive_ptr<XML_as> ptr = ensureType<XML_as>(fn.this_ptr);
-
- if (fn.nargs < 1)
- {
- IF_VERBOSE_ASCODING_ERRORS(
- log_aserror("XML.parseXML() needs one argument");
- );
- return as_value();
- }
-
- const std::string& text = fn.arg(0).to_string();
- ptr->parseXML(text);
-
- return as_value();
-}
-
-as_value
-xml_xmlDecl(const fn_call& fn)
-{
- boost::intrusive_ptr<XML_as> ptr = ensureType<XML_as>(fn.this_ptr);
-
- if (!fn.nargs)
- {
- // Getter
- const std::string& xml = ptr->getXMLDecl();
- if (xml.empty()) return as_value();
- return as_value(xml);
- }
-
- // Setter
-
- const std::string& xml = fn.arg(0).to_string();
- ptr->setDocTypeDecl(xml);
-
- return as_value();
-
-}
-
-as_value
-xml_docTypeDecl(const fn_call& fn)
-{
- boost::intrusive_ptr<XML_as> ptr = ensureType<XML_as>(fn.this_ptr);
-
- if (!fn.nargs)
- {
- // Getter
- const std::string& docType = ptr->getDocTypeDecl();
- if (docType.empty()) return as_value();
- return as_value(docType);
- }
-
- // Setter
-
- const std::string& docType = fn.arg(0).to_string();
- ptr->setDocTypeDecl(docType);
-
- return as_value();
-
-}
-
-as_value
-xml_ondata(const fn_call& fn)
-{
-
- as_object* thisPtr = fn.this_ptr.get();
- assert(thisPtr);
-
- // See http://gitweb.freedesktop.org/?p=swfdec/swfdec.git;
- // a=blob;f=libswfdec/swfdec_initialize.as
-
- as_value src;
- if (fn.nargs) src = fn.arg(0);
-
- if (!src.is_undefined()) {
- thisPtr->set_member(NSV::PROP_LOADED, true);
- thisPtr->callMethod(NSV::PROP_PARSE_XML, src);
- thisPtr->callMethod(NSV::PROP_ON_LOAD, true);
- }
- else {
- thisPtr->set_member(NSV::PROP_LOADED, false);
- thisPtr->callMethod(NSV::PROP_ON_LOAD, false);
- }
-
- return as_value();
-}
-
-/// Case insensitive match of a string, returning false if there too few
-/// DisplayObjects left or if there is no match. If there is a match, and
advance
-/// is not false, the iterator points to the DisplayObject after the match.
-bool
-textMatch(const std::string& xml, std::string::const_iterator& it,
- const std::string& match, bool advance)
-{
-
- const std::string::size_type len = match.length();
- const std::string::const_iterator end = xml.end();
-
- if (static_cast<size_t>(end - it) < len) return false;
-
- if (!std::equal(it, it + len, match.begin(), boost::is_iequal())) {
- return false;
- }
- if (advance) it += len;
- return true;
-}
-
-/// Advance past whitespace
-//
-/// @return true if there is text after the whitespace, false if we
-/// reach the end of the string.
-bool
-textAfterWhitespace(const std::string& xml, std::string::const_iterator& it)
-{
- const std::string whitespace("\r\t\n ");
- while (it != xml.end() && whitespace.find(*it) != std::string::npos) ++it;
- return (it != xml.end());
-}
-
-/// Parse a complete node up to a specified terminator.
-//
-/// @return false if we reach the end of the text before finding the
-/// terminator.
-/// @param it The current position of the iterator. If the return is true,
-/// this points to the first DisplayObject after the terminator
-/// after return
-/// @param content If the return is true, this is filled with the content of
-/// the tag.
-/// @param xml The complete XML string.
-bool
-parseNodeWithTerminator(const std::string& xml,
- std::string::const_iterator& it, const std::string& terminator,
- std::string& content)
-{
- std::string::const_iterator end = std::search(it, xml.end(),
- terminator.begin(), terminator.end());
-
- if (end == xml.end()) {
- return false;
- }
-
- content = std::string(it, end);
- it = end + terminator.length();
-
- return true;
-}
-
-} // anonymous namespace
-} // end of gnash namespace
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== removed file 'libcore/asobj/XML_as.h'
--- a/libcore/asobj/XML_as.h 2009-06-04 21:48:41 +0000
+++ b/libcore/asobj/XML_as.h 1970-01-01 00:00:00 +0000
@@ -1,191 +0,0 @@
-//
-// Copyright (C) 2005, 2006, 2007, 2008, 2009 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 3 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 GNASH_ASOBJ_XML_H
-#define GNASH_ASOBJ_XML_H
-
-#include "LoadableObject.h"
-#include "xml/XMLNode_as.h"
-#include "log.h"
-#include "dsodefs.h"
-#include "StringPredicates.h"
-
-#include <map>
-#include <string>
-
-//#define DEBUG_MEMORY_ALLOCATION 1
-
-namespace gnash {
-
-// Forward declarations
-class fn_call;
-class URL;
-class LoaderThread;
-
-/// XML class and ActionScript object
-class XML_as : public XMLNode_as, public LoadableObject
-{
-public:
-
- enum ParseStatus {
- XML_OK = 0,
- XML_UNTERMINATED_CDATA = -2,
- XML_UNTERMINATED_XML_DECL = -3,
- XML_UNTERMINATED_DOCTYPE_DECL = -4,
- XML_UNTERMINATED_COMMENT = -5,
- XML_UNTERMINATED_ELEMENT = -6,
- XML_OUT_OF_MEMORY = -7,
- XML_UNTERMINATED_ATTRIBUTE = -8,
- XML_MISSING_CLOSE_TAG = -9,
- XML_MISSING_OPEN_TAG = -10
- };
-
- XML_as();
-
- XML_as(const std::string& xml);
-
- ~XML_as() {};
-
- static void init(as_object& global);
- static void registerNative(as_object& global);
-
- /// Convert the XML object to a string
- //
- /// This calls XMLNode::toString after adding an xmlDecl and
- /// docTypeDecl
- //
- /// @param o The ostream to write the string to.
- /// @param encode Whether to URL encode the node values.
- void toString(std::ostream& o, bool encode) const;
-
- const std::string& getXMLDecl() const {
- return _xmlDecl;
- }
-
- void setXMLDecl(const std::string& xml) {
- _xmlDecl = xml;
- }
-
- const std::string& getDocTypeDecl() const {
- return _docTypeDecl;
- }
-
- void setDocTypeDecl(const std::string& docType) {
- _docTypeDecl = docType;
- }
-
- /// This is overridden to provide the 'status' and 'loaded' members,
- /// which are NOT proper properties !
- /// See actionscript.all/XML.as
- ///
- bool get_member(string_table::key name, as_value *val,
- string_table::key nsname = 0);
-
- /// This is overridden to provide the 'status' and 'loaded' members,
- /// which are NOT proper properties !
- /// See actionscript.all/XML.as
- ///
- bool set_member(string_table::key name, const as_value& val,
- string_table::key nsname = 0, bool ifFound=false);
-
- // Methods
-
- /// Parses an XML document into the specified XML object tree.
- //
- /// This reads in an XML file from disk and parses into into a memory
- /// resident tree which can be walked through later.
- ///
- /// Calls to this function clear any precedently parsed data.
- ///
- void parseXML(const std::string& xml);
-
- // An event handler that returns a what?
- bool onLoad();
-
- /// Escape using XML entities.
- //
- /// Note this is not the same as a URL escape.
- static void escape(std::string& text);
-
- /// Unescape XML entities.
- //
- /// Note this is not the same as a URL unescape.
- static void unescape(std::string& text);
-
- XMLNode_as* createElement(const std::string& name);
-
- XMLNode_as* createTextNode(const std::string& name);
-
-private:
-
- typedef std::map<std::string, std::string> Entities;
-
- static const Entities& getEntities();
-
- typedef std::map<std::string, std::string, StringNoCaseLessThan>
Attributes;
-
- void parseTag(XMLNode_as*& node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseAttribute(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it, Attributes& attributes);
-
- void parseDocTypeDecl(const std::string& xml,
- std::string::const_iterator& it);
-
- void parseText(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseXMLDecl(const std::string& xml,
- std::string::const_iterator& it);
-
- void parseComment(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseCData(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- /// Remove all children
- void clear();
-
- /// \brief
- /// Return true if ignoreWhite property was set to anything evaluating
- /// to true.
- bool ignoreWhite() const;
-
- // -1 if never asked to load anything
- // 0 if asked to load but not yet loaded (or failure)
- // 1 if successfully loaded
- int _loaded;
-
- ParseStatus _status;
-
- std::string _docTypeDecl;
-
- std::string _xmlDecl;
-
-};
-
-} // namespace gnash
-
-#endif
-
-
-// Local Variables:
-// mode: C++
-// indent-tabs-mode: t
-// End:
=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.cpp'
--- a/libcore/asobj/flash/xml/XMLDocument_as.cpp 2009-05-28 17:11:03
+0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.cpp 2009-06-08 16:08:56
+0000
@@ -21,107 +21,953 @@
#include "gnashconfig.h"
#endif
-#include "xml/XMLDocument_as.h"
#include "log.h"
+#include "as_function.h" //for as_function
#include "fn_call.h"
+
+#include "LoadableObject.h"
+#include "xml/XMLNode_as.h"
+#include "xml/XMLDocument_as.h"
+#include "builtin_function.h"
+#include "VM.h"
+#include "namedStrings.h"
+#include "StringPredicates.h"
#include "smart_ptr.h" // for boost intrusive_ptr
-#include "builtin_function.h" // need builtin_function
#include "GnashException.h" // for ActionException
+#include <string>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+#include <boost/assign/list_of.hpp>
+#include <boost/algorithm/string/compare.hpp>
+#include <boost/algorithm/string/replace.hpp>
+
+
namespace gnash {
// Forward declarations
namespace {
- as_value xmldocument_createTextNode(const fn_call& fn);
- as_value xmldocument_parseXML(const fn_call& fn);
- as_value xmldocument_toString(const fn_call& fn);
+ as_object* getXMLInterface();
+ void attachXMLInterface(as_object& o);
+ void attachXMLProperties(as_object& o);
+ //left as xml to not break everything else (these exist in AS2&3)
+ as_value xml_new(const fn_call& fn);
+ as_value xml_createElement(const fn_call& fn);
+ as_value xml_createTextNode(const fn_call& fn);
+ as_value xml_getBytesLoaded(const fn_call& fn);
+ as_value xml_getBytesTotal(const fn_call& fn);
+ as_value xml_parseXML(const fn_call& fn);
+ as_value xml_ondata(const fn_call& fn);
+ as_value xml_xmlDecl(const fn_call& fn);
+ as_value xml_docTypeDecl(const fn_call& fn);
+ as_value xml_escape(const fn_call& fn);
+
+ bool textAfterWhitespace(const std::string& xml,
+ std::string::const_iterator& it);
+ bool textMatch(const std::string& xml, std::string::const_iterator& it,
+ const std::string& match, bool advance = true);
+ bool parseNodeWithTerminator(const std::string& xml,
+ std::string::const_iterator& it, const std::string& terminator,
+ std::string& content);
+
+
as_value xmldocument_ctor(const fn_call& fn);
- void attachXMLDocumentInterface(as_object& o);
- void attachXMLDocumentStaticInterface(as_object& o);
- as_object* getXMLDocumentInterface();
-
-}
-
-class XMLDocument_as : public as_object
-{
-
-public:
-
- XMLDocument_as()
- :
- as_object(getXMLDocumentInterface())
- {}
-};
+ void attachXMLProperties(as_object& /*o*/);
+ void attachXMLInterface(as_object& o);
+ as_object* getXMLInterface();
+
+}
+
+XMLDocument_as::XMLDocument_as()
+ :
+ as_object(getXMLInterface()),
+ _loaded(-1),
+ _status(XML_OK)
+{
+#ifdef DEBUG_MEMORY_ALLOCATION
+ log_debug(_("Creating XML data at %p"), this);
+#endif
+
+ attachXMLProperties(*this);
+}
+
+// Parse the ASCII XML string into an XMLNode tree
+XMLDocument_as::XMLDocument_as(const std::string& xml)
+ :
+ as_object(getXMLInterface()),
+ _loaded(-1),
+ _status(XML_OK)
+{
+#ifdef DEBUG_MEMORY_ALLOCATION
+ log_debug(_("Creating XML data at %p"), this);
+#endif
+
+ parseXML(xml);
+}
+
+const XMLDocument_as::Entities&
+XMLDocument_as::getEntities()
+{
+
+ static Entities entities = boost::assign::map_list_of
+ ("&", "&")
+ (""", "\"")
+ ("<", "<")
+ (">", ">")
+ ("'", "'");
+
+ return entities;
+
+}
+
+void
+XMLDocument_as::escape(std::string& text)
+{
+ const Entities& ent = getEntities();
+
+ for (Entities::const_iterator i = ent.begin(), e = ent.end();
+ i != e; ++i)
+ {
+ boost::replace_all(text, i->second, i->first);
+ }
+}
+
+void
+XMLDocument_as::unescape(std::string& text)
+{
+ const Entities& ent = getEntities();
+
+ for (Entities::const_iterator i = ent.begin(), e = ent.end();
+ i != e; ++i)
+ {
+ boost::replace_all(text, i->first, i->second);
+ }
+
+}
+
+void
+XMLDocument_as::toString(std::ostream& o, bool encode) const
+{
+ if (!_xmlDecl.empty()) o << _xmlDecl;
+ if (!_docTypeDecl.empty()) o << _docTypeDecl;
+
+ XMLNode_as::toString(o, encode);
+}
+
+bool
+XMLDocument_as::get_member(string_table::key name, as_value *val,
+ string_table::key nsname)
+{
+ if (name == NSV::PROP_STATUS)
+ {
+ val->set_int(_status);
+ return true;
+ }
+ else if (name == NSV::PROP_LOADED)
+ {
+ if ( _loaded < 0 ) val->set_undefined();
+ else val->set_bool(_loaded);
+ return true;
+ }
+
+ return as_object::get_member(name, val, nsname);
+}
+
+bool
+XMLDocument_as::set_member(string_table::key name, const as_value& val,
+ string_table::key nsname, bool ifFound)
+{
+ if (name == NSV::PROP_STATUS)
+ {
+ // TODO: this should really be a proper property (see XML.as)
+ if ( ! val.is_number() )
+ {
+ _status = static_cast<ParseStatus>(
+ std::numeric_limits<boost::int32_t>::min());
+ }
+ else
+ {
+ unsigned int statusNumber = static_cast<int>(val.to_number());
+ _status = static_cast<ParseStatus>(statusNumber);
+ }
+ return true;
+ }
+ else if (name == NSV::PROP_LOADED)
+ {
+ // TODO: this should really be a proper property
+ bool b = val.to_bool();
+ if ( b ) _loaded = 1;
+ else _loaded = 0;
+ return true;
+ }
+
+ return as_object::set_member(name, val, nsname, ifFound);
+}
+
+void
+XMLDocument_as::parseAttribute(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it, Attributes& attributes)
+{
+
+ const std::string terminators("\r\t\n >=");
+
+ std::string::const_iterator end = std::find_first_of(it, xml.end(),
+ terminators.begin(), terminators.end());
+
+ if (end == xml.end()) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+ std::string name(it, end);
+
+ if (name.empty()) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+
+ // Point iterator to the DisplayObject after the name.
+ it = end;
+
+ // Skip any whitespace before the '='. If we reach the end of the string
+ // or don't find an '=', it's a parser error.
+ if (!textAfterWhitespace(xml, it) || *it != '=') {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+
+ // Point to the DisplayObject after the '='
+ ++it;
+
+ // Skip any whitespace. If we reach the end of the string, or don't find
+ // a " or ', it's a parser error.
+ if (!textAfterWhitespace(xml, it) || (*it != '"' && *it != '\'')) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+
+ // Find the end of the attribute, looking for the opening DisplayObject,
+ // as long as it's not escaped. We begin one after the present position,
+ // which should be the opening DisplayObject. We want to remember what the
+ // iterator is pointing to for a while, so don't advance it.
+ end = it;
+ do {
+ ++end;
+ end = std::find(end, xml.end(), *it);
+ } while (end != xml.end() && *(end - 1) == '\\');
+
+ if (end == xml.end()) {
+ _status = XML_UNTERMINATED_ATTRIBUTE;
+ return;
+ }
+ ++it;
+
+ std::string value(it, end);
+
+ // Replace entities in the value.
+ unescape(value);
+
+ //log_debug("adding attribute to node %s: %s, %s", node->nodeName(),
+ // name, value);
+
+ // We've already checked that end != xml.end(), so we can advance at
+ // least once.
+ it = end;
+ // Advance past the last attribute DisplayObject
+ ++it;
+
+ // Handle namespace. This is set once only for each node, and is also
+ // pushed to the attributes list once.
+ StringNoCaseEqual noCaseCompare;
+ if (noCaseCompare(name, "xmlns") || noCaseCompare(name, "xmlns:")) {
+ if (!node->getNamespaceURI().empty()) return;
+ node->setNamespaceURI(value);
+ }
+
+ // This ensures values are not inserted twice, which is expected
+ // behaviour
+ attributes.insert(std::make_pair(name, value));
+
+}
+
+/// Parse and set the docTypeDecl. This is stored without any validation and
+/// with the same case as in the parsed XML.
+void
+XMLDocument_as::parseDocTypeDecl(const std::string& xml,
+ std::string::const_iterator& it)
+{
+
+ std::string::const_iterator end;
+ std::string::const_iterator current = it;
+
+ std::string::size_type count = 1;
+
+ // Look for angle brackets in the doctype declaration.
+ while (count) {
+
+ // Find the next closing bracket after the current position.
+ end = std::find(current, xml.end(), '>');
+ if (end == xml.end()) {
+ _status = XML_UNTERMINATED_DOCTYPE_DECL;
+ return;
+ }
+ --count;
+
+ // Count any opening brackets in between.
+ count += std::count(current, end, '<');
+ current = end;
+ ++current;
+ }
+
+ const std::string content(it, end);
+ std::ostringstream os;
+ os << '<' << content << '>';
+ _docTypeDecl = os.str();
+ it = end + 1;
+}
+
+
+void
+XMLDocument_as::parseXMLDecl(const std::string& xml,
std::string::const_iterator& it)
+{
+ std::string content;
+ if (!parseNodeWithTerminator(xml, it, "?>", content))
+ {
+ _status = XML_UNTERMINATED_XML_DECL;
+ return;
+ }
+
+ std::ostringstream os;
+ os << "<" << content << "?>";
+
+ // This is appended to any xmlDecl already there.
+ _xmlDecl += os.str();
+
+}
+
+// The iterator should be pointing to the first char after the '<'
+void
+XMLDocument_as::parseTag(XMLNode_as*& node, const std::string& xml,
+ std::string::const_iterator& it)
+{
+ //log_debug("Processing node: %s", node->nodeName());
+
+ bool closing = (*it == '/');
+ if (closing) ++it;
+
+ // These are for terminating the tag name, not (necessarily) the tag.
+ const std::string terminators("\r\n\t >");
+
+ std::string::const_iterator endName = std::find_first_of(it, xml.end(),
+ terminators.begin(), terminators.end());
+
+ // Check that one of the terminators was found; otherwise it's malformed.
+ if (endName == xml.end()) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+
+ // Knock off the "/>" of a self-closing tag.
+ if (std::equal(endName - 1, endName + 1, "/>")) {
+ // This can leave endName before it, e.g when a self-closing tag is
+ // empty ("</>"). This must be checked before trying to construct
+ // a string!
+ --endName;
+ }
+
+ // If the tag is empty, the XML counts as malformed.
+ if (it >= endName) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+
+ std::string tagName(it, endName);
+
+ if (!closing) {
+
+ XMLNode_as* childNode = new XMLNode_as;
+ childNode->nodeNameSet(tagName);
+ childNode->nodeTypeSet(Element);
+
+ //log_debug("created childNode with name %s", childNode->nodeName());
+ // Skip to the end of any whitespace after the tag name
+ it = endName;
+
+ if (!textAfterWhitespace(xml, it)) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+
+ // Parse any attributes in an opening tag only, stopping at "/>" or
+ // '>'
+ // Attributes are added in reverse order and without any duplicates.
+ Attributes attributes;
+ while (it != xml.end() && *it != '>' && _status == XML_OK)
+ {
+ if (xml.end() - it > 1 && std::equal(it, it + 2, "/>")) break;
+
+ // This advances the iterator
+ parseAttribute(childNode, xml, it, attributes);
+
+ // Skip any whitespace. If we reach the end of the string,
+ // it's malformed.
+ if (!textAfterWhitespace(xml, it)) {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+ }
+
+ // Do nothing more if there was an error in attributes parsing.
+ if (_status != XML_OK) return;
+
+ for (Attributes::const_reverse_iterator i = attributes.rbegin(),
+ e = attributes.rend(); i != e; ++i) {
+ childNode->setAttribute(i->first, i->second);
+ }
+
+ node->appendChild(childNode);
+ if (*it == '/') ++it;
+ else node = childNode;
+
+ if (*it == '>') ++it;
+
+ return;
+ }
+
+ // If we reach here, this is a closing tag.
+
+ it = std::find(endName, xml.end(), '>');
+
+ if (it == xml.end())
+ {
+ _status = XML_UNTERMINATED_ELEMENT;
+ return;
+ }
+ ++it;
+
+ StringNoCaseEqual noCaseCompare;
+
+ if (node->getParent() && noCaseCompare(node->nodeName(), tagName)) {
+ node = node->getParent();
+ }
+ else {
+ // Malformed. Search for the parent node.
+ XMLNode_as* s = node;
+ while (s && !noCaseCompare(s->nodeName(), tagName)) {
+ //log_debug("parent: %s, this: %s", s->nodeName(), tagName);
+ s = s->getParent();
+ }
+ if (s) {
+ // If there's a parent, the open tag is orphaned.
+ _status = XML_MISSING_CLOSE_TAG;
+ }
+ else {
+ // If no parent, the close tag is orphaned.
+ _status = XML_MISSING_OPEN_TAG;
+ }
+ }
+
+}
+
+void
+XMLDocument_as::parseText(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it)
+{
+ std::string::const_iterator end = std::find(it, xml.end(), '<');
+ std::string content(it, end);
+
+ it = end;
+
+ if (ignoreWhite() &&
+ content.find_first_not_of("\t\r\n ") == std::string::npos) return;
+
+ XMLNode_as* childNode = new XMLNode_as;
+
+ childNode->nodeTypeSet(XMLNode_as::Text);
+
+ // Replace any entitites.
+ unescape(content);
+
+ childNode->nodeValueSet(content);
+ node->appendChild(childNode);
+
+ //log_debug("appended text node: %s", content);
+}
+
+
+
+void
+XMLDocument_as::parseComment(XMLNode_as* /*node*/, const std::string& xml,
+ std::string::const_iterator& it)
+{
+ //log_debug("discarding comment node");
+
+ std::string content;
+
+ if (!parseNodeWithTerminator(xml, it, "-->", content)) {
+ _status = XML_UNTERMINATED_COMMENT;
+ return;
+ }
+ // Comments are discarded at least up to SWF8
+
+}
+
+void
+XMLDocument_as::parseCData(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it)
+{
+ std::string content;
+
+ if (!parseNodeWithTerminator(xml, it, "]]>", content)) {
+ _status = XML_UNTERMINATED_CDATA;
+ return;
+ }
+
+ XMLNode_as* childNode = new XMLNode_as;
+ childNode->nodeValueSet(content);
+ childNode->nodeTypeSet(Text);
+ node->appendChild(childNode);
+
+}
+
+
+// This parses an XML string into a tree of XMLNodes.
+void
+XMLDocument_as::parseXML(const std::string& xml)
+{
+ GNASH_REPORT_FUNCTION;
+ if (xml.empty())
+ {
+ log_error(_("XML data is empty"));
+ return;
+ }
+
+ // Clear current data
+ clear();
+ _status = XML_OK;
+
+ std::string::const_iterator it = xml.begin();
+ XMLNode_as* node = this;
+
+ while (it != xml.end() && _status == XML_OK)
+ {
+ if (*it == '<')
+ {
+ ++it;
+ if (textMatch(xml, it, "!DOCTYPE", false))
+ {
+ // We should not advance past the DOCTYPE label, as
+ // the case is preserved.
+ parseDocTypeDecl(xml, it);
+ }
+ else if (textMatch(xml, it, "?xml", false))
+ {
+ // We should not advance past the xml label, as
+ // the case is preserved.
+ parseXMLDecl(xml, it);
+ }
+ else if (textMatch(xml, it, "!--"))
+ {
+ parseComment(node, xml, it);
+ }
+ else if (textMatch(xml, it, "![CDATA["))
+ {
+ parseCData(node, xml, it);
+ }
+ else parseTag(node, xml, it);
+ }
+ else parseText(node, xml, it);
+ }
+
+ // If everything parsed correctly, check that we've got back to the
+ // parent node. If not, there is a missing closing tag.
+ if (_status == XML_OK && node != this) {
+ _status = XML_MISSING_CLOSE_TAG;
+ }
+
+}
+
+bool
+XMLDocument_as::onLoad()
+{
+ log_debug(_("%s: FIXME: onLoad Default event handler"), __FUNCTION__);
+
+ return(_loaded);
+}
+
+
+void
+XMLDocument_as::clear()
+{
+ // TODO: should set childs's parent to NULL ?
+ _children.clear();
+ _docTypeDecl.clear();
+ _xmlDecl.clear();
+}
+
+bool
+XMLDocument_as::ignoreWhite() const
+{
+
+ string_table::key propnamekey = _vm.getStringTable().find("ignoreWhite");
+ as_value val;
+ if (!const_cast<XMLDocument_as*>(this)->get_member(propnamekey, &val)) {
+ return false;
+ }
+ return val.to_bool();
+}
+
// extern (used by Global.cpp)
-void xmldocument_class_init(as_object& global)
+void
+XMLDocument_as::init(as_object& global)
{
+
static boost::intrusive_ptr<builtin_function> cl;
- if (!cl) {
- cl = new builtin_function(&xmldocument_ctor,
getXMLDocumentInterface());
- attachXMLDocumentStaticInterface(*cl);
+ if ( cl == NULL )
+ {
+ cl=new builtin_function(&xml_new, getXMLInterface());
}
-
- // Register _global.XMLDocument
- global.init_member("XMLDocument", cl.get());
+
+ global.init_member("XML", cl.get());
+
+}
+
+void
+XMLDocument_as::registerNative(as_object& global)
+{
+ VM& vm = global.getVM();
+ vm.registerNative(xml_escape, 100, 5);
+ vm.registerNative(xml_createElement, 253, 8);
+ vm.registerNative(xml_createTextNode, 253, 9);
+ vm.registerNative(xml_parseXML, 253, 10);
}
namespace {
-
void
-attachXMLDocumentInterface(as_object& o)
+attachXMLProperties(as_object& /*o*/)
{
- o.init_member("createTextNode", new
builtin_function(xmldocument_createTextNode));
- o.init_member("parseXML", new builtin_function(xmldocument_parseXML));
- o.init_member("toString", new builtin_function(xmldocument_toString));
+ // if we use a proper member here hasOwnProperty() would return true
+ // but we want it to return false instead. See XML.as
+ //o.init_member("status", as_value(XML::sOK));
}
+
void
-attachXMLDocumentStaticInterface(as_object& o)
+attachXMLInterface(as_object& o)
{
+ VM& vm = o.getVM();
+
+ const int flags = 0;
+
+ // No flags:
+ o.init_member("addRequestHeader", new builtin_function(
+ LoadableObject::loadableobject_addRequestHeader), flags);
+ o.init_member("createElement", vm.getNative(253, 8), flags);
+ o.init_member("createTextNode", vm.getNative(253, 9), flags);
+ o.init_member("getBytesLoaded",
+ new builtin_function(xml_getBytesLoaded), flags);
+ o.init_member("getBytesTotal",
+ new builtin_function(xml_getBytesTotal), flags);
+ o.init_member("load", vm.getNative(301, 0), flags);
+ o.init_member("parseXML", vm.getNative(253, 10), flags);
+ o.init_member("send", vm.getNative(301, 1), flags);
+ o.init_member("sendAndLoad", vm.getNative(301, 2), flags);
+ o.init_member("onData", new builtin_function(xml_ondata), flags);
+
+ o.init_property("xmlDecl", &xml_xmlDecl, &xml_xmlDecl, flags);
+ o.init_property("docTypeDecl", &xml_docTypeDecl, &xml_docTypeDecl, flags);
}
as_object*
-getXMLDocumentInterface()
+getXMLInterface()
{
static boost::intrusive_ptr<as_object> o;
- if ( ! o ) {
- o = new as_object();
- attachXMLDocumentInterface(*o);
+ if ( o == NULL )
+ {
+ o = new as_object(XMLNode_as::getXMLNodeInterface());
+ VM::get().addStatic(o.get());
+ attachXMLInterface(*o);
}
return o.get();
}
as_value
-xmldocument_createTextNode(const fn_call& fn)
-{
- boost::intrusive_ptr<XMLDocument_as> ptr =
- ensureType<XMLDocument_as>(fn.this_ptr);
- UNUSED(ptr);
- log_unimpl (__FUNCTION__);
- return as_value();
-}
-
-as_value
-xmldocument_parseXML(const fn_call& fn)
-{
- boost::intrusive_ptr<XMLDocument_as> ptr =
- ensureType<XMLDocument_as>(fn.this_ptr);
- UNUSED(ptr);
- log_unimpl (__FUNCTION__);
- return as_value();
-}
-
-as_value
-xmldocument_toString(const fn_call& fn)
-{
- boost::intrusive_ptr<XMLDocument_as> ptr =
- ensureType<XMLDocument_as>(fn.this_ptr);
- UNUSED(ptr);
- log_unimpl (__FUNCTION__);
- return as_value();
+xml_new(const fn_call& fn)
+{
+ boost::intrusive_ptr<XMLDocument_as> xml_obj;
+
+ if ( fn.nargs > 0 )
+ {
+ if ( fn.arg(0).is_object() )
+ {
+ boost::intrusive_ptr<as_object> obj = fn.arg(0).to_object();
+ xml_obj = dynamic_cast<XMLDocument_as*>(obj.get());
+ if ( xml_obj )
+ {
+ log_debug(_("Cloned the XML object at %p"),
+ (void *)xml_obj.get());
+ return as_value(xml_obj->cloneNode(true).get());
+ }
+ }
+
+ const std::string& xml_in = fn.arg(0).to_string();
+ if ( xml_in.empty() )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror(_("First arg given to XML constructor (%s) "
+ "evaluates to the empty string"), fn.arg(0));
+ );
+ }
+ else
+ {
+ xml_obj = new XMLDocument_as(xml_in);
+ return as_value(xml_obj.get());
+ }
+ }
+
+ xml_obj = new XMLDocument_as;
+
+ return as_value(xml_obj.get());
+}
+
+
+/// Only available as ASnative.
+as_value
+xml_escape(const fn_call& fn)
+{
+ if (!fn.nargs) return as_value();
+
+ std::string escaped = fn.arg(0).to_string();
+ XMLDocument_as::escape(escaped);
+ return as_value(escaped);
+}
+
+/// \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.
+as_value
+xml_createElement(const fn_call& fn)
+{
+
+ if (fn.nargs > 0)
+ {
+ const std::string& text = fn.arg(0).to_string();
+ XMLNode_as *xml_obj = new XMLNode_as;
+ xml_obj->nodeNameSet(text);
+ xml_obj->nodeTypeSet(XMLNode_as::Text);
+
+ return as_value(xml_obj);
+
+ }
+ else {
+ log_error(_("no text for element creation"));
+ }
+ return as_value();
+}
+
+
+/// \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.
+as_value
+xml_createTextNode(const fn_call& fn)
+{
+
+ if (fn.nargs > 0) {
+ const std::string& text = fn.arg(0).to_string();
+ XMLNode_as* xml_obj = new XMLNode_as;
+ xml_obj->nodeValueSet(text);
+ xml_obj->nodeTypeSet(XMLNode_as::Text);
+ return as_value(xml_obj);
+ }
+ else {
+ log_error(_("no text for text node creation"));
+ }
+ return as_value();
+}
+
+
+as_value
+xml_getBytesLoaded(const fn_call& fn)
+{
+ boost::intrusive_ptr<XMLDocument_as> ptr =
ensureType<XMLDocument_as>(fn.this_ptr);
+ long int ret = ptr->getBytesLoaded();
+ if ( ret < 0 ) return as_value();
+ else return as_value(ret);
+}
+
+
+as_value
+xml_getBytesTotal(const fn_call& fn)
+{
+ boost::intrusive_ptr<XMLDocument_as> ptr =
ensureType<XMLDocument_as>(fn.this_ptr);
+ long int ret = ptr->getBytesTotal();
+ if ( ret < 0 ) return as_value();
+ else return as_value(ret);
+}
+
+
+as_value
+xml_parseXML(const fn_call& fn)
+{
+
+ boost::intrusive_ptr<XMLDocument_as> ptr =
ensureType<XMLDocument_as>(fn.this_ptr);
+
+ if (fn.nargs < 1)
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("XML.parseXML() needs one argument");
+ );
+ return as_value();
+ }
+
+ const std::string& text = fn.arg(0).to_string();
+ ptr->parseXML(text);
+
+ return as_value();
+}
+
+as_value
+xml_xmlDecl(const fn_call& fn)
+{
+ boost::intrusive_ptr<XMLDocument_as> ptr =
ensureType<XMLDocument_as>(fn.this_ptr);
+
+ if (!fn.nargs)
+ {
+ // Getter
+ const std::string& xml = ptr->getXMLDecl();
+ if (xml.empty()) return as_value();
+ return as_value(xml);
+ }
+
+ // Setter
+
+ const std::string& xml = fn.arg(0).to_string();
+ ptr->setDocTypeDecl(xml);
+
+ return as_value();
+
+}
+
+as_value
+xml_docTypeDecl(const fn_call& fn)
+{
+ boost::intrusive_ptr<XMLDocument_as> ptr =
ensureType<XMLDocument_as>(fn.this_ptr);
+
+ if (!fn.nargs)
+ {
+ // Getter
+ const std::string& docType = ptr->getDocTypeDecl();
+ if (docType.empty()) return as_value();
+ return as_value(docType);
+ }
+
+ // Setter
+
+ const std::string& docType = fn.arg(0).to_string();
+ ptr->setDocTypeDecl(docType);
+
+ return as_value();
+
+}
+
+as_value
+xml_ondata(const fn_call& fn)
+{
+
+ as_object* thisPtr = fn.this_ptr.get();
+ assert(thisPtr);
+
+ // See http://gitweb.freedesktop.org/?p=swfdec/swfdec.git;
+ // a=blob;f=libswfdec/swfdec_initialize.as
+
+ as_value src;
+ if (fn.nargs) src = fn.arg(0);
+
+ if (!src.is_undefined()) {
+ thisPtr->set_member(NSV::PROP_LOADED, true);
+ thisPtr->callMethod(NSV::PROP_PARSE_XML, src);
+ thisPtr->callMethod(NSV::PROP_ON_LOAD, true);
+ }
+ else {
+ thisPtr->set_member(NSV::PROP_LOADED, false);
+ thisPtr->callMethod(NSV::PROP_ON_LOAD, false);
+ }
+
+ return as_value();
+}
+
+/// Case insensitive match of a string, returning false if there too few
+/// DisplayObjects left or if there is no match. If there is a match, and
advance
+/// is not false, the iterator points to the DisplayObject after the match.
+bool
+textMatch(const std::string& xml, std::string::const_iterator& it,
+ const std::string& match, bool advance)
+{
+
+ const std::string::size_type len = match.length();
+ const std::string::const_iterator end = xml.end();
+
+ if (static_cast<size_t>(end - it) < len) return false;
+
+ if (!std::equal(it, it + len, match.begin(), boost::is_iequal())) {
+ return false;
+ }
+ if (advance) it += len;
+ return true;
+}
+
+/// Advance past whitespace
+//
+/// @return true if there is text after the whitespace, false if we
+/// reach the end of the string.
+bool
+textAfterWhitespace(const std::string& xml, std::string::const_iterator& it)
+{
+ const std::string whitespace("\r\t\n ");
+ while (it != xml.end() && whitespace.find(*it) != std::string::npos) ++it;
+ return (it != xml.end());
+}
+
+/// Parse a complete node up to a specified terminator.
+//
+/// @return false if we reach the end of the text before finding the
+/// terminator.
+/// @param it The current position of the iterator. If the return is true,
+/// this points to the first DisplayObject after the terminator
+/// after return
+/// @param content If the return is true, this is filled with the content of
+/// the tag.
+/// @param xml The complete XML string.
+bool
+parseNodeWithTerminator(const std::string& xml,
+ std::string::const_iterator& it, const std::string& terminator,
+ std::string& content)
+{
+ std::string::const_iterator end = std::search(it, xml.end(),
+ terminator.begin(), terminator.end());
+
+ if (end == xml.end()) {
+ return false;
+ }
+
+ content = std::string(it, end);
+ it = end + terminator.length();
+
+ return true;
}
as_value
=== modified file 'libcore/asobj/flash/xml/XMLDocument_as.h'
--- a/libcore/asobj/flash/xml/XMLDocument_as.h 2009-05-28 17:29:17 +0000
+++ b/libcore/asobj/flash/xml/XMLDocument_as.h 2009-06-08 16:08:56 +0000
@@ -24,17 +24,168 @@
#include "gnashconfig.h"
#endif
+#include "LoadableObject.h"
+#include "xml/XMLNode_as.h"
+#include "log.h"
+#include "dsodefs.h"
+#include "StringPredicates.h"
+
+#include <map>
+#include <string>
+
namespace gnash {
// Forward declarations
-class as_object;
-
-/// Initialize the global XMLDocument class
-void xmldocument_class_init(as_object& global);
-
-} // gnash namespace
-
+class fn_call;
+class URL;
+class LoaderThread;
+
+/// XML class and ActionScript object
+class XMLDocument_as : public XMLNode_as, public LoadableObject
+{
+public:
+
+ enum ParseStatus {
+ XML_OK = 0,
+ XML_UNTERMINATED_CDATA = -2,
+ XML_UNTERMINATED_XML_DECL = -3,
+ XML_UNTERMINATED_DOCTYPE_DECL = -4,
+ XML_UNTERMINATED_COMMENT = -5,
+ XML_UNTERMINATED_ELEMENT = -6,
+ XML_OUT_OF_MEMORY = -7,
+ XML_UNTERMINATED_ATTRIBUTE = -8,
+ XML_MISSING_CLOSE_TAG = -9,
+ XML_MISSING_OPEN_TAG = -10
+ };
+
+ XMLDocument_as();
+
+ XMLDocument_as(const std::string& xml);
+
+ ~XMLDocument_as() {};
+
+ static void init(as_object& global);
+ static void registerNative(as_object& global);
+
+ /// Convert the XML object to a string
+ //
+ /// This calls XMLNode::toString after adding an xmlDecl and
+ /// docTypeDecl
+ //
+ /// @param o The ostream to write the string to.
+ /// @param encode Whether to URL encode the node values.
+ void toString(std::ostream& o, bool encode) const;
+
+ const std::string& getXMLDecl() const {
+ return _xmlDecl;
+ }
+
+ void setXMLDecl(const std::string& xml) {
+ _xmlDecl = xml;
+ }
+
+ const std::string& getDocTypeDecl() const {
+ return _docTypeDecl;
+ }
+
+ void setDocTypeDecl(const std::string& docType) {
+ _docTypeDecl = docType;
+ }
+
+ /// This is overridden to provide the 'status' and 'loaded' members,
+ /// which are NOT proper properties !
+ /// See actionscript.all/XML.as
+ ///
+ bool get_member(string_table::key name, as_value *val,
+ string_table::key nsname = 0);
+
+ /// This is overridden to provide the 'status' and 'loaded' members,
+ /// which are NOT proper properties !
+ /// See actionscript.all/XML.as
+ ///
+ bool set_member(string_table::key name, const as_value& val,
+ string_table::key nsname = 0, bool ifFound=false);
+
+ // Methods
+
+ /// Parses an XML document into the specified XML object tree.
+ //
+ /// This reads in an XML file from disk and parses into into a memory
+ /// resident tree which can be walked through later.
+ ///
+ /// Calls to this function clear any precedently parsed data.
+ ///
+ void parseXML(const std::string& xml);
+
+ // An event handler that returns a what?
+ bool onLoad();
+
+ /// Escape using XML entities.
+ //
+ /// Note this is not the same as a URL escape.
+ static void escape(std::string& text);
+
+ /// Unescape XML entities.
+ //
+ /// Note this is not the same as a URL unescape.
+ static void unescape(std::string& text);
+
+ XMLNode_as* createElement(const std::string& name);
+
+ XMLNode_as* createTextNode(const std::string& name);
+
+private:
+
+ typedef std::map<std::string, std::string> Entities;
+
+ static const Entities& getEntities();
+
+ typedef std::map<std::string, std::string, StringNoCaseLessThan>
Attributes;
+
+ void parseTag(XMLNode_as*& node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseAttribute(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it, Attributes& attributes);
+
+ void parseDocTypeDecl(const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseText(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseXMLDecl(const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseComment(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseCData(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ /// Remove all children
+ void clear();
+
+ /// \brief
+ /// Return true if ignoreWhite property was set to anything evaluating
+ /// to true.
+ bool ignoreWhite() const;
+
+ // -1 if never asked to load anything
+ // 0 if asked to load but not yet loaded (or failure)
+ // 1 if successfully loaded
+ int _loaded;
+
+ ParseStatus _status;
+
+ std::string _docTypeDecl;
+
+ std::string _xmlDecl;
+
+};
+
+} // namespace gnash
// GNASH_ASOBJ3_XMLDOCUMENT_H
#endif
=== modified file 'libcore/asobj/flash/xml/XMLNode_as.cpp'
--- a/libcore/asobj/flash/xml/XMLNode_as.cpp 2009-06-05 18:31:42 +0000
+++ b/libcore/asobj/flash/xml/XMLNode_as.cpp 2009-06-08 16:10:02 +0000
@@ -23,7 +23,7 @@
#include "xml/XMLNode_as.h"
//FIXME: direct this to the proper flash namespace
-#include "XML_as.h"
+#include "xml/XMLDocument_as.h"
#include "Array_as.h"
#include "Object.h"
#include "VM.h"
@@ -356,7 +356,7 @@
for (PropertyList::SortedPropertyList::iterator i =
attrs.begin(), e = attrs.end(); i != e; ++i) {
- XML_as::escape(i->second);
+ XMLDocument_as::escape(i->second);
xmlout << " " << i->first << "=\"" << i->second << "\"";
}
}
@@ -381,7 +381,7 @@
// Insert entities.
std::string escaped(nodeValue);
- XML_as::escape(escaped);
+ XMLDocument_as::escape(escaped);
const std::string& val = encode ?
global->callMethod(NSV::PROP_ESCAPE, escaped).to_string() :
escaped;
=== modified file 'testsuite/actionscript.all/XML.as'
--- a/testsuite/actionscript.all/XML.as 2009-02-25 22:33:03 +0000
+++ b/testsuite/actionscript.all/XML.as 2009-06-08 16:08:56 +0000
@@ -798,14 +798,13 @@
if ( ! success )
{
- //note("No success loading gnash.xml");
+ note("No success loading gnash.xml");
check_equals(myxml.status, 0);
check(! myxml.loaded);
return;
}
- //note("gnash.xml successfully loaded");
- //note("myxml status is "+myxml.status);
-
+ note("gnash.xml successfully loaded");
+ note("myxml status is "+myxml.status);
check_equals(myxml.status, 0);
check(myxml.loaded);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11036: migrated the XML document to new namespace (still working on bug in testcase),
Ben Limmer <=