Wednesday, June 10, 2009

Member Field Serialisation for Config Storage

using System;

using System.Reflection;
using System.IO;
using System.Collections;

namespace ConfigTester
{


public class CFG
{
public int pi = 3;
public string word = "tetragrammatron";
public TimeSpan time = new TimeSpan(1,6,6,6);

public string homeDir = @"/home/david/Desktop/";
public string configFName = "config.cfg";

public CFG()
{
}

// ===== ----- ===== ----- =====

public string FieldToSerial(string fieldName, int fieldValue)
{
return string.Format("{0},{1}", fieldName, fieldValue.ToString());
}

public string FieldToSerial(string fieldName, string fieldValue)
{
return string.Format("{0},{1}", fieldName, fieldValue);
}

public string FieldToSerial(string fieldName, TimeSpan fieldValue)
{
return string.Format("{0},{1},{2},{3},{4}", fieldName, fieldValue.Days, fieldValue.Hours, fieldValue.Minutes, fieldValue.Seconds);
}

// ===== ----- ===== ----- =====

public string[] FieldsToSerial()
{
ArrayList lines = new ArrayList();

Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();

foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Type fieldType = fieldInfo.FieldType;

if (fieldInfo.FieldType == typeof(string))
{
string val = (string)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}

if (fieldInfo.FieldType == typeof(int))
{
int val = (int)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}

if (fieldInfo.FieldType == typeof(TimeSpan))
{
TimeSpan val = (TimeSpan)(fieldInfo.GetValue(this));
lines.Add(this.FieldToSerial(name, val));
}
}

int fieldCount = lines.Count;

string[] fields = new string[fieldCount];

for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
fields[fieldNum - 1] = (string)(lines[fieldNum - 1]);

return fields;
}

// ===== ----- ===== ----- =====

public void ListFieldInfo()
{

Console.WriteLine();
Console.WriteLine("FIELD INFO");
Console.WriteLine();

Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();

foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Console.WriteLine("name: {0}", name);

Type fieldType = fieldInfo.FieldType;
Console.WriteLine("type: {0}", fieldType);

object obj = fieldInfo.GetValue(this);
Console.WriteLine("value: {0}", obj.ToString());

Console.WriteLine();
}

Console.WriteLine("{0} fields", fieldInfos.Length);
}

// ===== ----- ===== ----- =====

public void SerializeFields()
{
string fullFName = this.homeDir + this.configFName;

try
{
FileStream fileStream = new FileStream(fullFName, FileMode.Create);
StreamWriter streamWriter = new StreamWriter(fileStream);

this.SerializeFields(streamWriter);

streamWriter.Close();
}
catch (Exception exc)
{
throw new Exception("ConfigSaveException");
}
}

// ===== ----- ===== ----- =====

public void SerializeFields(TextWriter tw)
{
string[] lines = this.FieldsToSerial();

foreach (string line in lines)
tw.WriteLine(line);
}

// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====
// ===== ----- ===== ----- =====

// ===== ----- ===== ----- =====

public void LoadSerialised()
{
string fullFName = this.homeDir + this.configFName;

ArrayList lines = new ArrayList();

try
{
FileStream fileStream = new FileStream(fullFName, FileMode.Open);
StreamReader streamReader = new StreamReader(fileStream);

string line;
while ((line = streamReader.ReadLine()) != null)
lines.Add(line);

streamReader.Close();

int fieldCount = lines.Count;

string[] serials = new string[fieldCount];
for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
serials[fieldNum - 1] = (string)(lines[fieldNum - 1]);

this.FieldsFromSerials(serials);
}
catch (Exception exc)
{
throw new Exception("ConfigLoadException");
}
}

// ===== ----- ===== ----- =====

public string StringFromSerial(string serial)
{
return serial;
}

// ===== ----- ===== ----- =====

public int IntFromSerial(string serial)
{
return Convert.ToInt32(serial);
}

// ===== ----- ===== ----- =====

public TimeSpan TimeSpanFromSerial(string serial)
{
string[] vals = serial.Split(',');

if (vals.Length != 4)
throw new Exception("timespan serial has incorrect number of variables");

int days = Convert.ToInt32(vals[0]);
int hrs = Convert.ToInt32(vals[1]);
int mins = Convert.ToInt32(vals[2]);
int secs = Convert.ToInt32(vals[3]);

return new TimeSpan(days, hrs, mins, secs);
}

// ===== ----- ===== ----- =====

public string MatchKey(string key, string[] keys, string[] values)
{
if (keys.Length != values.Length)
throw new Exception("key count must match value count, but does not");

for (int num = 1; num <= keys.Length; num++)
if (key == keys[num - 1])
return values[num - 1];

return null;
}

// ===== ----- ===== ----- =====

public void FieldsFromSerials(string[] serials)
{
// separate names & serialised form of fields retrieved from storage

int fieldCount = serials.Length;

string[] names = new string[fieldCount];
string[] forms = new string[fieldCount];

for (int fieldNum = 1; fieldNum <= fieldCount; fieldNum++)
{
int splitMarker = serials[fieldNum - 1].IndexOf(',');

string name = serials[fieldNum - 1].Substring(0, splitMarker);
string form = serials[fieldNum - 1].Substring(splitMarker + 1);

names[fieldNum - 1] = name;
forms[fieldNum - 1] = form;
}

// scan through this instantiated object

Type cfgType = typeof(CFG);
FieldInfo[] fieldInfos = cfgType.GetFields();

foreach (FieldInfo fieldInfo in fieldInfos)
{
string name = fieldInfo.Name;
Type fieldType = fieldInfo.FieldType;

string serialString = this.MatchKey(name, names, forms);

if (fieldInfo.FieldType == typeof(string))
{
string val = this.StringFromSerial(serialString);
fieldInfo.SetValue(this, val);
}

if (fieldInfo.FieldType == typeof(int))
{
int val = this.IntFromSerial(serialString);
fieldInfo.SetValue(this, val);
}

if (fieldInfo.FieldType == typeof(TimeSpan))
{
TimeSpan val = this.TimeSpanFromSerial(serialString);
fieldInfo.SetValue(this, val);
}
}

}

// ===== ----- ===== ----- =====

} // class
} // namespace

No comments:

Post a Comment

comment: