Free cookie consent management tool by TermsFeed Policy Generator

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

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

Format white space. (Ctrl-K, Ctrl-D) (#548)

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