Author: atsushi
Date: 2007-05-04 00:41:07 -0400 (Fri, 04 May 2007)
New Revision: 76658

Added:
   trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XAttributeTest.cs
Modified:
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq/ChangeLog
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XAttribute.cs
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XElement.cs
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XNode.cs
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XObject.cs
   trunk/olive/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources
   trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog
   trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs
Log:
2007-05-04  Atsushi Enomoto  <[EMAIL PROTECTED]>

        * XNode.cs
          XElement.cs
          XAttribute.cs
          XObject.cs
          XContainer.cs : Attribute support. Fixed Document property.

        * XAttributeTest.cs : new test, for XAttribute.
        * XElementTest.cs : attribute related tests.



Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq/ChangeLog
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq/ChangeLog 2007-05-04 
04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq/ChangeLog 2007-05-04 
04:41:07 UTC (rev 76658)
@@ -1,3 +1,11 @@
+2007-05-04  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
+       * XNode.cs
+         XElement.cs
+         XAttribute.cs
+         XObject.cs
+         XContainer.cs : Attribute support. Fixed Document property.
+
 2007-05-03  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * XNode.cs

Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XAttribute.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XAttribute.cs     
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XAttribute.cs     
2007-05-04 04:41:07 UTC (rev 76658)
@@ -6,11 +6,10 @@
 {
        public class XAttribute : XObject
        {
-               static IEnumerable <XAttribute> emptySequence =
-                       new List <XAttribute> ();
+               static readonly XAttribute [] empty_array = new XAttribute [0];
 
                public static IEnumerable <XAttribute> EmptySequence {
-                       get { return emptySequence; }
+                       get { return empty_array; }
                }
 
                XName name;
@@ -18,40 +17,42 @@
                XAttribute next;
                XAttribute previous;
 
-               public XAttribute (XAttribute source)
+               public XAttribute (XAttribute other)
                {
-                       name = source.name;
-                       value = source.value;
+                       if (other == null)
+                               throw new ArgumentNullException ("other");
+                       name = other.name;
+                       value = other.value;
                }
 
                public XAttribute (XName name, object value)
                {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
                        this.name = name;
-                       this.value = XUtil.ToString (value);
+                       SetValue (value);
                }
 
-               [MonoTODO]
                public bool IsNamespaceDeclaration {
-                       get { throw new NotImplementedException (); }
+                       get { return name.Namespace == XNamespace.Xmlns || 
(name.LocalName == "xmlns" && name.Namespace == XNamespace.Blank); }
                }
 
                public XName Name {
                        get { return name; }
                }
 
-               [MonoTODO]
                public XAttribute NextAttribute {
                        get { return next; }
+                       internal set { next = value; }
                }
 
-               [MonoTODO]
                public override XmlNodeType NodeType {
                        get { return XmlNodeType.Attribute; }
                }
 
-               [MonoTODO]
                public XAttribute PreviousAttribute {
                        get { return previous; }
+                       internal set { previous = value; }
                }
 
                public string Value {
@@ -59,49 +60,27 @@
                        set { this.value = value; }
                }
 
-               /*
-               public override bool Equals (object obj)
-               {
-                       XAttribute a = obj as XAttribute;
-                       if (a == null)
-                               return false;
-                       return a.Name == name && a.value == value;
-               }
-
-               public override int GetHashCode ()
-               {
-                       return name.GetHashCode () ^ value.GetHashCode ();
-               }
-
-               public static explicit operator bool (XAttribute a)
-               {
-                       return XUtil.ToBoolean (a.value);
-               }
-
-               public static explicit operator Nullable <bool> (XAttribute a)
-               {
-                       return a.value == null || String.Empty == a.value as 
string ?
-                               null : XUtil.ToNullableBoolean (a.value);
-               }
-
-               // FIXME: similar conversion methods follow.
-               */
-
                public void Remove ()
                {
-                       next = null;
-                       previous = null;
-
                        if (Parent != null) {
-                               Parent.InternalRemoveAttribute (this);
-                               Parent = null;
+                               if (next != null)
+                                       next.previous = previous;
+                               if (previous != null)
+                                       previous.next = next;
+                               if (Parent.FirstAttribute == this)
+                                       Parent.FirstAttribute = next;
+                               if (Parent.LastAttribute == this)
+                                       Parent.LastAttribute = previous;
+                               SetOwner (null);
                        }
+                       next = null;
+                       previous = null;
                }
 
                [MonoTODO]
                public void SetValue (object value)
                {
-                       throw new NotImplementedException ();
+                       this.value = XUtil.ToString (value);
                }
 
                [MonoTODO]

Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs     
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XContainer.cs     
2007-05-04 04:41:07 UTC (rev 76658)
@@ -61,7 +61,7 @@
                        XNode n = XUtil.ToNode (content);
                        CheckChildType (n, false);
                        OnAdded (n, false);
-                       n.Parent = this as XElement;
+                       n.SetOwner (this);
                        if (first == null)
                                last = first = n;
                        else {
@@ -88,7 +88,7 @@
                        XNode n = XUtil.ToNode (content);
                        OnAdded (n, true);
                        CheckChildType (n, true);
-                       n.Parent = this as XElement;
+                       n.SetOwner (this);
                        if (first == null)
                                first = last = n;
                        else {

Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XElement.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XElement.cs       
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XElement.cs       
2007-05-04 04:41:07 UTC (rev 76658)
@@ -20,7 +20,8 @@
                }
 
                XName name;
-               List <XAttribute> attributes;
+               //List <XAttribute> attributes;
+               XAttribute attr_first, attr_last;
 
                public XElement (XName name, object value)
                {
@@ -44,6 +45,7 @@
                        Add (contents);
                }
 
+               /*
                internal List <XAttribute> SafeAttributes {
                        get {
                                if (attributes == null)
@@ -51,19 +53,20 @@
                                return attributes;
                        }
                }
+               */
 
-               [MonoTODO]
                public XAttribute FirstAttribute {
-                       get { throw new NotImplementedException (); }
+                       get { return attr_first; }
+                       internal set { attr_first = value; }
                }
 
-               [MonoTODO]
                public XAttribute LastAttribute {
-                       get { throw new NotImplementedException (); }
+                       get { return attr_last; }
+                       internal set { attr_last = value; }
                }
 
                public bool HasAttributes {
-                       get { return attributes != null && attributes.Count > 
0; }
+                       get { return attr_first != null; }
                }
 
                public bool HasElements {
@@ -121,9 +124,7 @@
 
                public XAttribute Attribute (XName name)
                {
-                       if (attributes == null)
-                               return null;
-                       foreach (XAttribute a in attributes)
+                       foreach (XAttribute a in Attributes ())
                                if (a.Name == name)
                                        return a;
                        return null;
@@ -131,17 +132,16 @@
 
                public IEnumerable <XAttribute> Attributes ()
                {
-                       return attributes != null ? attributes : 
XAttribute.EmptySequence;
+                       for (XAttribute a = attr_first; a != null; a = 
a.NextAttribute)
+                               yield return a;
                }
 
+               // huh?
                public IEnumerable <XAttribute> Attributes (XName name)
                {
-                       XAttribute a = Attribute (name);
-                       if (a == null)
-                               return XAttribute.EmptySequence;
-                       List <XAttribute> list = new List <XAttribute> ();
-                       list.Add (a);
-                       return list;
+                       foreach (XAttribute a in Attributes ())
+                               if (a.Name == name)
+                                       yield return a;
                }
 
                /*
@@ -177,6 +177,7 @@
                }
                */
 
+/*
                // Only XAttribute.set_Parent() can invoke this.
                internal void InternalAppendAttribute (XAttribute attr)
                {
@@ -191,6 +192,7 @@
                                throw new SystemException ("INTERNAL ERROR: 
should not happen.");
                        attributes.Remove (attr);
                }
+*/
 
                public static XElement Load (string uri)
                {
@@ -243,7 +245,11 @@
                        XElement e = new XElement (name);
                        if (r.MoveToFirstAttribute ()) {
                                do {
-                                       e.SetAttributeValue (XName.Get 
(r.LocalName, r.NamespaceURI), r.Value);
+                                       // not sure how current Orcas behavior 
makes sense here though ...
+                                       if (r.LocalName == "xmlns" && 
r.NamespaceURI == XNamespace.Xmlns.NamespaceName)
+                                               e.SetAttributeValue 
(XNamespace.Blank.GetName ("xmlns"), r.Value);
+                                       else
+                                               e.SetAttributeValue (XName.Get 
(r.LocalName, r.NamespaceURI), r.Value);
                                } while (r.MoveToNextAttribute ());
                                r.MoveToElement ();
                        }
@@ -275,11 +281,8 @@
 
                public void RemoveAttributes ()
                {
-                       if (attributes != null)
-                               // FIXME: should avoid modification?
-                               foreach (XAttribute a in attributes)
-                                       a.Remove ();
-                       attributes = null;
+                       while (attr_first != null)
+                               attr_last.Remove ();
                }
 
                public void Save (string filename)
@@ -367,48 +370,31 @@
                                        a.Remove ();
                        } else {
                                if (a == null) {
-                                       new XAttribute (name, value).Parent = 
this;
+                                       a = new XAttribute (name, value);
+                                       a.SetOwner (this);
+                                       if (attr_first == null) {
+                                               attr_first = a;
+                                               attr_last = a;
+                                       } else {
+                                               attr_last.NextAttribute = a;
+                                               a.PreviousAttribute = attr_last;
+                                               attr_last = a;
+                                       }
                                }
                                else
                                        a.Value = XUtil.ToString (value);
                        }
                }
 
-               /*
-               public void SetAttributeNode (XAttribute attr)
-               {
-                       foreach (XAttribute a in Attributes (attr.Name))
-                               a.Remove ();
-                       attr.Parent = this;
-               }
-
-               public void SetElement (XName name, object value)
-               {
-                       IEnumerator <XElement> en = Elements 
(name).GetEnumerator ();
-                       XElement e = en.MoveNext () ? en.Current : null;
-                       if (value == null) {
-                               if (e != null)
-                                       e.Remove ();
-                       } else {
-                               if (e == null)
-                                       Add (new XElement (name, value));
-                               else
-                                       e.Value = XUtil.ToString (value);
-                       }
-               }
-               */
-
                public override void WriteTo (XmlWriter w)
                {
                        w.WriteStartElement (name.LocalName, 
name.Namespace.NamespaceName);
 
-                       if (attributes != null) {
-                               foreach (XAttribute a in attributes) {
-                                       if (a.Name.Namespace == 
XNamespace.Xmlns && a.Name.LocalName != String.Empty)
-                                               w.WriteAttributeString 
("xmlns", a.Name.LocalName, XNamespace.Xmlns.NamespaceName, a.Value);
-                                       else
-                                               w.WriteAttributeString 
(a.Name.LocalName, a.Name.Namespace.NamespaceName, a.Value);
-                               }
+                       foreach (XAttribute a in Attributes ()) {
+                               if (a.Name.Namespace == XNamespace.Xmlns && 
a.Name.LocalName != String.Empty)
+                                       w.WriteAttributeString ("xmlns", 
a.Name.LocalName, XNamespace.Xmlns.NamespaceName, a.Value);
+                               else
+                                       w.WriteAttributeString 
(a.Name.LocalName, a.Name.Namespace.NamespaceName, a.Value);
                        }
 
                        foreach (XNode node in Nodes ())

Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XNode.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XNode.cs  2007-05-04 
04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XNode.cs  2007-05-04 
04:41:07 UTC (rev 76658)
@@ -11,16 +11,14 @@
 {
        public abstract class XNode : XObject
        {
-               [MonoTODO]
                public static int CompareDocumentOrder (XNode n1, XNode n2)
                {
-                       throw new NotImplementedException ();
+                       return order_comparer.Compare (n1, n2);
                }
 
-               [MonoTODO]
                public static bool DeepEquals (XNode n1, XNode n2)
                {
-                       throw new NotImplementedException ();
+                       return eq_comparer.Equals (n1, n2);
                }
 
                static XNodeEqualityComparer eq_comparer =
@@ -74,7 +72,7 @@
                        if (Parent == null)
                                throw new InvalidOperationException ();
                        XNode n = XUtil.ToNode (content);
-                       n.Parent = Parent;
+                       n.SetOwner (Parent);
                        n.previous = this;
                        next = n;
                        if (Parent.LastNode == this)
@@ -94,7 +92,7 @@
                        if (Parent == null)
                                throw new InvalidOperationException ();
                        XNode n = XUtil.ToNode (content);
-                       n.Parent = Parent;
+                       n.SetOwner (Parent);
                        n.next = this;
                        previous = n;
                        if (Parent.FirstNode == this)
@@ -149,7 +147,7 @@
                        PreviousNode.next = NextNode;
                        previous = null;
                        next = null;
-                       Parent = null;
+                       SetOwner (null);
                }
 
                public override string ToString ()

Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XObject.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XObject.cs        
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq/XObject.cs        
2007-05-04 04:41:07 UTC (rev 76658)
@@ -10,7 +10,7 @@
                {
                }
 
-               XElement parent;
+               XContainer owner;
                List<object> annotations;
                string baseuri;
                int line, column;
@@ -25,24 +25,27 @@
 
                public XDocument Document {
                        get {
-                               XContainer e = Parent;
-                               if (e == null)
-                                       return null;
-                               do {
-                                       XContainer p = e.Parent;
-                                       if (p == null)
-                                               return e as XDocument; // might 
be XElement
-                               } while (true);
+                               if (this is XDocument)
+                                       return (XDocument) this;
+
+                               for (XContainer e = owner; e != null; e = 
e.owner)
+                                       if (e is XDocument)
+                                               return (XDocument) e;
+                               return null;
                        }
                }
 
                public abstract XmlNodeType NodeType { get; }
 
                public XElement Parent {
-                       get { return parent; }
-                       internal set { parent = value; }
+                       get { return owner as XElement; }
                }
 
+               internal void SetOwner (XContainer node)
+               {
+                       owner = node;
+               }
+
                public void AddAnnotation (object annotation)
                {
                        if (annotation == null)

Modified: trunk/olive/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources
===================================================================
--- trunk/olive/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources  
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources  
2007-05-04 04:41:07 UTC (rev 76658)
@@ -1,3 +1,4 @@
+System.Xml.Linq/XAttributeTest.cs
 System.Xml.Linq/XDocumentTest.cs
 System.Xml.Linq/XElementTest.cs
 System.Xml.Linq/XNameTest.cs

Modified: trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog
===================================================================
--- trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog    
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/ChangeLog    
2007-05-04 04:41:07 UTC (rev 76658)
@@ -1,3 +1,8 @@
+2007-05-04  Atsushi Enomoto  <[EMAIL PROTECTED]>
+
+       * XAttributeTest.cs : new test, for XAttribute.
+       * XElementTest.cs : attribute related tests.
+
 2007-05-03  Atsushi Enomoto  <[EMAIL PROTECTED]>
 
        * XElementTest.cs : new test.

Added: trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XAttributeTest.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XAttributeTest.cs    
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XAttributeTest.cs    
2007-05-04 04:41:07 UTC (rev 76658)
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.Linq;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Xml.Linq
+{
+       [TestFixture]
+       public class XAttributeTest
+       {
+               [Test]
+               public void IsNamespaceDeclaration ()
+               {
+                       string xml = "<root a='v' xmlns='urn:foo' 
xmlns:x='urn:x' x:a='v' xmlns:xml='http://www.w3.org/XML/1998/namespace' />";
+                       XElement el = XElement.Parse (xml);
+                       List<XAttribute> l = new List<XAttribute> 
(el.Attributes ());
+                       Assert.IsFalse (l [0].IsNamespaceDeclaration, "#1");
+                       Assert.IsTrue (l [1].IsNamespaceDeclaration, "#2");
+                       Assert.IsTrue (l [2].IsNamespaceDeclaration, "#3");
+                       Assert.IsFalse (l [3].IsNamespaceDeclaration, "#4");
+                       Assert.IsTrue (l [4].IsNamespaceDeclaration, "#5");
+
+                       Assert.AreEqual ("a", l [0].Name.LocalName, "#2-1");
+                       Assert.AreEqual ("xmlns", l [1].Name.LocalName, "#2-2");
+                       Assert.AreEqual ("x", l [2].Name.LocalName, "#2-3");
+                       Assert.AreEqual ("a", l [3].Name.LocalName, "#2-4");
+                       Assert.AreEqual ("xml", l [4].Name.LocalName, "#2-5");
+
+                       Assert.AreEqual ("", l [0].Name.NamespaceName, "#3-1");
+                       // not sure how current Orcas behavior makes sense here 
though ...
+                       Assert.AreEqual ("", l [1].Name.NamespaceName, "#3-2");
+                       Assert.AreEqual ("http://www.w3.org/2000/xmlns/";, l 
[2].Name.NamespaceName, "#3-3");
+                       Assert.AreEqual ("urn:x", l [3].Name.NamespaceName, 
"#3-4");
+                       Assert.AreEqual ("http://www.w3.org/2000/xmlns/";, l 
[4].Name.NamespaceName, "#3-5");
+               }
+
+               [Test]
+               public void Document ()
+               {
+                       XDocument doc = XDocument.Parse ("<root a='v' />");
+                       Assert.AreEqual (doc, doc.Root.Document, "#1");
+                       foreach (XAttribute a in doc.Root.Attributes ())
+                               Assert.AreEqual (doc, a.Document, "#2");
+                       Assert.AreEqual (doc, doc.Document, "#3");
+               }
+       }
+}

Modified: trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs
===================================================================
--- trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs      
2007-05-04 04:25:27 UTC (rev 76657)
+++ trunk/olive/class/System.Xml.Linq/Test/System.Xml.Linq/XElementTest.cs      
2007-05-04 04:41:07 UTC (rev 76658)
@@ -104,5 +104,49 @@
                        el.Add (new XDeclaration ("1.0", null, null));
                        Assert.AreEqual ("<?xml version=\"1.0\"?>", ((XText) 
el.FirstNode).Value, "#1");
                }
+
+               [Test]
+               public void SetAttribute ()
+               {
+                       XElement el = new XElement (XName.Get ("foo"));
+                       el.SetAttributeValue (XName.Get ("a1"), "v1");
+                       XAttribute a = el.FirstAttribute;
+                       Assert.IsNotNull (a, "#1-1");
+                       Assert.AreEqual (el, a.Parent, "#1-2");
+                       Assert.IsNotNull (el.LastAttribute, "#1-3");
+                       Assert.AreEqual (a, el.LastAttribute, "#1-4");
+                       Assert.AreEqual ("a1", a.Name.LocalName, "#1-5");
+                       Assert.AreEqual ("v1", a.Value, "#1-6");
+                       Assert.IsNull (a.PreviousAttribute, "#1-7");
+                       Assert.IsNull (a.NextAttribute, "#1-8");
+
+                       el.SetAttributeValue (XName.Get ("a2"), "v2");
+                       Assert.IsFalse (el.FirstAttribute == el.LastAttribute, 
"#2-1");
+                       Assert.AreEqual ("a2", el.LastAttribute.Name.LocalName, 
"#2-2");
+
+                       el.SetAttributeValue (XName.Get ("a1"), "v3");
+                       XAttribute b = el.FirstAttribute;
+                       Assert.IsNotNull (b, "#2-3");
+                       Assert.IsNotNull (el.LastAttribute, "#2-4");
+                       Assert.AreEqual ("a1", b.Name.LocalName, "#2-5");
+                       Assert.AreEqual ("v3", b.Value, "#2-6");
+                       Assert.AreEqual (a, b, "#2-7");
+                       XAttribute c = el.LastAttribute;
+                       Assert.AreEqual (a, c.PreviousAttribute, "#2-8");
+
+                       a.Remove ();
+                       Assert.IsNull (a.Parent, "#3-1");
+                       Assert.IsNull (a.PreviousAttribute, "#3-2");
+                       Assert.IsNull (a.NextAttribute, "#3-3");
+                       Assert.IsNull (c.PreviousAttribute, "#3-4");
+                       Assert.IsNull (c.NextAttribute, "#3-5");
+
+                       el.RemoveAttributes ();
+                       Assert.IsFalse (el.HasAttributes, "#4-1");
+                       Assert.IsNull (b.Parent, "#4-2");
+                       Assert.IsNull (c.Parent, "#4-3");
+                       Assert.IsNull (el.FirstAttribute, "#4-4");
+                       Assert.IsNull (el.LastAttribute, "#4-5");
+               }
        }
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to