Changeset 1553 for trunk/sources/HeuristicLab.Persistence/3.3/Core
- Timestamp:
- 04/14/09 13:23:08 (16 years ago)
- 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 8 8 public class ParentReference {} 9 9 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; } 11 15 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; 14 20 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>(); 18 32 } 19 33 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); 23 38 } 24 39 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 } 28 46 } 29 }30 47 31 public delegate void Thunk(); 48 public void Populate() { 49 decomposer.Populate(Obj, customValues, type); 50 } 51 } 32 52 33 53 public class Deserializer { 34 54 35 55 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; 40 59 41 60 public Deserializer( 42 IEnumerable<TypeMapping> typeCache) { 61 IEnumerable<TypeMapping> typeCache) { 43 62 id2obj = new Dictionary<int, object>(); 44 parentStack = new Stack< CompositeObject>();63 parentStack = new Stack<Midwife>(); 45 64 typeIds = new Dictionary<int, Type>(); 46 65 serializerMapping = CreateSerializers(typeCache); … … 60 79 } 61 80 62 public object Deserialize(IEnumerable<ISerializationToken> tokens) { 63 finalFixes = new List<Thunk>(); 81 public object Deserialize(IEnumerable<ISerializationToken> tokens) { 64 82 foreach (ISerializationToken token in tokens) { 65 83 Type t = token.GetType(); … … 74 92 } else if (t == typeof(NullReferenceToken)) { 75 93 NullHandler((NullReferenceToken)token); 94 } else if (t == typeof(MetaInfoBeginToken)) { 95 MetaInfoBegin((MetaInfoBeginToken)token); 96 } else if (t == typeof(MetaInfoEndToken)) { 97 MetaInfoEnd((MetaInfoEndToken)token); 76 98 } else { 77 99 throw new ApplicationException("invalid token type"); 78 100 } 79 101 } 80 foreach (Thunk fix in finalFixes) {81 fix();82 }83 102 return parentStack.Pop().Obj; 84 103 } 85 104 86 private void CompositeStartHandler(BeginToken token) { 105 private void CompositeStartHandler(BeginToken token) { 87 106 Type type = typeIds[(int)token.TypeId]; 88 107 IDecomposer decomposer = null; 89 108 if ( serializerMapping.ContainsKey(type) ) 90 decomposer = serializerMapping[type] as IDecomposer; 109 decomposer = serializerMapping[type] as IDecomposer; 91 110 if (decomposer == null) 92 111 throw new ApplicationException(String.Format( 93 112 "No suitable method for deserialization of type \"{0}\" found.", 94 113 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)); 101 115 } 102 116 103 private void CompositeEndHandler(EndToken token) { 117 private void CompositeEndHandler(EndToken token) { 104 118 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); 118 122 } 119 123 120 private void PrimitiveHandler(PrimitiveToken token) { 124 private void PrimitiveHandler(PrimitiveToken token) { 121 125 Type type = typeIds[(int)token.TypeId]; 122 126 object value = ((IFormatter) serializerMapping[type]).Parse(token.SerialData); … … 126 130 } 127 131 128 private void ReferenceHandler(ReferenceToken token) { 132 private void ReferenceHandler(ReferenceToken token) { 129 133 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); 135 135 } 136 136 137 private void NullHandler(NullReferenceToken token) { 137 private void NullHandler(NullReferenceToken token) { 138 138 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 } 140 156 141 157 private void SetValue(string name, object value) { 142 158 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); 146 165 } 147 166 } -
trunk/sources/HeuristicLab.Persistence/3.3/Core/Serializer.cs
r1542 r1553 72 72 IDecomposer decomposer = configuration.GetDecomposer(value.GetType()); 73 73 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)); 75 75 throw new ApplicationException( 76 76 String.Format( … … 92 92 } 93 93 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) { 96 96 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; 102 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 } 103 116 yield return new EndToken(name, typeId, id); 104 117 } -
trunk/sources/HeuristicLab.Persistence/3.3/Core/Tag.cs
r1542 r1553 4 4 5 5 public class Tag { 6 internal List<Thunk> globalFinalFixes; // reference to final fixes of Deserializer7 6 public string Name { get; private set; } 8 7 public object Value { get; set; } … … 16 15 Value = value; 17 16 } 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 } 25 18 26 19 }
Note: See TracChangeset
for help on using the changeset viewer.