Free cookie consent management tool by TermsFeed Policy Generator

source: branches/New Persistence Exploration/Persistence/Persistence/CompoundSerializers.cs @ 1319

Last change on this file since 1319 was 1319, checked in by epitzer, 15 years ago

fix ArraySerializer.CanSerialize for Array datatype. (#506)

File size: 3.7 KB
Line 
1using System;
2using System.Collections;
3using System.Reflection;
4using System.Collections.Generic;
5namespace Persistence {
6
7  public interface ICompoundSerializer {
8    bool CanSerialize(Type type);
9    IEnumerable Serialize(object o);
10    object DeSerialize(IEnumerable o, Type t);
11  }
12
13  public class EnumerableSerializer : ICompoundSerializer {
14    public bool CanSerialize(Type type) {
15      if (type.GetInterface("IEnumerable") == null)
16        return false;
17      if (type.GetMethod("GetEnumerator", new Type[] { }) == null)
18        return false;
19      MethodInfo addMethod = type.GetMethod("Add");
20      if (addMethod == null)
21        return false;
22      if (addMethod.GetParameters().Length != 1)
23        return false;
24      return true;
25    }
26    public IEnumerable Serialize(object o) {
27      return (IEnumerable)o;
28    }
29    public object DeSerialize(IEnumerable objects, Type t) {
30      object instance = Activator.CreateInstance(t);
31      foreach (object o in objects) {
32        t.GetMethod("Add").Invoke(instance, new object[] { o });
33      }
34      return instance;
35    }
36  }
37
38  public class ArraySerializer : ICompoundSerializer {
39    public bool CanSerialize(Type type) {
40      return type.IsArray || type == typeof(Array);
41    }
42    public IEnumerable Serialize(object array) {
43      Array a = (Array)array;
44      yield return a.Rank;
45      for (int i = 0; i < a.Rank; i++) {
46        yield return a.GetLength(i);
47      }
48      foreach (object o in (Array)array) {
49        yield return o;
50      }
51    }
52    public object DeSerialize(IEnumerable elements, Type t) {
53      IEnumerator e = elements.GetEnumerator();
54      e.MoveNext();
55      int rank = (int)e.Current;
56      int[] lengths = new int[rank];
57      for (int i = 0; i < rank; i++) {
58        e.MoveNext();
59        lengths[i] = (int)e.Current;
60      }
61      Array a = Array.CreateInstance(t.GetElementType(), lengths);     
62      int[] positions = new int[rank];
63      while (e.MoveNext()) {
64        a.SetValue(e.Current, positions);
65        positions[0] += 1;
66        for (int i = 0; i < rank-1; i++) {
67          if (positions[i] >= lengths[i]) {
68            positions[i] = 0;
69            positions[i + 1] += 1;
70          } else {
71            break;
72          }
73        }
74      }
75      return a;
76    }
77  }
78
79  public class KeyValuePair2XmlSerializer : ICompoundSerializer {   
80    public bool CanSerialize(Type type) {
81      return type.IsGenericType &&
82        type.GetGenericTypeDefinition().Name == "KeyValuePair`2";
83    }
84    public IEnumerable Serialize(object o) {     
85      Type t = o.GetType();
86      yield return t.GetProperty("Key").GetValue(o, null);
87      yield return t.GetProperty("Value").GetValue(o, null);
88    }
89    public object DeSerialize(IEnumerable o, Type t) {
90      return Activator.CreateInstance(t,
91        new List<object>((IEnumerable<object>)o).ToArray());
92    }   
93  }
94
95  public class Dictionary2XmlSerializer : ICompoundSerializer {
96    public bool CanSerialize(Type type) {
97      return type.GetInterface("IDictionary") != null;       
98    }
99    public IEnumerable Serialize(object o) {
100      IDictionary dict = (IDictionary)o;     
101      foreach ( DictionaryEntry entry in dict) {
102        yield return entry.Key;
103        yield return entry.Value;
104      }
105    }
106    public object DeSerialize(IEnumerable o, Type t) {
107      IDictionary dict = (IDictionary)Activator.CreateInstance(t);
108      IEnumerator iter = o.GetEnumerator();
109      while (iter.MoveNext()) {
110        object key = iter.Current;
111        iter.MoveNext();
112        object value = iter.Current;
113        dict.Add(key, value);
114      }
115      return dict;
116    }
117  }
118
119}
Note: See TracBrowser for help on using the repository browser.