- Timestamp:
- 04/14/09 13:23:08 (15 years ago)
- File:
-
- 1 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 }
Note: See TracChangeset
for help on using the changeset viewer.