Free cookie consent management tool by TermsFeed Policy Generator

source: branches/New Persistence Exploration/Persistence/Persistence/Decomposers.cs @ 1354

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

minor code cleanup.

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