Free cookie consent management tool by TermsFeed Policy Generator

source: branches/New Persistence Exploration/Persistence/Persistence/Core/Serializer.cs @ 1425

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

Use version invariant assembly qualified name and update plug-in assembly name. (#506)

File size: 4.8 KB
Line 
1using System.Collections.Generic;
2using System.Collections;
3using System;
4using HeuristicLab.Persistence.Interfaces;
5
6namespace HeuristicLab.Persistence.Core {
7
8  public struct TypeMapping {
9    public readonly int Id;
10    public readonly string TypeName;
11    public readonly string Serializer;   
12    public TypeMapping(int id, string typeName, string serializer) {
13      Id = id;
14      TypeName = typeName;
15      Serializer = serializer;
16    }
17    public Dictionary<string, object> GetDict() {
18      return new Dictionary<string, object> {
19        {"id", Id},
20        {"typeName", TypeName},
21        {"serializer", Serializer}};                                           
22    }
23  }
24
25  public class Serializer : IEnumerable<ISerializationToken> {
26
27    private readonly object obj;
28    private readonly string rootName;
29    private readonly Dictionary<object, int> obj2id;
30    private readonly Dictionary<Type, int> typeCache;
31    private readonly Configuration configuration;
32
33    public List<TypeMapping> TypeCache {
34      get {       
35        List<TypeMapping> result = new List<TypeMapping>();
36        foreach (var pair in typeCache) {
37          string serializer = null;
38          IFormatter f = configuration.GetFormatter(pair.Key);
39          if (f != null) {
40            serializer = f.GetType().VersionInvariantName();
41          } else {
42            IDecomposer d = configuration.GetDecomposer(pair.Key);
43            if (d != null)
44              serializer = d.GetType().VersionInvariantName();
45          }
46          result.Add(new TypeMapping(pair.Value, pair.Key.VersionInvariantName(), serializer));
47        }
48        return result;                                     
49      }
50    }
51
52    public Serializer(object obj, Configuration configuration) :       
53      this(obj, configuration, "ROOT") { }
54
55    public Serializer(object obj, Configuration configuration, string rootName) {
56      this.obj = obj;
57      this.rootName = rootName;
58      this.configuration = configuration;     
59      obj2id = new Dictionary<object, int> {{new object(), 0}};
60      typeCache = new Dictionary<Type, int>();
61    }
62
63    IEnumerator IEnumerable.GetEnumerator() {
64      return GetEnumerator();
65    }
66
67    public IEnumerator<ISerializationToken> GetEnumerator() {
68      DataMemberAccessor rootAccessor = new DataMemberAccessor(
69        rootName, null, () => obj, null);
70      IEnumerator<ISerializationToken> iterator = Serialize(rootAccessor);
71      while (iterator.MoveNext())
72        yield return iterator.Current;     
73    }
74   
75    private IEnumerator<ISerializationToken> Serialize(DataMemberAccessor accessor) {
76      object value = accessor.Get();
77      if (value == null)
78        return NullReferenceEnumerator(accessor.Name);
79      if (obj2id.ContainsKey(value))
80        return ReferenceEnumerator(accessor.Name, obj2id[value]);             
81      if ( ! typeCache.ContainsKey(value.GetType()))
82        typeCache.Add(value.GetType(), typeCache.Count);
83      int typeId = typeCache[value.GetType()];
84      int? id = null;
85      if ( ! value.GetType().IsValueType) {
86        id = obj2id.Count;
87        obj2id.Add(value, (int)id);
88      }
89      IFormatter formatter = configuration.GetFormatter(value.GetType());
90      if (formatter != null)
91        return PrimitiveEnumerator(accessor.Name, typeId, formatter.DoFormat(value), id);
92      IDecomposer decomposer = configuration.GetDecomposer(value.GetType());
93      if (decomposer != null)
94        return CompositeEnumerator(accessor.Name, decomposer.DeCompose(value), id, typeId);                 
95      throw new ApplicationException(
96          String.Format(
97          "No suitable method for serializing values of type \"{0}\" found.",
98          value.GetType().VersionInvariantName()));     
99    }
100
101    private IEnumerator<ISerializationToken> NullReferenceEnumerator(string name) {
102      yield return new NullReferenceToken(name);
103    }
104
105    private IEnumerator<ISerializationToken> ReferenceEnumerator(string name, int id) {
106      yield return new ReferenceToken(name, id);
107    }
108
109    private IEnumerator<ISerializationToken> PrimitiveEnumerator(string name,
110        int typeId, object serializedValue, int? id) {
111      yield return new PrimitiveToken(name, typeId, serializedValue, id);
112    }
113
114    private IEnumerator<ISerializationToken> CompositeEnumerator(string name,
115        IEnumerable<Tag> tags, int? id, int typeId) {
116      yield return new BeginToken(name, typeId, id);     
117        foreach (var tag in tags) {
118          IEnumerator<ISerializationToken> iterator = Serialize(           
119            new DataMemberAccessor(tag.Value, tag.Name));
120          while (iterator.MoveNext())
121            yield return iterator.Current;
122        }
123      yield return new EndToken(name, typeId, id);       
124    }
125
126  }
127
128
129}
Note: See TracBrowser for help on using the repository browser.