Google Protocol Buffersが公開されたとのことで、C#版のシリアライザ(仕様の確認はまた今度)を作ってみました。
namespace ProtocolBuffers
{
using System;
using System.IO;
using System.Text;
public class Serializer
{
#region Serialize
public static void Serialize<TSerialize>(StreamWriter writer, TSerialize instance)
{
SerializeInternal(writer, instance.GetType(), instance, 0);
}
public static void Serialize(StreamWriter writer, Type type, Object instance)
{
SerializeInternal(writer, type, instance, 0);
}
private static void SerializeInternal(StreamWriter writer, Type type, Object instance, Int32 depth)
{
if (writer == null) throw new System.ArgumentNullException("writer");
if (type == null) throw new System.ArgumentNullException("type");
if (instance == null) throw new System.ArgumentNullException("instance");
WriteIndent(writer, depth);
writer.Write(type.Name);
writer.WriteLine("{");
foreach (var propertyInfo in type.GetProperties())
{
if (!propertyInfo.CanRead) continue;
var propertyType = propertyInfo.PropertyType;
var propertyName = propertyInfo.Name;
var propertyValue = propertyInfo.GetValue(instance, null) ?? String.Empty;
if (IsSystemType(propertyType))
{
WriteIndent(writer, depth + 1);
writer.WriteLine("{0} : \"{1}\"", propertyName, propertyValue.ToString().Replace("\"", "\\\""));
}
else
{
SerializeInternal(writer, propertyType, propertyValue, depth + 1);
}
}
WriteIndent(writer, depth);
writer.WriteLine("}");
}
private static void WriteIndent(StreamWriter writer, Int32 depth)
{
StringBuilder sb = new StringBuilder();
sb.Append(' ', depth);
writer.Write(sb.ToString());
}
#endregion
#region Utility
private static Boolean IsSystemType(Type type)
{
return type.Namespace.StartsWith("System");
}
#endregion
}
}
使い方は、以下
namespace ProtocolBuffers
{
using System;
using System.IO;
public class Test
{
public String Name { get; set; }
public String EMail { get; set; }
}
public class Test2
{
public Test Test { get; set; }
public Int32 Hash { get { return this.GetHashCode(); } }
public DateTime DateTime { get { return DateTime.Now; } }
}
class TestProgram
{
static void Main(string[] args)
{
var testObject = new Test { Name = "Hirase", EMail = "hirase@example.com" };
var test2Object = new Test2 { Test = testObject };
using (var writer = new StreamWriter(@"test.pb"))
{
Serializer.Serialize<Test2>(writer, test2Object);
}
}
}
}
結果は以下
Test2{
Test{
Name : "Hirase"
EMail : "hirase@example.com"
}
Hash : "54267293"
DateTime : "2008/07/09 14:37:08"
}