gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10294: Corrections to and more impl


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10294: Corrections to and more implementation of XML methods.
Date: Tue, 18 Nov 2008 15:39:48 +0100
User-agent: Bazaar (1.5)

------------------------------------------------------------
revno: 10294
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2008-11-18 15:39:48 +0100
message:
  Corrections to and more implementation of XML methods.
modified:
  libcore/asobj/XMLNode_as.h
  libcore/asobj/XML_as.cpp
  libcore/asobj/XML_as.h
  testsuite/actionscript.all/XML.as
    ------------------------------------------------------------
    revno: 10285.1.6
    committer: Benjamin Wolsey <address@hidden>
    branch nick: test
    timestamp: Tue 2008-11-18 13:39:43 +0100
    message:
      Add some tests for malformed XML. Get &quot; and &apos; the right way
      round.
    modified:
      libcore/asobj/XML_as.cpp
      testsuite/actionscript.all/XML.as
    ------------------------------------------------------------
    revno: 10285.1.7
    committer: Benjamin Wolsey <address@hidden>
    branch nick: test
    timestamp: Tue 2008-11-18 14:36:25 +0100
    message:
      Add doctype to XML.toString output. Make XMLNode::toString virtual so 
      XML::toString is called. Implement docTypeDecl getter/setter.
    modified:
      libcore/asobj/XMLNode_as.h
      libcore/asobj/XML_as.cpp
      libcore/asobj/XML_as.h
      testsuite/actionscript.all/XML.as
    ------------------------------------------------------------
    revno: 10285.1.8
    committer: Benjamin Wolsey <address@hidden>
    branch nick: test
    timestamp: Tue 2008-11-18 15:30:05 +0100
    message:
      Test and implement XML.xmlDecl property.
    modified:
      libcore/asobj/XML_as.cpp
      libcore/asobj/XML_as.h
      testsuite/actionscript.all/XML.as
=== modified file 'libcore/asobj/XMLNode_as.h'
--- a/libcore/asobj/XMLNode_as.h        2008-11-18 09:42:06 +0000
+++ b/libcore/asobj/XMLNode_as.h        2008-11-18 13:36:25 +0000
@@ -211,7 +211,7 @@
     /// @param encode   Whether to URL encode the node values. This
     ///                 is false by default, as it is only necessary
     ///                 for XML.sendAndLoad.
-    void toString(std::ostream& str, bool encode = false) const;
+    virtual void toString(std::ostream& str, bool encode = false) const;
 
     // We might turn this back to a dumb pointer, as long
     // as we'll make sure in the XMLNode destructor and

=== modified file 'libcore/asobj/XML_as.cpp'
--- a/libcore/asobj/XML_as.cpp  2008-11-18 11:21:17 +0000
+++ b/libcore/asobj/XML_as.cpp  2008-11-18 14:39:48 +0000
@@ -68,11 +68,13 @@
     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);
 
     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);
+            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);
@@ -112,10 +114,10 @@
 
     static Entities entities = boost::assign::map_list_of
         ("&amp;", "&")
-        ("&apos;", "\"")
+        ("&quot;", "\"")
         ("&lt;", "<")
         ("&gt;", ">")
-        ("&quot;", "'");
+        ("&apos;", "'");
 
     return entities;
 
@@ -146,6 +148,15 @@
 
 }
 
+void
+XML_as::toString(std::ostream& o, bool encode) const
+{
+    if (!_xmlDecl.empty()) o << _xmlDecl;
+    if (!_docTypeDecl.empty()) o << _docTypeDecl;
+
+    XMLNode::toString(o, encode);
+}
+
 bool
 XML_as::get_member(string_table::key name, as_value *val,
         string_table::key nsname)
@@ -266,22 +277,40 @@
 
 }
 
+/// 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(XMLNode* /*node*/, const std::string& xml,
-    std::string::const_iterator& it)
+XML_as::parseDocTypeDecl(const std::string& xml,
+        std::string::const_iterator& it)
 {
     std::string content;
-    parseNodeWithTerminator(xml, it, ">", content);
+    if (!parseNodeWithTerminator(xml, it, ">", content))
+    {
+        _status = XML_UNTERMINATED_DOCTYPE_DECL;
+        return;
+    }
+    std::ostringstream os;
+    os << '<' << content << '>';
+    _docTypeDecl = os.str();
 }
 
+
 void
-XML_as::parseXMLDecl(XMLNode* /*node*/, const std::string& xml,
-    std::string::const_iterator& it)
+XML_as::parseXMLDecl(const std::string& xml, std::string::const_iterator& it)
 {
     std::string content;
-    parseNodeWithTerminator(xml, it, "?>", content);
-
-    // Handle 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 '<'
@@ -476,13 +505,17 @@
         if (*it == '<')
         {
             ++it;
-            if (textMatch(xml, it, "!DOCTYPE"))
+            if (textMatch(xml, it, "!DOCTYPE", false))
             {
-                parseDocTypeDecl(node, xml, it);
+                // We should not advance past the DOCTYPE label, as
+                // the case is preserved.
+                parseDocTypeDecl(xml, it);
             }
-            else if (textMatch(xml, it, "?xml"))
+            else if (textMatch(xml, it, "?xml", false))
             {
-                parseXMLDecl(node, xml, it);
+                // We should not advance past the xml label, as
+                // the case is preserved.
+                parseXMLDecl(xml, it);
             }
             else if (textMatch(xml, it, "!--"))
             {
@@ -514,8 +547,9 @@
 {
     // TODO: should set childs's parent to NULL ?
     _children.clear();
-
     _attributes.clear();
+    _docTypeDecl.clear();
+    _xmlDecl.clear();
 }
 
 bool
@@ -585,6 +619,8 @@
                 LoadableObject::loadableobject_sendAndLoad), 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*
@@ -735,11 +771,53 @@
     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)
 {
-    GNASH_REPORT_FUNCTION;
 
     as_object* thisPtr = fn.this_ptr.get();
     assert(thisPtr);
@@ -765,11 +843,11 @@
 }
 
 /// Case insenstive match of a string, returning false if there too few
-/// characters left or if there is no match. If there is a match, the
-/// iterator points to the character after the match.
+/// characters left or if there is no match. If there is a match, and advance
+/// is not false, the iterator points to the character after the match.
 bool
 textMatch(const std::string& xml, std::string::const_iterator& it,
-        const std::string& match)
+        const std::string& match, bool advance)
 {
 
     const std::string::size_type len = match.length();
@@ -780,7 +858,7 @@
     if (!std::equal(it, it + len, match.begin(), boost::is_iequal())) {
         return false;
     }
-    it += len;
+    if (advance) it += len;
     return true;
 }
 

=== modified file 'libcore/asobj/XML_as.h'
--- a/libcore/asobj/XML_as.h    2008-11-18 09:46:03 +0000
+++ b/libcore/asobj/XML_as.h    2008-11-18 14:30:05 +0000
@@ -61,12 +61,27 @@
 
     /// Convert the XML object to a string
     //
-    /// This calls XMLNode::toString.
+    /// 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
-    {
-        XMLNode::toString(o, encode);
+    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,
@@ -100,13 +115,13 @@
     void parseAttribute(XMLNode* node, const std::string& xml, 
             std::string::const_iterator& it);
 
-    void parseDocTypeDecl(XMLNode* node, const std::string& xml, 
+    void parseDocTypeDecl(const std::string& xml, 
             std::string::const_iterator& it);
 
     void parseText(XMLNode* node, const std::string& xml, 
             std::string::const_iterator& it);
 
-    void parseXMLDecl(XMLNode* node, const std::string& xml, 
+    void parseXMLDecl(const std::string& xml, 
             std::string::const_iterator& it);
 
     void parseComment(XMLNode* node, const std::string& xml, 
@@ -152,7 +167,11 @@
     int _loaded;
 
     ParseStatus _status;       
-    
+ 
+    std::string _docTypeDecl;
+
+    std::string _xmlDecl;
+
 };
 
 

=== modified file 'testsuite/actionscript.all/XML.as'
--- a/testsuite/actionscript.all/XML.as 2008-11-18 09:29:12 +0000
+++ b/testsuite/actionscript.all/XML.as 2008-11-18 14:30:05 +0000
@@ -448,7 +448,7 @@
 //note("Parsed XML: "+tmp.toString());
 
 // TODO: FIX THIS !
-xcheck_equals(tmp.toString(), xml_out);
+check_equals(tmp.toString(), xml_out);
 
 //------------------------------------------------
 // Test XML editing
@@ -864,9 +864,9 @@
        if ( this.onLoadCalls == 2 )
        {
 #if OUTPUT_VERSION < 6
-               check_totals(361);
+               check_totals(386);
 #else
-               check_totals(401);
+               check_totals(426);
 #endif
                play();
        }
@@ -948,5 +948,70 @@
 myxml2.parseXML("<X1> t </X1>");
 check_equals(myxml2.toString(), "<X1> t </X1>"); 
 
+/// Check various malformed XMLs
+
+h = new XML("<open>");
+check_equals(h.toString(), "<open />");
+
+h = new XML("<open></close>");
+check_equals(h.toString(), "<open />");
+
+h = new XML("<open><open2></open>");
+check_equals(h.toString(), "<open><open2 /></open>");
+
+h = new XML("<open att='");
+xcheck_equals(h.toString(), "");
+
+h = new XML("<open att      r='kk'");
+xcheck_equals(h.toString(), "");
+
+h = new XML("<open>& ' \"<");
+check_equals(h.toString(), "<open>&amp; &apos; &quot;</open>");
+
+h = new XML("</open><open>node with \"</open>");
+check_equals(h.toString(), "");
+
+h = new XML("<open/><open><!-- lkjsdcölkj<hello>");
+check_equals(h.toString(), "<open /><open />");
+
+h = new XML("<open><![CDATA[jlkjdc</open>");
+check_equals(h.toString(), "<open />");
+
+// Check DOCTYPE and xml declarations.
+
+check_equals(h.docTypeDecl, undefined);
+check_equals(h.xmlDecl, undefined);
+
+h = new XML("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 
'http://www.w3.org/TR/html4/loose.dtd'><tag></tag>");
+check_equals(h.toString(), "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 
Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><tag />");
+check_equals(h.docTypeDecl, "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 
Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>");
+
+h = new XML("<!DOcTyPE text><tag></tag>");
+check_equals(h.toString(), "<!DOcTyPE text><tag />");
+check_equals(h.docTypeDecl, "<!DOcTyPE text>");
+
+h = new XML("<?xml declaration goes here?><tag>content</tag>");
+check_equals(h.toString(), "<?xml declaration goes here?><tag>content</tag>");
+check_equals(h.xmlDecl, "<?xml declaration goes here?>");
+
+h = new XML("<?xMl declaration goes here?><tag>content</tag>");
+check_equals(h.toString(), "<?xMl declaration goes here?><tag>content</tag>");
+check_equals(h.xmlDecl, "<?xMl declaration goes here?>");
+
+// Check order
+h = new XML("<!doctype d><?xMl declaration goes here?><tag>content</tag>");
+check_equals(h.toString(), "<?xMl declaration goes here?><!doctype 
d><tag>content</tag>");
+check_equals(h.xmlDecl, "<?xMl declaration goes here?>");
+check_equals(h.docTypeDecl, "<!doctype d>");
+
+// Check order
+h = new XML("<tag></tag><!doctype d><?xMl declaration goes 
here?><tag>content</tag>");
+check_equals(h.toString(), "<?xMl declaration goes here?><!doctype d><tag 
/><tag>content</tag>");
+
+// Check multiple declarations
+h = new XML("<tag></tag><!doctype d><?xMl decl?><!dOcType new><?XMl new?>");
+check_equals(h.toString(), "<?xMl decl?><?XMl new?><!dOcType new><tag />");
+check_equals(h.xmlDecl, "<?xMl decl?><?XMl new?>");
+
 stop();
 


reply via email to

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