Implementation and tests for XmlAttributeCollection.RemoveAll and XmlElement.RemoveAl...
[mono.git] / mcs / class / System.XML / System.Xml / XmlTextReader.cs
index f49090793fda12c7f819c229a3e532921910c429..178d9a06d3ceabfcf9904a8d7564d909c22e0f26 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Jason Diamond (jason@injektilo.org)
+//   Adam Treat (manyoso@yahoo.com)
 //
 // (C) 2001, 2002 Jason Diamond  http://injektilo.org/
 //
@@ -48,13 +49,22 @@ namespace System.Xml
                [MonoTODO]
                public XmlTextReader (Stream input)
                {
-                       throw new NotImplementedException ();
+                       // We can share some code in the constructors (at least for this one and next 2)
+                       XmlNameTable nt = new NameTable ();
+                       XmlNamespaceManager nsMgr = new XmlNamespaceManager (nt);
+                       parserContext = new XmlParserContext (null, nsMgr, null, XmlSpace.None);
+                       Init ();
+                       reader = new StreamReader (input);
                }
 
                [MonoTODO]
                public XmlTextReader (string url)
                {
-                       throw new NotImplementedException ();
+                       XmlNameTable nt = new NameTable ();
+                       XmlNamespaceManager nsMgr = new XmlNamespaceManager (nt);
+                       parserContext = new XmlParserContext (null, nsMgr, null, XmlSpace.None);
+                       Init ();
+                       reader = new StreamReader(url);
                }
 
                [MonoTODO]
@@ -124,7 +134,10 @@ namespace System.Xml
                [MonoTODO]
                public XmlTextReader (string xmlFragment, XmlNodeType fragType, XmlParserContext context)
                {
-                       throw new NotImplementedException ();
+                       //Waiting for Validating reader for fragType rules.
+                       parserContext = context;
+                       Init ();
+                       reader = new StringReader(xmlFragment);
                }
 
                #endregion
@@ -197,16 +210,14 @@ namespace System.Xml
                        get { return GetAttribute (localName, namespaceName); }
                }
 
-               [MonoTODO]
                public int LineNumber
                {
-                       get { throw new NotImplementedException (); }
+                       get { return line; }
                }
 
-               [MonoTODO]
                public int LinePosition
                {
-                       get { throw new NotImplementedException (); }
+                       get { return column; }
                }
 
                public override string LocalName
@@ -349,7 +360,7 @@ namespace System.Xml
                [MonoTODO]
                bool IXmlLineInfo.HasLineInfo ()
                {
-                       throw new NotImplementedException ();
+                       return false;
                }
 
                public override string LookupNamespace (string prefix)
@@ -363,10 +374,39 @@ namespace System.Xml
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public override bool MoveToAttribute (string name)
                {
-                       throw new NotImplementedException ();
+                       MoveToElement ();
+                       bool match = false;
+
+                       if (attributes == null)
+                               return false;
+
+                       if (orderedAttributesEnumerator == null) {
+                               SaveProperties ();
+                               orderedAttributesEnumerator = orderedAttributes.GetEnumerator ();
+                       }
+
+                       while (orderedAttributesEnumerator.MoveNext ()) {
+                               if(name == orderedAttributesEnumerator.Current as string) {
+                                       match = true;
+                                       break;
+                               }
+                       }
+
+                       if (match) {
+                                       
+                               string value = attributes [name] as string;
+                               SetProperties (
+                                       XmlNodeType.Attribute, // nodeType
+                                       name, // name
+                                       false, // isEmptyElement
+                                       value, // value
+                                       false // clearAttributes
+                               );
+                       }
+                       
+                       return match;
                }
 
                [MonoTODO]
@@ -377,7 +417,8 @@ namespace System.Xml
 
                public override bool MoveToElement ()
                {
-                       if (nodeType == XmlNodeType.Attribute) {
+                       if (orderedAttributesEnumerator != null) {
+                               orderedAttributesEnumerator = null;
                                RestoreProperties ();
                                return true;
                        }
@@ -396,14 +437,14 @@ namespace System.Xml
                        if (attributes == null)
                                return false;
 
-                       if (attributeEnumerator == null) {
+                       if (orderedAttributesEnumerator == null) {
                                SaveProperties ();
-                               attributeEnumerator = attributes.GetEnumerator ();
+                               orderedAttributesEnumerator = orderedAttributes.GetEnumerator ();
                        }
 
-                       if (attributeEnumerator.MoveNext ()) {
-                               string name = attributeEnumerator.Key as string;
-                               string value = attributeEnumerator.Value as string;
+                       if (orderedAttributesEnumerator.MoveNext ()) {
+                               string name = orderedAttributesEnumerator.Current as string;
+                               string value = attributes [name] as string;
                                SetProperties (
                                        XmlNodeType.Attribute, // nodeType
                                        name, // name
@@ -455,13 +496,52 @@ namespace System.Xml
                [MonoTODO]
                public override string ReadInnerXml ()
                {
-                       throw new NotImplementedException ();
+                       // Still need a Well Formedness check.
+                       // Will wait for Validating reader ;-)
+                       if (NodeType == XmlNodeType.Attribute) {
+                               return Value;
+                       } else {
+                               saveToXmlBuffer = true;
+                               string startname = this.Name;
+                               string endname = string.Empty;
+                               readState = ReadState.Interactive;
+
+                               while (startname != endname) {
+                                       ReadContent ();
+                               endname = this.Name;
+                               }
+
+                               xmlBuffer.Replace(currentTag.ToString (), "");
+                               saveToXmlBuffer = false;
+                               string InnerXml = xmlBuffer.ToString ();
+                               xmlBuffer.Length = 0;
+                               return InnerXml;
+                       }
                }
 
                [MonoTODO]
                public override string ReadOuterXml ()
                {
-                       throw new NotImplementedException ();
+                       // Still need a Well Formedness check.
+                       // Will wait for Validating reader ;-)
+                       if (NodeType == XmlNodeType.Attribute) {
+                               return Name+"=\""+Value+"\"";
+                       } else {
+                               saveToXmlBuffer = true;
+                               xmlBuffer.Append(currentTag.ToString ());
+                               string startname = this.Name;
+                               string endname = string.Empty;
+                               readState = ReadState.Interactive;
+
+                               while (startname != endname) {
+                                       ReadContent ();
+                               endname = this.Name;
+                               }
+                               saveToXmlBuffer = false;
+                               string OuterXml = xmlBuffer.ToString ();
+                               xmlBuffer.Length = 0;
+                               return OuterXml;
+                       }
                }
 
                [MonoTODO]
@@ -510,9 +590,10 @@ namespace System.Xml
                private string saveLocalName;
                private string saveNamespaceURI;
                private bool saveIsEmptyElement;
-       
+
                private Hashtable attributes;
-               private IDictionaryEnumerator attributeEnumerator;
+               private ArrayList orderedAttributes;
+               private IEnumerator orderedAttributesEnumerator;
 
                private bool returnEntityReference;
                private string entityReferenceName;
@@ -527,6 +608,12 @@ namespace System.Xml
                private int valueCapacity;
                private const int initialValueCapacity = 8192;
 
+               private StringBuilder xmlBuffer; // This is for Read(Inner|Outer)Xml
+               private StringBuilder currentTag; // A buffer for ReadContent for ReadOuterXml
+               private bool saveToXmlBuffer;
+               private int line;
+               private int column;
+
                private void Init ()
                {
                        readState = ReadState.Initial;
@@ -544,7 +631,8 @@ namespace System.Xml
                        value = String.Empty;
 
                        attributes = new Hashtable ();
-                       attributeEnumerator = null;
+                       orderedAttributes = new ArrayList ();
+                       orderedAttributesEnumerator = null;
 
                        returnEntityReference = false;
                        entityReferenceName = String.Empty;
@@ -556,6 +644,9 @@ namespace System.Xml
                        valueBuffer = new char [initialValueCapacity];
                        valueLength = 0;
                        valueCapacity = initialValueCapacity;
+
+                       xmlBuffer = new StringBuilder ();
+                       currentTag = new StringBuilder ();
                }
 
                // Use this method rather than setting the properties
@@ -616,14 +707,17 @@ namespace System.Xml
                private void AddAttribute (string name, string value)
                {
                        attributes.Add (name, value);
+                       orderedAttributes.Add (name);
                }
 
                private void ClearAttributes ()
                {
-                       if (attributes.Count > 0)
+                       if (attributes.Count > 0) {
                                attributes.Clear ();
+                               orderedAttributes.Clear ();
+                       }
 
-                       attributeEnumerator = null;
+                       orderedAttributesEnumerator = null;
                }
 
                private int PeekChar ()
@@ -633,7 +727,18 @@ namespace System.Xml
 
                private int ReadChar ()
                {
-                       return reader.Read ();
+                       int ch = reader.Read ();
+                       if (ch == '\n') {
+                               line++;
+                               column = 1;
+                       } else {
+                               column++;
+                       }
+                       if (saveToXmlBuffer) {
+                               xmlBuffer.Append ((char) ch);
+                       }
+                       currentTag.Append ((char) ch);
+                       return ch;
                }
 
                // This should really keep track of some state so
@@ -642,7 +747,7 @@ namespace System.Xml
                private bool ReadContent ()
                {
                        bool more = false;
-
+                       currentTag.Length = 0;
                        if (popScope) {
                                parserContext.NamespaceManager.PopScope ();
                                popScope = false;
@@ -656,7 +761,7 @@ namespace System.Xml
                                SetEntityReferenceProperties ();
                                more = true;
                        } else {
-                               switch (PeekChar ())
+                       switch (PeekChar ())
                                {
                                case '<':
                                        ReadChar ();