2003-01-18 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / System.Xml / XmlTextWriter.cs
index a07793621296711c875374c6d75dc8245e817a3a..dba8ed19f329fe4b6284c58b07050214f9e19a6f 100644 (file)
@@ -18,28 +18,28 @@ namespace System.Xml
        {
                #region Fields
 
-               protected TextWriter w;
-               protected bool nullEncoding = false;
-               protected bool openWriter = true;
-               protected bool openStartElement = false;
-               protected bool openStartAttribute = false;
-               protected bool documentStarted = false;
-               private bool namespaces = true;
-               protected bool openAttribute = false;
-               protected bool attributeWrittenForElement = false;
-               protected Stack openElements = new Stack ();
-               private Formatting formatting = Formatting.None;
-               private int indentation = 2;
-               private char indentChar = ' ';
-               protected string indentChars = "  ";
-               private char quoteChar = '\"';
-               protected int indentLevel = 0;
-               protected string indentFormatting;
-               protected Stream baseStream = null;
-               protected string xmlLang = null;
-               protected XmlSpace xmlSpace = XmlSpace.None;
-               protected bool openXmlLang = false;
-               protected bool openXmlSpace = false;
+               TextWriter w;
+               bool nullEncoding = false;
+               bool openWriter = true;
+               bool openStartElement = false;
+               bool openStartAttribute = false;
+               bool documentStarted = false;
+               bool namespaces = true;
+               bool openAttribute = false;
+               bool attributeWrittenForElement = false;
+               Stack openElements = new Stack ();
+               Formatting formatting = Formatting.None;
+               int indentation = 2;
+               char indentChar = ' ';
+               string indentChars = "  ";
+               char quoteChar = '\"';
+               int indentLevel = 0;
+               string indentFormatting;
+               Stream baseStream = null;
+               string xmlLang = null;
+               XmlSpace xmlSpace = XmlSpace.None;
+               bool openXmlLang = false;
+               bool openXmlSpace = false;
 
                #endregion
 
@@ -67,10 +67,9 @@ namespace System.Xml
                        baseStream = w;
                }
 
-               public XmlTextWriter (string filename, Encoding encoding) : base ()
+               public XmlTextWriter (string filename, Encoding encoding) :
+                       this (new FileStream (filename, FileMode.Create, FileAccess.Write, FileShare.None), encoding)
                {
-                       this.w = new StreamWriter(filename, false, encoding);
-                       baseStream = ((StreamWriter)w).BaseStream;
                }
 
                #endregion
@@ -87,7 +86,7 @@ namespace System.Xml
                        set { formatting = value; }
                }
 
-               public bool IndentingOverriden 
+               private bool IndentingOverriden 
                {
                        get {
                                if (openElements.Count == 0)
@@ -298,10 +297,23 @@ namespace System.Xml
                        w.Write ("<!--{0}-->", text);
                }
 
-               [MonoTODO]
                public override void WriteDocType (string name, string pubid, string sysid, string subset)
                {
-                       throw new NotImplementedException ();
+                       if (name == null || name.Trim ().Length == 0)
+                               throw new ArgumentException ("Invalid DOCTYPE name", "name");
+
+                       w.Write ("<!DOCTYPE ");
+                       w.Write (name);
+                       if (pubid != null) {
+                               w.Write (String.Format (" PUBLIC {0}{1}{0} {0}{2}{0}", quoteChar, pubid, sysid));
+                       } else if (sysid != null) {
+                               w.Write (String.Format (" SYSTEM {0}{1}{0}", quoteChar, sysid));
+                       }
+
+                       if (subset != null)
+                               w.Write ("[" + subset + "]");
+
+                       w.Write('>');
                }
 
                public override void WriteEndAttribute ()
@@ -331,11 +343,11 @@ namespace System.Xml
 
                public override void WriteEndDocument ()
                {
+                       CloseOpenAttributeAndElements ();
+
                        if ((ws == WriteState.Start) || (ws == WriteState.Prolog))
                                throw new ArgumentException ("This document does not have a root element.");
 
-                       CloseOpenAttributeAndElements ();
-
                        ws = WriteState.Start;
                }
 
@@ -380,16 +392,25 @@ namespace System.Xml
                        WriteEndElementInternal (true);
                }
 
-               [MonoTODO]
+               private void CheckValidChars (string name, bool firstOnlyLetter)
+               {
+                       foreach (char c in name) {
+                               if (XmlConvert.IsInvalid (c, firstOnlyLetter))
+                                       throw new ArgumentException ("There is an invalid character: '" + c +
+                                                                    "'", "name");
+                       }
+               }
+
                public override void WriteName (string name)
                {
-                       throw new NotImplementedException ();
+                       CheckValidChars (name, true);
+                       w.Write (name);
                }
 
-               [MonoTODO]
                public override void WriteNmToken (string name)
                {
-                       throw new NotImplementedException ();
+                       CheckValidChars (name, false);
+                       w.Write (name);
                }
 
                public override void WriteProcessingInstruction (string name, string text)
@@ -515,7 +536,7 @@ namespace System.Xml
                        WriteStartElementInternal (prefix, localName, ns);
                }
 
-               protected override void WriteStartElementInternal (string prefix, string localName, string ns)
+               private void WriteStartElementInternal (string prefix, string localName, string ns)
                {
                        if (prefix == null)
                                prefix = String.Empty;
@@ -534,13 +555,19 @@ namespace System.Xml
                                if (ns != String.Empty) 
                                {
                                        string existingPrefix = namespaceManager.LookupPrefix (ns);
+                                       bool addDefaultNamespace = false;
+
+                                       if (existingPrefix == String.Empty && !namespaceManager.HasNamespace (prefix)) {
+                                               namespaceManager.AddNamespace (prefix, ns);
+                                               addDefaultNamespace = true;
+                                       }
 
                                        if (prefix == String.Empty)
                                                prefix = existingPrefix;
 
                                        if (prefix != existingPrefix)
                                                formatXmlns = String.Format (" xmlns:{0}={1}{2}{1}", prefix, quoteChar, ns);
-                                       else if (existingPrefix == String.Empty)
+                                       else if (addDefaultNamespace)
                                                formatXmlns = String.Format (" xmlns={0}{1}{0}", quoteChar, ns);
                                }
                                else if ((prefix == String.Empty) && (namespaceManager.LookupNamespace(prefix) != String.Empty)) {
@@ -575,7 +602,7 @@ namespace System.Xml
                        WriteStringInternal (text, true);
                }
 
-               public void WriteStringInternal (string text, bool entitize)
+               private void WriteStringInternal (string text, bool entitize)
                {
                        if (text == null)
                                text = String.Empty;