2008-11-20 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mcs / class / System / System.Configuration / ConfigurationSettings.cs
index dba99ccde2333ca967b3ca7628835fdd5e2fc744..199d83fe7bb383121660fd6e0dc5199d262e4321 100644 (file)
@@ -32,7 +32,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if CONFIGURATION_DEP
+#if CONFIGURATION_DEP && !TARGET_JVM
 extern alias PrebuiltSystem;
 using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
 #endif
@@ -83,7 +83,11 @@ namespace System.Configuration
 #endif
                public static object GetConfig (string sectionName)
                {
+#if NET_2_0 && CONFIGURATION_DEP
+                       return ConfigurationManager.GetSection (sectionName);
+#else
                        return config.GetConfig (sectionName);
+#endif
                }
 
 #if NET_2_0
@@ -167,9 +171,13 @@ namespace System.Configuration
                                        return;
 
                                ConfigurationData data = new ConfigurationData ();
-                               if (!data.Load (GetMachineConfigPath ()))
-                                       throw new ConfigurationException ("Cannot find " + GetMachineConfigPath ());
+                               if (data.LoadString (GetBundledMachineConfig ())) {
+                                       // do nothing
+                               } else {
+                                       if (!data.Load (GetMachineConfigPath ()))
+                                               throw new ConfigurationException ("Cannot find " + GetMachineConfigPath ());
 
+                               }
                                string appfile = GetAppConfigPath ();
                                if (appfile == null) {
                                        config = data;
@@ -184,11 +192,21 @@ namespace System.Configuration
                        }
                }
 #if TARGET_JVM
+               internal static string GetBundledMachineConfig ()
+               {
+                       return null;
+               }
                internal static string GetMachineConfigPath ()
                {
-                       return "/machine.config";
+                       return System.Runtime.InteropServices.RuntimeEnvironment.SystemConfigurationFile;
                }
 #else
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               extern private static string get_bundled_machine_config ();
+               internal static string GetBundledMachineConfig ()
+               {
+                       return get_bundled_machine_config ();
+               }
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern private static string get_machine_config_path ();
                internal static string GetMachineConfigPath ()
@@ -196,7 +214,6 @@ namespace System.Configuration
                        return get_machine_config_path ();
                }
 #endif
-
                private static string GetAppConfigPath ()
                {
                        AppDomainSetup currentInfo = AppDomain.CurrentDomain.SetupInformation;
@@ -302,8 +319,32 @@ namespace System.Configuration
                                }
 #endif
                                reader = new XmlTextReader (fs);
-                               InitRead (reader);
-                               ReadConfigFile (reader);
+                               if (InitRead (reader))
+                                       ReadConfigFile (reader);
+                       } catch (ConfigurationException) {
+                               throw;
+                       } catch (Exception e) {
+                               throw new ConfigurationException ("Error reading " + fileName, e);
+                       } finally {
+                               if (reader != null)
+                                       reader.Close();
+                       }
+#endif
+                       return true;
+               }
+               
+               public bool LoadString (string data)
+               {
+                       if (data == null)
+                               return false;
+#if (XML_DEP)
+                       XmlTextReader reader = null;
+
+                       try {
+                               TextReader tr = new StringReader (data);
+                               reader = new XmlTextReader (tr);
+                               if (InitRead (reader))
+                                       ReadConfigFile (reader);
                        } catch (ConfigurationException) {
                                throw;
                        } catch (Exception e) {
@@ -451,7 +492,7 @@ namespace System.Configuration
                        return null;
                }
 #if (XML_DEP)
-               private void InitRead (XmlTextReader reader)
+               private bool InitRead (XmlTextReader reader)
                {
                        reader.MoveToContent ();
                        if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration")
@@ -459,10 +500,16 @@ namespace System.Configuration
 
                        if (reader.HasAttributes)
                                ThrowException ("Unrecognized attribute in root element", reader);
-
-                       MoveToNextElement (reader);
+                       if (reader.IsEmptyElement) {
+                               reader.Skip ();
+                               return false;
+                       }
+                       reader.Read ();
+                       reader.MoveToContent ();
+                       return reader.NodeType != XmlNodeType.EndElement;
                }
 
+               // FIXME: this approach is not always safe and likely to cause bugs.
                private void MoveToNextElement (XmlTextReader reader)
                {
                        while (reader.Read ()) {
@@ -565,7 +612,17 @@ namespace System.Configuration
                        section.FileName = fileName;
                        factories [nameValue] = section;
 
-                       MoveToNextElement (reader);
+                       if (reader.IsEmptyElement)
+                               reader.Skip ();
+                       else {
+                               reader.Read ();
+                               reader.MoveToContent ();
+                               if (reader.NodeType != XmlNodeType.EndElement)
+                                       // sub-section inside a section
+                                       ReadSections (reader, nameValue);
+                               reader.ReadEndElement ();
+                       }
+                       reader.MoveToContent ();
                }
 
                private void ReadRemoveSection (XmlTextReader reader, string sectionName)
@@ -623,14 +680,28 @@ namespace System.Configuration
                                ThrowException ("Already have a factory for " + value, reader);
 
                        factories [value] = groupMark;
-                       MoveToNextElement (reader);
-                       ReadSections (reader, value);
+
+                       if (reader.IsEmptyElement) {
+                               reader.Skip ();
+                               reader.MoveToContent ();
+                       } else {
+                               reader.Read ();
+                               reader.MoveToContent ();
+                               if (reader.NodeType != XmlNodeType.EndElement)
+                                       ReadSections (reader, value);
+                               reader.ReadEndElement ();
+                               reader.MoveToContent ();
+                       }
                }
 
+               // It stops XmlReader consumption at where it found
+               // surrounding EndElement i.e. EndElement is not consumed here
                private void ReadSections (XmlTextReader reader, string configSection)
                {
                        int depth = reader.Depth;
-                       while (reader.Depth == depth) {
+                       for (reader.MoveToContent ();
+                            reader.Depth == depth;
+                            reader.MoveToContent ()) {
                                string name = reader.Name;
                                if (name == "section") {
                                        ReadSection (reader, configSection);
@@ -671,16 +742,23 @@ namespace System.Configuration
 
                private void ReadConfigFile (XmlTextReader reader)
                {
-                       int depth = reader.Depth;
-                       while (!reader.EOF && reader.Depth == depth) {
+                       //int depth = reader.Depth;
+                       for (reader.MoveToContent ();
+                            !reader.EOF && reader.NodeType != XmlNodeType.EndElement;
+                            reader.MoveToContent ()) {
                                string name = reader.Name;
                                if (name == "configSections") {
                                        if (reader.HasAttributes)
                                                ThrowException ("Unrecognized attribute in <configSections>.", reader);
-
-                                       MoveToNextElement (reader);
-                                       if (reader.Depth > depth)
-                                               ReadSections (reader, null);
+                                       if (reader.IsEmptyElement)
+                                               reader.Skip ();
+                                       else {
+                                               reader.Read ();
+                                               reader.MoveToContent ();
+                                               if (reader.NodeType != XmlNodeType.EndElement)
+                                                       ReadSections (reader, null);
+                                               reader.ReadEndElement ();
+                                       }
                                } else if (name != null && name != "") {
                                        StorePending (name, reader);
                                        MoveToNextElement (reader);