Free cookie consent management tool by TermsFeed Policy Generator

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

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

Better formatting configuration interface. (#506)

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