2002-08-16 Jason Diamond <jason@injektilo.org>
[mono.git] / mcs / class / System.XML / System.Xml / XmlTextReader.cs
index 289bc3637c4cc57da9d98574cf9cced5651f03ce..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,7 +49,12 @@ 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]
@@ -128,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
@@ -201,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
@@ -353,7 +360,7 @@ namespace System.Xml
                [MonoTODO]
                bool IXmlLineInfo.HasLineInfo ()
                {
-                       throw new NotImplementedException ();
+                       return false;
                }
 
                public override string LookupNamespace (string prefix)
@@ -367,34 +374,38 @@ namespace System.Xml
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public override bool MoveToAttribute (string name)
                {
+                       MoveToElement ();
                        bool match = false;
+
                        if (attributes == null)
                                return false;
 
-                       if (attributeEnumerator == null) {
+                       if (orderedAttributesEnumerator == null) {
                                SaveProperties ();
-                               attributeEnumerator = attributes.GetEnumerator ();
+                               orderedAttributesEnumerator = orderedAttributes.GetEnumerator ();
                        }
 
-                       while (attributeEnumerator.MoveNext ()) {
-                               if(name == attributeEnumerator.Key as string) match = true; break;
+                       while (orderedAttributesEnumerator.MoveNext ()) {
+                               if(name == orderedAttributesEnumerator.Current as string) {
+                                       match = true;
+                                       break;
+                               }
                        }
 
                        if (match) {
-                               string attname = attributeEnumerator.Key as string;
-                               string value = attributeEnumerator.Value as string;
+                                       
+                               string value = attributes [name] as string;
                                SetProperties (
                                        XmlNodeType.Attribute, // nodeType
-                                       attname, // name
+                                       name, // name
                                        false, // isEmptyElement
                                        value, // value
                                        false // clearAttributes
                                );
                        }
-
+                       
                        return match;
                }
 
@@ -406,8 +417,8 @@ namespace System.Xml
 
                public override bool MoveToElement ()
                {
-                       if (attributeEnumerator != null) {
-                               attributeEnumerator = null;
+                       if (orderedAttributesEnumerator != null) {
+                               orderedAttributesEnumerator = null;
                                RestoreProperties ();
                                return true;
                        }
@@ -426,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
@@ -485,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]
@@ -542,7 +592,8 @@ namespace System.Xml
                private bool saveIsEmptyElement;
 
                private Hashtable attributes;
-               private IDictionaryEnumerator attributeEnumerator;
+               private ArrayList orderedAttributes;
+               private IEnumerator orderedAttributesEnumerator;
 
                private bool returnEntityReference;
                private string entityReferenceName;
@@ -557,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;
@@ -574,7 +631,8 @@ namespace System.Xml
                        value = String.Empty;
 
                        attributes = new Hashtable ();
-                       attributeEnumerator = null;
+                       orderedAttributes = new ArrayList ();
+                       orderedAttributesEnumerator = null;
 
                        returnEntityReference = false;
                        entityReferenceName = String.Empty;
@@ -586,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
@@ -646,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 ()
@@ -663,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
@@ -672,7 +747,7 @@ namespace System.Xml
                private bool ReadContent ()
                {
                        bool more = false;
-
+                       currentTag.Length = 0;
                        if (popScope) {
                                parserContext.NamespaceManager.PopScope ();
                                popScope = false;
@@ -686,7 +761,7 @@ namespace System.Xml
                                SetEntityReferenceProperties ();
                                more = true;
                        } else {
-                               switch (PeekChar ())
+                       switch (PeekChar ())
                                {
                                case '<':
                                        ReadChar ();