Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/14/09 13:23:08 (16 years ago)
Author:
epitzer
Message:

Replace final fixes for broken parent references with separation of instance creation with meta information. (#548)

Location:
trunk/sources/HeuristicLab.Persistence/3.3/Core
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs

    r1542 r1553  
    88  public class ParentReference {} 
    99
    10   class CompositeObject {
     10  class Midwife {
     11   
     12    public int? Id { get; private set; }   
     13    public bool MetaMode { get; set; }
     14    public object Obj { get; private set; }
    1115
    12     public object Obj { get; private set; }
    13     public List<Tag> customValues;
     16    private List<Tag> metaInfo;
     17    private List<Tag> customValues;
     18    private Type type;
     19    private IDecomposer decomposer;
    1420
    15     public CompositeObject(object obj) {
    16       Obj = obj;
    17       customValues = new List<Tag>();
     21    public Midwife(object value) {
     22      this.Obj = value;
     23    }
     24       
     25    public Midwife(Type type, IDecomposer decomposer, int? id) {   
     26      this.type = type;
     27      this.decomposer = decomposer;     
     28      this.Id = id;
     29      MetaMode = false;     
     30      metaInfo = new List<Tag>();
     31      customValues = new List<Tag>();           
    1832    }
    1933
    20     public void AddValue(string name, object value, List<Thunk> finalFixes) {
    21       Tag t = new Tag(name, value) {globalFinalFixes = finalFixes};
    22       customValues.Add(t);
     34    public void CreateInstance() {
     35      if (Obj != null)
     36        throw new ApplicationException("object already instantiated");
     37      Obj = decomposer.CreateInstance(type, metaInfo);     
    2338    }
    2439
    25     public Setter GetSetterForLastAddedValue(string name) {           
    26       Tag t = customValues[customValues.Count - 1];     
    27       return value => t.Value = value;
     40    public void AddValue(string name, object value) {
     41      if (MetaMode) {
     42        metaInfo.Add(new Tag(name, value));
     43      } else {
     44        customValues.Add(new Tag(name, value));
     45      }
    2846    }
    29   }
    3047
    31   public delegate void Thunk();
     48    public void Populate() {
     49      decomposer.Populate(Obj, customValues, type);
     50    }
     51  } 
    3252
    3353  public class Deserializer {
    3454   
    3555    private readonly Dictionary<int, object> id2obj;
    36     private readonly Dictionary<Type, object> serializerMapping;   
    37     private readonly Stack<CompositeObject> parentStack;   
    38     private readonly Dictionary<int, Type> typeIds;   
    39     private List<Thunk> finalFixes;
     56    private readonly Dictionary<Type, object> serializerMapping;
     57    private readonly Stack<Midwife> parentStack;   
     58    private readonly Dictionary<int, Type> typeIds;
    4059
    4160    public Deserializer(
    42       IEnumerable<TypeMapping> typeCache) {     
     61      IEnumerable<TypeMapping> typeCache) {
    4362      id2obj = new Dictionary<int, object>();
    44       parentStack = new Stack<CompositeObject>();
     63      parentStack = new Stack<Midwife>();
    4564      typeIds = new Dictionary<int, Type>();
    4665      serializerMapping = CreateSerializers(typeCache);
     
    6079    }
    6180
    62     public object Deserialize(IEnumerable<ISerializationToken> tokens) {
    63       finalFixes = new List<Thunk>();     
     81    public object Deserialize(IEnumerable<ISerializationToken> tokens) {     
    6482      foreach (ISerializationToken token in tokens) {
    6583        Type t = token.GetType();
     
    7492        } else if (t == typeof(NullReferenceToken)) {
    7593          NullHandler((NullReferenceToken)token);
     94        } else if (t == typeof(MetaInfoBeginToken)) {
     95          MetaInfoBegin((MetaInfoBeginToken)token);
     96        } else if (t == typeof(MetaInfoEndToken)) {
     97          MetaInfoEnd((MetaInfoEndToken)token);
    7698        } else {
    7799          throw new ApplicationException("invalid token type");
    78100        }
    79101      }
    80       foreach (Thunk fix in finalFixes) {
    81         fix();
    82       }
    83102      return parentStack.Pop().Obj;
    84103    }
    85104
    86     private void CompositeStartHandler(BeginToken token) {     
     105    private void CompositeStartHandler(BeginToken token) {
    87106      Type type = typeIds[(int)token.TypeId];
    88107      IDecomposer decomposer = null;
    89108      if ( serializerMapping.ContainsKey(type) )
    90         decomposer = serializerMapping[type] as IDecomposer;     
     109        decomposer = serializerMapping[type] as IDecomposer;
    91110      if (decomposer == null)
    92111        throw new ApplicationException(String.Format(
    93112          "No suitable method for deserialization of type \"{0}\" found.",
    94113          type.VersionInvariantName()));
    95       object instance =
    96         decomposer.CreateInstance(type) ??
    97         new ParentReference();
    98       parentStack.Push(new CompositeObject(instance));             
    99       if ( token.Id != null )
    100         id2obj.Add((int)token.Id, instance);
     114      parentStack.Push(new Midwife(type, decomposer, token.Id));
    101115    }
    102116
    103     private void CompositeEndHandler(EndToken token) {     
     117    private void CompositeEndHandler(EndToken token) {
    104118      Type type = typeIds[(int)token.TypeId];
    105       IDecomposer decomposer = null;
    106       if (serializerMapping.ContainsKey(type))
    107         decomposer = serializerMapping[type] as IDecomposer;           
    108       if (decomposer == null)
    109         throw new ApplicationException(String.Format(
    110           "No suitable method for deserialization of type \"{0}\" found.",
    111           type.VersionInvariantName()));
    112       CompositeObject customComposite = parentStack.Pop();
    113       object deserializedObject =         
    114         decomposer.Populate(customComposite.Obj, customComposite.customValues, type);
    115       if ( token.Id != null )
    116         id2obj[(int)token.Id] = deserializedObject;       
    117       SetValue(token.Name, deserializedObject);         
     119      Midwife midwife = parentStack.Pop();
     120      midwife.Populate();
     121      SetValue(token.Name, midwife.Obj);
    118122    }
    119123
    120     private void PrimitiveHandler(PrimitiveToken token) {     
     124    private void PrimitiveHandler(PrimitiveToken token) {
    121125      Type type = typeIds[(int)token.TypeId];
    122126      object value = ((IFormatter) serializerMapping[type]).Parse(token.SerialData);
     
    126130    }
    127131
    128     private void ReferenceHandler(ReferenceToken token) {     
     132    private void ReferenceHandler(ReferenceToken token) {
    129133      object referredObject = id2obj[token.Id];
    130       SetValue(token.Name, referredObject);     
    131       if (referredObject is ParentReference) {
    132         Setter set = parentStack.Peek().GetSetterForLastAddedValue(token.Name);               
    133         finalFixes.Add(() => set(id2obj[token.Id]));
    134       }
     134      SetValue(token.Name, referredObject);
    135135    }
    136136
    137     private void NullHandler(NullReferenceToken token) {     
     137    private void NullHandler(NullReferenceToken token) {
    138138      SetValue(token.Name, null);
    139     }   
     139    }
     140
     141    private void MetaInfoBegin(MetaInfoBeginToken token) {
     142      parentStack.Peek().MetaMode = true;
     143    }
     144
     145    private void MetaInfoEnd(MetaInfoEndToken token) {
     146      Midwife m = parentStack.Peek();     
     147      m.MetaMode = false;
     148      CreateInstance(m);
     149    }
     150
     151    private void CreateInstance(Midwife m) {
     152      m.CreateInstance();
     153      if (m.Id != null)
     154        id2obj.Add((int)m.Id, m.Obj);     
     155    }
    140156
    141157    private void SetValue(string name, object value) {
    142158      if (parentStack.Count == 0) {       
    143         parentStack.Push(new CompositeObject(value));
    144       } else {       
    145         parentStack.Peek().AddValue(name, value, finalFixes);       
     159        parentStack.Push(new Midwife(value));
     160      } else {
     161        Midwife m = parentStack.Peek();
     162        if (m.MetaMode == false && m.Obj == null)
     163          CreateInstance(m);
     164        m.AddValue(name, value);       
    146165      }
    147166    }
  • trunk/sources/HeuristicLab.Persistence/3.3/Core/Serializer.cs

    r1542 r1553  
    7272      IDecomposer decomposer = configuration.GetDecomposer(value.GetType());
    7373      if (decomposer != null)
    74         return CompositeEnumerator(accessor.Name, decomposer.Decompose(value), id, typeId);                 
     74        return CompositeEnumerator(accessor.Name, decomposer.Decompose(value), id, typeId, decomposer.CreateMetaInfo(value));
    7575      throw new ApplicationException(
    7676          String.Format(
     
    9292    }
    9393
    94     private IEnumerator<ISerializationToken> CompositeEnumerator(string name,
    95         IEnumerable<Tag> tags, int? id, int typeId) {
     94    private IEnumerator<ISerializationToken> CompositeEnumerator(
     95        string name, IEnumerable<Tag> tags, int? id, int typeId, IEnumerable<Tag> metaInfo) {
    9696      yield return new BeginToken(name, typeId, id);     
    97         foreach (var tag in tags) {
    98           IEnumerator<ISerializationToken> iterator = Serialize(           
    99             new DataMemberAccessor(tag.Value, tag.Name));
    100           while (iterator.MoveNext())
    101             yield return iterator.Current;
     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;
    102106        }
     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      }
    103116      yield return new EndToken(name, typeId, id);       
    104117    }
  • trunk/sources/HeuristicLab.Persistence/3.3/Core/Tag.cs

    r1542 r1553  
    44
    55  public class Tag {
    6     internal List<Thunk> globalFinalFixes; // reference to final fixes of Deserializer
    76    public string Name { get; private set; }
    87    public object Value { get; set; }     
     
    1615      Value = value;
    1716    }
    18     public void SafeSet(Setter setter) {
    19       if ( Value as ParentReference != null)
    20         globalFinalFixes.Add(() => setter(Value));
    21       else
    22         setter(Value);
    23     }
    24   } 
     17  }
    2518
    2619}
Note: See TracChangeset for help on using the changeset viewer.