Stephane@212: using System;
Stephane@212: using System.Collections.Generic;
Stephane@212: using System.ComponentModel;
Stephane@212: using System.IO;
Stephane@212: using System.Linq;
Stephane@212: using System.Text;
Stephane@212: using System.Threading.Tasks;
Stephane@212: using System.Runtime.Serialization;
Stephane@212: using System.Runtime.Serialization.Json;
Stephane@212: using System.Globalization;
Stephane@212: 
Stephane@212: namespace SharpLib.Utils
Stephane@212: {
Stephane@212:     /// <summary>
Stephane@212:     /// Allow serialization into JSON.
Stephane@212:     /// Most useful to be able to save complex settings for instance.
Stephane@212:     /// Usage:
Stephane@212:     /// ...
Stephane@212:     /// [TypeConverter(typeof(TypeConverterJson<PersistantObject>))]
Stephane@212:     /// [DataContract]
Stephane@212:     /// public class PersistantObject
Stephane@212:     /// ...
Stephane@212:     /// </summary>
Stephane@212:     /// <typeparam name="T"></typeparam>
Stephane@212:     public class TypeConverterJson<T> : TypeConverter where T : class
Stephane@212:     {
Stephane@212:         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
Stephane@212:         {
Stephane@212:             if (sourceType == typeof(string))
Stephane@212:                 return true;
Stephane@212:             else
Stephane@212:                 return base.CanConvertFrom(context, sourceType);
Stephane@212:         }
Stephane@212: 
Stephane@212:         /// <summary>
StephaneLenclud@222:         /// Internalize
Stephane@212:         /// </summary>
Stephane@212:         /// <param name="context"></param>
Stephane@212:         /// <param name="culture"></param>
Stephane@212:         /// <param name="value"></param>
Stephane@212:         /// <returns></returns>
Stephane@212:         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
Stephane@212:         {
Stephane@212:             string stringValue = value as string;
Stephane@212:             if (stringValue != null)
Stephane@212:             {
StephaneLenclud@222:                 //try
StephaneLenclud@222:                 //{
StephaneLenclud@222:                     //Load object form JSON string
StephaneLenclud@222:                     byte[] byteArray = Encoding.UTF8.GetBytes(stringValue);
StephaneLenclud@222:                     MemoryStream stream = new MemoryStream(byteArray);
StephaneLenclud@222:                     DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T),
StephaneLenclud@222:                         new DataContractJsonSerializerSettings()
StephaneLenclud@222:                         {
StephaneLenclud@222:                             UseSimpleDictionaryFormat = true
StephaneLenclud@222:                         });
StephaneLenclud@222:                     T settings = (T)ser.ReadObject(stream);
StephaneLenclud@222:                     return settings;
StephaneLenclud@222:                 //}
StephaneLenclud@222:                 //catch (Exception ex)
StephaneLenclud@222:                 //{
StephaneLenclud@222:                     //That's not helping with partial loading
StephaneLenclud@222:                 //    Console.WriteLine("WARNING: Internalize exception -" + ex.ToString() );
StephaneLenclud@222:                 //    return null;
StephaneLenclud@222:                 //}
Stephane@212:             }
Stephane@212:             else
StephaneLenclud@222:             {
Stephane@212:                 return base.ConvertFrom(context, culture, value);
StephaneLenclud@222:             }
StephaneLenclud@222:                 
Stephane@212:         }
Stephane@212: 
Stephane@212:         /// <summary>
StephaneLenclud@222:         /// Externalize
Stephane@212:         /// </summary>
Stephane@212:         /// <param name="context"></param>
Stephane@212:         /// <param name="culture"></param>
Stephane@212:         /// <param name="value"></param>
Stephane@212:         /// <param name="destinationType"></param>
Stephane@212:         /// <returns></returns>
Stephane@212:         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
Stephane@212:         {
Stephane@212:             if (destinationType == typeof(string))
Stephane@212:             {
Stephane@212:                 //Save settings into JSON string
Stephane@212:                 MemoryStream stream = new MemoryStream();
Stephane@212:                 DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings()
Stephane@212:                 {
Stephane@212:                     UseSimpleDictionaryFormat = true
Stephane@212:                 });
Stephane@212:                 ser.WriteObject(stream, value);
Stephane@212:                 // convert stream to string
Stephane@212:                 stream.Position = 0;
Stephane@212:                 StreamReader reader = new StreamReader(stream);
Stephane@212:                 string text = reader.ReadToEnd();
Stephane@212:                 return text;
Stephane@212:             }
Stephane@212:             else
Stephane@212:             {
Stephane@212:                 return base.ConvertTo(context,culture,value,destinationType);
Stephane@212:             }
Stephane@212:         }
Stephane@212:     }
Stephane@212: }