65.9K
CodeProject is changing. Read more.
Home

Option Library

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (6 votes)

Aug 2, 2002

viewsIcon

88972

downloadIcon

582

Provides methods to save and load option classes

Sample Image - OptionLib.jpg

Introduction

I have looked around for a way of saving my application settings, but there are several stumbling blocks. The class should overcome them all. There are only 2 static methods. Load and Save.

Problems

  1. All serializable objects should be serialized.
  2. BinaryFormatter works fine as long as class is not changed in structure.
  3. XmlSerializer do provide methods to serialize classes without a default constructor.

Option class requirements

  • Class MUST have default constructor.
  • An instance of the class must exist before calling Load

Source code

public static void Save(string filename, object options)
{

  Byte[] buffer = new Byte[80];
  MemoryStream ms;
  BinaryFormatter bf = new BinaryFormatter();

  System.Xml.XmlTextWriter xmlwriter = 
    new XmlTextWriter(filename, System.Text.Encoding.Default);

  xmlwriter.Formatting = Formatting.Indented;
  xmlwriter.WriteStartDocument();

  xmlwriter.WriteComment("Option File. Do not edit!");
  xmlwriter.WriteStartElement(options.ToString());
		
  PropertyInfo[] props = options.GetType().GetProperties(
    BindingFlags.Public | 
    BindingFlags.Instance | 
    BindingFlags.SetField);

  foreach (PropertyInfo prop in props)
  {
    xmlwriter.WriteStartElement(prop.Name);

    object da = prop.GetValue(options, null);

    if (da != null) 
    {
      xmlwriter.WriteAttributeString("Value", da.ToString());

      ms = new MemoryStream();
      try 
      {
        bf.Serialize(ms, da);
        ms.Position = 0;
        int count = 0;
        do 
        {
          count = ms.Read(buffer, 0, buffer.Length);
          xmlwriter.WriteBase64(buffer, 0, count);
        }
        while ( count == buffer.Length);
      } 
      catch (System.Runtime.Serialization.SerializationException e)
      {
        Console.WriteLine("SERIALIZATION FAILED: {0}", prop.Name);
      }

    }
    else xmlwriter.WriteAttributeString("Value", "null");

    xmlwriter.WriteEndElement();
  }
  xmlwriter.WriteEndElement();
  xmlwriter.WriteEndDocument();
  xmlwriter.Flush();
  xmlwriter.Close();
}

public static void Load(string filename, object options)
{
  Byte[] buffer = new Byte[80];
  MemoryStream ms;
  BinaryFormatter bf = new BinaryFormatter();

  System.Xml.XmlTextReader reader = new XmlTextReader(filename);

  while (reader.Read())
  {
    switch (reader.NodeType)
    {
      case XmlNodeType.Element:

        if (reader.HasAttributes)
        {
          string name = reader.Name;
          string val = reader.GetAttribute("Value");

          ms = new MemoryStream();
		
          int count = 0;
          do 
          {
            count = reader.ReadBase64(buffer, 0 , buffer.Length);
            ms.Write(buffer, 0,count);
          }
          while (count == buffer.Length);

          ms.Position = 0;

          if (val != "null") 
          {
            try 
            {
              object da = bf.Deserialize(ms);

              Console.Write("Applying {0} : ", name);
              options.GetType().GetProperty(name).SetValue(options, da, null);
              Console.WriteLine("OK");
            }
            catch (System.Runtime.Serialization.SerializationException e)
            {
              Console.WriteLine("FAIL: {0}",e.Message);
            }
          }
        }
        break;
    }
  }
  reader.Close();
}

Implementation

  • static Load(string filename, object optionclass);
  • static Save(string filename, object optionclass);

That's it. Any problems, let me know.