Free cookie consent management tool by TermsFeed Policy Generator

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

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

Scrap Storable-based cloning & reorganize namespaces. (#506)

File size: 4.6 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 Dictionary<string, int> TypeCache {
17      get {       
18        Dictionary<string, int> result = new Dictionary<string, int>();
19        foreach ( var pair in typeCache )
20          result.Add(pair.Key.AssemblyQualifiedName, pair.Value);
21        return result;                                     
22      }
23    }
24
25    public Serializer(object obj, Configuration configuration) :       
26      this(obj, configuration, "ROOT") { }
27
28    public Serializer(object obj, Configuration configuration, string rootName) {
29      this.obj = obj;
30      this.rootName = rootName;
31      this.configuration = configuration;     
32      obj2id = new Dictionary<object, int> {{new object(), 0}};
33      typeCache = new Dictionary<Type, int>();
34    }
35
36    IEnumerator IEnumerable.GetEnumerator() {
37      return GetEnumerator();
38    }
39
40    public IEnumerator<ISerializationToken> GetEnumerator() {
41      DataMemberAccessor rootAccessor = new DataMemberAccessor(
42        rootName, obj.GetType(), null, () => obj, null);
43      IEnumerator<ISerializationToken> iterator = Serialize(rootAccessor);
44      while (iterator.MoveNext())
45        yield return iterator.Current;     
46    }
47
48   
49    private IEnumerator<ISerializationToken> Serialize(DataMemberAccessor accessor) {
50      object value = accessor.Get();
51      if (value == null)
52        return NullReferenceEnumeration(accessor.Name);
53      if (obj2id.ContainsKey(value))
54        return ReferenceTokenEnumeration(accessor.Name, obj2id[value]);             
55      if ( ! typeCache.ContainsKey(value.GetType()))
56        typeCache.Add(value.GetType(), typeCache.Count);
57      int typeId = typeCache[value.GetType()];
58      int? id = null;
59      if ( ! value.GetType().IsValueType) {
60        id = obj2id.Count;
61        obj2id.Add(value, (int)id);
62      }
63      IFormatter formatter = configuration.GetFormatter(value.GetType());
64      if (formatter != null)
65        return PrimitiveEnumeration(accessor.Name, typeId, formatter.DoFormat(value), id);
66      IDecomposer decomposer = configuration.GetDecomposer(value.GetType());
67      if (decomposer != null)
68        return CompositeEnumeration(accessor.Name, decomposer.DeCompose(value), id, typeId);           
69      return StorableEnumeration(accessor.Name, value, id, typeId);
70    }
71
72    private IEnumerator<ISerializationToken> NullReferenceEnumeration(string name) {
73      yield return new NullReferenceToken(name);
74    }
75
76    private IEnumerator<ISerializationToken> ReferenceTokenEnumeration(string name, int id) {
77      yield return new ReferenceToken(name, id);
78    }
79
80    private IEnumerator<ISerializationToken> PrimitiveEnumeration(string name, int typeId, object serializedValue, int? id) {
81      yield return new PrimitiveToken(name, typeId, serializedValue, id);
82    }
83
84    private IEnumerator<ISerializationToken> CompositeEnumeration(string name, IEnumerable values, int? id, int typeId) {
85      yield return new BeginToken(name, typeId, id);     
86        foreach (object o in values) {
87          IEnumerator<ISerializationToken> iterator = Serialize(new DataMemberAccessor(o));
88          while (iterator.MoveNext())
89            yield return iterator.Current;
90        }
91      yield return new EndToken(name, typeId, id);       
92    }
93
94    private IEnumerator<ISerializationToken> StorableEnumeration(string name, object value, int? id, int typeId) {           
95      yield return new BeginToken(name, typeId, id);
96      int nSubComponents = 0;
97      foreach (KeyValuePair<string, DataMemberAccessor> mapping in
98        StorableAttribute.GetAutostorableAccessors(value)) {
99        nSubComponents += 1;
100        IEnumerator<ISerializationToken> iterator = Serialize(mapping.Value);
101        while (iterator.MoveNext()) {
102          yield return iterator.Current;
103        }
104      }
105      if (nSubComponents == 0) {
106        throw new ApplicationException(String.Format(
107                                         "Composite value of type \"{0}\" contains no subcomponents",
108                                         value.GetType().FullName));
109      }
110      yield return new EndToken(name, typeId, id);
111    }
112  }
113
114
115}
Note: See TracBrowser for help on using the repository browser.