#region License Information /* HeuristicLab * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Persistence { [Transformer("78556C88-0FEE-4602-95C7-A469B2DDB468", 100)] internal sealed class StorableClassBoxTransformer : BoxTransformer { public override bool CanTransformType(Type type) { return StorableClassAttribute.IsStorableClass(type); } protected override void Populate(Box.Builder box, object value, Mapper mapper) { var b = StorableClassBox.CreateBuilder(); var type = value.GetType(); var typeInfo = Mapper.StaticCache.GetTypeInfo(type); var emptyArgs = new object[0]; foreach (var hook in typeInfo.BeforeSerializationHooks) { hook.Invoke(value, emptyArgs); } var components = new Dictionary(); foreach (var componentInfo in typeInfo.Fields) { var field = (FieldInfo)componentInfo.MemberInfo; var component = mapper.GetBoxId(field.GetValue(value)); components.Add(mapper.GetStringId(componentInfo.Name), component); } foreach (var componentInfo in typeInfo.Properties.Where(x => x.Readable)) { var property = (PropertyInfo)componentInfo.MemberInfo; var component = mapper.GetBoxId(property.GetValue(value, null)); components.Add(mapper.GetStringId(componentInfo.Name), component); } b.AddRangeKeyIds(components.Keys); b.AddRangeValueIds(components.Values); box.SetExtension(StorableClassBox.StorableClass, b.Build()); } protected override object Extract(Box box, Type type, Mapper mapper) { return mapper.CreateInstance(type); } public override void FillFromBox(object obj, Box box, Mapper mapper) { var data = box.GetExtension(StorableClassBox.StorableClass); var type = obj.GetType(); var typeInfo = Mapper.StaticCache.GetTypeInfo(type); var components = new Dictionary(); for (int i = 0; i < data.KeyIdsList.Count; i++) { components.Add(data.KeyIdsList[i], data.ValueIdsList[i]); } foreach (var componentInfo in typeInfo.Fields) { var field = (FieldInfo)componentInfo.MemberInfo; uint componentId; bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId); field.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue); } foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) { var property = (PropertyInfo)componentInfo.MemberInfo; uint componentId; bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId); property.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null); } var emptyArgs = new object[0]; foreach (var hook in typeInfo.AfterDeserializationHooks) { hook.Invoke(obj, emptyArgs); } } } }