Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / System / System.Configuration / SettingsPropertyValue.cs
index db1e781159289d0666f99395bf8b3da149b1ae4d..2d554cc7571ff2069d05c817a5c3db0d2c07ba76 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
 using System;
+using System.Globalization;
 using System.IO;
+using System.ComponentModel;
 using System.Runtime.Serialization.Formatters.Binary;
 #if (XML_DEP)
+using System.Xml;
 using System.Xml.Serialization;
 #endif
 
@@ -50,7 +52,7 @@ namespace System.Configuration
                                return deserialized;
                        }
                        set {
-                               deserialized = true;
+                               deserialized = value;
                        }
                }
 
@@ -78,20 +80,19 @@ namespace System.Configuration
                public object PropertyValue {
                        get {
                                if (needPropertyValue) {
+                                       propertyValue = GetDeserializedValue (serializedValue);
+                                       if (propertyValue == null) {
+                                               propertyValue = GetDeserializedDefaultValue ();
+                                               defaulted = true;
+                                       }
                                        needPropertyValue = false;
-                                       propertyValue = property.DefaultValue;
-                                       defaulted = true;
                                }
 
-#if notyet
-                               /* LAMESPEC: the msdn2 docs say that
-                                * for object types this
-                                * pessimistically sets Dirty == true.
-                                * tests, however, point out that that
-                                * is not the case. */
-                               if (!property.PropertyType.IsValueType)
+                               if (propertyValue != null &&
+                                       !(propertyValue is string) &&
+                                       !(propertyValue is DateTime) &&
+                                       !property.PropertyType.IsPrimitive)
                                        dirty = true;
-#endif
 
                                return propertyValue;
                        }
@@ -104,7 +105,6 @@ namespace System.Configuration
                        }
                }
 
-               [MonoTODO ("string type converter?")]
                public object SerializedValue {
                        get {
                                if (needSerializedValue) {
@@ -113,23 +113,30 @@ namespace System.Configuration
                                        switch (property.SerializeAs)
                                        {
                                        case SettingsSerializeAs.String:
-                                               /* the docs say use a string type converter.. this means what? */
-                                               serializedValue = propertyValue.ToString();
+                                               serializedValue = TypeDescriptor.GetConverter (property.PropertyType).ConvertToInvariantString (propertyValue);
                                                break;
 #if (XML_DEP)
                                        case SettingsSerializeAs.Xml:
-                                               XmlSerializer serializer = new XmlSerializer (propertyValue.GetType());
-                                               StringWriter w = new StringWriter();
-
-                                               serializer.Serialize (w, propertyValue);
-                                               serializedValue = w.ToString();
+                                               if (propertyValue != null) {
+                                                       XmlSerializer serializer = new XmlSerializer (propertyValue.GetType ());
+                                                       StringWriter w = new StringWriter(CultureInfo.InvariantCulture);
+       
+                                                       serializer.Serialize (w, propertyValue);
+                                                       serializedValue = w.ToString();
+                                               }
+                                               else
+                                                       serializedValue = null;
                                                break;
 #endif
                                        case SettingsSerializeAs.Binary:
-                                               BinaryFormatter bf = new BinaryFormatter ();
-                                               MemoryStream ms = new MemoryStream ();
-                                               bf.Serialize (ms, propertyValue);
-                                               serializedValue = ms.ToArray();
+                                               if (propertyValue != null) {
+                                                       BinaryFormatter bf = new BinaryFormatter ();
+                                                       MemoryStream ms = new MemoryStream ();
+                                                       bf.Serialize (ms, propertyValue);
+                                                       serializedValue = ms.ToArray();
+                                               }
+                                               else
+                                                       serializedValue = null;
                                                break;
                                        default:
                                                serializedValue = null;
@@ -142,6 +149,7 @@ namespace System.Configuration
                        }
                        set {
                                serializedValue = value;
+                               needPropertyValue = true;
                        }
                }
 
@@ -151,16 +159,87 @@ namespace System.Configuration
                        }
                }
 
-               SettingsProperty property;
+               internal object Reset ()
+               {
+                       propertyValue = GetDeserializedDefaultValue ();
+                       dirty = true;
+                       defaulted = true;
+                       needPropertyValue = true;
+                       return propertyValue;
+               }
+
+               private object GetDeserializedDefaultValue ()
+               {
+                       if (property.DefaultValue == null)
+                               if (property.PropertyType.IsValueType)
+                                       return Activator.CreateInstance (property.PropertyType);
+                               else
+                                       return null;
+
+                       if (property.DefaultValue is string && ((string) property.DefaultValue).Length == 0)
+                               if (property.PropertyType != typeof (string))
+                                       return Activator.CreateInstance (property.PropertyType);
+                               else
+                                       return string.Empty;
+
+                       if (property.DefaultValue is string && ((string) property.DefaultValue).Length > 0)
+                               return GetDeserializedValue (property.DefaultValue);
+
+                       if (!property.PropertyType.IsAssignableFrom (property.DefaultValue.GetType ())) {
+                               TypeConverter converter = TypeDescriptor.GetConverter (property.PropertyType);
+                               return converter.ConvertFrom (null, CultureInfo.InvariantCulture, property.DefaultValue);
+                       }
+                       return property.DefaultValue;
+               }
+
+               private object GetDeserializedValue (object serializedValue)
+               {
+                       if (serializedValue == null)
+                               return null;
+
+                       object deserializedObject = null;
+
+                       try {
+                               switch (property.SerializeAs) {
+                                       case SettingsSerializeAs.String:
+                                               if (serializedValue is string)
+                                                       deserializedObject = TypeDescriptor.GetConverter (property.PropertyType).ConvertFromInvariantString ((string) serializedValue);
+                                               break;
+#if (XML_DEP)
+                                       case SettingsSerializeAs.Xml:
+                                               XmlSerializer serializer = new XmlSerializer (property.PropertyType);
+                                               StringReader str = new StringReader ((string) serializedValue);
+                                               deserializedObject = serializer.Deserialize (XmlReader.Create (str));
+                                               break;
+#endif
+                                       case SettingsSerializeAs.Binary:
+                                               BinaryFormatter bf = new BinaryFormatter ();
+                                               MemoryStream ms;
+                                               if (serializedValue is string)
+                                                       ms = new MemoryStream (Convert.FromBase64String ((string) serializedValue));
+                                               else
+                                                       ms = new MemoryStream ((byte []) serializedValue);
+                                               deserializedObject = bf.Deserialize (ms);
+                                               break;
+                               }
+                       }
+                       catch (Exception e) {
+                               if (property.ThrowOnErrorDeserializing)
+                                       throw e;
+                       }
+
+                       return deserializedObject;
+               }
+
+               readonly SettingsProperty property;
                object propertyValue;
                object serializedValue;
                bool needSerializedValue;
                bool needPropertyValue;
                bool dirty;
-               bool defaulted;
+               bool defaulted = false;
                bool deserialized;
        }
 
 }
 
-#endif