123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // $Id$
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using System.IO;
- using Lisp;
- namespace LispReader
- {
- /// <summary>This class allows serialization of .net Classes to/from lisp constructs.</summary>
- /// <remarks>
- /// <para>You just have to annotate the class to specify a mapping from fields/lists to
- /// lisp structures.</para>
- /// <para>The design is similar to <see cref="System.Xml.Serialization.XmlSerializer"/></para>
- /// </remarks>
- public class LispSerializer {
- private Type RootType;
- private static Dictionary<Type, ILispSerializer> typeSerializers
- = new Dictionary<Type, ILispSerializer>();
- static LispSerializer()
- {
- SetupSerializers(typeof(LispSerializer).Assembly);
- }
- public LispSerializer(Type RootType)
- {
- this.RootType = RootType;
- }
- public void Write(string FileName, object Object)
- {
- TextWriter Writer = new StreamWriter(FileName);
- try {
- Write(Writer, FileName, Object);
- } finally {
- Writer.Close();
- }
- }
- public void Write(TextWriter TextWriter, string Dest, object Object)
- {
- LispRootAttribute rootAttrib = (LispRootAttribute)
- Attribute.GetCustomAttribute(RootType, typeof(LispRootAttribute));
- if(rootAttrib == null)
- throw new LispException("Type needs to have LispRoot attribute");
- Writer Writer = new Writer(TextWriter);
- Write(Writer, rootAttrib.Name, Object);
- }
- public void Write(Writer Writer, string name, object Object)
- {
- WriteType(Writer, RootType, name, Object);
- }
- public object Read(string FileName)
- {
- TextReader Reader = new StreamReader(FileName);
- try {
- return Read(Reader, FileName);
- } finally {
- Reader.Close();
- }
- }
- public object Read(TextReader Reader, string Source)
- {
- LispRootAttribute RootAttrib = (LispRootAttribute)
- Attribute.GetCustomAttribute(RootType, typeof(LispRootAttribute));
- if(RootAttrib == null)
- throw new LispException("Type needs to have LispRoot attribute");
- Lexer Lexer = new Lexer(Reader);
- Parser Parser = new Parser(Lexer);
- List Root = Parser.Parse();
- Properties RootP = new Properties(Root);
- List List = null;
- if(!RootP.Get(RootAttrib.Name, ref List))
- throw new LispException("'" + Source + "' is not a " + RootAttrib.Name + " file");
- return ReadType(RootType, List);
- }
- public object Read(List List)
- {
- return ReadType(RootType, List);
- }
- private static object ReadType(Type type, List list)
- {
- ILispSerializer serializer = GetSerializer(type);
- if(serializer == null)
- serializer = CreateRootSerializer(type);
- return serializer.Read(list);
- }
- private static void WriteType(Writer writer, Type type, string name, object Object)
- {
- ILispSerializer serializer = GetSerializer(type);
- if(serializer == null)
- serializer = CreateRootSerializer(type);
- serializer.Write(writer, name, Object);
- }
- private static object CreateObject(Type Type)
- {
- // create object
- ConstructorInfo Constructor = Type.GetConstructor(Type.EmptyTypes);
- if(Constructor == null)
- throw new LispException("Type '" + Type + "' has no public constructor without arguments");
- object Result = Constructor.Invoke(new object[] {});
- return Result;
- }
- public static ILispSerializer GetSerializer(Type type)
- {
- ILispSerializer result;
- typeSerializers.TryGetValue(type, out result);
- return result;
- }
- public static void SetupSerializers(Assembly assembly)
- {
- foreach(Type type in assembly.GetTypes()) {
- ScanType(type);
- }
- }
- public static void ScanType(Type type)
- {
- foreach(Type nestedType in type.GetNestedTypes())
- ScanType(nestedType);
- LispCustomSerializerAttribute customSerializer =
- (LispCustomSerializerAttribute)
- Attribute.GetCustomAttribute(type, typeof(LispCustomSerializerAttribute));
- if(customSerializer != null) {
- object instance = CreateObject(type);
- typeSerializers.Add(customSerializer.Type, (ILispSerializer) instance);
- return;
- }
- LispRootAttribute rootAttrib = (LispRootAttribute)
- Attribute.GetCustomAttribute(type, typeof(LispRootAttribute));
- if(rootAttrib != null) {
- LispRootSerializer serializer = new LispRootSerializer(type);
- typeSerializers.Add(type, serializer);
- return;
- }
- }
- internal static ILispSerializer CreateRootSerializer(Type type)
- {
- LispRootSerializer serializer = new LispRootSerializer(type);
- typeSerializers.Add(type, serializer);
- return serializer;
- }
- }
- }
|