Skip to content

Instantly share code, notes, and snippets.

@stofte
Created August 19, 2013 17:15
Show Gist options
  • Save stofte/6271588 to your computer and use it in GitHub Desktop.
Save stofte/6271588 to your computer and use it in GitHub Desktop.
ini file serializer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
using System.IO;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Collections;
using System.Threading;
namespace ConsoleApplication2
{
[Serializable]
public class IniFile
{
public IList<Section> Sections;
}
[Serializable]
public class Section
{
public string Title;
public IDictionary<string, object> Entries;
}
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
var formatter = new CrappyIniFormatter();
var output = new FileStream("foo.ini", FileMode.Create);
var inifile = new IniFile { Sections = new List<Section>() };
var entries = new Dictionary<string, object> {
{ "foo", 1.2f },
{ "bar", "baz" }
};
var section = new Section { Title = "My stuff", Entries = entries };
inifile.Sections.Add(section);
formatter.Serialize(output, inifile);
output.Close();
var s = new FileStream("foo.ini", FileMode.Open);
var t = (IniFile)formatter.Deserialize(s);
}
}
public class CrappyIniFormatter : IFormatter
{
SerializationBinder binder;
StreamingContext context;
ISurrogateSelector surrogateSelector;
public CrappyIniFormatter()
{
context = new StreamingContext(StreamingContextStates.All);
}
public object Deserialize(System.IO.Stream serializationStream)
{
object obj = FormatterServices.GetUninitializedObject(typeof(IniFile));
var members = FormatterServices.GetSerializableMembers(obj.GetType(), Context);
var sections = new List<Section>();
Section section = null;
string key = null;
object value = null;
var sr = new StreamReader(serializationStream);
while (sr.Peek() >= 0)
{
var line = sr.ReadLine();
var sectionMatch = Regex.Match(line, @"^\[([^]]+)\]$");
var stringEntryMatch = Regex.Match(line, @"^(.*?)=""(.*)""$");
var floatEntryMatch = Regex.Match(line, @"^(.*?)=(.*)f$");
if (sectionMatch.Success)
{
if (section != null)
{
sections.Add(section);
}
var title = sectionMatch.Groups[0].Value;
section = new Section { Entries = new Dictionary<string, object>(), Title = title };
}
else if (stringEntryMatch.Success)
{
key = stringEntryMatch.Groups[1].Value;
value = stringEntryMatch.Groups[2].Value;
}
else if (floatEntryMatch.Success)
{
key = floatEntryMatch.Groups[1].Value;
value = float.Parse(floatEntryMatch.Groups[2].Value);
}
// any matches ...
if (key != null && value != null)
{
section.Entries.Add(new KeyValuePair<string, object>(key, value));
}
}
if (section != null)
{
sections.Add(section);
}
object[] data = new object[1] { sections };
return FormatterServices.PopulateObjectMembers(obj, members, data);
}
public void Serialize(System.IO.Stream serializationStream, object graph)
{
var members = FormatterServices.GetSerializableMembers(graph.GetType(), Context);
object[] inifile = FormatterServices.GetObjectData(graph, members);
var sw = new StreamWriter(serializationStream);
if (inifile[0] is IEnumerable)
{
foreach (object section in (inifile[0] as IEnumerable))
{
var title = section.GetType().GetField("Title").GetValue(section);
var entries = section.GetType().GetField("Entries").GetValue(section);
sw.WriteLine("[{0}]", title);
if (entries is IEnumerable)
{
foreach (object entry in (entries as IEnumerable))
{
var key = entry.GetType().GetProperty("Key").GetValue(entry);
var value = entry.GetType().GetProperty("Value").GetValue(entry);
if (value is string)
{
sw.WriteLine("{0}=\"{1}\"", key, value);
}
else if (value is float)
{
sw.WriteLine("{0}={1}f", key, value.ToString());
}
}
}
}
}
sw.Close();
}
public ISurrogateSelector SurrogateSelector
{
get { return surrogateSelector; }
set { surrogateSelector = value; }
}
public SerializationBinder Binder
{
get { return binder; }
set { binder = value; }
}
public StreamingContext Context
{
get { return context; }
set { context = value; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment