Changeset 14549
- Timestamp:
- 01/05/17 17:36:50 (8 years ago)
- Location:
- branches/PersistenceOverhaul
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Index.cs
r13347 r14549 20 20 #endregion 21 21 22 using System;23 22 using System.Collections.Generic; 24 using System.Linq;25 23 using HeuristicLab.PluginInfrastructure; 26 24 … … 35 33 this.indexes = new Dictionary<T, uint>(); 36 34 this.values = new Dictionary<uint, T>(); 37 nextIndex = 0;35 nextIndex = 1; 38 36 } 39 37 public Index(IEnumerable<T> values) … … 47 45 48 46 public uint GetIndex(T value) { 49 uint index ;50 if ( !indexes.TryGetValue(value, out index)) {47 uint index = 0; 48 if (value != null && !indexes.TryGetValue(value, out index)) { 51 49 index = nextIndex; 52 50 nextIndex++; … … 57 55 } 58 56 public T GetValue(uint index) { 59 return values[index];57 return index == 0 ? null : values[index]; 60 58 } 61 59 public IEnumerable<T> GetValues() { -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs
r14537 r14549 27 27 namespace HeuristicLab.Persistence { 28 28 public sealed class Mapper { 29 internal class MappingEqualityComparer : IEqualityComparer<object> { 30 bool IEqualityComparer<object>.Equals(object x, object y) { 31 if (x == null && y == null) return true; 32 if (x == null ^ y == null) return false; 33 if (x.GetType() != y.GetType()) return false; 34 35 var type = x.GetType(); 36 if (type.IsValueType || type == typeof(string)) return x.Equals(y); 37 return object.ReferenceEquals(x, y); 38 } 39 40 int IEqualityComparer<object>.GetHashCode(object obj) { 41 return obj == null ? 0 : obj.GetHashCode(); 42 } 43 } 44 29 45 private static StaticCache staticCache = null; 30 46 private static object locker = new object(); … … 41 57 private Index<Type> types; 42 58 private Index<string> strings; 43 private Index<Box> boxes;59 private Dictionary<uint, Box> boxId2Box; 44 60 private Dictionary<object, uint> object2BoxId; 45 61 private Dictionary<uint, object> boxId2object; 46 62 47 public longBoxCount { get; private set; }63 public uint BoxCount { get; private set; } 48 64 49 65 public Mapper() { … … 51 67 types = new Index<Type>(); 52 68 strings = new Index<string>(); 53 box es = new Index<Box>();54 object2BoxId = new Dictionary<object, uint>(new ReferenceEqualityComparer<object>());69 boxId2Box = new Dictionary<uint, Box>(); 70 object2BoxId = new Dictionary<object, uint>(new MappingEqualityComparer()); 55 71 boxId2object = new Dictionary<uint, object>(); 56 72 … … 81 97 public uint GetBoxId(object o) { 82 98 uint boxId; 83 if (object2BoxId.TryGetValue(o, out boxId)) return boxId;84 99 85 100 if (o == null) 86 boxId = boxes.GetIndex(null);101 boxId = 0; 87 102 else { 103 if (object2BoxId.TryGetValue(o, out boxId)) return boxId; 88 104 var type = o.GetType(); 89 105 var typeInfo = StaticCache.GetTypeInfo(type); 90 106 if (typeInfo.Transformer == null) throw new ArgumentException("Cannot serialize object of type " + o.GetType()); 91 BoxCount++;107 boxId = ++BoxCount; 92 108 typeInfo.Used++; 93 boxId = boxes.GetIndex(typeInfo.Transformer.ToBox(o, this)); 109 object2BoxId.Add(o, boxId); 110 boxId2Box.Add(boxId, typeInfo.Transformer.ToBox(o, this)); 94 111 } 95 object2BoxId.Add(o, boxId);96 112 return boxId; 97 113 } … … 100 116 if (boxId2object.TryGetValue(boxId, out o)) return o; 101 117 102 var box = this.boxes.GetValue(boxId); 118 Box box; 119 boxId2Box.TryGetValue(boxId, out box); 120 103 121 if (box == null) 104 122 o = null; … … 106 124 var transformer = transformers.GetValue(box.TransformerId); 107 125 o = transformer.ToObject(box, this); 126 boxId2object.Add(boxId, o); 127 transformer.FillFromBox(o, box, this); 108 128 } 109 boxId2object.Add(boxId, o);110 129 return o; 111 130 } … … 122 141 bundle.AddRangeTypeGuids(mapper.types.GetValues().Select(x => StaticCache.GetGuid(x)).Select(x => ByteString.CopyFromUtf8(x))); 123 142 bundle.AddRangeStrings(mapper.strings.GetValues()); 124 bundle.AddRangeBoxes(mapper.box es.GetValues());143 bundle.AddRangeBoxes(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value)); 125 144 return bundle.Build(); 126 145 } … … 129 148 mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => x.ToStringUtf8()).Select(x => StaticCache.GetType(x))); 130 149 mapper.strings = new Index<string>(bundle.StringsList); 131 mapper.box es = new Index<Box>(bundle.BoxesList);150 mapper.boxId2Box = bundle.BoxesList.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box); 132 151 mapper.transformers = new Index<ITransformer>(bundle.TransformerGuidsList.Select(x => new Guid(x.ToByteArray())).Select(x => StaticCache.GetTransformer(x))); 133 152 return mapper.GetObject(bundle.RootBoxId); -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs
r14537 r14549 21 21 22 22 using System; 23 using System.Collections; 23 24 using System.Collections.Generic; 24 25 using System.Drawing; … … 103 104 // RegisterType(new Guid("E92C35AD-32B1-4F37-B8D2-BE2F5FEB465B"), typeof(Dictionary<,>)); 104 105 105 106 RegisterTypeAndFullName(typeof(object)); 106 107 RegisterTypeAndFullName(typeof(bool)); 107 108 RegisterTypeAndFullName(typeof(byte)); … … 116 117 RegisterTypeAndFullName(typeof(float)); 117 118 RegisterTypeAndFullName(typeof(double)); 119 RegisterTypeAndFullName(typeof(decimal)); 118 120 RegisterTypeAndFullName(typeof(DateTime)); 119 121 RegisterTypeAndFullName(typeof(TimeSpan)); 122 RegisterTypeAndFullName(typeof(Font)); 120 123 RegisterTypeAndFullName(typeof(Color)); 124 RegisterTypeAndFullName(typeof(Bitmap)); 121 125 RegisterTypeAndFullName(typeof(Point)); 122 126 RegisterTypeAndFullName(typeof(KeyValuePair<,>)); 127 RegisterTypeAndFullName(typeof(Tuple<>)); 128 RegisterTypeAndFullName(typeof(Tuple<,>)); 129 RegisterTypeAndFullName(typeof(Tuple<,,>)); 130 RegisterTypeAndFullName(typeof(Tuple<,,,>)); 131 RegisterTypeAndFullName(typeof(Tuple<,,,,>)); 132 RegisterTypeAndFullName(typeof(Tuple<,,,,,>)); 133 RegisterTypeAndFullName(typeof(Tuple<,,,,,,>)); 134 RegisterTypeAndFullName(typeof(Tuple<,,,,,,,>)); 135 RegisterTypeAndFullName(typeof(Nullable<>)); 123 136 RegisterTypeAndFullName(typeof(string)); 124 137 … … 138 151 RegisterTypeAndFullName(typeof(string[])); 139 152 RegisterTypeAndFullName(typeof(List<>)); 153 RegisterTypeAndFullName(typeof(ArrayList)); 154 RegisterTypeAndFullName(typeof(HashSet<>)); 140 155 RegisterTypeAndFullName(typeof(Stack<>)); 141 RegisterTypeAndFullName(typeof(System.Collections.Stack)); 142 RegisterTypeAndFullName(typeof(HashSet<>)); 156 RegisterTypeAndFullName(typeof(Stack)); 157 RegisterTypeAndFullName(typeof(Queue<>)); 158 RegisterTypeAndFullName(typeof(Queue)); 143 159 RegisterTypeAndFullName(typeof(Dictionary<,>)); 144 160 145 146 161 foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { 147 foreach (var t in asm.GetTypes().Where(x => StorableClassAttribute.IsStorableClass(x) ))162 foreach (var t in asm.GetTypes().Where(x => StorableClassAttribute.IsStorableClass(x) || x.IsValueType && !x.IsPrimitive && !x.IsEnum && x.IsSealed)) 148 163 RegisterTypeAndFullName(t); 149 164 } -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Transformer.cs
r13367 r14549 35 35 public abstract Box ToBox(object o, Mapper mapper); 36 36 public abstract object ToObject(Box box, Mapper mapper); 37 38 public virtual void FillFromBox(object obj, Box box, Mapper mapper) { } 37 39 } 38 40 } -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs
r13347 r14549 72 72 while (types.Count > 0) { 73 73 type = types.Pop(); 74 var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic). 75 Where(x => StorableAttribute.IsStorable(x)); 76 foreach (var field in fieldInfos) { 77 var attrib = StorableAttribute.GetStorableAttribute(field); 78 var name = string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name; 79 fields.Add(new ComponentInfo(name, field, attrib, true, true)); 74 if (StorableClassAttribute.Type != StorableClassType.AllProperties) { 75 var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic) 76 .Where(x => !x.Name.StartsWith("<") && !x.Name.EndsWith("k__BackingField")); // exclude backing fields 77 if (StorableClassAttribute.Type == StorableClassType.MarkedOnly) 78 fieldInfos = fieldInfos.Where(x => StorableAttribute.IsStorable(x)).ToArray(); 79 foreach (var field in fieldInfos) { 80 var attrib = StorableAttribute.GetStorableAttribute(field); 81 var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name; 82 fields.Add(new ComponentInfo(type.Name + '.' + name, field, attrib, true, true)); 83 } 80 84 } 81 85 82 var propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic). 83 Where(x => x.GetIndexParameters().Length == 0). // exclude indexed properties 84 Where(x => StorableAttribute.IsStorable(x)); 85 foreach (var property in propertyInfos) { 86 var attrib = StorableAttribute.GetStorableAttribute(property); 87 var name = string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name; 88 properties.Add(new ComponentInfo(name, property, attrib, property.CanRead, property.CanWrite)); 86 if (StorableClassAttribute.Type != StorableClassType.AllFields) { 87 var propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic). 88 Where(x => x.GetIndexParameters().Length == 0); // exclude indexed properties 89 if (StorableClassAttribute.Type == StorableClassType.MarkedOnly) 90 propertyInfos = propertyInfos.Where(x => StorableAttribute.IsStorable(x)).ToArray(); 91 foreach (var property in propertyInfos) { 92 var attrib = StorableAttribute.GetStorableAttribute(property); 93 var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name; 94 properties.Add(new ComponentInfo(type.Name + '.' + name, property, attrib, property.CanRead, property.CanWrite)); 95 } 89 96 } 90 97 -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/ITransformer.cs
r13367 r14549 30 30 Box ToBox(object o, Mapper mapper); 31 31 object ToObject(Box box, Mapper mapper); 32 void FillFromBox(object obj, Box box, Mapper mapper); 32 33 } 33 34 } -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs
r14537 r14549 63 63 64 64 protected override object Extract(Box box, Type type, Mapper mapper) { 65 return mapper.CreateInstance(type); 66 } 67 public override void FillFromBox(object obj, Box box, Mapper mapper) { 65 68 var data = box.GetExtension(StorableClassBox.StorableClass); 69 var type = obj.GetType(); 66 70 var typeInfo = Mapper.StaticCache.GetTypeInfo(type); 67 var o = mapper.CreateInstance(type);68 71 69 72 var components = new Dictionary<uint, uint>(); … … 76 79 uint componentId; 77 80 bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId); 78 field.SetValue(o , found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue);81 field.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue); 79 82 } 80 83 … … 83 86 uint componentId; 84 87 bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId); 85 property.SetValue(o , found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null);88 property.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null); 86 89 } 87 90 88 91 var emptyArgs = new object[0]; 89 92 foreach (var hook in typeInfo.AfterDeserializationHooks) { 90 hook.Invoke(o , emptyArgs);93 hook.Invoke(obj, emptyArgs); 91 94 } 92 93 return o;94 95 } 95 96 } -
branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
r14537 r14549 23 23 using System.Collections; 24 24 using System.Collections.Generic; 25 using System.ComponentModel; 25 26 using System.Drawing; 27 using System.Drawing.Imaging; 28 using System.Globalization; 29 using System.IO; 26 30 using System.Linq; 31 using System.Reflection; 27 32 using Google.ProtocolBuffers; 33 using HeuristicLab.Persistence.Core; 28 34 29 35 namespace HeuristicLab.Persistence { … … 36 42 var box = Box.CreateBuilder(); 37 43 box.TransformerId = mapper.GetTransformerId(this); 38 box.TypeId = mapper.Get TypeId(o.GetType());44 box.TypeId = mapper.GetBoxId(o.GetType()); 39 45 Populate(box, (T)o, mapper); 40 46 return box.Build(); 41 47 } 42 48 public override object ToObject(Box box, Mapper mapper) { 43 return Extract(box, mapper.GetType(box.TypeId), mapper);49 return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper); 44 50 } 45 51 protected abstract void Populate(Box.Builder box, T value, Mapper mapper); … … 269 275 #endregion 270 276 277 [Transformer("11B822C9-46A0-4B65-AE4A-D12F63DDE9F6", 50)] 278 internal sealed class TypeTransformer : Transformer { 279 public override bool CanTransformType(Type type) { 280 return typeof(Type).IsAssignableFrom(type); 281 } 282 public override Box ToBox(object o, Mapper mapper) { 283 var box = Box.CreateBuilder(); 284 box.TransformerId = mapper.GetTransformerId(this); 285 Populate(box, o, mapper); 286 return box.Build(); 287 } 288 private void Populate(Box.Builder box, object value, Mapper mapper) { 289 var type = (Type)value; 290 var typeBox = TypeBox.CreateBuilder(); 291 if (type.IsGenericType) { 292 box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition()); 293 typeBox.AddRangeGenericTypeIds(type.GetGenericArguments().Select(t => mapper.GetBoxId(t))); 294 } else if (type.IsArray) { 295 box.TypeId = mapper.GetTypeId(typeof(Array)); 296 typeBox.AddGenericTypeIds(mapper.GetBoxId(type.GetElementType())); 297 } else { 298 box.TypeId = mapper.GetTypeId(type); 299 } 300 box.SetExtension(TypeBox.Type, typeBox.Build()); 301 } 302 public override object ToObject(Box box, Mapper mapper) { 303 return Extract(box, mapper.GetType(box.TypeId), mapper); 304 } 305 private object Extract(Box box, Type type, Mapper mapper) { 306 var b = box.GetExtension(TypeBox.Type); 307 if (type.IsGenericType) { 308 return type.MakeGenericType(b.GenericTypeIdsList.Select(id => (Type)mapper.GetObject(id)).ToArray()); 309 } else if (type == typeof(Array)) { 310 return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType(); 311 } else { 312 return type; 313 } 314 } 315 } 316 271 317 #region Primitive Value Types 318 [Transformer("268617FE-3F0F-4029-8248-EDA420901FB6", 10000)] 319 internal sealed class ObjectTransformer : BoxTransformer<object> { 320 protected override void Populate(Box.Builder box, object value, Mapper mapper) { } 321 protected override object Extract(Box box, Type type, Mapper mapper) { return new object(); } 322 } 323 272 324 [Transformer("9FA1C6A8-517E-4623-AC1B-7E9AEF6ED13D", 200)] 273 325 internal sealed class BoolTransformer : BoolBoxTransformer<bool> { … … 367 419 368 420 [Transformer("97B5CFC8-CDFA-4EB5-B4CD-5B3CFA5CD844", 216)] 369 internal sealed class KeyValuePairTransformer : UnsignedIntArrayBoxTransformer<object> {421 internal sealed class KeyValuePairTransformer : BoxTransformer<object> { 370 422 public override bool CanTransformType(Type type) { 371 423 return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)); 372 424 } 373 protected override IEnumerable<uint> ToBoxType(object value, Mapper mapper) { 425 protected override void Populate(Box.Builder box, object value, Mapper mapper) { 426 var b = UnsignedIntArrayBox.CreateBuilder(); 374 427 var type = value.GetType(); 375 428 var pair = new uint[2]; 376 429 pair[0] = mapper.GetBoxId(type.GetProperty("Key").GetValue(value)); 377 430 pair[1] = mapper.GetBoxId(type.GetProperty("Value").GetValue(value)); 378 return pair; 379 } 380 protected override object ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { 381 var key = mapper.GetObject(value.ElementAt(0)); 382 var val = mapper.GetObject(value.ElementAt(1)); 383 return Activator.CreateInstance(type, key, val); 431 b.AddRangeValues(pair); 432 box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build()); 433 } 434 public override void FillFromBox(object obj, Box box, Mapper mapper) { 435 var b = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 436 var key = mapper.GetObject(b.GetValues(0)); 437 var val = mapper.GetObject(b.GetValues(1)); 438 var type = obj.GetType(); 439 //DataMemberAccessor.GenerateFieldSetter(type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance))(obj, key); 440 //DataMemberAccessor.GenerateFieldSetter(type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance))(obj, val); 441 type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, key); 442 type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, val); 443 } 444 protected override object Extract(Box box, Type type, Mapper mapper) { 445 return Activator.CreateInstance(type); 446 } 447 } 448 449 [Transformer("EBD8BF65-D97D-4FD4-BF4F-9D58A72B6249", 217)] 450 internal sealed class DecimalTransformer : UnsignedIntBoxTransformer<decimal> { 451 protected override uint ToBoxType(decimal value, Mapper mapper) { 452 return mapper.GetStringId(FormatG30(value)); 453 } 454 protected override decimal ToValueType(uint value, Type type, Mapper mapper) { 455 var converter = TypeDescriptor.GetConverter(typeof(Font)); 456 return ParseG30(mapper.GetString(value)); 457 } 458 private static decimal ParseG30(string s) { 459 decimal d; 460 if (decimal.TryParse(s, 461 NumberStyles.AllowDecimalPoint | 462 NumberStyles.AllowExponent | 463 NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out d)) 464 return d; 465 throw new FormatException( 466 string.Format("Invalid decimal G30 number format \"{0}\" could not be parsed", s)); 467 } 468 private static string FormatG30(decimal d) { 469 return d.ToString("g30", CultureInfo.InvariantCulture); 384 470 } 385 471 } … … 387 473 388 474 #region String 389 [Transformer("E75A594C-0034-4DAB-B28E-8F84F9F6DE8D", 21 7)]475 [Transformer("E75A594C-0034-4DAB-B28E-8F84F9F6DE8D", 218)] 390 476 internal sealed class StringTransformer : UnsignedIntBoxTransformer<string> { 391 477 protected override uint ToBoxType(string value, Mapper mapper) { return mapper.GetStringId(value); } … … 395 481 396 482 #region Enum 397 [Transformer("93FF076B-BC4B-4C39-8C40-15E004468C98", 21 8)]483 [Transformer("93FF076B-BC4B-4C39-8C40-15E004468C98", 219)] 398 484 internal sealed class EnumTransformer : Transformer { 399 485 public override bool CanTransformType(Type type) { … … 420 506 #endregion 421 507 422 // #region Type 423 // [Transformer("8D17FD28-383B-44E9-9BBF-B19D351C5E38", 219)] 424 // internal sealed class TypeTransformer : Transformer { 425 // public override bool CanTransformType(Type type) { 426 // return typeof(Type).IsAssignableFrom(type); 427 // } 428 // public override Box ToBox(object o, Mapper mapper) { 429 // var boxBuilder = Box.CreateBuilder(); 430 // 431 // boxBuilder.TransformerId = mapper.GetTransformerId(this); 432 // boxBuilder.TypeId = mapper.GetStringId(((Type)o).AssemblyQualifiedName); 433 // 434 // return boxBuilder.Build(); 435 // } 436 // 437 // public override object ToObject(Box box, Mapper mapper) { 438 // return Type.GetType(mapper.GetString(box.TypeId)); 439 // } 440 // } 441 // #endregion 508 #region Struct 509 [Transformer("89DAAFC5-726C-48D4-A4E0-2B0D27329642", 220)] 510 internal sealed class StructTransformer : Transformer { 511 public override bool CanTransformType(Type type) { 512 return type.IsValueType && !type.IsPrimitive && !type.IsEnum && type.IsSealed; 513 } 514 public override Box ToBox(object o, Mapper mapper) { 515 var box = Box.CreateBuilder(); 516 box.TransformerId = mapper.GetTransformerId(this); 517 Populate(box, o, mapper); 518 return box.Build(); 519 } 520 public override object ToObject(Box box, Mapper mapper) { 521 return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper); 522 } 523 private void Populate(Box.Builder box, object value, Mapper mapper) { 524 var b = StorableClassBox.CreateBuilder(); 525 var type = value.GetType(); 526 527 var components = new Dictionary<uint, uint>(); 528 foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { 529 var component = mapper.GetBoxId(fieldInfo.GetValue(value)); 530 components.Add(mapper.GetStringId(fieldInfo.Name), component); 531 } 532 533 b.AddRangeKeyIds(components.Keys); 534 b.AddRangeValueIds(components.Values); 535 536 box.TypeId = mapper.GetBoxId(type); 537 box.SetExtension(StorableClassBox.StorableClass, b.Build()); 538 } 539 private object Extract(Box box, Type type, Mapper mapper) { 540 var data = box.GetExtension(StorableClassBox.StorableClass); 541 var obj = Activator.CreateInstance(type); 542 543 var components = new Dictionary<uint, uint>(); 544 for (int i = 0; i < data.KeyIdsList.Count; i++) { 545 components.Add(data.KeyIdsList[i], data.ValueIdsList[i]); 546 } 547 548 foreach (var t in components) { 549 string name = mapper.GetString(t.Key); 550 MemberInfo[] mis = type.GetMember(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 551 if (mis.Length != 1) 552 throw new Exception("ambiguous struct member name " + name); 553 MemberInfo mi = mis[0]; 554 if (mi.MemberType == MemberTypes.Field) 555 ((FieldInfo)mi).SetValue(obj, mapper.GetObject(t.Value)); 556 else 557 throw new Exception("invalid struct member type " + mi.MemberType.ToString()); 558 } 559 560 return obj; 561 } 562 } 563 #endregion 564 565 #region Tuple 566 [Transformer("63A19D57-EEEF-4346-9F06-B35B15EBFFA3", 221)] 567 internal sealed class TupleTransformer : Transformer { 568 private static readonly HashSet<Type> supportedTypes = new HashSet<Type> { 569 typeof(Tuple<>), typeof(Tuple<,>), typeof(Tuple<,,>), typeof(Tuple<,,,>), 570 typeof(Tuple<,,,,>), typeof(Tuple<,,,,,>), typeof(Tuple<,,,,,,>), typeof(Tuple<,,,,,,,>) 571 }; 572 public override bool CanTransformType(Type type) { 573 return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition()); 574 } 575 public override Box ToBox(object o, Mapper mapper) { 576 var box = Box.CreateBuilder(); 577 box.TransformerId = mapper.GetTransformerId(this); 578 Populate(box, o, mapper); 579 return box.Build(); 580 } 581 private void Populate(Box.Builder box, object value, Mapper mapper) { 582 var type = value.GetType(); 583 var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder(); 584 for (int i = 1; i <= type.GetGenericArguments().Length; i++) { 585 string name = string.Format("Item{0}", i); 586 uIntArrayBox.AddValues(mapper.GetBoxId(type.GetProperty(name).GetValue(value))); 587 } 588 box.TypeId = mapper.GetBoxId(type); 589 box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build()); 590 } 591 public override object ToObject(Box box, Mapper mapper) { 592 var type = (Type)mapper.GetObject(box.TypeId); 593 var defaultValues = type.GetGenericArguments().Select(x => 594 x.IsValueType ? Activator.CreateInstance(x) : null 595 ).ToArray(); 596 return Activator.CreateInstance(type, defaultValues); 597 } 598 public override void FillFromBox(object obj, Box box, Mapper mapper) { 599 var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 600 var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject).ToArray(); 601 var type = obj.GetType(); 602 for (int i = 1; i <= elements.Length; i++) { 603 string name = string.Format("m_Item{0}", i); 604 DataMemberAccessor.GenerateFieldSetter(type.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance))(obj, elements[i - 1]); 605 } 606 } 607 } 608 #endregion 609 610 #region Bitmap 611 [Transformer("D0ADB806-2DFD-459D-B5DA-14B5F1152534", 222)] 612 internal sealed class BitmapTransformer : ByteArrayBoxTransformer<Bitmap> { 613 protected override ByteString ToByteString(Bitmap value) { 614 lock (value) 615 using (var ms = new MemoryStream()) { 616 value.Save(ms, ImageFormat.Png); 617 return ByteString.CopyFrom(ms.ToArray()); 618 } 619 } 620 protected override Bitmap FromByteString(ByteString byteString) { 621 using (var ms = new MemoryStream()) { 622 ms.Write(byteString.ToArray(), 0, byteString.Length); 623 ms.Seek(0, SeekOrigin.Begin); 624 return new Bitmap(ms); 625 } 626 } 627 } 628 #endregion 629 630 #region Font 631 [Transformer("AFF27987-3301-4D70-9601-EFCA31BDA0DB", 223)] 632 internal sealed class FontTransformer : UnsignedIntArrayBoxTransformer<Font> { 633 634 protected override IEnumerable<uint> ToBoxType(Font value, Mapper mapper) { 635 yield return mapper.GetStringId(GetFontFamilyName(value.FontFamily)); 636 yield return mapper.GetBoxId(value.Size); 637 yield return mapper.GetBoxId(value.Style); 638 yield return mapper.GetBoxId(value.Unit); 639 yield return mapper.GetBoxId(value.GdiCharSet); 640 yield return mapper.GetBoxId(value.GdiVerticalFont); 641 } 642 protected override Font ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { 643 var fontData = value.ToArray(); 644 return new Font( 645 GetFontFamily(mapper.GetString(fontData[0])), 646 (float)mapper.GetObject(fontData[1]), 647 (FontStyle)mapper.GetObject(fontData[2]), 648 (GraphicsUnit)mapper.GetObject(fontData[3]), 649 (byte)mapper.GetObject(fontData[4]), 650 (bool)mapper.GetObject(fontData[5]) 651 ); 652 } 653 654 public const string GENERIC_MONOSPACE_NAME = "_GenericMonospace"; 655 public const string GENERIC_SANS_SERIF_NAME = "_GenericSansSerif"; 656 public const string GENERIC_SERIF_NAME = "_GenericSerif"; 657 658 public static FontFamily GetFontFamily(string name) { 659 if (name == GENERIC_MONOSPACE_NAME) return FontFamily.GenericMonospace; 660 if (name == GENERIC_SANS_SERIF_NAME) return FontFamily.GenericSansSerif; 661 if (name == GENERIC_SERIF_NAME) return FontFamily.GenericSerif; 662 return new FontFamily(name); 663 } 664 665 public static string GetFontFamilyName(FontFamily ff) { 666 if (ff.Equals(FontFamily.GenericMonospace)) return GENERIC_MONOSPACE_NAME; 667 if (ff.Equals(FontFamily.GenericSansSerif)) return GENERIC_SANS_SERIF_NAME; 668 if (ff.Equals(FontFamily.GenericSerif)) return GENERIC_SERIF_NAME; 669 return ff.Name; 670 } 671 } 672 #endregion 442 673 443 674 #region Array Types … … 570 801 } 571 802 572 //[Transformer("C83F0B5A-68D8-4271-81F9-FF259FC6F126", 400)] 573 //internal sealed class GenericArrayTransformer : UnsignedIntArrayBoxTransformer<object> { 574 // public override bool CanTransformType(Type type) { 575 // return type.IsArray; 576 // } 577 // protected override IEnumerable<uint> ToBoxType(object value, Mapper mapper) { 578 // var arr = (object[])value; 579 // return arr.Select(x => mapper.GetBoxId(x)); 580 // } 581 // protected override object ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { 582 // return value.Select(x => mapper.GetObject(x)).ToArray(); 583 // } 584 //} 585 586 // internal sealed class QueueTransformer : Transformer { 587 // public override bool CanTransformType(Type type) { 588 // return type == typeof(System.Collections.Queue) || type == typeof(Queue<>); 589 // } 590 // public override Box ToBox(object o, Mapper mapper) { 591 // var box = Box.CreateBuilder(); 592 // box.TransformerId = mapper.GetTransformerId(this); 593 // Populate(box, o, mapper); 594 // return box.Build(); 595 // } 596 // public override object ToObject(Box box, Mapper mapper) { 597 // return Extract(box, mapper.GetType(box.TypeId), mapper); 598 // } 599 // private void Populate(Box.Builder box, object value, Mapper mapper) { 600 // var elements = (System.Collections.IEnumerable)value; 601 // if (value.GetType().IsGenericType) { 602 // var elementType = value.GetType().GetGenericTypeDefinition().GetGenericArguments().First(); 603 // box.TypeId = mapper.GetTypeId(elementType); 604 // } 605 // 606 // var b = UnsignedIntArrayBox.CreateBuilder(); 607 // foreach (var elem in elements) { 608 // b.AddValues(mapper.GetBoxId(elem)); 609 // } 610 // 611 // box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build()); 612 // } 613 // private object Extract(Box box, Type type, Mapper mapper) { 614 // } 615 // } 616 617 [Transformer("B01ADF0A-ACAA-444E-9F82-0C7C2AF1F490", 2000)] 803 [Transformer("B01ADF0A-ACAA-444E-9F82-0C7C2AF1F490", 400)] 618 804 internal sealed class ArrayTransformer : Transformer { 619 805 public override bool CanTransformType(Type type) { 620 806 return type.IsArray; 807 } 808 public override Box ToBox(object o, Mapper mapper) { 809 Array arr = (Array)o; 810 if (arr.GetLowerBound(0) != 0 || arr.Rank > 1) throw new NotSupportedException(); 811 812 var box = Box.CreateBuilder(); 813 box.TransformerId = mapper.GetTransformerId(this); 814 Populate(box, o, mapper); 815 return box.Build(); 816 } 817 private void Populate(Box.Builder box, object value, Mapper mapper) { 818 var array = (Array)value; 819 var elementType = value.GetType().GetElementType(); 820 821 var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder(); 822 foreach (var item in (IEnumerable)array) 823 uIntArrayBox.AddValues(mapper.GetBoxId(item)); 824 825 box.TypeId = mapper.GetBoxId(elementType); 826 box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build()); 827 } 828 public override object ToObject(Box box, Mapper mapper) { 829 var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 830 var type = (Type)mapper.GetObject(box.TypeId); 831 return Array.CreateInstance(type, uIntArrayBox.ValuesCount); 832 } 833 public override void FillFromBox(object obj, Box box, Mapper mapper) { 834 var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 835 Array.Copy(uIntArrayBox.ValuesList.Select(x => mapper.GetObject(x)).ToArray(), (Array)obj, uIntArrayBox.ValuesCount); 836 } 837 } 838 #endregion 839 840 [Transformer("4FA5EAAF-ECC7-4A9C-84E7-6583DA96F3B9", 500)] 841 internal sealed class EnumerableTransformer : Transformer { 842 private static readonly HashSet<Type> supportedTypes = new HashSet<Type> { 843 typeof(Stack<>), typeof(Stack), 844 typeof(Queue<>), typeof(Queue), 845 typeof(HashSet<>), 846 typeof(List<>), typeof(ArrayList) 847 }; 848 public override bool CanTransformType(Type type) { 849 return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition()) || supportedTypes.Contains(type); 621 850 } 622 851 public override Box ToBox(object o, Mapper mapper) { … … 626 855 return box.Build(); 627 856 } 857 private void Populate(Box.Builder box, object value, Mapper mapper) { 858 var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder(); 859 foreach (var item in (IEnumerable)value) 860 uIntArrayBox.AddValues(mapper.GetBoxId(item)); 861 box.TypeId = mapper.GetBoxId(value.GetType()); 862 box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build()); 863 } 628 864 public override object ToObject(Box box, Mapper mapper) { 629 return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper); 630 } 631 private void Populate(Box.Builder box, object value, Mapper mapper) { 632 var array = (object[])value; 633 var elementType = value.GetType().GetElementType(); 634 635 var b = UnsignedIntArrayBox.CreateBuilder(); 636 b.AddRangeValues(array.Select(x => mapper.GetBoxId(x))); 637 638 box.TypeId = mapper.GetBoxId(elementType); 639 box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build()); 640 } 641 private object Extract(Box box, Type type, Mapper mapper) { 642 var b = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 643 644 var array = (object[])Array.CreateInstance((Type)mapper.GetObject(box.TypeId), b.ValuesCount); 645 646 for (int i = 0; i < array.Length; i++) { 647 array[i] = mapper.GetObject(b.GetValues(i)); 648 } 649 650 return array; 651 } 652 } 653 654 [Transformer("11B822C9-46A0-4B65-AE4A-D12F63DDE9F6", 1)] 655 internal sealed class TypeTransformer : Transformer { 865 var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 866 var type = (Type)mapper.GetObject(box.TypeId); 867 return Activator.CreateInstance(type, uIntArrayBox.ValuesCount); 868 } 869 public override void FillFromBox(object obj, Box box, Mapper mapper) { 870 var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray); 871 var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject); 872 var type = obj.GetType(); 873 string methodName = string.Empty; 874 if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Stack<>) || type == typeof(Stack)) { 875 elements = elements.Reverse(); 876 methodName = "Push"; 877 } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Queue<>) || type == typeof(Queue)) { 878 methodName = "Enqueue"; 879 } else { 880 methodName = "Add"; 881 } 882 883 MethodInfo addMethod = type.GetMethod(methodName); 884 foreach (var e in elements) 885 addMethod.Invoke(obj, new[] { e }); 886 } 887 } 888 889 [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 501)] 890 internal sealed class DictionaryTransformer : Transformer { 656 891 public override bool CanTransformType(Type type) { 657 return typeof(Type).IsAssignableFrom(type); 658 } 659 892 return type.IsGenericType && typeof(Dictionary<,>) == type.GetGenericTypeDefinition(); 893 } 660 894 public override Box ToBox(object o, Mapper mapper) { 661 895 var box = Box.CreateBuilder(); … … 664 898 return box.Build(); 665 899 } 666 667 private void Populate(Box.Builder box, object o, Mapper mapper) {668 var type = (Type)o;669 670 var b = TypeBox.CreateBuilder();671 if (type.IsGenericType) {672 box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition());673 b.AddRangeGenericTypeIds(type.GetGenericArguments().Select(t => mapper.GetBoxId(t)));674 } else if (type.IsArray) {675 box.TypeId = mapper.GetTypeId(typeof(Array));676 b.AddGenericTypeIds(mapper.GetBoxId(type.GetElementType()));677 } else {678 box.TypeId = mapper.GetTypeId(type);679 }680 box.SetExtension(TypeBox.Type, b.Build());681 }682 683 public override object ToObject(Box box, Mapper mapper) {684 return Extract(box, mapper.GetType(box.TypeId), mapper);685 }686 687 private object Extract(Box box, Type type, Mapper mapper) {688 var b = box.GetExtension(TypeBox.Type);689 if (b.GenericTypeIdsCount > 0) {690 if (typeof(Array).IsAssignableFrom(type)) {691 return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType();692 } else {693 return type.MakeGenericType(b.GenericTypeIdsList.Select(id => (Type)mapper.GetObject(id)).ToArray());694 }695 } else {696 return mapper.GetType(box.TypeId);697 }698 }699 }700 701 [Transformer("4FA5EAAF-ECC7-4A9C-84E7-6583DA96F3B9", 1000)]702 internal sealed class EnumerableTransformer : Transformer {703 public override bool CanTransformType(Type type) {704 return (type.IsGenericType && typeof(Stack<>) == type.GetGenericTypeDefinition()) ||705 type == typeof(System.Collections.Stack);706 }707 public override Box ToBox(object o, Mapper mapper) {708 var box = Box.CreateBuilder();709 box.TransformerId = mapper.GetTransformerId(this);710 Populate(box, o, mapper);711 return box.Build();712 }713 public override object ToObject(Box box, Mapper mapper) {714 return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);715 }716 private void Populate(Box.Builder box, object value, Mapper mapper) {717 var enumerableBox = UnsignedIntArrayBox.CreateBuilder();718 box.TypeId = mapper.GetBoxId(value.GetType());719 enumerableBox.AddRangeValues(((IEnumerable)value).OfType<object>().Select(mapper.GetBoxId));720 721 box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, enumerableBox.Build());722 }723 private object Extract(Box box, Type type, Mapper mapper) {724 var enumerableBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);725 if ((type.IsGenericType && typeof(Stack<>) == type.GetGenericTypeDefinition())) {726 var elemType = type.GenericTypeArguments[0];727 var stack = Activator.CreateInstance(type);728 var addMeth = type.GetMethod("Push");729 foreach (var e in enumerableBox.ValuesList.Select(mapper.GetObject).Reverse())730 addMeth.Invoke(stack, new[] { e });731 return stack;732 } else if (typeof(Stack).IsAssignableFrom(type)) {733 var l = new System.Collections.ArrayList();734 foreach (var e in enumerableBox.ValuesList.Select(mapper.GetObject)) {735 l.Add(e);736 }737 l.Reverse();738 return Activator.CreateInstance(type, l);739 } else {740 throw new NotSupportedException();741 }742 }743 }744 745 [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 500)]746 internal sealed class DictionaryTransformer : Transformer {747 public override bool CanTransformType(Type type) {748 return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type);749 }750 public override Box ToBox(object o, Mapper mapper) {751 var box = Box.CreateBuilder();752 box.TransformerId = mapper.GetTransformerId(this);753 Populate(box, o, mapper);754 return box.Build();755 }756 public override object ToObject(Box box, Mapper mapper) {757 return Extract(box, mapper.GetType(box.TypeId), mapper);758 }759 900 private void Populate(Box.Builder box, object value, Mapper mapper) { 760 901 var dictionaryBox = DictionaryBox.CreateBuilder(); … … 763 904 dictionaryBox.AddValueIds(mapper.GetBoxId(item.Value)); 764 905 } 765 // TODO: comparer 766 } 767 private object Extract(Box box, Type type, Mapper mapper) { 768 throw new NotImplementedException(); 769 } 770 } 771 #endregion 906 907 var type = value.GetType(); 908 var propertyInfo = type.GetProperty("Comparer"); 909 var comparer = propertyInfo.GetValue(value); 910 911 dictionaryBox.SetComparerId(mapper.GetBoxId(comparer)); 912 box.TypeId = mapper.GetBoxId(value.GetType()); 913 box.SetExtension(DictionaryBox.Dictionary, dictionaryBox.Build()); 914 } 915 public override object ToObject(Box box, Mapper mapper) { 916 var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary); 917 return Activator.CreateInstance((Type)mapper.GetObject(box.TypeId), dictionaryBox.ValueIdsCount); 918 } 919 public override void FillFromBox(object obj, Box box, Mapper mapper) { 920 var type = obj.GetType(); 921 var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary); 922 var comparer = mapper.GetObject(dictionaryBox.ComparerId); 923 var addMethod = type.GetMethod("Add"); 924 for (int i = 0; i < dictionaryBox.KeyIdsCount; i++) { 925 var key = mapper.GetObject(dictionaryBox.GetKeyIds(i)); 926 var value = mapper.GetObject(dictionaryBox.GetValueIds(i)); 927 addMethod.Invoke(obj, new[] { key, value }); 928 } 929 } 930 } 772 931 } -
branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs
r14537 r14549 33 33 using HeuristicLab.Algorithms.GeneticAlgorithm; 34 34 using HeuristicLab.Data; 35 using HeuristicLab.Persistence;36 35 using HeuristicLab.Persistence.Auxiliary; 37 36 using HeuristicLab.Persistence.Core; … … 945 944 #region Old persistence test methods 946 945 [TestMethod] 947 [TestCategory("Persistence4 ")]946 [TestCategory("Persistence4-EXEPTION")] 948 947 [TestProperty("Time", "short")] 949 948 public void ComplexStorable() { … … 1035 1034 1036 1035 [TestMethod] 1037 [TestCategory("Persistence4 ")]1036 [TestCategory("Persistence4-EXEPTION")] 1038 1037 [TestProperty("Time", "short")] 1039 1038 public void SelfReferences() { … … 1063 1062 1064 1063 [TestMethod] 1065 [TestCategory("Persistence4 ")]1064 [TestCategory("Persistence4-EXEPTION")] 1066 1065 [TestProperty("Time", "short")] 1067 1066 public void ArrayCreation() { … … 1076 1075 arrayListArray[2].Add(arrayListArray); 1077 1076 arrayListArray[2].Add(arrayListArray); 1078 Array a = Array.CreateInstance(1079 typeof(object),1080 new[] { 1, 2 }, new[] { 3, 4 });1081 arrayListArray[2].Add(a);1077 //Array a = Array.CreateInstance( 1078 // typeof(object), 1079 // new[] { 1, 2 }, new[] { 3, 4 }); 1080 //arrayListArray[2].Add(a); 1082 1081 serializer.Serialize(arrayListArray, tempFile); 1083 1082 object o = serializer.Deserialize(tempFile); … … 1353 1352 1354 1353 [TestMethod] 1355 [TestCategory("Persistence4 ")]1354 [TestCategory("Persistence4-EXEPTION")] 1356 1355 [TestProperty("Time", "short")] 1357 1356 public void InstantiateParentChainReference() { … … 1517 1516 1518 1517 [TestMethod] 1519 [TestCategory("Persistence4 ")]1518 [TestCategory("Persistence4-EXEPTION")] 1520 1519 [TestProperty("Time", "short")] 1521 1520 public void TestStreaming() { … … 2057 2056 } 2058 2057 #endregion 2058 2059 [StorableClass("6075F1E8-948A-4AD8-8F5A-942B777852EC")] 2060 public class A { 2061 [Storable] 2062 public Tuple<B> B { get; set; } 2063 } 2064 [StorableClass("6075F1E8-948A-4AD8-8F5A-942B777852EC")] 2065 public class B { 2066 [Storable] 2067 public A A { get; set; } 2068 } 2069 2070 [TestMethod] 2071 [TestCategory("Persistence4")] 2072 [TestProperty("Time", "short")] 2073 public void TestCyclicReferencesWithTuple() { 2074 var test = new Func<A>(() => { 2075 var a = new A { }; 2076 var b = new B { A = a }; 2077 a.B = Tuple.Create(b); 2078 return a; 2079 }); 2080 ProtoBufSerializer serializer = new ProtoBufSerializer(); 2081 serializer.Serialize(test(), tempFile); 2082 object o = serializer.Deserialize(tempFile); 2083 A result = (A)o; 2084 2085 Assert.AreEqual(result, result.B.Item1.A); 2086 Assert.AreSame(result, result.B.Item1.A); 2087 2088 string msg = Profile(test); 2089 Console.WriteLine(msg); 2090 } 2059 2091 } 2060 2092 }
Note: See TracChangeset
for help on using the changeset viewer.