Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Core/Serializer.cs @ 1530

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

merge persistence exploration branch into trunk as HL plugin. (#506)

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