Changeset 1435


Ignore:
Timestamp:
03/27/09 11:22:11 (12 years ago)
Author:
epitzer
Message:

Properly deserialize enumerables with parent references, use single Setter delegate, fix id references of primitive values. (#506)

Location:
branches/New Persistence Exploration/Persistence
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/New Persistence Exploration/Persistence/Persistence/Core/DataMemberAccessor.cs

    r1419 r1435  
    55namespace HeuristicLab.Persistence {
    66
     7  public delegate object Getter();
     8  public delegate void Setter(object value);
     9
    710  public class DataMemberAccessor {
    8 
    9     public delegate object Getter();
    10     public delegate void Setter(object value);
    1111
    1212    public readonly Getter Get;
  • branches/New Persistence Exploration/Persistence/Persistence/Core/DeSerializer.cs

    r1434 r1435  
    55namespace HeuristicLab.Persistence.Core { 
    66
    7   public struct ParentReference {}
    8   delegate void Setter(object value); 
     7  public struct ParentReference {} 
    98
    109  class CompositeObject {
     
    121120      Type type = typeIds[(int)primitive.TypeId];
    122121      object value = ((IFormatter) serializerMapping[type]).Parse(primitive.SerialData);
    123       if ( ! value.GetType().IsValueType )
     122      if ( primitive.Id != null )     
    124123        id2obj[(int)primitive.Id] = value;
    125124      SetValue(primitive.Name, value);
  • branches/New Persistence Exploration/Persistence/Persistence/Default/Decomposers/EnumerableDecomposer.cs

    r1434 r1435  
    88namespace HeuristicLab.Persistence.Default.Decomposers {
    99
    10   public abstract class EnumerableDecomposer : IDecomposer {
     10  public class EnumerableCache {   
    1111
    12     public abstract void PerformAdd(object instance, MethodInfo addMethod, Tag tag);
     12    List<object> values;
     13    int nSet;
     14    int count;
     15    object enumerable;
     16    MethodInfo addMethod;
     17
     18    public EnumerableCache(object enumerable, MethodInfo addMethod) {     
     19      values = new List<object>();
     20      this.enumerable = enumerable;
     21      this.addMethod = addMethod;
     22      count = -1;
     23    }
     24
     25    public Setter GetNextSetter() {     
     26      int index = values.Count;     
     27      values.Add(new object());
     28      return (v) => Set(index, v);
     29    }
     30
     31    private void Set(int index, object value) {     
     32      values[index] = value;
     33      nSet += 1;
     34      if (count >= 0 && nSet >= count)
     35        Fill();
     36    }
     37
     38    public void Terminate() {
     39      count = values.Count;     
     40      if (nSet >= count)
     41        Fill();
     42    }
     43
     44    private void Fill() {     
     45      foreach ( object v in values ) {
     46        addMethod.Invoke(enumerable, new[] {v});
     47      }
     48    }
     49
     50  }
     51
     52  public class EnumerableDecomposer : IDecomposer {   
    1353
    1454    public bool CanDecompose(Type type) {
     
    3676    public object Populate(object instance, IEnumerable<Tag> tags, Type type) {
    3777      MethodInfo addMethod = type.GetMethod("Add");
     78      EnumerableCache cache = new EnumerableCache(instance, addMethod);
    3879      foreach (var tag in tags) {
    39         PerformAdd(instance, addMethod, tag);       
     80        tag.SafeSet(cache.GetNextSetter());
    4081      }
     82      cache.Terminate();
    4183      return instance;
    4284    }
    4385
    44   }
    45 
    46   /// <summary>
    47   /// Does never re-order elements but cannot reconstruct enumerables that directly
    48   /// or indirectly contain references to not-yet-contructed parent objects (e.g. arrays).
    49   /// </summary>
    50   public class SafeEnumerableDecomposer : EnumerableDecomposer {
    51     public override void PerformAdd(object instance, MethodInfo addMethod, Tag tag) {
    52       addMethod.Invoke(instance, new[] { tag.Value });
    53     }
    54   }
    55   /// <summary>
    56   /// May re-order elements if the enumerable contains references to
    57   /// not-yet-constructed parent objects (e.g. arrays).
    58   /// </summary>
    59   public class RobustEnumerableDecomposer : EnumerableDecomposer {
    60      public override void PerformAdd(object instance, MethodInfo addMethod, Tag tag) {
    61       tag.SafeSet((value) => addMethod.Invoke(instance, new[] { value }));
    62     }   
    63   }
     86  } 
    6487
    6588}
  • branches/New Persistence Exploration/Persistence/Persistence/Interfaces/IDecomposer.cs

    r1434 r1435  
    1919      this.Value = value;
    2020    }
    21     public void SafeSet(DataMemberAccessor.Setter setter) {
     21    public void SafeSet(Setter setter) {
    2222      if ( Value != null && Value.GetType() == typeof(ParentReference))
    2323        finalFixes.Add(() => setter(Value));
  • branches/New Persistence Exploration/Persistence/Test/NewSerializationTest.cs

    r1434 r1435  
    182182    }
    183183
     184    public static void Test4() {
     185      ArrayList[] arrayListArray = new ArrayList[3];
     186      arrayListArray[0] = new ArrayList();
     187      arrayListArray[0].Add(arrayListArray);
     188      arrayListArray[0].Add(arrayListArray);
     189      arrayListArray[1] = new ArrayList();
     190      arrayListArray[1].Add(arrayListArray);
     191      arrayListArray[2] = new ArrayList();
     192      arrayListArray[2].Add(arrayListArray);
     193      arrayListArray[2].Add(arrayListArray);
     194      XmlGenerator.Serialize(arrayListArray, "test4");
     195      object o = XmlParser.DeSerialize("test4");
     196      Console.Out.WriteLine(Util.AutoFormat(o, true));
     197      Console.WriteLine(ViewOnlyGenerator.Serialize(arrayListArray));
     198      Console.WriteLine(ViewOnlyGenerator.Serialize(o));
     199    }
     200
    184201    public static void Test2() {
    185202      Manager m = new Manager();     
     
    212229    public static void Main() {           
    213230      Test1();     
    214       //Test2();
     231      Test2();
    215232      Test3();
     233      Test4();
    216234      //SpeedTest();
    217235      //SpeedTest2();
Note: See TracChangeset for help on using the changeset viewer.