source: branches/New Persistence Exploration/Persistence/Persistence/Serializer.cs @ 1314

Last change on this file since 1314 was 1314, checked in by epitzer, 11 years ago

rename ICustomSerializer to ICompoundSerializer. (#506)

File size: 3.3 KB
Line 
1using System.Collections.Generic;
2using System.Collections;
3using System;
4
5namespace Persistence {
6
7  public class Serializer : IEnumerable<ISerializationToken> {
8
9    private object obj;
10    private string rootName;
11    private Dictionary<object, int> obj2id;
12    private Dictionary<Type, IPrimitiveSerializer> primitiveSerializers;
13    private List<ICompoundSerializer> customSerializers;
14
15    public Serializer(object obj, IEnumerable<IPrimitiveSerializer> primitiveSerializers) :
16      this(obj, primitiveSerializers, "ROOT") { }
17
18    public Serializer(object obj, IEnumerable<IPrimitiveSerializer> primitiveSerializers, string rootName) {
19      this.obj = obj;
20      this.rootName = rootName;
21      this.primitiveSerializers = new Dictionary<Type, IPrimitiveSerializer>();
22      foreach (IPrimitiveSerializer serializer in primitiveSerializers) {
23        this.primitiveSerializers.Add(serializer.Type, serializer);
24      }
25      this.customSerializers = new List<ICompoundSerializer>();
26      customSerializers.Add(new EnumerableSerializer());
27      customSerializers.Add(new ArraySerializer());
28      this.obj2id = new Dictionary<object, int>();
29      obj2id.Add(new object(), 0);
30    }
31
32    IEnumerator IEnumerable.GetEnumerator() {
33      return this.GetEnumerator();
34    }
35
36    public IEnumerator<ISerializationToken> GetEnumerator() {
37      DataMemberAccessor rootAccessor = new DataMemberAccessor(
38        this.rootName, obj.GetType(), null, () => this.obj, null);
39      IEnumerator<ISerializationToken> iterator = Serialize(rootAccessor);
40      while (iterator.MoveNext())
41        yield return iterator.Current;
42    }
43
44    private IEnumerator<ISerializationToken> Serialize(DataMemberAccessor accessor) {
45      object value = accessor.Get();
46      if (value == null) {
47        yield return new NullReferenceToken(accessor.Name);
48      } else if (this.primitiveSerializers.ContainsKey(value.GetType())) {
49        yield return new PrimitiveToken(accessor, this.primitiveSerializers[value.GetType()].Serialize(value));
50      } else if (this.obj2id.ContainsKey(value)) {
51        yield return new ReferenceToken(accessor.Name, this.obj2id[value]);
52      } else {
53        int id = obj2id.Count;
54        this.obj2id.Add(value, id);
55        yield return new BeginToken(accessor, id);
56        ICompoundSerializer customSerializer = this.FindCustomSerializer(value.GetType());
57        if (customSerializer != null) {
58          foreach (object obj in customSerializer.Serialize(value)) {
59            IEnumerator<ISerializationToken> iterator = this.Serialize(new DataMemberAccessor(obj));
60            while (iterator.MoveNext())
61              yield return iterator.Current;
62          }
63        } else { // composite serialization
64          foreach (KeyValuePair<string, DataMemberAccessor> mapping in
65            StorableAttribute.GetAutostorableAccessors(value)) {
66            IEnumerator<ISerializationToken> iterator = this.Serialize(mapping.Value);
67            while (iterator.MoveNext())
68              yield return iterator.Current;
69          }
70        }
71        yield return new EndToken(accessor, id);
72      }
73    }
74
75    private ICompoundSerializer FindCustomSerializer(Type type) {
76      foreach (ICompoundSerializer s in customSerializers) {
77        if (s.CanSerialize(type))
78          return s;
79      }
80      return null;
81    }
82  }
83}
Note: See TracBrowser for help on using the repository browser.