Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/11/17 17:46:11 (7 years ago)
Author:
jkarder
Message:

#2520: worked on new persistence

  • changed message definitions
  • updated transformers
  • cleaned up
Location:
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0
Files:
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/Index.cs

    r14549 r15509  
    2626  [NonDiscoverableType]
    2727  internal sealed class Index<T> where T : class {
    28     private Dictionary<T, uint> indexes;
    29     private Dictionary<uint, T> values;
     28    private readonly Dictionary<T, uint> indexes;
     29    private readonly Dictionary<uint, T> values;
    3030    private uint nextIndex;
    3131
     
    3535      nextIndex = 1;
    3636    }
    37     public Index(IEnumerable<T> values)
    38       : this() {
     37
     38    public Index(IEnumerable<T> values) : this() {
    3939      foreach (var value in values) {
    4040        this.indexes.Add(value, nextIndex);
     
    5454      return index;
    5555    }
     56
    5657    public T GetValue(uint index) {
    5758      return index == 0 ? null : values[index];
    5859    }
     60
    5961    public IEnumerable<T> GetValues() {
    6062      return values.Values;
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/Mapper.cs

    r15020 r15509  
    2323using System.Collections.Generic;
    2424using System.Linq;
    25 using Google.ProtocolBuffers;
     25using Google.Protobuf;
    2626
    2727namespace HeuristicLab.Persistence {
     
    4343    }
    4444
    45     private static StaticCache staticCache = null;
     45    private static StaticCache staticCache;
    4646    private static object locker = new object();
    4747    public static StaticCache StaticCache {
     
    5656    private Index<ITransformer> transformers;
    5757    private Index<Type> types;
    58     private Index<string> strings;
     58
    5959    private Dictionary<uint, Box> boxId2Box;
    6060    private Dictionary<object, uint> object2BoxId;
    61     private Dictionary<uint, object> boxId2object;
     61    private Dictionary<uint, object> boxId2Object;
     62    private Index<TypeBox> typeBoxes;
     63
     64    private Index<string> strings;
     65
     66    private Index<BoolArrayBox> boolArrayBoxes;
     67    private Index<IntArrayBox> intArrayBoxes;
     68    private Index<UnsignedIntArrayBox> unsignedIntArrayBoxes;
     69    private Index<LongArrayBox> longArrayBoxes;
     70    private Index<UnsignedLongArrayBox> unsignedLongArrayBoxes;
     71    private Index<FloatArrayBox> floatArrayBoxes;
     72    private Index<DoubleArrayBox> doubleArrayBoxes;
     73
     74    private Index<DictionaryBox> dictionaryBoxes;
     75    private Index<StorableClassBox> storableClassBoxes;
    6276
    6377    public uint BoxCount { get; private set; }
     78
    6479
    6580    public Mapper() {
    6681      transformers = new Index<ITransformer>();
    6782      types = new Index<Type>();
    68       strings = new Index<string>();
     83
    6984      boxId2Box = new Dictionary<uint, Box>();
    7085      object2BoxId = new Dictionary<object, uint>(new MappingEqualityComparer());
    71       boxId2object = new Dictionary<uint, object>();
     86      boxId2Object = new Dictionary<uint, object>();
     87      typeBoxes = new Index<TypeBox>();
     88
     89      strings = new Index<string>();
     90
     91      boolArrayBoxes = new Index<BoolArrayBox>();
     92      intArrayBoxes = new Index<IntArrayBox>();
     93      unsignedIntArrayBoxes = new Index<UnsignedIntArrayBox>();
     94      longArrayBoxes = new Index<LongArrayBox>();
     95      unsignedLongArrayBoxes = new Index<UnsignedLongArrayBox>();
     96      floatArrayBoxes = new Index<FloatArrayBox>();
     97      doubleArrayBoxes = new Index<DoubleArrayBox>();
     98
     99      dictionaryBoxes = new Index<DictionaryBox>();
     100      storableClassBoxes = new Index<StorableClassBox>();
    72101
    73102      BoxCount = 0;
    74103    }
    75104
     105    #region Transformers
    76106    public uint GetTransformerId(ITransformer transformer) {
    77107      return transformers.GetIndex(transformer);
    78108    }
     109
    79110    public ITransformer GetTransformer(uint transformerId) {
    80111      return transformers.GetValue(transformerId);
    81112    }
    82 
     113    #endregion
     114
     115    #region Types
    83116    public uint GetTypeId(Type type) {
    84117      return types.GetIndex(type);
    85118    }
     119
    86120    public Type GetType(uint typeId) {
    87121      return types.GetValue(typeId);
    88122    }
    89 
    90     public uint GetStringId(string str) {
    91       return strings.GetIndex(str);
    92     }
    93     public string GetString(uint stringId) {
    94       return strings.GetValue(stringId);
    95     }
    96 
    97     public Box GetBox(uint boxId) {
    98       return boxId2Box[boxId];
    99     }
     123    #endregion
     124
     125    #region Boxes
    100126    public uint GetBoxId(object o) {
    101127      uint boxId;
     
    115141      return boxId;
    116142    }
     143
     144    public Box GetBox(uint boxId) {
     145      return boxId2Box[boxId];
     146    }
     147
    117148    public object GetObject(uint boxId) {
    118149      object o;
    119       if (boxId2object.TryGetValue(boxId, out o)) return o;
     150      if (boxId2Object.TryGetValue(boxId, out o)) return o;
    120151
    121152      Box box;
     
    127158        var transformer = transformers.GetValue(box.TransformerId);
    128159        o = transformer.ToObject(box, this);
    129         boxId2object.Add(boxId, o);
     160        boxId2Object.Add(boxId, o);
    130161        transformer.FillFromBox(o, box, this);
    131162      }
     163
    132164      return o;
    133165    }
     166
     167    #region Referenced Boxes
     168    #region TypeBoxes
     169    public uint GetTypeBoxId(TypeBox typeBox) { return typeBoxes.GetIndex(typeBox); }
     170    public TypeBox GetTypeBox(uint typeBoxId) { return typeBoxes.GetValue(typeBoxId); }
     171    #endregion
     172
     173    #region BoolArrayBox
     174    public uint GetBoolArrayBoxId(BoolArrayBox boolArrayBox) { return boolArrayBoxes.GetIndex(boolArrayBox); }
     175    public BoolArrayBox GetBoolArrayBox(uint boolArrayBoxId) { return boolArrayBoxes.GetValue(boolArrayBoxId); }
     176    #endregion
     177
     178    #region IntArrayBox
     179    public uint GetIntArrayBoxId(IntArrayBox intArrayBox) { return intArrayBoxes.GetIndex(intArrayBox); }
     180    public IntArrayBox GetIntArrayBox(uint intArrayBoxId) { return intArrayBoxes.GetValue(intArrayBoxId); }
     181    #endregion
     182
     183    #region UnsignedIntArrayBox
     184    public uint GetUnsignedIntArrayBoxId(UnsignedIntArrayBox unsignedIntArrayBox) { return unsignedIntArrayBoxes.GetIndex(unsignedIntArrayBox); }
     185    public UnsignedIntArrayBox GetUnsignedIntArrayBox(uint unsignedIntArrayBoxId) { return unsignedIntArrayBoxes.GetValue(unsignedIntArrayBoxId); }
     186    #endregion
     187
     188    #region LongArrayBox
     189    public uint GetLongArrayBoxId(LongArrayBox longArrayBox) { return longArrayBoxes.GetIndex(longArrayBox); }
     190    public LongArrayBox GetLongArrayBox(uint longArrayBoxId) { return longArrayBoxes.GetValue(longArrayBoxId); }
     191    #endregion
     192
     193    #region UnsignedLongArrayBox
     194    public uint GetUnsignedLongArrayBoxId(UnsignedLongArrayBox unsignedLongArrayBox) { return unsignedLongArrayBoxes.GetIndex(unsignedLongArrayBox); }
     195    public UnsignedLongArrayBox GetUnsignedLongArrayBox(uint unsignedLongArrayBoxId) { return unsignedLongArrayBoxes.GetValue(unsignedLongArrayBoxId); }
     196    #endregion
     197
     198    #region FloatArrayBox
     199    public uint GetFloatArrayBoxId(FloatArrayBox floatArrayBox) { return floatArrayBoxes.GetIndex(floatArrayBox); }
     200    public FloatArrayBox GetFloatArrayBox(uint floatArrayBoxId) { return floatArrayBoxes.GetValue(floatArrayBoxId); }
     201    #endregion
     202
     203    #region DoubleArrayBox
     204    public uint GetDoubleArrayBoxId(DoubleArrayBox doubleArrayBox) { return doubleArrayBoxes.GetIndex(doubleArrayBox); }
     205    public DoubleArrayBox GetDoubleArrayBox(uint doubleArrayBoxId) { return doubleArrayBoxes.GetValue(doubleArrayBoxId); }
     206    #endregion
     207
     208    #region DictionaryBox
     209    public uint GetDictionaryBoxId(DictionaryBox dictionaryBox) { return dictionaryBoxes.GetIndex(dictionaryBox); }
     210    public DictionaryBox GetDictionaryBox(uint dictionaryBoxId) { return dictionaryBoxes.GetValue(dictionaryBoxId); }
     211    #endregion
     212
     213    #region StorableClassBox
     214    public uint GetStorableClassBoxId(StorableClassBox storableClassBox) { return storableClassBoxes.GetIndex(storableClassBox); }
     215    public StorableClassBox GetStorableClassBox(uint storableClassBoxId) { return storableClassBoxes.GetValue(storableClassBoxId); }
     216    #endregion
     217    #endregion
     218    #endregion
     219
     220    #region Strings
     221    public uint GetStringId(string str) {
     222      return strings.GetIndex(str);
     223    }
     224    public string GetString(uint stringId) {
     225      return strings.GetValue(stringId);
     226    }
     227    #endregion
    134228
    135229    public object CreateInstance(Type type) {
     
    143237    public static Bundle ToBundle(object o) {
    144238      var mapper = new Mapper();
    145       var bundle = Bundle.CreateBuilder();
     239      var bundle = new Bundle();
     240
    146241      bundle.RootBoxId = mapper.GetBoxId(o);
    147       bundle.AddRangeTransformerGuids(mapper.transformers.GetValues().Select(x => x.Guid).Select(x => ByteString.CopyFrom(x.ToByteArray())));
    148       bundle.AddRangeTypeGuids(mapper.types.GetValues().Select(x => ByteString.CopyFrom(StaticCache.GetGuid(x).ToByteArray())));
    149       bundle.AddRangeStrings(mapper.strings.GetValues());
    150       bundle.AddRangeBoxes(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value));
    151       return bundle.Build();
     242      bundle.TransformerGuids.AddRange(mapper.transformers.GetValues().Select(x => x.Guid).Select(x => ByteString.CopyFrom(x.ToByteArray())));
     243      bundle.TypeGuids.AddRange(mapper.types.GetValues().Select(x => ByteString.CopyFrom(StaticCache.GetGuid(x).ToByteArray())));
     244      bundle.Boxes.AddRange(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value));
     245      bundle.TypeBoxes.AddRange(mapper.typeBoxes.GetValues());
     246
     247      bundle.Strings.AddRange(mapper.strings.GetValues());
     248
     249      bundle.BoolArrayBoxes.AddRange(mapper.boolArrayBoxes.GetValues());
     250      bundle.IntArrayBoxes.AddRange(mapper.intArrayBoxes.GetValues());
     251      bundle.UnsignedIntArrayBoxes.AddRange(mapper.unsignedIntArrayBoxes.GetValues());
     252      bundle.LongArrayBoxes.AddRange(mapper.longArrayBoxes.GetValues());
     253      bundle.UnsignedLongArrayBoxes.AddRange(mapper.unsignedLongArrayBoxes.GetValues());
     254      bundle.FloatArrayBoxes.AddRange(mapper.floatArrayBoxes.GetValues());
     255      bundle.DoubleArrayBoxes.AddRange(mapper.doubleArrayBoxes.GetValues());
     256
     257      bundle.DictionaryBoxes.AddRange(mapper.dictionaryBoxes.GetValues());
     258      bundle.StorableClassBoxes.AddRange(mapper.storableClassBoxes.GetValues());
     259
     260      return bundle;
    152261    }
    153262    public static object ToObject(Bundle bundle) {
    154263      var mapper = new Mapper();
    155       mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => StaticCache.GetType(new Guid(x.ToByteArray()))));
    156       mapper.strings = new Index<string>(bundle.StringsList);
    157       mapper.boxId2Box = bundle.BoxesList.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box);
    158       mapper.transformers = new Index<ITransformer>(bundle.TransformerGuidsList.Select(x => new Guid(x.ToByteArray())).Select(x => StaticCache.GetTransformer(x)));
     264
     265      mapper.transformers = new Index<ITransformer>(bundle.TransformerGuids.Select(x => new Guid(x.ToByteArray())).Select(StaticCache.GetTransformer));
     266      mapper.types = new Index<Type>(bundle.TypeGuids.Select(x => StaticCache.GetType(new Guid(x.ToByteArray()))));
     267
     268      mapper.boxId2Box = bundle.Boxes.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box);
     269      mapper.typeBoxes = new Index<TypeBox>(bundle.TypeBoxes);
     270
     271      mapper.strings = new Index<string>(bundle.Strings);
     272
     273      mapper.boolArrayBoxes = new Index<BoolArrayBox>(bundle.BoolArrayBoxes);
     274      mapper.intArrayBoxes = new Index<IntArrayBox>(bundle.IntArrayBoxes);
     275      mapper.unsignedIntArrayBoxes = new Index<UnsignedIntArrayBox>(bundle.UnsignedIntArrayBoxes);
     276      mapper.longArrayBoxes = new Index<LongArrayBox>(bundle.LongArrayBoxes);
     277      mapper.unsignedLongArrayBoxes = new Index<UnsignedLongArrayBox>(bundle.UnsignedLongArrayBoxes);
     278      mapper.floatArrayBoxes = new Index<FloatArrayBox>(bundle.FloatArrayBoxes);
     279      mapper.doubleArrayBoxes = new Index<DoubleArrayBox>(bundle.DoubleArrayBoxes);
     280
     281      mapper.dictionaryBoxes = new Index<DictionaryBox>(bundle.DictionaryBoxes);
     282      mapper.storableClassBoxes = new Index<StorableClassBox>(bundle.StorableClassBoxes);
     283
    159284      return mapper.GetObject(bundle.RootBoxId);
    160285    }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/ProtoBufSerializer.cs

    r13367 r15509  
    2121
    2222using System.IO;
     23using Google.Protobuf;
    2324
    2425namespace HeuristicLab.Persistence {
    2526  public sealed class ProtoBufSerializer : Serializer {
    2627    protected override void SerializeBundle(Bundle bundle, Stream stream) {
    27       bundle.WriteTo(stream);
     28      using (var outputStream = new CodedOutputStream(stream))
     29        bundle.WriteTo(outputStream);
    2830    }
    2931
    3032    protected override Bundle DeserializeBundle(Stream stream) {
    31       return Bundle.ParseFrom(stream, Mapper.StaticCache.GetExtensionRegistry());
     33      using (var inputStream = new CodedInputStream(stream))
     34        return Bundle.Parser.ParseFrom(inputStream);
    3235    }
    3336  }
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StaticCache.cs

    r15020 r15509  
    2525using System.Drawing;
    2626using System.Linq;
    27 using Google.ProtocolBuffers;
    2827using HeuristicLab.PluginInfrastructure;
    2928
    3029namespace HeuristicLab.Persistence {
    3130  public sealed class StaticCache {
    32     private static object locker = new object();
     31    private static readonly object locker = new object();
    3332
    34     private Dictionary<Guid, ITransformer> guid2Transformer;
    35     private Dictionary<ITransformer, Guid> transformer2Guid;
    36     private Dictionary<Guid, Type> guid2Type;
    37     private Dictionary<Type, Guid> type2Guid;
    38     private Dictionary<Type, TypeInfo> typeInfos;
    39     private ExtensionRegistry extensionRegistry;
     33    private readonly Dictionary<Guid, ITransformer> guid2Transformer;
     34    private readonly Dictionary<ITransformer, Guid> transformer2Guid;
     35    private readonly Dictionary<Guid, Type> guid2Type;
     36    private readonly Dictionary<Type, Guid> type2Guid;
     37    private readonly Dictionary<Type, TypeInfo> typeInfos;
    4038
    4139    internal StaticCache() {
     
    4543      type2Guid = new Dictionary<Type, Guid>();
    4644      typeInfos = new Dictionary<Type, TypeInfo>();
    47       extensionRegistry = ExtensionRegistry.CreateInstance();
    4845
    4946      foreach (var transformer in ApplicationManager.Manager.GetInstances<ITransformer>())
     
    8279      RegisterType(new Guid("E84C326A-7E14-4F28-AEFF-BC16CC671655"), typeof(KeyValuePair<,>));
    8380      RegisterType(new Guid("F0280B55-25E8-4981-B309-D675D081402A"), typeof(string));
    84       //
     81
    8582      RegisterType(new Guid("9CF55419-439B-4A90-B2ED-8C7F7768EB61"), typeof(Array));
    86       // RegisterType(new Guid("D15AD28B-203A-460E-815C-F7230C4B1F75"), typeof(bool[]));
    87       // RegisterType(new Guid("EE318DC4-580D-4DB1-9AAD-988B0E50A3DB"), typeof(byte[]));
    88       // RegisterType(new Guid("326B9484-361F-46F8-B8A6-46C781A8C51F"), typeof(sbyte[]));
    89       // RegisterType(new Guid("C854783D-4C91-43C8-A19A-F96012494F8A"), typeof(short[]));
    90       // RegisterType(new Guid("C47FB329-2A1D-4EB7-AFB1-1CF72AB30E98"), typeof(ushort[]));
    91       // RegisterType(new Guid("9681D044-B50C-4907-B23E-BDFEBC6C3FFC"), typeof(char[]));
    92       // RegisterType(new Guid("0FC62D91-D63F-4507-8696-885D4C07285A"), typeof(int[]));
    93       // RegisterType(new Guid("C43A25A0-9B99-4DA4-9279-7495FE10428E"), typeof(uint[]));
    94       // RegisterType(new Guid("7AC4DDAC-0E13-428E-BF49-7BE7B76746CB"), typeof(long[]));
    95       // RegisterType(new Guid("8D9283A7-FE49-4AEA-A09F-D53CF3BE520A"), typeof(ulong[]));
    96       // RegisterType(new Guid("BB9CFA0B-DD29-4C44-85C6-3A6289C55448"), typeof(float[]));
    97       // RegisterType(new Guid("3B3AA69E-1641-4202-AE1D-7EEFF60FA355"), typeof(double[]));
    98       // RegisterType(new Guid("7DF325A6-2553-4915-B7C6-D98191107CB7"), typeof(string[]));
    99 
    100       RegisterType(new Guid("E451A99B-0CFD-48E6-9BEF-0AE9D1E73628"), typeof(IList));
    10183      RegisterType(new Guid("B7313EE2-045F-41C9-AEC9-7B1A8CDBF90F"), typeof(IEnumerable));
    10284      RegisterType(new Guid("D5265599-7380-4A28-AB0D-9F336EF290C5"), typeof(IEnumerable<>));
     85      RegisterType(new Guid("E451A99B-0CFD-48E6-9BEF-0AE9D1E73628"), typeof(IList));
    10386      RegisterType(new Guid("DB2A785C-5803-42C7-A01F-E1FD845A83A1"), typeof(List<>));
    10487      RegisterType(new Guid("EB98A564-BEDC-458A-9E9B-4BF3CDAFB9BE"), typeof(Stack<>));
     
    129112        }
    130113      }
     114
    131115      RegisterType(new Guid("67C35B3B-DC23-4929-9BA9-0A0CD5FE17F5"), allTypes["System.StringComparer"]);
    132116      RegisterType(new Guid("C7FDE8F0-EF3F-4A4D-8D87-5559C32A8B90"), allTypes["System.CultureAwareComparer"]);
     
    151135      RegisterType(new Guid("00C8C940-63D9-43FF-99BA-9C69301BF043"), allTypes["System.Collections.Generic.RandomizedObjectEqualityComparer"]);
    152136      RegisterType(new Guid("DAF22757-7FCC-49AC-B148-F3DD7E9E0A3B"), allTypes["System.Collections.Generic.IEqualityComparer`1"]);
    153 
    154       //var registeredTypes = type2Guid.Keys.ToArray();
    155       //foreach (var t in registeredTypes) {
    156       //  AddBaseTypesRec(t);
    157       //}
    158 
    159       RegisterExtension(BoolBox.Bool);
    160       RegisterExtension(IntBox.Int);
    161       RegisterExtension(LongBox.Long);
    162       RegisterExtension(UnsignedIntBox.UnsignedInt);
    163       RegisterExtension(UnsignedLongBox.UnsignedLong);
    164       RegisterExtension(FloatBox.Float);
    165       RegisterExtension(DoubleBox.Double);
    166       RegisterExtension(StringBox.String);
    167       RegisterExtension(BytesBox.Bytes);
    168       RegisterExtension(BoolArrayBox.BoolArray);
    169       RegisterExtension(ByteArrayBox.ByteArray);
    170       RegisterExtension(IntArrayBox.IntArray);
    171       RegisterExtension(LongArrayBox.LongArray);
    172       RegisterExtension(UnsignedIntArrayBox.UnsignedIntArray);
    173       RegisterExtension(UnsignedLongArrayBox.UnsignedLongArray);
    174       RegisterExtension(FloatArrayBox.FloatArray);
    175       RegisterExtension(DoubleArrayBox.DoubleArray);
    176       RegisterExtension(StringArrayBox.StringArray);
    177       RegisterExtension(MatrixBox.Matrix);
    178       RegisterExtension(BoolMatrixBox.BoolMatrix);
    179       RegisterExtension(IntMatrixBox.IntMatrix);
    180       RegisterExtension(DictionaryBox.Dictionary);
    181       RegisterExtension(StorableClassBox.StorableClass);
    182       RegisterExtension(TypeBox.Type);
    183137    }
    184 
    185     //private void AddBaseTypesRec(MemberSelection t) {
    186     //  foreach (var interfaceType in t.GetInterfaces()) {
    187     //    RegisterTypeAndFullName(interfaceType);
    188     //    AddBaseTypesRec(interfaceType);
    189     //  }
    190     //  if (t.BaseType != null) {
    191     //    RegisterTypeAndFullName(t.BaseType);
    192     //    AddBaseTypesRec(t.BaseType);
    193     //  }
    194     //}
    195138
    196139    public void RegisterTransformer(ITransformer transformer) {
     
    206149      }
    207150    }
     151
    208152    // mainly for testing
    209153    public void DeregisterType(Guid guid) {
     
    213157      }
    214158    }
    215     //public void RegisterTypeAndFullName(MemberSelection type) {
    216     //  lock (locker) {
    217     //    var key = type.AssemblyQualifiedName ?? type.Name;
    218     //    if (!guid2Type.ContainsKey(key)) {
    219     //      guid2Type.Add(key, type);
    220     //      type2Guid.Add(type, key);
    221     //    }
    222     //  }
    223     //}
    224     public void RegisterExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
    225       lock (locker) {
    226         extensionRegistry.Add(extension);
    227       }
    228     }
    229159
    230160    public ITransformer GetTransformer(Guid guid) {
    231161      return guid2Transformer[guid];
    232162    }
     163
    233164    public Guid GetGuid(ITransformer transformer) {
    234165      return transformer2Guid[transformer];
    235166    }
     167
    236168    public Type GetType(Guid guid) {
    237169      return guid2Type[guid];
    238170    }
     171
    239172    public Guid GetGuid(Type type) {
    240173      return type2Guid[type];
    241174    }
     175
    242176    public TypeInfo GetTypeInfo(Type type) {
    243177      lock (locker) {
     
    245179        if (!typeInfos.TryGetValue(type, out typeInfo)) {
    246180          var transformer = guid2Transformer.Values.OrderBy(x => x.Priority).FirstOrDefault(x => x.CanTransformType(type));
    247           if(transformer == null) throw new PersistenceException("No transformer found for type " + type.AssemblyQualifiedName);
     181          if (transformer == null) throw new PersistenceException("No transformer found for type " + type.AssemblyQualifiedName);
    248182          typeInfo = new TypeInfo(type, transformer);
    249183          typeInfos.Add(type, typeInfo);
     
    252186      }
    253187    }
    254     public ExtensionRegistry GetExtensionRegistry() {
    255       return extensionRegistry;
    256     }
    257188  }
    258189}
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/HeuristicLab.Persistence-4.0.csproj

    r15501 r15509  
    7373    <Compile Include="Properties\AssemblyInfo.cs" />
    7474    <Compile Include="Protos\PersistenceMessages.cs" />
    75     <Compile Include="Transformers\StorableClassTransformer.cs" />
    7675    <Compile Include="Transformers\Transformers.cs" />
    7776  </ItemGroup>
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Protos/PersistenceMessages.proto

    r15501 r15509  
    99  uint32 root_box_id = 10;
    1010  repeated Box boxes = 20;
     11  repeated TypeBox type_boxes = 30;
    1112
    1213  repeated string strings = 100;
    13   repeated bool bools = 101;
    14   repeated int32 ints = 102;
    15   repeated int64 longs = 103;
    16   repeated uint32 uints = 104;
    17   repeated uint64 ulongs = 105;
    18   repeated float floats = 106;
    19   repeated double doubles = 107;
    20   repeated bytes bytes = 108;
    2114
    22   repeated StringArrayBox string_arrays = 200;
    23   repeated BoolArrayBox bool_arrays = 201;
    24   repeated IntArrayBox int_arrays = 202;
    25   repeated LongArrayBox long_arrays = 203;
    26   repeated UnsignedIntArrayBox uint_arrays = 204;
    27   repeated UnsignedLongArrayBox ulong_arrays = 205;
    28   repeated FloatArrayBox float_arrays = 206;
    29   repeated DoubleArrayBox double_arrays = 207;
    30   repeated ByteArrayBox byte_arrays = 208;
    31 
    32   repeated MatrixBox matrices = 300;
    33   repeated BoolMatrixBox bool_matrices = 310;
    34   repeated IntMatrixBox int_matrices = 311;
    35 
    36   repeated DictionaryBox dictionaries = 400;
    37   repeated StorableClassBox storables = 410;
     15  repeated BoolArrayBox bool_array_boxes = 200;
     16  repeated IntArrayBox int_array_boxes = 201;
     17  repeated UnsignedIntArrayBox unsigned_int_array_boxes = 203;
     18  repeated LongArrayBox long_array_boxes = 202;
     19  repeated UnsignedLongArrayBox unsigned_long_array_boxes = 204;
     20  repeated FloatArrayBox float_array_boxes = 205;
     21  repeated DoubleArrayBox double_array_boxes = 206;
     22 
     23  repeated DictionaryBox dictionary_boxes = 300;
     24  repeated StorableClassBox storable_class_boxes = 310;
    3825}
    3926message Box {
     
    4128  uint32 type_id = 2;
    4229  uint32 box_id = 3;
     30
    4331  bool bool = 10;
    4432  int32 int = 11;
    4533  int64 long = 12;
    46   uint32 uint = 13;
    47   uint64 ulong = 14;
     34  uint32 u_int = 13;
     35  uint64 u_long = 14;
    4836  float float = 15;
    4937  double double = 16;
     38  bytes bytes = 17;
    5039}
    5140message TypeBox {
     
    6352message FloatArrayBox { repeated float values = 1; }
    6453message DoubleArrayBox { repeated double values = 1; }
    65 message ByteArrayBox { bytes values = 1; }
    6654
    6755// matrix boxes
  • branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs

    r15034 r15509  
    2323using System.Collections;
    2424using System.Collections.Generic;
    25 using System.ComponentModel;
    2625using System.Drawing;
    2726using System.Drawing.Imaging;
     
    3029using System.Linq;
    3130using System.Reflection;
    32 using Google.ProtocolBuffers;
     31using Google.Protobuf;
    3332
    3433namespace HeuristicLab.Persistence {
     
    4039
    4140    public override Box ToBox(object o, Mapper mapper) {
    42       var box = Box.CreateBuilder();
    43       box.TransformerId = mapper.GetTransformerId(this);
    44       box.TypeId = mapper.GetBoxId(o.GetType());
     41      var box = new Box {
     42        TransformerId = mapper.GetTransformerId(this),
     43        TypeId = mapper.GetBoxId(o.GetType())
     44      };
    4545      Populate(box, (T)o, mapper);
    46       return box.Build();
    47     }
     46      return box;
     47    }
     48
    4849    public override object ToObject(Box box, Mapper mapper) {
    4950      return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
    5051    }
    51     protected abstract void Populate(Box.Builder box, T value, Mapper mapper);
     52
     53    protected abstract void Populate(Box box, T value, Mapper mapper);
    5254    protected abstract T Extract(Box box, Type type, Mapper mapper);
    5355  }
    5456
    55   #region Scalar Box Transformers
    56   [StorableType("4b800c20-e93d-4186-9ccc-9e8081c028bb")]
    57   public abstract class BoolBoxTransformer<T> : BoxTransformer<T> {
    58     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    59       var b = BoolBox.CreateBuilder();
    60       b.Value = ToBoxType(value, mapper);
    61       box.SetExtension<BoolBox>(BoolBox.Bool, b.Build());
    62     }
    63     protected override T Extract(Box box, Type type, Mapper mapper) {
    64       return ToValueType(box.GetExtension(BoolBox.Bool).Value, type, mapper);
    65     }
    66     protected abstract bool ToBoxType(T value, Mapper mapper);
    67     protected abstract T ToValueType(bool value, Type type, Mapper mapper);
    68   }
    69   [StorableType("72b92810-3eee-4a35-b87a-0a9b06b58945")]
    70   public abstract class IntBoxTransformer<T> : BoxTransformer<T> {
    71     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    72       var b = IntBox.CreateBuilder();
    73       b.Value = ToBoxType(value, mapper);
    74       box.SetExtension<IntBox>(IntBox.Int, b.Build());
    75     }
    76     protected override T Extract(Box box, Type type, Mapper mapper) {
    77       return ToValueType(box.GetExtension(IntBox.Int).Value, type, mapper);
    78     }
    79     protected abstract int ToBoxType(T value, Mapper mapper);
    80     protected abstract T ToValueType(int value, Type type, Mapper mapper);
    81   }
    82   [StorableType("e7344a71-276d-4fc7-9d80-1f0a8b10dde5")]
    83   public abstract class LongBoxTransformer<T> : BoxTransformer<T> {
    84     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    85       var b = LongBox.CreateBuilder();
    86       b.Value = ToBoxType(value, mapper);
    87       box.SetExtension<LongBox>(LongBox.Long, b.Build());
    88     }
    89     protected override T Extract(Box box, Type type, Mapper mapper) {
    90       return ToValueType(box.GetExtension(LongBox.Long).Value, type, mapper);
    91     }
    92     protected abstract long ToBoxType(T value, Mapper mapper);
    93     protected abstract T ToValueType(long value, Type type, Mapper mapper);
    94   }
    95   [StorableType("76833301-5d1d-436d-86f6-6cfe1830405e")]
    96   public abstract class UnsignedIntBoxTransformer<T> : BoxTransformer<T> {
    97     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    98       var b = UnsignedIntBox.CreateBuilder();
    99       b.Value = ToBoxType(value, mapper);
    100       box.SetExtension<UnsignedIntBox>(UnsignedIntBox.UnsignedInt, b.Build());
    101     }
    102     protected override T Extract(Box box, Type type, Mapper mapper) {
    103       return ToValueType(box.GetExtension(UnsignedIntBox.UnsignedInt).Value, type, mapper);
    104     }
    105     protected abstract uint ToBoxType(T value, Mapper mapper);
    106     protected abstract T ToValueType(uint value, Type type, Mapper mapper);
    107   }
    108   [StorableType("4eb19b56-7ac7-497c-b25c-a860d3d72565")]
    109   public abstract class UnsignedLongBoxTransformer<T> : BoxTransformer<T> {
    110     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    111       var b = UnsignedLongBox.CreateBuilder();
    112       b.Value = ToBoxType(value, mapper);
    113       box.SetExtension<UnsignedLongBox>(UnsignedLongBox.UnsignedLong, b.Build());
    114     }
    115     protected override T Extract(Box box, Type type, Mapper mapper) {
    116       return ToValueType(box.GetExtension(UnsignedLongBox.UnsignedLong).Value, type, mapper);
    117     }
    118     protected abstract ulong ToBoxType(T value, Mapper mapper);
    119     protected abstract T ToValueType(ulong value, Type type, Mapper mapper);
    120   }
    121   [StorableType("1a6613b2-772f-4334-b688-8b2a8483123b")]
    122   public abstract class FloatBoxTransformer<T> : BoxTransformer<T> {
    123     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    124       var b = FloatBox.CreateBuilder();
    125       b.Value = ToBoxType(value, mapper);
    126       box.SetExtension<FloatBox>(FloatBox.Float, b.Build());
    127     }
    128     protected override T Extract(Box box, Type type, Mapper mapper) {
    129       return ToValueType(box.GetExtension(FloatBox.Float).Value, type, mapper);
    130     }
    131     protected abstract float ToBoxType(T value, Mapper mapper);
    132     protected abstract T ToValueType(float value, Type type, Mapper mapper);
    133   }
    134   [StorableType("c7fee156-6310-42a6-9f07-838cef8f405e")]
    135   public abstract class DoubleBoxTransformer<T> : BoxTransformer<T> {
    136     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    137       var b = DoubleBox.CreateBuilder();
    138       b.Value = ToBoxType(value, mapper);
    139       box.SetExtension<DoubleBox>(DoubleBox.Double, b.Build());
    140     }
    141     protected override T Extract(Box box, Type type, Mapper mapper) {
    142       return ToValueType(box.GetExtension(DoubleBox.Double).Value, type, mapper);
    143     }
    144     protected abstract double ToBoxType(T value, Mapper mapper);
    145     protected abstract T ToValueType(double value, Type type, Mapper mapper);
    146   }
    147   [StorableType("f7ea684c-8784-4939-80d4-318558a8b4a4")]
    148   public abstract class StringBoxTransformer<T> : BoxTransformer<T> {
    149     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    150       var b = StringBox.CreateBuilder();
    151       b.Value = ToBoxType(value, mapper);
    152       box.SetExtension<StringBox>(StringBox.String, b.Build());
    153     }
    154     protected override T Extract(Box box, Type type, Mapper mapper) {
    155       return ToValueType(box.GetExtension(StringBox.String).Value, type, mapper);
    156     }
    157     protected abstract string ToBoxType(T value, Mapper mapper);
    158     protected abstract T ToValueType(string value, Type type, Mapper mapper);
    159   }
    160   [StorableType("cb1680ec-3141-437d-b28d-f17595ca6815")]
    161   public abstract class BytesBoxTransformer<T> : BoxTransformer<T> {
    162     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    163       var b = BytesBox.CreateBuilder();
    164       b.Value = ByteString.CopyFrom(ToBoxType(value, mapper));
    165       box.SetExtension<BytesBox>(BytesBox.Bytes, b.Build());
    166     }
    167     protected override T Extract(Box box, Type type, Mapper mapper) {
    168       return ToValueType(box.GetExtension(BytesBox.Bytes).Value.ToByteArray(), type, mapper);
    169     }
    170     protected abstract byte[] ToBoxType(T value, Mapper mapper);
    171     protected abstract T ToValueType(byte[] value, Type type, Mapper mapper);
    172   }
    173   #endregion
    174 
    175   #region Array Box Transformers
    176   [StorableType("a6840c61-cf07-4e0a-a13c-392565e7326e")]
    177   public abstract class ByteArrayBoxTransformer<T> : BoxTransformer<T> {
    178     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    179       var b = ByteArrayBox.CreateBuilder();
    180       b.SetValues(ToByteString(value));
    181       box.SetExtension(ByteArrayBox.ByteArray, b.Build());
    182     }
    183     protected override T Extract(Box box, Type type, Mapper mapper) {
    184       return FromByteString(box.GetExtension(ByteArrayBox.ByteArray).Values);
    185     }
    186     protected abstract ByteString ToByteString(T value);
    187     protected abstract T FromByteString(ByteString byteString);
    188   }
    189   [StorableType("543de8f9-bf32-431d-af52-8dd95cfd876f")]
    190   public abstract class BoolArrayBoxTransformer<T> : BoxTransformer<T> {
    191     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    192       var b = BoolArrayBox.CreateBuilder();
    193       b.AddRangeValues(ToBoxType(value, mapper));
    194       box.SetExtension<BoolArrayBox>(BoolArrayBox.BoolArray, b.Build());
    195     }
    196     protected override T Extract(Box box, Type type, Mapper mapper) {
    197       return ToValueType(box.GetExtension(BoolArrayBox.BoolArray).ValuesList, type, mapper);
    198     }
    199     protected abstract IEnumerable<bool> ToBoxType(T value, Mapper mapper);
    200     protected abstract T ToValueType(IEnumerable<bool> value, Type type, Mapper mapper);
    201   }
    202   [StorableType("fb338e93-09c1-4e6e-8731-c5fefbb7fa82")]
    203   public abstract class IntArrayBoxTransformer<T> : BoxTransformer<T> {
    204     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    205       var b = IntArrayBox.CreateBuilder();
    206       b.AddRangeValues(ToBoxType(value, mapper));
    207       box.SetExtension<IntArrayBox>(IntArrayBox.IntArray, b.Build());
    208     }
    209     protected override T Extract(Box box, Type type, Mapper mapper) {
    210       return ToValueType(box.GetExtension(IntArrayBox.IntArray).ValuesList, type, mapper);
    211     }
    212     protected abstract IEnumerable<int> ToBoxType(T value, Mapper mapper);
    213     protected abstract T ToValueType(IEnumerable<int> value, Type type, Mapper mapper);
    214   }
    215   [StorableType("f751fbbd-ddd9-4f22-bf5e-9336d8913ab0")]
    216   public abstract class LongArrayBoxTransformer<T> : BoxTransformer<T> {
    217     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    218       var b = LongArrayBox.CreateBuilder();
    219       b.AddRangeValues(ToBoxType(value, mapper));
    220       box.SetExtension<LongArrayBox>(LongArrayBox.LongArray, b.Build());
    221     }
    222     protected override T Extract(Box box, Type type, Mapper mapper) {
    223       return ToValueType(box.GetExtension(LongArrayBox.LongArray).ValuesList, type, mapper);
    224     }
    225     protected abstract IEnumerable<long> ToBoxType(T value, Mapper mapper);
    226     protected abstract T ToValueType(IEnumerable<long> value, Type type, Mapper mapper);
    227   }
    228   [StorableType("912793f8-0136-4621-880c-5d6da0bbefa5")]
    229   public abstract class UnsignedIntArrayBoxTransformer<T> : BoxTransformer<T> {
    230     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    231       var b = UnsignedIntArrayBox.CreateBuilder();
    232       b.AddRangeValues(ToBoxType(value, mapper));
    233       box.SetExtension<UnsignedIntArrayBox>(UnsignedIntArrayBox.UnsignedIntArray, b.Build());
    234     }
    235     protected override T Extract(Box box, Type type, Mapper mapper) {
    236       return ToValueType(box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray).ValuesList, type, mapper);
    237     }
    238     protected abstract IEnumerable<uint> ToBoxType(T value, Mapper mapper);
    239     protected abstract T ToValueType(IEnumerable<uint> value, Type type, Mapper mapper);
    240   }
    241   [StorableType("e9b844a1-9f14-438f-abd8-8af0fdb73d77")]
    242   public abstract class UnsignedLongArrayBoxTransformer<T> : BoxTransformer<T> {
    243     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    244       var b = UnsignedLongArrayBox.CreateBuilder();
    245       b.AddRangeValues(ToBoxType(value, mapper));
    246       box.SetExtension<UnsignedLongArrayBox>(UnsignedLongArrayBox.UnsignedLongArray, b.Build());
    247     }
    248     protected override T Extract(Box box, Type type, Mapper mapper) {
    249       return ToValueType(box.GetExtension(UnsignedLongArrayBox.UnsignedLongArray).ValuesList, type, mapper);
    250     }
    251     protected abstract IEnumerable<ulong> ToBoxType(T value, Mapper mapper);
    252     protected abstract T ToValueType(IEnumerable<ulong> value, Type type, Mapper mapper);
    253   }
    254   [StorableType("f08a787d-d695-44ee-a9ac-e8b966f98c34")]
    255   public abstract class FloatArrayBoxTransformer<T> : BoxTransformer<T> {
    256     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    257       var b = FloatArrayBox.CreateBuilder();
    258       b.AddRangeValues(ToBoxType(value, mapper));
    259       box.SetExtension<FloatArrayBox>(FloatArrayBox.FloatArray, b.Build());
    260     }
    261     protected override T Extract(Box box, Type type, Mapper mapper) {
    262       return ToValueType(box.GetExtension(FloatArrayBox.FloatArray).ValuesList, type, mapper);
    263     }
    264     protected abstract IEnumerable<float> ToBoxType(T value, Mapper mapper);
    265     protected abstract T ToValueType(IEnumerable<float> value, Type type, Mapper mapper);
    266   }
    267   [StorableType("622efa85-484e-459e-b79d-4462ba225394")]
    268   public abstract class DoubleArrayBoxTransformer<T> : BoxTransformer<T> {
    269     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    270       var b = DoubleArrayBox.CreateBuilder();
    271       b.AddRangeValues(ToBoxType(value, mapper));
    272       box.SetExtension<DoubleArrayBox>(DoubleArrayBox.DoubleArray, b.Build());
    273     }
    274     protected override T Extract(Box box, Type type, Mapper mapper) {
    275       return ToValueType(box.GetExtension(DoubleArrayBox.DoubleArray).ValuesList, type, mapper);
    276     }
    277     protected abstract IEnumerable<double> ToBoxType(T value, Mapper mapper);
    278     protected abstract T ToValueType(IEnumerable<double> value, Type type, Mapper mapper);
    279   }
    280   [StorableType("5dfba6f6-2762-4d08-9c34-f6d10cc20913")]
    281   public abstract class StringArrayBoxTransformer<T> : BoxTransformer<T> {
    282     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
    283       var b = StringArrayBox.CreateBuilder();
    284       b.AddRangeValues(ToBoxType(value, mapper));
    285       box.SetExtension<StringArrayBox>(StringArrayBox.StringArray, b.Build());
    286     }
    287     protected override T Extract(Box box, Type type, Mapper mapper) {
    288       return ToValueType(box.GetExtension(StringArrayBox.StringArray).ValuesList, type, mapper);
    289     }
    290     protected abstract IEnumerable<string> ToBoxType(T value, Mapper mapper);
    291     protected abstract T ToValueType(IEnumerable<string> value, Type type, Mapper mapper);
    292   }
    293   #endregion
    294 
    295   [Transformer("11B822C9-46A0-4B65-AE4A-D12F63DDE9F6", 50)]
    296   [StorableType("7d783c07-2e05-4d89-9c06-b243c546e667")]
     57  [Transformer("854156DA-2A37-450F-92ED-355FBBD8D131", 50)]
     58  [StorableType("D48991BB-1DDA-4D64-A2E6-5B5608F85F2A")]
    29759  internal sealed class TypeTransformer : Transformer {
    29860    public override bool CanTransformType(Type type) {
    29961      return typeof(Type).IsAssignableFrom(type);
    30062    }
     63
    30164    public override Box ToBox(object o, Mapper mapper) {
    302       var box = Box.CreateBuilder();
    303       box.TransformerId = mapper.GetTransformerId(this);
     65      var box = new Box {
     66        TransformerId = mapper.GetTransformerId(this)
     67      };
    30468      Populate(box, o, mapper);
    305       return box.Build();
    306     }
    307     private void Populate(Box.Builder box, object value, Mapper mapper) {
     69      return box;
     70    }
     71
     72    private void Populate(Box box, object value, Mapper mapper) {
    30873      var type = (Type)value;
    309       var typeBox = TypeBox.CreateBuilder();
     74      var typeBox = new TypeBox();
     75
    31076      if (type.IsGenericType) {
    31177        box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition());
    312         typeBox.AddRangeGenericTypeIds(type.GetGenericArguments().Select(t => mapper.GetBoxId(t)));
     78        typeBox.GenericTypeIds.AddRange(type.GetGenericArguments().Select(mapper.GetBoxId));
    31379      } else if (type.IsArray) {
    31480        box.TypeId = mapper.GetTypeId(typeof(Array));
    315         typeBox.AddGenericTypeIds(mapper.GetBoxId(type.GetElementType()));
     81        typeBox.GenericTypeIds.Add(mapper.GetBoxId(type.GetElementType()));
    31682      } else {
    31783        box.TypeId = mapper.GetTypeId(type);
     
    32086      if (StorableTypeAttribute.IsStorableType(type))
    32187        typeBox.Version = StorableTypeAttribute.GetStorableTypeAttribute(type).Version;
    322       box.SetExtension(TypeBox.Type, typeBox.Build());
    323     }
     88
     89      box.BoxId = mapper.GetTypeBoxId(typeBox);
     90    }
     91
    32492    public override object ToObject(Box box, Mapper mapper) {
    32593      return Extract(box, mapper.GetType(box.TypeId), mapper);
    32694    }
     95
    32796    private object Extract(Box box, Type type, Mapper mapper) {
    328       var b = box.GetExtension(TypeBox.Type);
     97      var typeBox = mapper.GetTypeBox(box.BoxId);
     98
    32999      if (type.IsGenericType) {
    330         return type.MakeGenericType(b.GenericTypeIdsList.Select(id => (Type)mapper.GetObject(id)).ToArray());
     100        return type.MakeGenericType(typeBox.GenericTypeIds.Select(id => (Type)mapper.GetObject(id)).ToArray());
    331101      } else if (type == typeof(Array)) {
    332         return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType();
     102        return ((Type)mapper.GetObject(typeBox.GenericTypeIds[0])).MakeArrayType();
    333103      } else {
    334        
     104
    335105        return type;
    336106      }
     
    338108  }
    339109
    340   #region Primitive Value Types
    341   [Transformer("268617FE-3F0F-4029-8248-EDA420901FB6", 10000)]
    342   [StorableType("320cba58-1aaf-492b-be3b-f59eea085ebe")]
    343   internal sealed class ObjectTransformer : BoxTransformer<object> {
    344     protected override void Populate(Box.Builder box, object value, Mapper mapper) { }
    345     protected override object Extract(Box box, Type type, Mapper mapper) { return new object(); }
    346   }
    347 
    348   [Transformer("9FA1C6A8-517E-4623-AC1B-7E9AEF6ED13D", 200)]
    349   [StorableType("be3c6d74-5c67-4a54-ab3c-f1040795d364")]
    350   internal sealed class BoolTransformer : BoolBoxTransformer<bool> {
    351     protected override bool ToBoxType(bool value, Mapper mapper) { return value; }
    352     protected override bool ToValueType(bool value, Type type, Mapper mapper) { return value; }
    353   }
    354 
    355   [Transformer("059633E9-12CB-43EC-8544-57746536E281", 201)]
    356   [StorableType("3f1e111d-3ea8-4318-884f-185ef96bdfe4")]
    357   internal sealed class ByteTransformer : UnsignedIntBoxTransformer<byte> {
    358     protected override uint ToBoxType(byte value, Mapper mapper) { return value; }
    359     protected override byte ToValueType(uint value, Type type, Mapper mapper) { return (byte)value; }
    360   }
    361 
    362   [Transformer("5DC2F3AC-0852-4B57-A861-D29CC814A94C", 202)]
    363   [StorableType("498da443-43d3-4bc4-9ee9-c41416bb5c6b")]
    364   internal sealed class SByteTransformer : IntBoxTransformer<sbyte> {
    365     protected override int ToBoxType(sbyte value, Mapper mapper) { return value; }
    366     protected override sbyte ToValueType(int value, Type type, Mapper mapper) { return (sbyte)value; }
    367   }
    368 
    369   [Transformer("B862E642-A94A-4870-8065-06126A35A9E1", 203)]
    370   [StorableType("9f9ea850-1dd5-4dc0-abb5-8e75b22a0ffe")]
    371   internal sealed class ShortTransformer : IntBoxTransformer<short> {
    372     protected override int ToBoxType(short value, Mapper mapper) { return value; }
    373     protected override short ToValueType(int value, Type type, Mapper mapper) { return (short)value; }
    374   }
    375 
    376   [Transformer("D1D3062D-F1BB-4189-AE50-D6986E1DEB4E", 204)]
    377   [StorableType("4b70fdb5-a2ed-4a08-ab17-10fb5db11ada")]
    378   internal sealed class UShortTransformer : UnsignedIntBoxTransformer<ushort> {
    379     protected override uint ToBoxType(ushort value, Mapper mapper) { return value; }
    380     protected override ushort ToValueType(uint value, Type type, Mapper mapper) { return (ushort)value; }
    381   }
    382 
    383   [Transformer("6C444645-3062-4D15-AD01-E6E1B0692A2B", 205)]
    384   [StorableType("fdf24c34-7c10-49bb-aad2-a668c1490381")]
    385   internal sealed class CharTransformer : UnsignedIntBoxTransformer<char> {
    386     protected override uint ToBoxType(char value, Mapper mapper) { return value; }
    387     protected override char ToValueType(uint value, Type type, Mapper mapper) { return (char)value; }
    388   }
    389 
    390   [Transformer("649E73B2-EFA6-4E01-BCB4-4B29D652C9CB", 206)]
    391   [StorableType("0b2bcdf7-5787-4027-acd4-46f5f7641bff")]
    392   internal sealed class IntTransformer : IntBoxTransformer<int> {
    393     protected override int ToBoxType(int value, Mapper mapper) { return value; }
    394     protected override int ToValueType(int value, Type type, Mapper mapper) { return value; }
    395   }
    396 
    397   [Transformer("BCF25010-81A2-49BC-88CC-407D3F393D5B", 207)]
    398   [StorableType("eec933ec-f705-435e-9b7e-e4fc4d90c21e")]
    399   internal sealed class UIntTransformer : UnsignedIntBoxTransformer<uint> {
    400     protected override uint ToBoxType(uint value, Mapper mapper) { return value; }
    401     protected override uint ToValueType(uint value, Type type, Mapper mapper) { return value; }
    402   }
    403 
    404   [Transformer("B6F6ACAE-755C-47EE-B8BF-7CDECBE19C30", 208)]
    405   [StorableType("b0edffdd-8a00-48e1-a7a1-808ddec3b933")]
    406   internal sealed class LongTransformer : LongBoxTransformer<long> {
    407     protected override long ToBoxType(long value, Mapper mapper) { return value; }
    408     protected override long ToValueType(long value, Type type, Mapper mapper) { return value; }
    409   }
    410 
    411   [Transformer("82333ACA-F041-44E0-B365-27C399594BA7", 209)]
    412   [StorableType("0ebd1d6b-aa2d-442b-b524-68558d77e22e")]
    413   internal sealed class ULongTransformer : UnsignedLongBoxTransformer<ulong> {
    414     protected override ulong ToBoxType(ulong value, Mapper mapper) { return value; }
    415     protected override ulong ToValueType(ulong value, Type type, Mapper mapper) { return value; }
    416   }
    417 
    418   [Transformer("8FE91ECF-2261-4934-BECD-C38923B7A703", 210)]
    419   [StorableType("d9f05b32-218f-4b8e-9ec7-ab5dcbbaf0fc")]
    420   internal sealed class FloatTransformer : FloatBoxTransformer<float> {
    421     protected override float ToBoxType(float value, Mapper mapper) { return value; }
    422     protected override float ToValueType(float value, Type type, Mapper mapper) { return value; }
    423   }
    424 
    425   [Transformer("070D23EA-7F38-46B7-A667-219BEF914E49", 211)]
    426   [StorableType("70b79b46-2713-42ac-ace6-a55ffb0624be")]
    427   internal sealed class DoubleTransformer : DoubleBoxTransformer<double> {
    428     protected override double ToBoxType(double value, Mapper mapper) { return value; }
    429     protected override double ToValueType(double value, Type type, Mapper mapper) { return value; }
    430   }
    431 
    432   [Transformer("BA55C7A6-C91E-4351-A889-E4A7E647F16D", 212)]
    433   [StorableType("4ed946fd-aac8-407b-bb9e-093048024d15")]
    434   internal sealed class DateTimeTransformer : LongBoxTransformer<DateTime> {
    435     protected override long ToBoxType(DateTime value, Mapper mapper) { return value.Ticks; }
    436     protected override DateTime ToValueType(long value, Type type, Mapper mapper) { return new DateTime(value); }
    437   }
    438 
    439   [Transformer("0C91441B-2D97-432B-B493-D6EC483FC5AD", 213)]
    440   [StorableType("bbc20151-b695-43dc-a38a-a610c8410fd2")]
    441   internal sealed class TimeSpanTransformer : LongBoxTransformer<TimeSpan> {
    442     protected override long ToBoxType(TimeSpan value, Mapper mapper) { return value.Ticks; }
    443     protected override TimeSpan ToValueType(long value, Type type, Mapper mapper) { return new TimeSpan(value); }
    444   }
    445 
    446   [Transformer("2E6D4A40-B4BE-425F-8E35-2D7C00054639", 215)]
    447   [StorableType("11a33d00-5edc-4c49-884a-9f2809c23b30")]
    448   internal sealed class PointTransformer : IntArrayBoxTransformer<Point> {
    449     protected override IEnumerable<int> ToBoxType(Point value, Mapper mapper) { return new int[] { value.X, value.Y }; }
    450     protected override Point ToValueType(IEnumerable<int> value, Type type, Mapper mapper) { return new Point(value.ElementAt(0), value.ElementAt(1)); }
    451   }
    452 
    453   [Transformer("97B5CFC8-CDFA-4EB5-B4CD-5B3CFA5CD844", 216)]
    454   [StorableType("993238c2-a2ed-4e0d-84ae-ad025f2f20f4")]
    455   internal sealed class KeyValuePairTransformer : BoxTransformer<object> {
     110  [Transformer("4C610596-5234-4C49-998E-30007D64492E", 100)]
     111  [StorableType("69870239-00B7-4C9D-AF0B-14208069FAC8")]
     112  internal sealed class StringBoxTransformer : BoxTransformer<string> {
     113    protected override void Populate(Box box, string value, Mapper mapper) { box.UInt = mapper.GetStringId(value); }
     114    protected override string Extract(Box box, Type type, Mapper mapper) { return mapper.GetString(box.UInt); }
     115  }
     116
     117  [Transformer("58E69402-2533-426A-B9B5-9F2EB5241560", 101)]
     118  [StorableType("667182BB-D2D5-46C6-97CB-593CE1B19CBC")]
     119  internal sealed class BoolBoxTransformer : BoxTransformer<bool> {
     120    protected override void Populate(Box box, bool value, Mapper mapper) { box.Bool = value; }
     121    protected override bool Extract(Box box, Type type, Mapper mapper) { return box.Bool; }
     122  }
     123
     124  [Transformer("D78F3391-3CAE-4376-9348-7FB38A4DE0EB", 102)]
     125  [StorableType("1E75D1D8-3FAD-4D68-86BB-95DE981FDDD2")]
     126  internal sealed class IntBoxTransformer : BoxTransformer<int> {
     127    protected override void Populate(Box box, int value, Mapper mapper) { box.Int = value; }
     128    protected override int Extract(Box box, Type type, Mapper mapper) { return box.Int; }
     129  }
     130
     131  [Transformer("25881263-F452-492E-9FD1-24E1938B048B", 103)]
     132  [StorableType("7742A4A3-31B4-4449-9657-0D9F50F2382F")]
     133  internal sealed class UIntBoxTransformer : BoxTransformer<uint> {
     134    protected override void Populate(Box box, uint value, Mapper mapper) { box.UInt = value; }
     135    protected override uint Extract(Box box, Type type, Mapper mapper) { return box.UInt; }
     136  }
     137
     138  [Transformer("F4175165-382B-4B03-921E-5F923510FB1E", 104)]
     139  [StorableType("985427E0-E4F0-4182-8D30-63DA7FB69735")]
     140  internal sealed class LongBoxTransformer : BoxTransformer<long> {
     141    protected override void Populate(Box box, long value, Mapper mapper) { box.Long = value; }
     142    protected override long Extract(Box box, Type type, Mapper mapper) { return box.Long; }
     143  }
     144
     145  [Transformer("E8F63973-3C0C-4FA9-B068-40EF4463B30B", 105)]
     146  [StorableType("C9F95D84-BCDC-498E-A9AE-7187E483BBBA")]
     147  internal sealed class ULongBoxTransformer : BoxTransformer<ulong> {
     148    protected override void Populate(Box box, ulong value, Mapper mapper) { box.ULong = value; }
     149    protected override ulong Extract(Box box, Type type, Mapper mapper) { return box.ULong; }
     150  }
     151
     152  [Transformer("15489146-EA11-4B90-8020-AF5C10A2531C", 106)]
     153  [StorableType("AF1C5176-859C-423B-A2BF-2AEA4D0792C7")]
     154  internal sealed class FloatBoxTransformer : BoxTransformer<float> {
     155    protected override void Populate(Box box, float value, Mapper mapper) { box.Float = value; }
     156    protected override float Extract(Box box, Type type, Mapper mapper) { return box.Float; }
     157  }
     158
     159  [Transformer("91FD51F3-9C47-4944-AC85-273ED0561E87", 107)]
     160  [StorableType("4AB25AE9-2600-4041-8F31-C02CCE9A3BEC")]
     161  internal sealed class DoubleBoxTransformer : BoxTransformer<double> {
     162    protected override void Populate(Box box, double value, Mapper mapper) { box.Double = value; }
     163    protected override double Extract(Box box, Type type, Mapper mapper) { return box.Double; }
     164  }
     165
     166  [Transformer("BCB087EA-E477-47EB-9BCE-8C64BAC2F288", 108)]
     167  [StorableType("341C2F99-8849-408E-99AA-7700FE0FB789")]
     168  internal sealed class ByteBoxTransformer : BoxTransformer<byte> {
     169    protected override void Populate(Box box, byte value, Mapper mapper) { box.UInt = value; }
     170    protected override byte Extract(Box box, Type type, Mapper mapper) { return (byte)box.UInt; }
     171  }
     172
     173  [Transformer("B90F61D9-75D0-4CAC-AF93-B8C6AB68F642", 109)]
     174  [StorableType("FEC52DD5-A422-45C4-995F-09F3B0DEC13F")]
     175  internal sealed class SByteBoxTransformer : BoxTransformer<sbyte> {
     176    protected override void Populate(Box box, sbyte value, Mapper mapper) { box.Int = value; }
     177    protected override sbyte Extract(Box box, Type type, Mapper mapper) { return (sbyte)box.Int; }
     178  }
     179
     180  [Transformer("95EB44A4-EADD-4DA9-B60F-3262FAD6134B", 110)]
     181  [StorableType("48744968-15F2-4B22-AAF2-6C0910239384")]
     182  internal sealed class ShortBoxTransformer : BoxTransformer<short> {
     183    protected override void Populate(Box box, short value, Mapper mapper) { box.Int = value; }
     184    protected override short Extract(Box box, Type type, Mapper mapper) { return (short)box.Int; }
     185  }
     186
     187  [Transformer("E3A33614-9120-400E-BAD9-2594F6804DA8", 111)]
     188  [StorableType("DCF05BA3-3C57-4DBB-96B4-B2CE31CA60C5")]
     189  internal sealed class UShortBoxTransformer : BoxTransformer<ushort> {
     190    protected override void Populate(Box box, ushort value, Mapper mapper) { box.Int = value; }
     191    protected override ushort Extract(Box box, Type type, Mapper mapper) { return (ushort)box.Int; }
     192  }
     193
     194  [Transformer("C64EA534-E2E1-48F0-86C5-648AA02117BC", 112)]
     195  [StorableType("142980B3-A251-48D2-BF02-A66C483D6385")]
     196  internal sealed class CharBoxTransformer : BoxTransformer<char> {
     197    protected override void Populate(Box box, char value, Mapper mapper) { box.UInt = value; }
     198    protected override char Extract(Box box, Type type, Mapper mapper) { return (char)box.UInt; }
     199  }
     200
     201  [Transformer("D50C4782-7211-4476-B50F-7D3378EE3E53", 200)]
     202  [StorableType("4397B775-7D48-4C2A-8D28-ACC8C196CF70")]
     203  internal sealed class StringArrayBoxTransformer : BoxTransformer<string[]> {
     204    protected override void Populate(Box box, string[] value, Mapper mapper) {
     205      var unsignedIntArrayBox = new UnsignedIntArrayBox();
     206      unsignedIntArrayBox.Values.AddRange(value.Select(mapper.GetStringId));
     207      box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
     208    }
     209
     210    protected override string[] Extract(Box box, Type type, Mapper mapper) {
     211      var unsignedIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
     212      return unsignedIntArrayBox.Values.Select(mapper.GetString).ToArray();
     213    }
     214  }
     215
     216  [Transformer("C9CFA67B-DF13-4125-B781-98EC8F5E390F", 201)]
     217  [StorableType("9719DB59-C6BC-4788-BBB0-389A1B49CFEE")]
     218  internal sealed class BoolArrayBoxTransformer : BoxTransformer<bool[]> {
     219    protected override void Populate(Box box, bool[] value, Mapper mapper) {
     220      var boolArrayBox = new BoolArrayBox();
     221      boolArrayBox.Values.AddRange(value);
     222      box.BoxId = mapper.GetBoolArrayBoxId(boolArrayBox);
     223    }
     224
     225    protected override bool[] Extract(Box box, Type type, Mapper mapper) {
     226      var boolArrayBox = mapper.GetBoolArrayBox(box.BoxId);
     227      return boolArrayBox.Values.ToArray();
     228    }
     229  }
     230
     231  [Transformer("BA2E18F6-5C17-40CA-A5B8-5690C5EFE872", 202)]
     232  [StorableType("6548E9F0-621D-47BA-A605-8A47EF85C231")]
     233  internal sealed class IntArrayBoxTransformer : BoxTransformer<int[]> {
     234    protected override void Populate(Box box, int[] value, Mapper mapper) {
     235      var intArrayBox = new IntArrayBox();
     236      intArrayBox.Values.AddRange(value);
     237      box.BoxId = mapper.GetIntArrayBoxId(intArrayBox);
     238    }
     239
     240    protected override int[] Extract(Box box, Type type, Mapper mapper) {
     241      var intArrayBox = mapper.GetIntArrayBox(box.BoxId);
     242      return intArrayBox.Values.ToArray();
     243    }
     244  }
     245
     246  [Transformer("EEE7710D-86DE-47E1-887D-BDA2996B141E", 203)]
     247  [StorableType("4127B466-AFC0-4050-8C45-1376A0E3E016")]
     248  internal sealed class UnsignedIntArrayBoxTransformer : BoxTransformer<uint[]> {
     249    protected override void Populate(Box box, uint[] value, Mapper mapper) {
     250      var unsignedIntArrayBox = new UnsignedIntArrayBox();
     251      unsignedIntArrayBox.Values.AddRange(value);
     252      box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
     253    }
     254
     255    protected override uint[] Extract(Box box, Type type, Mapper mapper) {
     256      var unsignedIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
     257      return unsignedIntArrayBox.Values.ToArray();
     258    }
     259  }
     260
     261  [Transformer("557932AA-F023-477F-AAD0-5098E8B8CD56", 204)]
     262  [StorableType("C2ED50C8-C340-40C1-B00C-2F398EB709A0")]
     263  internal sealed class LongArrayBoxTransformer : BoxTransformer<long[]> {
     264    protected override void Populate(Box box, long[] value, Mapper mapper) {
     265      var longArrayBox = new LongArrayBox();
     266      longArrayBox.Values.AddRange(value);
     267      box.BoxId = mapper.GetLongArrayBoxId(longArrayBox);
     268    }
     269
     270    protected override long[] Extract(Box box, Type type, Mapper mapper) {
     271      var longArrayBox = mapper.GetLongArrayBox(box.BoxId);
     272      return longArrayBox.Values.ToArray();
     273    }
     274  }
     275
     276  [Transformer("CFF20DEE-2A55-4D04-B543-A4C7E0A8F7BF", 205)]
     277  [StorableType("641AE353-5373-4811-BACB-C13D3144809C")]
     278  internal sealed class UnsignedLongArrayBoxTransformer : BoxTransformer<ulong[]> {
     279    protected override void Populate(Box box, ulong[] value, Mapper mapper) {
     280      var unsignedLongArrayBox = new UnsignedLongArrayBox();
     281      unsignedLongArrayBox.Values.AddRange(value);
     282      box.BoxId = mapper.GetUnsignedLongArrayBoxId(unsignedLongArrayBox);
     283    }
     284
     285    protected override ulong[] Extract(Box box, Type type, Mapper mapper) {
     286      var unsignedLongArrayBox = mapper.GetUnsignedLongArrayBox(box.BoxId);
     287      return unsignedLongArrayBox.Values.ToArray();
     288    }
     289  }
     290
     291  [Transformer("2A0F766D-FE71-4415-A75F-A32FB8BB9E2D", 206)]
     292  [StorableType("AEE9384F-3857-4CE4-AE30-B99474F7A6C9")]
     293  internal sealed class FloatArrayBoxTransformer : BoxTransformer<float[]> {
     294    protected override void Populate(Box box, float[] value, Mapper mapper) {
     295      var floatArrayBox = new FloatArrayBox();
     296      floatArrayBox.Values.AddRange(value);
     297      box.BoxId = mapper.GetFloatArrayBoxId(floatArrayBox);
     298    }
     299
     300    protected override float[] Extract(Box box, Type type, Mapper mapper) {
     301      var floatArrayBox = mapper.GetFloatArrayBox(box.BoxId);
     302      return floatArrayBox.Values.ToArray();
     303    }
     304  }
     305
     306  [Transformer("192A8F7D-84C7-44BF-B0CA-AD387A241AAD", 207)]
     307  [StorableType("17D0BA74-CB84-405C-8DBB-D9E361274A0A")]
     308  internal sealed class DoubleArrayBoxTransformer : BoxTransformer<double[]> {
     309    protected override void Populate(Box box, double[] value, Mapper mapper) {
     310      var doubleArrayBox = new DoubleArrayBox();
     311      doubleArrayBox.Values.AddRange(value);
     312      box.BoxId = mapper.GetDoubleArrayBoxId(doubleArrayBox);
     313    }
     314
     315    protected override double[] Extract(Box box, Type type, Mapper mapper) {
     316      var doubleArrayBox = mapper.GetDoubleArrayBox(box.BoxId);
     317      return doubleArrayBox.Values.ToArray();
     318    }
     319  }
     320
     321  [Transformer("3A35CECE-9953-4C29-A796-A56C02D80A05", 208)]
     322  [StorableType("A076D11E-89AA-43C8-87F5-A0D0F52569EB")]
     323  internal sealed class ByteArrayBoxTransformer : BoxTransformer<byte[]> {
     324    protected override void Populate(Box box, byte[] value, Mapper mapper) {
     325      box.Bytes = ByteString.CopyFrom(value);
     326    }
     327
     328    protected override byte[] Extract(Box box, Type type, Mapper mapper) {
     329      return box.Bytes.ToArray();
     330    }
     331  }
     332
     333  [Transformer("880D4A63-6C77-4F9F-8F7C-2D365F0AE829", 209)]
     334  [StorableType("74F6FD4B-D7D7-43CD-B28B-3A775505FEE3")]
     335  internal sealed class SByteArrayBoxTransformer : BoxTransformer<sbyte[]> {
     336    protected override void Populate(Box box, sbyte[] value, Mapper mapper) {
     337      box.Bytes = ByteString.CopyFrom(value.Select(x => (byte)x).ToArray());
     338    }
     339
     340    protected override sbyte[] Extract(Box box, Type type, Mapper mapper) {
     341      return box.Bytes.Select(x => (sbyte)x).ToArray();
     342    }
     343  }
     344
     345  [Transformer("9786E711-7C1D-4761-BD6B-445793834264", 210)]
     346  [StorableType("5F32480E-AACB-4DB3-ADE3-1CF36E33C037")]
     347  internal sealed class ShortArrayBoxTransformer : BoxTransformer<short[]> {
     348    protected override void Populate(Box box, short[] value, Mapper mapper) {
     349      var res = new byte[value.Length * 2];
     350      for (int i = 0; i < value.Length; i++) {
     351        var bytes = BitConverter.GetBytes(value[i]);
     352        Array.Copy(bytes, 0, res, i * 2, 2);
     353      }
     354      box.Bytes = ByteString.CopyFrom(res);
     355    }
     356
     357    protected override short[] Extract(Box box, Type type, Mapper mapper) {
     358      var bytes = box.Bytes.ToArray();
     359      var res = new short[bytes.Length / 2];
     360      for (int i = 0; i < bytes.Length; i += 2) {
     361        res[i / 2] = BitConverter.ToInt16(bytes, i);
     362      }
     363      return res;
     364    }
     365  }
     366
     367  [Transformer("1AAC2625-356C-40BC-8CB4-15CB3D047EB8", 211)]
     368  [StorableType("C303B4CF-FFD0-47E2-9D94-07F2D558D17F")]
     369  internal sealed class UShortArrayTransformer : BoxTransformer<ushort[]> {
     370    protected override void Populate(Box box, ushort[] value, Mapper mapper) {
     371      var res = new byte[value.Length * 2];
     372      for (int i = 0; i < value.Length; i++) {
     373        var bytes = BitConverter.GetBytes(value[i]);
     374        Array.Copy(bytes, 0, res, i * 2, 2);
     375      }
     376      box.Bytes = ByteString.CopyFrom(res);
     377    }
     378
     379    protected override ushort[] Extract(Box box, Type type, Mapper mapper) {
     380      var bytes = box.Bytes.ToArray();
     381      var res = new ushort[bytes.Length / 2];
     382      for (int i = 0; i < bytes.Length; i += 2) {
     383        res[i / 2] = BitConverter.ToUInt16(bytes, i);
     384      }
     385      return res;
     386    }
     387  }
     388
     389  [Transformer("12F19098-5D49-4C23-8897-69087F1C146D", 212)]
     390  [StorableType("55F7C8B0-F2AA-4830-857D-6CE2807DA138")]
     391  internal sealed class CharArrayTransformer : BoxTransformer<char[]> {
     392    protected override void Populate(Box box, char[] value, Mapper mapper) {
     393      var res = new byte[value.Length * 2];
     394      for (int i = 0; i < value.Length; i++) {
     395        var bytes = BitConverter.GetBytes(value[i]);
     396        Array.Copy(bytes, 0, res, i * 2, 2);
     397      }
     398      box.Bytes = ByteString.CopyFrom(res);
     399    }
     400    protected override char[] Extract(Box box, Type type, Mapper mapper) {
     401      var bytes = box.Bytes.ToArray();
     402      var res = new char[bytes.Length / 2];
     403      for (int i = 0; i < bytes.Length; i += 2) {
     404        res[i / 2] = BitConverter.ToChar(bytes, i);
     405      }
     406      return res;
     407    }
     408  }
     409
     410  [Transformer("05AE4C5D-4D0C-47C7-B6D5-F04230C6F565", 301)]
     411  [StorableType("A74820C8-F400-462A-913A-610BB588D04A")]
     412  internal sealed class ArrayBoxTransformer : BoxTransformer<object> {
    456413    public override bool CanTransformType(Type type) {
    457       return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>));
    458     }
    459     protected override void Populate(Box.Builder box, object value, Mapper mapper) {
    460       var b = UnsignedIntArrayBox.CreateBuilder();
     414      return type.IsArray;
     415    }
     416
     417    protected override void Populate(Box box, object value, Mapper mapper) {
    461418      var type = value.GetType();
    462       var pair = new uint[2];
    463       pair[0] = mapper.GetBoxId(type.GetProperty("Key").GetValue(value));
    464       pair[1] = mapper.GetBoxId(type.GetProperty("Value").GetValue(value));
    465       b.AddRangeValues(pair);
    466       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build());
    467     }
     419      var array = (Array)value;
     420      var rank = array.Rank;
     421
     422      var uIntArrayBox = new UnsignedIntArrayBox();
     423      uIntArrayBox.Values.Add(mapper.GetBoxId(rank));
     424
     425      int[] lengths = new int[rank];
     426      int[] lowerBounds = new int[rank];
     427      for (int i = 0; i < rank; i++) {
     428        lengths[i] = array.GetLength(i);
     429        lowerBounds[i] = array.GetLowerBound(i);
     430      }
     431
     432      uIntArrayBox.Values.AddRange(lengths.Select(x => mapper.GetBoxId(x)));
     433      uIntArrayBox.Values.AddRange(lowerBounds.Select(x => mapper.GetBoxId(x)));
     434
     435      int[] positions = (int[])lowerBounds.Clone();
     436      while (positions[rank - 1] < lengths[rank - 1] + lowerBounds[rank - 1]) {
     437        uIntArrayBox.Values.Add(mapper.GetBoxId(array.GetValue(positions)));
     438        positions[0] += 1;
     439        for (int i = 0; i < rank - 1; i++) {
     440          if (positions[i] >= lowerBounds[i] + lengths[i]) {
     441            positions[i] = lowerBounds[i];
     442            positions[i + 1] += 1;
     443          } else {
     444            break;
     445          }
     446        }
     447      }
     448
     449      box.BoxId = mapper.GetUnsignedIntArrayBoxId(uIntArrayBox);
     450    }
     451
     452    protected override object Extract(Box box, Type type, Mapper mapper) {
     453      var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
     454      var rank = (int)mapper.GetObject(uIntArrayBox.Values[0]);
     455
     456      int[] lengths = new int[rank], lowerBounds = new int[rank];
     457      for (int i = 0; i < rank; i++)
     458        lengths[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1]);
     459      for (int i = 0; i < rank; i++)
     460        lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1 + rank]);
     461
     462      return Array.CreateInstance(type.GetElementType(), lengths, lowerBounds);
     463    }
     464
    468465    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    469       var b = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    470       var key = mapper.GetObject(b.GetValues(0));
    471       var val = mapper.GetObject(b.GetValues(1));
    472       var type = obj.GetType();
    473       //DataMemberAccessor.GenerateFieldSetter(type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance))(obj, key);
    474       //DataMemberAccessor.GenerateFieldSetter(type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance))(obj, val);
    475       type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, key);
    476       type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, val);
    477     }
     466      var array = (Array)obj;
     467      var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
     468      var rank = (int)mapper.GetObject(uIntArrayBox.Values[0]);
     469
     470      int[] lengths = new int[rank], lowerBounds = new int[rank];
     471      for (int i = 0; i < rank; i++)
     472        lengths[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1]);
     473      for (int i = 0; i < rank; i++)
     474        lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.Values[i + 1 + rank]);
     475
     476      int[] positions = (int[])lowerBounds.Clone();
     477      var e = uIntArrayBox.Values.Skip(1 + 2 * rank).GetEnumerator();
     478      while (e.MoveNext()) {
     479        int[] currentPositions = positions;
     480        array.SetValue(mapper.GetObject(e.Current), currentPositions);
     481        positions[0] += 1;
     482        for (int i = 0; i < rank - 1; i++) {
     483          if (positions[i] >= lengths[i] + lowerBounds[i]) {
     484            positions[i] = lowerBounds[i];
     485            positions[i + 1] += 1;
     486          } else {
     487            break;
     488          }
     489        }
     490      }
     491    }
     492  }
     493
     494  [Transformer("26AD5F85-1D77-4579-BCB9-CD409B48AC7A", 302)]
     495  [StorableType("A96E2C1E-EBDF-4D81-A0ED-91677BC84FEE")]
     496  internal sealed class EnumerableBoxTransformer : BoxTransformer<object> {
     497    private static readonly HashSet<Type> supportedTypes = new HashSet<Type> {
     498      typeof(Stack<>), typeof(Stack),
     499      typeof(Queue<>), typeof(Queue),
     500      typeof(HashSet<>),
     501      typeof(List<>), typeof(ArrayList)
     502    };
     503
     504    public override bool CanTransformType(Type type) {
     505      return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition()) || supportedTypes.Contains(type);
     506    }
     507
     508    protected override void Populate(Box box, object value, Mapper mapper) {
     509      var uIntArrayBox = new UnsignedIntArrayBox();
     510
     511      var type = value.GetType();
     512      var propertyInfo = type.GetProperty("Comparer");
     513      if (propertyInfo != null) {
     514        // TODO: where to store id for comparer box? (atm: first element in int array ...)
     515        var comparer = propertyInfo.GetValue(value);
     516        var comparerType = comparer.GetType();
     517        if (StorableTypeAttribute.IsStorableType(comparerType))
     518          uIntArrayBox.Values.Add(mapper.GetBoxId(comparer));
     519        else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
     520          throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
     521        else
     522          uIntArrayBox.Values.Add(mapper.GetBoxId(comparerType));
     523      }
     524
     525      foreach (var item in (IEnumerable)value)
     526        uIntArrayBox.Values.Add(mapper.GetBoxId(item));
     527
     528      box.BoxId = mapper.GetUnsignedIntArrayBoxId(uIntArrayBox);
     529    }
     530
    478531    protected override object Extract(Box box, Type type, Mapper mapper) {
    479532      return Activator.CreateInstance(type);
    480533    }
    481   }
    482 
    483   [Transformer("EBD8BF65-D97D-4FD4-BF4F-9D58A72B6249", 217)]
    484   [StorableType("b7725dfa-94fb-4169-b375-6e46b7ca4810")]
    485   internal sealed class DecimalTransformer : UnsignedIntBoxTransformer<decimal> {
    486     protected override uint ToBoxType(decimal value, Mapper mapper) {
    487       return mapper.GetStringId(FormatG30(value));
    488     }
    489     protected override decimal ToValueType(uint value, Type type, Mapper mapper) {
    490       var converter = TypeDescriptor.GetConverter(typeof(Font));
    491       return ParseG30(mapper.GetString(value));
    492     }
     534
     535    public override void FillFromBox(object obj, Box box, Mapper mapper) {
     536      var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
     537      var elements = uIntArrayBox.Values.Select(mapper.GetObject);
     538      var type = obj.GetType();
     539
     540      string methodName = string.Empty;
     541      if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Stack<>) || type == typeof(Stack)) {
     542        elements = elements.Reverse();
     543        methodName = "Push";
     544      } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Queue<>) || type == typeof(Queue)) {
     545        methodName = "Enqueue";
     546      } else {
     547        methodName = "Add";
     548        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) {
     549          var fieldInfo = type.GetField("m_comparer", BindingFlags.NonPublic | BindingFlags.Instance);
     550          var comparerObj = mapper.GetObject(uIntArrayBox.Values[0]);
     551          var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
     552          fieldInfo.SetValue(obj, comparer);
     553          elements = elements.Skip(1);
     554        }
     555      }
     556
     557      MethodInfo addMethod = type.GetMethod(methodName);
     558      foreach (var e in elements)
     559        addMethod.Invoke(obj, new[] { e });
     560    }
     561  }
     562
     563  [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 303)]
     564  [StorableType("BA53DF84-DC97-4D8D-A493-868972ED1002")]
     565  internal sealed class DictionaryTransformer : BoxTransformer<object> {
     566    public override bool CanTransformType(Type type) {
     567      return type.IsGenericType && typeof(Dictionary<,>) == type.GetGenericTypeDefinition();
     568    }
     569
     570    protected override void Populate(Box box, object value, Mapper mapper) {
     571      var dictionaryBox = new DictionaryBox();
     572      foreach (DictionaryEntry item in (IDictionary)value) {
     573        dictionaryBox.KeyValuePairs.Add(mapper.GetBoxId(item.Key), mapper.GetBoxId(item.Value));
     574      }
     575
     576      var type = value.GetType();
     577      var propertyInfo = type.GetProperty("Comparer");
     578      var comparer = propertyInfo.GetValue(value);
     579
     580      var comparerType = comparer.GetType();
     581      if (StorableTypeAttribute.IsStorableType(comparerType))
     582        dictionaryBox.ComparerId = mapper.GetBoxId(comparer);
     583      else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
     584        throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
     585      else
     586        dictionaryBox.ComparerId = mapper.GetBoxId(comparerType);
     587
     588      box.BoxId = mapper.GetDictionaryBoxId(dictionaryBox);
     589    }
     590
     591    protected override object Extract(Box box, Type type, Mapper mapper) {
     592      var dictionaryBox = mapper.GetDictionaryBox(box.BoxId);
     593      return Activator.CreateInstance(type, dictionaryBox.KeyValuePairs.Count);
     594    }
     595
     596    public override void FillFromBox(object obj, Box box, Mapper mapper) {
     597      var type = obj.GetType();
     598      var dictionaryBox = mapper.GetDictionaryBox(box.BoxId);
     599      var comparerObj = mapper.GetObject(dictionaryBox.ComparerId);
     600      var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
     601
     602      var fieldInfo = type.GetField("comparer", BindingFlags.NonPublic | BindingFlags.Instance);
     603      fieldInfo.SetValue(obj, comparer);
     604
     605      var addMethod = type.GetMethod("Add");
     606      foreach (var entry in dictionaryBox.KeyValuePairs) {
     607        var key = mapper.GetObject(entry.Key);
     608        var value = mapper.GetObject(entry.Value);
     609        addMethod.Invoke(obj, new[] { key, value });
     610      }
     611    }
     612
     613    [Transformer("93FF076B-BC4B-4C39-8C40-15E004468C98", 219)]
     614    [StorableType("F8A7DBB4-E1CE-4DB8-905E-F3A05F5CA000")]
     615    internal sealed class EnumTransformer : Transformer {
     616      public override bool CanTransformType(Type type) {
     617        return typeof(Enum).IsAssignableFrom(type);
     618      }
     619
     620      public override Box ToBox(object o, Mapper mapper) {
     621        var box = new Box {
     622          TransformerId = mapper.GetTransformerId(this),
     623          TypeId = mapper.GetStringId(o.GetType().AssemblyQualifiedName),
     624          UInt = mapper.GetStringId(Enum.Format(o.GetType(), o, "G")),
     625        };
     626        return box;
     627      }
     628
     629      public override object ToObject(Box box, Mapper mapper) {
     630        return Enum.Parse(Type.GetType(mapper.GetString(box.TypeId)), mapper.GetString(box.UInt));
     631      }
     632    }
     633
     634    [Transformer("268617FE-3F0F-4029-8248-EDA420901FB6", 10000)]
     635    [StorableType("320CBA58-1AAF-492B-BE3B-F59EEA085EBE")]
     636    internal sealed class ObjectBoxTransformer : BoxTransformer<object> {
     637      protected override void Populate(Box box, object value, Mapper mapper) { }
     638      protected override object Extract(Box box, Type type, Mapper mapper) { return new object(); }
     639    }
     640  }
     641
     642  [Transformer("90F9F16D-9F94-491B-AC3B-E1C6F3432127", 400)]
     643  [StorableType("C3C23FEE-DB96-4CEA-A38B-6BB73811F877")]
     644  internal sealed class DecimalBoxTransformer : BoxTransformer<decimal> {
     645    protected override decimal Extract(Box box, Type type, Mapper mapper) {
     646      return ParseG30(mapper.GetString(box.UInt));
     647    }
     648
     649    protected override void Populate(Box box, decimal value, Mapper mapper) {
     650      box.UInt = mapper.GetStringId(FormatG30(value));
     651    }
     652
    493653    private static decimal ParseG30(string s) {
    494654      decimal d;
     
    501661        string.Format("Invalid decimal G30 number format \"{0}\" could not be parsed", s));
    502662    }
     663
    503664    private static string FormatG30(decimal d) {
    504665      return d.ToString("g30", CultureInfo.InvariantCulture);
    505666    }
    506667  }
    507   #endregion
    508 
    509   #region String
    510   [Transformer("E75A594C-0034-4DAB-B28E-8F84F9F6DE8D", 218)]
    511   [StorableType("ba52fce8-bf0c-47ad-95dd-df5d9281942d")]
    512   internal sealed class StringTransformer : UnsignedIntBoxTransformer<string> {
    513     protected override uint ToBoxType(string value, Mapper mapper) { return mapper.GetStringId(value); }
    514     protected override string ToValueType(uint value, Type type, Mapper mapper) { return mapper.GetString(value); }
    515   }
    516   #endregion
    517 
    518   #region Enum
    519   [Transformer("93FF076B-BC4B-4C39-8C40-15E004468C98", 219)]
    520   [StorableType("f8a7dbb4-e1ce-4db8-905e-f3a05f5ca000")]
    521   internal sealed class EnumTransformer : Transformer {
     668
     669  [Transformer("1C6C350F-B2C8-40F0-A964-54DDB0D087A3", 401)]
     670  [StorableType("9D99D155-E3BB-40CE-AF64-6E153D876148")]
     671  internal sealed class DateTimeBoxTransformer : BoxTransformer<DateTime> {
     672    protected override void Populate(Box box, DateTime value, Mapper mapper) {
     673      box.Long = value.Ticks;
     674    }
     675
     676    protected override DateTime Extract(Box box, Type type, Mapper mapper) {
     677      return new DateTime(box.Long);
     678    }
     679  }
     680
     681  [Transformer("964074C9-4B82-4725-97AF-612A193EA5C6", 402)]
     682  [StorableType("9CA7C1F7-784C-48D5-A6F4-E1FD7B3A2FEC")]
     683  internal sealed class TimeSpanBoxTransformer : BoxTransformer<TimeSpan> {
     684    protected override void Populate(Box box, TimeSpan value, Mapper mapper) {
     685      box.Long = value.Ticks;
     686    }
     687
     688    protected override TimeSpan Extract(Box box, Type type, Mapper mapper) {
     689      return new TimeSpan(box.Long);
     690    }
     691  }
     692
     693  [Transformer("B0C0165B-6279-4CC3-8DB7-D36898BFBC38", 403)]
     694  [StorableType("ED6B7AE1-CE2B-4891-9BF3-72F5D1D67D93")]
     695  internal sealed class PointTransformer : BoxTransformer<Point> {
     696    protected override void Populate(Box box, Point value, Mapper mapper) {
     697      var intArrayBox = new IntArrayBox();
     698      intArrayBox.Values.AddRange(new[] { value.X, value.Y });
     699      box.BoxId = mapper.GetIntArrayBoxId(intArrayBox);
     700    }
     701
     702    protected override Point Extract(Box box, Type type, Mapper mapper) {
     703      var intArrayBox = mapper.GetIntArrayBox(box.BoxId);
     704      return new Point(intArrayBox.Values[0], intArrayBox.Values[1]);
     705    }
     706  }
     707
     708  [Transformer("D0ADB806-2DFD-459D-B5DA-14B5F1152534", 404)]
     709  [StorableType("B13D6153-E71D-4B76-9893-81D3570403E8")]
     710  internal sealed class BitmapTransformer : BoxTransformer<Bitmap> {
     711    protected override void Populate(Box box, Bitmap value, Mapper mapper) {
     712      lock (value)
     713        using (var ms = new MemoryStream()) {
     714          value.Save(ms, ImageFormat.Png);
     715          box.Bytes = ByteString.CopyFrom(ms.ToArray());
     716        }
     717    }
     718
     719    protected override Bitmap Extract(Box box, Type type, Mapper mapper) {
     720      using (var ms = new MemoryStream()) {
     721        ms.Write(box.Bytes.ToArray(), 0, box.Bytes.Length);
     722        ms.Seek(0, SeekOrigin.Begin);
     723        return new Bitmap(ms);
     724      }
     725    }
     726  }
     727
     728  [Transformer("AFF27987-3301-4D70-9601-EFCA31BDA0DB", 405)]
     729  [StorableType("B9F9A371-4DCB-478B-B0D4-6F87A15C02B5")]
     730  internal sealed class FontTransformer : BoxTransformer<Font> {
     731    protected override void Populate(Box box, Font value, Mapper mapper) {
     732      var unsignedIntArrayBox = new UnsignedIntArrayBox();
     733      unsignedIntArrayBox.Values.Add(mapper.GetStringId(GetFontFamilyName(value.FontFamily)));
     734      unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.Size));
     735      unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.Style));
     736      unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.Unit));
     737      unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.GdiCharSet));
     738      unsignedIntArrayBox.Values.Add(mapper.GetBoxId(value.GdiVerticalFont));
     739      box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
     740    }
     741
     742    protected override Font Extract(Box box, Type type, Mapper mapper) {
     743      var value = mapper.GetUnsignedIntArrayBox(box.BoxId);
     744      var fontData = value.Values;
     745      return new Font(
     746        GetFontFamily(mapper.GetString(fontData[0])),
     747        (float)mapper.GetObject(fontData[1]),
     748        (FontStyle)mapper.GetObject(fontData[2]),
     749        (GraphicsUnit)mapper.GetObject(fontData[3]),
     750        (byte)mapper.GetObject(fontData[4]),
     751        (bool)mapper.GetObject(fontData[5])
     752      );
     753    }
     754
     755    public const string GENERIC_MONOSPACE_NAME = "_GenericMonospace";
     756    public const string GENERIC_SANS_SERIF_NAME = "_GenericSansSerif";
     757    public const string GENERIC_SERIF_NAME = "_GenericSerif";
     758
     759    public static FontFamily GetFontFamily(string name) {
     760      if (name == GENERIC_MONOSPACE_NAME) return FontFamily.GenericMonospace;
     761      if (name == GENERIC_SANS_SERIF_NAME) return FontFamily.GenericSansSerif;
     762      if (name == GENERIC_SERIF_NAME) return FontFamily.GenericSerif;
     763      return new FontFamily(name);
     764    }
     765
     766    public static string GetFontFamilyName(FontFamily ff) {
     767      if (ff.Equals(FontFamily.GenericMonospace)) return GENERIC_MONOSPACE_NAME;
     768      if (ff.Equals(FontFamily.GenericSansSerif)) return GENERIC_SANS_SERIF_NAME;
     769      if (ff.Equals(FontFamily.GenericSerif)) return GENERIC_SERIF_NAME;
     770      return ff.Name;
     771    }
     772  }
     773
     774  [Transformer("D912D573-CE41-40B8-8F95-646C183662F6", 406)]
     775  [StorableType("3ED2C12F-BE41-45F5-AA0A-C2F23EB99FBD")]
     776  internal sealed class KeyValuePairBoxTransformer : BoxTransformer<object> {
    522777    public override bool CanTransformType(Type type) {
    523       return typeof(Enum).IsAssignableFrom(type);
    524     }
    525 
    526     public override Box ToBox(object o, Mapper mapper) {
    527       var boxBuilder = Box.CreateBuilder();
    528       var enumBuilder = new UnsignedIntBox.Builder();
    529 
    530       boxBuilder.TransformerId = mapper.GetTransformerId(this);
    531       boxBuilder.TypeId = mapper.GetStringId(o.GetType().AssemblyQualifiedName);
    532       enumBuilder.Value = mapper.GetStringId(Enum.Format(o.GetType(), o, "G"));
    533 
    534       boxBuilder.SetExtension(UnsignedIntBox.UnsignedInt, enumBuilder.Build());
    535       return boxBuilder.Build();
    536     }
    537 
    538     public override object ToObject(Box box, Mapper mapper) {
    539       uint value = box.GetExtension(UnsignedIntBox.UnsignedInt).Value;
    540       return Enum.Parse(Type.GetType(mapper.GetString(box.TypeId)), mapper.GetString(value));
    541     }
    542   }
    543   #endregion
    544 
    545   #region Struct
    546   [Transformer("89DAAFC5-726C-48D4-A4E0-2B0D27329642", 220)]
    547   [StorableType("c3c4ad38-7110-439c-b73c-d33466db3db4")]
    548   internal sealed class StructTransformer : Transformer {
     778      return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>));
     779    }
     780
     781    protected override void Populate(Box box, object value, Mapper mapper) {
     782      var unsignedIntArrayBox = new UnsignedIntArrayBox();
     783      var type = value.GetType();
     784      var pair = new uint[2];
     785      pair[0] = mapper.GetBoxId(type.GetProperty("Key").GetValue(value));
     786      pair[1] = mapper.GetBoxId(type.GetProperty("Value").GetValue(value));
     787      unsignedIntArrayBox.Values.AddRange(pair);
     788      box.BoxId = mapper.GetUnsignedIntArrayBoxId(unsignedIntArrayBox);
     789    }
     790
     791    public override void FillFromBox(object obj, Box box, Mapper mapper) {
     792      var b = mapper.GetUnsignedIntArrayBox(box.BoxId);
     793      var key = mapper.GetObject(b.Values[0]);
     794      var val = mapper.GetObject(b.Values[1]);
     795      var type = obj.GetType();
     796      //DataMemberAccessor.GenerateFieldSetter(type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance))(obj, key);
     797      //DataMemberAccessor.GenerateFieldSetter(type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance))(obj, val);
     798      type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, key);
     799      type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, val);
     800    }
     801
     802    protected override object Extract(Box box, Type type, Mapper mapper) {
     803      return Activator.CreateInstance(type);
     804    }
     805  }
     806
     807  [Transformer("BBA08D33-FDA4-4EB6-8D94-9BF3D30C3E11", 407)]
     808  [StorableType("B0333A12-7D91-47A5-ACD4-49E43E5A18DC")]
     809  internal sealed class TupleBoxTransformer : BoxTransformer<object> {
     810    private static readonly HashSet<Type> supportedTypes = new HashSet<Type> {
     811      typeof(Tuple<>), typeof(Tuple<,>), typeof(Tuple<,,>), typeof(Tuple<,,,>),
     812      typeof(Tuple<,,,,>), typeof(Tuple<,,,,,>), typeof(Tuple<,,,,,,>), typeof(Tuple<,,,,,,,>)
     813    };
     814
     815    public override bool CanTransformType(Type type) {
     816      return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition());
     817    }
     818
     819    protected override void Populate(Box box, object value, Mapper mapper) {
     820      var type = value.GetType();
     821      var uIntArrayBox = new UnsignedIntArrayBox();
     822      for (int i = 1; i <= type.GetGenericArguments().Length; i++) {
     823        string name = string.Format("Item{0}", i);
     824        uIntArrayBox.Values.Add(mapper.GetBoxId(type.GetProperty(name).GetValue(value)));
     825      }
     826      box.BoxId = mapper.GetUnsignedIntArrayBoxId(uIntArrayBox);
     827    }
     828
     829    protected override object Extract(Box box, Type type, Mapper mapper) {
     830      var defaultValues = type.GetGenericArguments().Select(x =>
     831        x.IsValueType ? Activator.CreateInstance(x) : null
     832      ).ToArray();
     833      return Activator.CreateInstance(type, defaultValues);
     834    }
     835
     836    public override void FillFromBox(object obj, Box box, Mapper mapper) {
     837      var uIntArrayBox = mapper.GetUnsignedIntArrayBox(box.BoxId);
     838      var elements = uIntArrayBox.Values.Select(mapper.GetObject).ToArray();
     839      var type = obj.GetType();
     840      for (int i = 1; i <= elements.Length; i++) {
     841        string name = string.Format("m_Item{0}", i);
     842        DataMemberAccessor.GenerateFieldSetter(type.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance))(obj, elements[i - 1]);
     843      }
     844    }
     845  }
     846
     847  [Transformer("731F9A18-6BF4-43BE-95CF-8205552C9B70", 500)]
     848  [StorableType("73FCDE79-436D-476E-B2EA-A7A1A4A810B5")]
     849  internal sealed class StructBoxTransformer : BoxTransformer<object> {
    549850    public override bool CanTransformType(Type type) {
    550851      return type.IsValueType && !type.IsPrimitive && !type.IsEnum && type.IsSealed;
    551852    }
    552     public override Box ToBox(object o, Mapper mapper) {
    553       var box = Box.CreateBuilder();
    554       box.TransformerId = mapper.GetTransformerId(this);
    555       Populate(box, o, mapper);
    556       return box.Build();
    557     }
    558     public override object ToObject(Box box, Mapper mapper) {
    559       return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
    560     }
    561     private void Populate(Box.Builder box, object value, Mapper mapper) {
    562       var b = StorableClassBox.CreateBuilder();
     853
     854    protected override void Populate(Box box, object value, Mapper mapper) {
     855      var b = new StorableClassBox();
    563856      var type = value.GetType();
    564857
     
    569862      }
    570863
    571       b.AddRangeKeyIds(components.Keys);
    572       b.AddRangeValueIds(components.Values);
    573 
    574       box.TypeId = mapper.GetBoxId(type);
    575       box.SetExtension(StorableClassBox.StorableClass, b.Build());
    576     }
    577     private object Extract(Box box, Type type, Mapper mapper) {
    578       var data = box.GetExtension(StorableClassBox.StorableClass);
     864      foreach (var component in components) {
     865        b.KeyValuePairs.Add(component.Key, component.Value);
     866      }
     867
     868      box.BoxId = mapper.GetStorableClassBoxId(b);
     869    }
     870
     871    protected override object Extract(Box box, Type type, Mapper mapper) {
     872      var data = mapper.GetStorableClassBox(box.BoxId);
    579873      var obj = Activator.CreateInstance(type);
    580874
    581875      var components = new Dictionary<uint, uint>();
    582       for (int i = 0; i < data.KeyIdsList.Count; i++) {
    583         components.Add(data.KeyIdsList[i], data.ValueIdsList[i]);
     876      foreach (var kvp in data.KeyValuePairs) {
     877        components.Add(kvp.Key, kvp.Value);
    584878      }
    585879
     
    600894      return obj;
    601895    }
    602   }
    603   #endregion
    604 
    605   #region Tuple
    606   [Transformer("63A19D57-EEEF-4346-9F06-B35B15EBFFA3", 221)]
    607   [StorableType("ab537f25-dc21-4585-b743-0350a5cf1e54")]
    608   internal sealed class TupleTransformer : Transformer {
    609     private static readonly HashSet<Type> supportedTypes = new HashSet<Type> {
    610       typeof(Tuple<>), typeof(Tuple<,>), typeof(Tuple<,,>), typeof(Tuple<,,,>),
    611       typeof(Tuple<,,,,>), typeof(Tuple<,,,,,>), typeof(Tuple<,,,,,,>), typeof(Tuple<,,,,,,,>)
    612     };
     896
     897  }
     898
     899  [Transformer("78556C88-0FEE-4602-95C7-A469B2DDB468", 600)]
     900  [StorableType("3A578289-43CA-40F8-9F1E-2BDD255CB8FB")]
     901  internal sealed class StorableTypeBoxTransformer : BoxTransformer<object> {
    613902    public override bool CanTransformType(Type type) {
    614       return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition());
    615     }
    616     public override Box ToBox(object o, Mapper mapper) {
    617       var box = Box.CreateBuilder();
    618       box.TransformerId = mapper.GetTransformerId(this);
    619       Populate(box, o, mapper);
    620       return box.Build();
    621     }
    622     private void Populate(Box.Builder box, object value, Mapper mapper) {
     903      return StorableTypeAttribute.IsStorableType(type) && !type.IsValueType && !type.IsEnum || // don't transform structs or enums
     904        type.BaseType != null && CanTransformType(type.BaseType);
     905    }
     906
     907    protected override void Populate(Box box, object value, Mapper mapper) {
     908      var b = new StorableClassBox();
    623909      var type = value.GetType();
    624       var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
    625       for (int i = 1; i <= type.GetGenericArguments().Length; i++) {
    626         string name = string.Format("Item{0}", i);
    627         uIntArrayBox.AddValues(mapper.GetBoxId(type.GetProperty(name).GetValue(value)));
    628       }
    629       box.TypeId = mapper.GetBoxId(type);
    630       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
    631     }
    632     public override object ToObject(Box box, Mapper mapper) {
    633       var type = (Type)mapper.GetObject(box.TypeId);
    634       var defaultValues = type.GetGenericArguments().Select(x =>
    635         x.IsValueType ? Activator.CreateInstance(x) : null
    636       ).ToArray();
    637       return Activator.CreateInstance(type, defaultValues);
    638     }
     910      var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
     911
     912      var emptyArgs = new object[0];
     913      foreach (var hook in typeInfo.BeforeSerializationHooks) {
     914        hook.Invoke(value, emptyArgs);
     915      }
     916
     917      var components = new Dictionary<uint, uint>();
     918      foreach (var componentInfo in typeInfo.Fields) {
     919        var field = (FieldInfo)componentInfo.MemberInfo;
     920        var component = mapper.GetBoxId(field.GetValue(value));
     921        components.Add(mapper.GetStringId(componentInfo.Name), component);
     922      }
     923
     924      foreach (var componentInfo in typeInfo.Properties.Where(x => x.Readable)) {
     925        var property = (PropertyInfo)componentInfo.MemberInfo;
     926        var component = mapper.GetBoxId(property.GetValue(value, null));
     927        components.Add(mapper.GetStringId(componentInfo.Name), component);
     928      }
     929
     930      foreach (var component in components) {
     931        b.KeyValuePairs.Add(component.Key, component.Value);
     932      }
     933
     934      box.BoxId = mapper.GetStorableClassBoxId(b);
     935    }
     936
     937    protected override object Extract(Box box, Type type, Mapper mapper) {
     938      return mapper.CreateInstance(type);
     939    }
     940
    639941    public override void FillFromBox(object obj, Box box, Mapper mapper) {
    640       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    641       var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject).ToArray();
     942      var data = mapper.GetStorableClassBox(box.BoxId);
    642943      var type = obj.GetType();
    643       for (int i = 1; i <= elements.Length; i++) {
    644         string name = string.Format("m_Item{0}", i);
    645         DataMemberAccessor.GenerateFieldSetter(type.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance))(obj, elements[i - 1]);
    646       }
    647     }
    648   }
    649   #endregion
    650 
    651   #region Bitmap
    652   [Transformer("D0ADB806-2DFD-459D-B5DA-14B5F1152534", 222)]
    653   [StorableType("b13d6153-e71d-4b76-9893-81d3570403e8")]
    654   internal sealed class BitmapTransformer : ByteArrayBoxTransformer<Bitmap> {
    655     protected override ByteString ToByteString(Bitmap value) {
    656       lock (value)
    657         using (var ms = new MemoryStream()) {
    658           value.Save(ms, ImageFormat.Png);
    659           return ByteString.CopyFrom(ms.ToArray());
     944      var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
     945      var typeBox = mapper.GetTypeBox(mapper.GetBox(box.TypeId).BoxId);
     946      var version = Math.Max(typeBox.Version, 1);
     947      var typeGuid = typeInfo.StorableTypeAttribute.Guid;
     948
     949      var components = new Dictionary<uint, uint>();
     950      foreach (var kvp in data.KeyValuePairs) {
     951        components.Add(kvp.Key, kvp.Value);
     952      }
     953
     954      var conversionMethods =
     955        type.Assembly.GetTypes().SelectMany(t =>
     956          t.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
     957          .Where(StorableConversionAttribute.IsStorableConversionMethod)
     958          .Where(mi => StorableConversionAttribute.GetGuid(mi) == typeGuid &&
     959                       StorableConversionAttribute.GetVersion(mi) >= version))
     960          .OrderBy(StorableConversionAttribute.GetVersion)
     961          .ToArray();
     962
     963      // put all objects into dictionary for conversion
     964      var dict = new Dictionary<string, object>();
     965      foreach (var component in components) {
     966        dict.Add(mapper.GetString(component.Key), mapper.GetObject(component.Value));
     967      }
     968
     969      Dictionary<string, object> lastDict = new Dictionary<string, object>();
     970      foreach (var convMeth in conversionMethods) {
     971        if (StorableConversionAttribute.GetVersion(convMeth) != version)
     972          throw new PersistenceException(string.Format("No conversion method defined for type {0} version {1}", typeGuid, version));
     973        lastDict = (Dictionary<string, object>)convMeth.Invoke(null, new object[] { dict });
     974        foreach (var kvp in lastDict) {
     975          dict[kvp.Key] = kvp.Value;
    660976        }
    661     }
    662     protected override Bitmap FromByteString(ByteString byteString) {
    663       using (var ms = new MemoryStream()) {
    664         ms.Write(byteString.ToArray(), 0, byteString.Length);
    665         ms.Seek(0, SeekOrigin.Begin);
    666         return new Bitmap(ms);
    667       }
    668     }
    669   }
    670   #endregion
    671 
    672   #region Font
    673   [Transformer("AFF27987-3301-4D70-9601-EFCA31BDA0DB", 223)]
    674   [StorableType("b9f9a371-4dcb-478b-b0d4-6f87a15c02b5")]
    675   internal sealed class FontTransformer : UnsignedIntArrayBoxTransformer<Font> {
    676 
    677     protected override IEnumerable<uint> ToBoxType(Font value, Mapper mapper) {
    678       yield return mapper.GetStringId(GetFontFamilyName(value.FontFamily));
    679       yield return mapper.GetBoxId(value.Size);
    680       yield return mapper.GetBoxId(value.Style);
    681       yield return mapper.GetBoxId(value.Unit);
    682       yield return mapper.GetBoxId(value.GdiCharSet);
    683       yield return mapper.GetBoxId(value.GdiVerticalFont);
    684     }
    685     protected override Font ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) {
    686       var fontData = value.ToArray();
    687       return new Font(
    688         GetFontFamily(mapper.GetString(fontData[0])),
    689         (float)mapper.GetObject(fontData[1]),
    690         (FontStyle)mapper.GetObject(fontData[2]),
    691         (GraphicsUnit)mapper.GetObject(fontData[3]),
    692         (byte)mapper.GetObject(fontData[4]),
    693         (bool)mapper.GetObject(fontData[5])
    694       );
    695     }
    696 
    697     public const string GENERIC_MONOSPACE_NAME = "_GenericMonospace";
    698     public const string GENERIC_SANS_SERIF_NAME = "_GenericSansSerif";
    699     public const string GENERIC_SERIF_NAME = "_GenericSerif";
    700 
    701     public static FontFamily GetFontFamily(string name) {
    702       if (name == GENERIC_MONOSPACE_NAME) return FontFamily.GenericMonospace;
    703       if (name == GENERIC_SANS_SERIF_NAME) return FontFamily.GenericSansSerif;
    704       if (name == GENERIC_SERIF_NAME) return FontFamily.GenericSerif;
    705       return new FontFamily(name);
    706     }
    707 
    708     public static string GetFontFamilyName(FontFamily ff) {
    709       if (ff.Equals(FontFamily.GenericMonospace)) return GENERIC_MONOSPACE_NAME;
    710       if (ff.Equals(FontFamily.GenericSansSerif)) return GENERIC_SANS_SERIF_NAME;
    711       if (ff.Equals(FontFamily.GenericSerif)) return GENERIC_SERIF_NAME;
    712       return ff.Name;
    713     }
    714   }
    715   #endregion
    716 
    717   #region Array Types
    718   [Transformer("FF89F6D1-CDE3-498E-9166-F70AC6EB01F1", 301)]
    719   [StorableType("59d8363a-7e6c-4d29-9432-8274acd2145f")]
    720   internal sealed class ByteArrayTransformer : ByteArrayBoxTransformer<byte[]> {
    721     protected override ByteString ToByteString(byte[] value) {
    722       return ByteString.CopyFrom(value);
    723     }
    724     protected override byte[] FromByteString(ByteString byteString) {
    725       return byteString.ToArray();
    726     }
    727   }
    728 
    729   [Transformer("B49B3F2D-2E97-4BAB-8705-8D29DA707C6A", 302)]
    730   [StorableType("304c7463-4575-481b-8922-6a54957305c7")]
    731   internal sealed class SByteArrayTransformer : ByteArrayBoxTransformer<sbyte[]> {
    732     protected override ByteString ToByteString(sbyte[] value) {
    733       return ByteString.CopyFrom(value.Select(b => (byte)b).ToArray());
    734     }
    735     protected override sbyte[] FromByteString(ByteString byteString) {
    736       return byteString.Select(b => (sbyte)b).ToArray();
    737     }
    738   }
    739 
    740   [Transformer("F25A73B2-6B67-4493-BD59-B836AF4455D1", 300)]
    741   [StorableType("06fdb68c-ec5e-4cb5-9ad1-063fca0b9c2e")]
    742   internal sealed class BoolArrayTransformer : BoolArrayBoxTransformer<bool[]> {
    743     protected override IEnumerable<bool> ToBoxType(bool[] value, Mapper mapper) { return value; }
    744     protected override bool[] ToValueType(IEnumerable<bool> value, Type type, Mapper mapper) { return value.ToArray(); }
    745   }
    746 
    747   [Transformer("2811FDD4-6800-4CBA-86D7-9071ED5775ED", 303)]
    748   [StorableType("832d8971-51b1-4264-b7eb-07d6e836bf7b")]
    749   internal sealed class ShortArrayTransformer : ByteArrayBoxTransformer<short[]> {
    750     protected override ByteString ToByteString(short[] value) {
    751       var res = new byte[value.Length * 2];
    752       for (int i = 0; i < value.Length; i++) {
    753         var bytes = BitConverter.GetBytes(value[i]);
    754         Array.Copy(bytes, 0, res, i * 2, 2);
    755       }
    756       return ByteString.CopyFrom(res);
    757     }
    758     protected override short[] FromByteString(ByteString byteString) {
    759       var bytes = byteString.ToArray();
    760       var res = new short[bytes.Length / 2];
    761       for (int i = 0; i < bytes.Length; i += 2) {
    762         res[i / 2] = BitConverter.ToInt16(bytes, i);
    763       }
    764       return res;
    765     }
    766   }
    767 
    768   [Transformer("1AAC2625-356C-40BC-8CB4-15CB3D047EB8", 304)]
    769   [StorableType("c303b4cf-ffd0-47e2-9d94-07f2d558d17f")]
    770   internal sealed class UShortArrayTransformer : ByteArrayBoxTransformer<ushort[]> {
    771     protected override ByteString ToByteString(ushort[] value) {
    772       var res = new byte[value.Length * 2];
    773       for (int i = 0; i < value.Length; i++) {
    774         var bytes = BitConverter.GetBytes(value[i]);
    775         Array.Copy(bytes, 0, res, i * 2, 2);
    776       }
    777       return ByteString.CopyFrom(res);
    778     }
    779     protected override ushort[] FromByteString(ByteString byteString) {
    780       var bytes = byteString.ToArray();
    781       var res = new ushort[bytes.Length / 2];
    782       for (int i = 0; i < bytes.Length; i += 2) {
    783         res[i / 2] = BitConverter.ToUInt16(bytes, i);
    784       }
    785       return res;
    786     }
    787   }
    788 
    789   [Transformer("12F19098-5D49-4C23-8897-69087F1C146D", 305)]
    790   [StorableType("55f7c8b0-f2aa-4830-857d-6ce2807da138")]
    791   internal sealed class CharArrayTransformer : ByteArrayBoxTransformer<char[]> {
    792     protected override ByteString ToByteString(char[] value) {
    793       var res = new byte[value.Length * 2];
    794       for (int i = 0; i < value.Length; i++) {
    795         var bytes = BitConverter.GetBytes(value[i]);
    796         Array.Copy(bytes, 0, res, i * 2, 2);
    797       }
    798       return ByteString.CopyFrom(res);
    799     }
    800     protected override char[] FromByteString(ByteString byteString) {
    801       var bytes = byteString.ToArray();
    802       var res = new char[bytes.Length / 2];
    803       for (int i = 0; i < bytes.Length; i += 2) {
    804         res[i / 2] = BitConverter.ToChar(bytes, i);
    805       }
    806       return res;
    807     }
    808   }
    809 
    810   [Transformer("5F6DC3BC-4433-4AE9-A636-4BD126F7DACD", 306)]
    811   [StorableType("e7089621-5236-4d37-a592-c8a0816c59fa")]
    812   internal sealed class IntArrayTransformer : IntArrayBoxTransformer<int[]> {
    813     protected override IEnumerable<int> ToBoxType(int[] value, Mapper mapper) { return value; }
    814     protected override int[] ToValueType(IEnumerable<int> value, Type type, Mapper mapper) { return value.ToArray(); }
    815   }
    816 
    817   [Transformer("3F10274F-D350-4C82-89EA-A5EB36D4EFCC", 307)]
    818   [StorableType("0972d235-5e21-4abf-84f8-aad1bbfdff40")]
    819   internal sealed class UIntArrayTransformer : UnsignedIntArrayBoxTransformer<uint[]> {
    820     protected override IEnumerable<uint> ToBoxType(uint[] value, Mapper mapper) { return value; }
    821     protected override uint[] ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { return value.ToArray(); }
    822   }
    823 
    824   [Transformer("E9D550E2-57F7-47F3-803D-37A619DA1A5C", 308)]
    825   [StorableType("0c656d5d-11dc-4a75-895a-06701048cd70")]
    826   internal sealed class LongArrayTransformer : LongArrayBoxTransformer<long[]> {
    827     protected override IEnumerable<long> ToBoxType(long[] value, Mapper mapper) { return value; }
    828     protected override long[] ToValueType(IEnumerable<long> value, Type type, Mapper mapper) { return value.ToArray(); }
    829   }
    830 
    831   [Transformer("C02A205B-2176-4282-AC2B-ADEF96DDBE24", 309)]
    832   [StorableType("c5f87514-a6c1-400b-9a6c-8adcf980f701")]
    833   internal sealed class ULongArrayTransformer : UnsignedLongArrayBoxTransformer<ulong[]> {
    834     protected override IEnumerable<ulong> ToBoxType(ulong[] value, Mapper mapper) { return value; }
    835     protected override ulong[] ToValueType(IEnumerable<ulong> value, Type type, Mapper mapper) { return value.ToArray(); }
    836   }
    837 
    838   [Transformer("3C4590D9-C76E-4AFB-98FD-E50D3D051648", 310)]
    839   [StorableType("ecc63624-1b78-4bef-8326-74c1a43078ff")]
    840   internal sealed class FloatArrayTransformer : FloatArrayBoxTransformer<float[]> {
    841     protected override IEnumerable<float> ToBoxType(float[] value, Mapper mapper) { return value; }
    842     protected override float[] ToValueType(IEnumerable<float> value, Type type, Mapper mapper) { return value.ToArray(); }
    843   }
    844 
    845   [Transformer("FB98C399-9323-4470-9A85-9186C2B2D5D4", 311)]
    846   [StorableType("03025baa-f57a-48de-b0e2-8e6dc10740ee")]
    847   internal sealed class DoubleArrayTransformer : DoubleArrayBoxTransformer<double[]> {
    848     protected override IEnumerable<double> ToBoxType(double[] value, Mapper mapper) { return value; }
    849     protected override double[] ToValueType(IEnumerable<double> value, Type type, Mapper mapper) { return value.ToArray(); }
    850   }
    851 
    852   [Transformer("68332513-9CF1-47FA-A093-6DDB663186EC", 312)]
    853   [StorableType("791ea34d-e071-4ef2-812b-eb8e2faced45")]
    854   internal sealed class StringArrayTransformer : StringArrayBoxTransformer<string[]> {
    855     protected override IEnumerable<string> ToBoxType(string[] value, Mapper mapper) { return value; }
    856     protected override string[] ToValueType(IEnumerable<string> value, Type type, Mapper mapper) { return value.ToArray(); }
    857   }
    858 
    859   [Transformer("B01ADF0A-ACAA-444E-9F82-0C7C2AF1F490", 400)]
    860   [StorableType("56ae4f46-9fc1-4243-a07f-7b7c24e30545")]
    861   internal sealed class ArrayTransformer : Transformer {
    862     public override bool CanTransformType(Type type) {
    863       return type.IsArray;
    864     }
    865     public override Box ToBox(object o, Mapper mapper) {
    866       var box = Box.CreateBuilder();
    867       box.TransformerId = mapper.GetTransformerId(this);
    868       Populate(box, o, mapper);
    869       return box.Build();
    870     }
    871     private void Populate(Box.Builder box, object value, Mapper mapper) {
    872       var type = value.GetType();
    873       var array = (Array)value;
    874       var rank = array.Rank;
    875 
    876       var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
    877       uIntArrayBox.AddValues(mapper.GetBoxId(rank));
    878 
    879       int[] lengths = new int[rank];
    880       int[] lowerBounds = new int[rank];
    881       for (int i = 0; i < rank; i++) {
    882         lengths[i] = array.GetLength(i);
    883         lowerBounds[i] = array.GetLowerBound(i);
    884       }
    885 
    886       uIntArrayBox.AddRangeValues(lengths.Select(x => mapper.GetBoxId(x)));
    887       uIntArrayBox.AddRangeValues(lowerBounds.Select(x => mapper.GetBoxId(x)));
    888 
    889       int[] positions = (int[])lowerBounds.Clone();
    890       while (positions[rank - 1] < lengths[rank - 1] + lowerBounds[rank - 1]) {
    891         uIntArrayBox.AddValues(mapper.GetBoxId(array.GetValue(positions)));
    892         positions[0] += 1;
    893         for (int i = 0; i < rank - 1; i++) {
    894           if (positions[i] >= lowerBounds[i] + lengths[i]) {
    895             positions[i] = lowerBounds[i];
    896             positions[i + 1] += 1;
    897           } else {
    898             break;
    899           }
     977        version++;
     978      }
     979      if (version != typeInfo.StorableTypeAttribute.Version)
     980        throw new PersistenceException(string.Format("Missing one or more conversion methods for type {0} version {1}",
     981          typeGuid, typeInfo.StorableTypeAttribute.Version));
     982
     983      // set default values for all fields and properties
     984      foreach (var componentInfo in typeInfo.Fields) {
     985        var field = (FieldInfo)componentInfo.MemberInfo;
     986        if (componentInfo.StorableAttribute != null && componentInfo.StorableAttribute.DefaultValue != null)
     987          field.SetValue(obj, componentInfo.StorableAttribute.DefaultValue);
     988      }
     989      foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
     990        var property = (PropertyInfo)componentInfo.MemberInfo;
     991        if (componentInfo.StorableAttribute != null && componentInfo.StorableAttribute.DefaultValue != null)
     992          property.SetValue(obj, componentInfo.StorableAttribute.DefaultValue, null);
     993      }
     994
     995      // set all members as generated by conversion method chain
     996      foreach (var kvp in dict) {
     997        var key = kvp.Key;
     998        var val = kvp.Value;
     999        var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == key);
     1000        if (fieldInfo != null) {
     1001          var field = (FieldInfo)fieldInfo.MemberInfo;
     1002          field.SetValue(obj, val);
     1003          lastDict.Remove(fieldInfo.Name); // only for consistency check
     1004          continue;
    9001005        }
    901       }
    902 
    903       box.TypeId = mapper.GetBoxId(type);
    904       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
    905     }
    906     public override object ToObject(Box box, Mapper mapper) {
    907       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    908       var rank = (int)mapper.GetObject(uIntArrayBox.GetValues(0));
    909 
    910       int[] lengths = new int[rank], lowerBounds = new int[rank];
    911       for (int i = 0; i < rank; i++)
    912         lengths[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1));
    913       for (int i = 0; i < rank; i++)
    914         lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1 + rank));
    915 
    916       var type = (Type)mapper.GetObject(box.TypeId);
    917       return Array.CreateInstance(type.GetElementType(), lengths, lowerBounds);
    918     }
    919     public override void FillFromBox(object obj, Box box, Mapper mapper) {
    920       var array = (Array)obj;
    921       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    922       var rank = (int)mapper.GetObject(uIntArrayBox.GetValues(0));
    923 
    924       int[] lengths = new int[rank], lowerBounds = new int[rank];
    925       for (int i = 0; i < rank; i++)
    926         lengths[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1));
    927       for (int i = 0; i < rank; i++)
    928         lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1 + rank));
    929 
    930       int[] positions = (int[])lowerBounds.Clone();
    931       var e = uIntArrayBox.ValuesList.Skip(1 + 2 * rank).GetEnumerator();
    932       while (e.MoveNext()) {
    933         int[] currentPositions = positions;
    934         array.SetValue(mapper.GetObject(e.Current), currentPositions);
    935         positions[0] += 1;
    936         for (int i = 0; i < rank - 1; i++) {
    937           if (positions[i] >= lengths[i] + lowerBounds[i]) {
    938             positions[i] = lowerBounds[i];
    939             positions[i + 1] += 1;
    940           } else {
    941             break;
    942           }
     1006        var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(pi => pi.Name == key);
     1007        if (propInfo != null) {
     1008          var prop = (PropertyInfo)propInfo.MemberInfo;
     1009          prop.SetValue(obj, val, null);
     1010          lastDict.Remove(propInfo.Name);    // only for consistency check
     1011          continue;
    9431012        }
    9441013      }
    945     }
    946   }
    947   #endregion
    948 
    949   [Transformer("4FA5EAAF-ECC7-4A9C-84E7-6583DA96F3B9", 500)]
    950   [StorableType("b19c0fe5-6bba-4492-af91-c111edce77dc")]
    951   internal sealed class EnumerableTransformer : Transformer {
    952     private static readonly HashSet<Type> supportedTypes = new HashSet<Type> {
    953       typeof(Stack<>), typeof(Stack),
    954       typeof(Queue<>), typeof(Queue),
    955       typeof(HashSet<>),
    956       typeof(List<>), typeof(ArrayList)
    957     };
    958     public override bool CanTransformType(Type type) {
    959       return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition()) || supportedTypes.Contains(type);
    960     }
    961     public override Box ToBox(object o, Mapper mapper) {
    962       var box = Box.CreateBuilder();
    963       box.TransformerId = mapper.GetTransformerId(this);
    964       Populate(box, o, mapper);
    965       return box.Build();
    966     }
    967     private void Populate(Box.Builder box, object value, Mapper mapper) {
    968       var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
    969 
    970       var type = value.GetType();
    971       var propertyInfo = type.GetProperty("Comparer");
    972       if (propertyInfo != null) {
    973         // TODO: where to store id for comparer box? (atm: first element in int array ...)
    974         var comparer = propertyInfo.GetValue(value);
    975         var comparerType = comparer.GetType();
    976         if (StorableTypeAttribute.IsStorableType(comparerType))
    977           uIntArrayBox.AddValues(mapper.GetBoxId(comparer));
    978         else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
    979           throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
    980         else
    981           uIntArrayBox.AddValues(mapper.GetBoxId(comparerType));
    982       }
    983 
    984       foreach (var item in (IEnumerable)value)
    985         uIntArrayBox.AddValues(mapper.GetBoxId(item));
    986 
    987       box.TypeId = mapper.GetBoxId(type);
    988       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
    989     }
    990     public override object ToObject(Box box, Mapper mapper) {
    991       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    992       var type = (Type)mapper.GetObject(box.TypeId);
    993       return Activator.CreateInstance(type);
    994     }
    995     public override void FillFromBox(object obj, Box box, Mapper mapper) {
    996       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
    997       var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject);
    998       var type = obj.GetType();
    999 
    1000       string methodName = string.Empty;
    1001       if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Stack<>) || type == typeof(Stack)) {
    1002         elements = elements.Reverse();
    1003         methodName = "Push";
    1004       } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Queue<>) || type == typeof(Queue)) {
    1005         methodName = "Enqueue";
    1006       } else {
    1007         methodName = "Add";
    1008         if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) {
    1009           var fieldInfo = type.GetField("m_comparer", BindingFlags.NonPublic | BindingFlags.Instance);
    1010           var comparerObj = mapper.GetObject(uIntArrayBox.GetValues(0));
    1011           var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
    1012           fieldInfo.SetValue(obj, comparer);
    1013           elements = elements.Skip(1);
    1014         }
    1015       }
    1016 
    1017       MethodInfo addMethod = type.GetMethod(methodName);
    1018       foreach (var e in elements)
    1019         addMethod.Invoke(obj, new[] { e });
    1020     }
    1021   }
    1022 
    1023   [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 501)]
    1024   [StorableType("ba53df84-dc97-4d8d-a493-868972ed1002")]
    1025   internal sealed class DictionaryTransformer : Transformer {
    1026     public override bool CanTransformType(Type type) {
    1027       return type.IsGenericType && typeof(Dictionary<,>) == type.GetGenericTypeDefinition();
    1028     }
    1029     public override Box ToBox(object o, Mapper mapper) {
    1030       var box = Box.CreateBuilder();
    1031       box.TransformerId = mapper.GetTransformerId(this);
    1032       Populate(box, o, mapper);
    1033       return box.Build();
    1034     }
    1035     private void Populate(Box.Builder box, object value, Mapper mapper) {
    1036       var dictionaryBox = DictionaryBox.CreateBuilder();
    1037       foreach (DictionaryEntry item in (IDictionary)value) {
    1038         dictionaryBox.AddKeyIds(mapper.GetBoxId(item.Key));
    1039         dictionaryBox.AddValueIds(mapper.GetBoxId(item.Value));
    1040       }
    1041 
    1042       var type = value.GetType();
    1043       var propertyInfo = type.GetProperty("Comparer");
    1044       var comparer = propertyInfo.GetValue(value);
    1045 
    1046       var comparerType = comparer.GetType();
    1047       if (StorableTypeAttribute.IsStorableType(comparerType))
    1048         dictionaryBox.SetComparerId(mapper.GetBoxId(comparer));
    1049       else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
    1050         throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
    1051       else
    1052         dictionaryBox.SetComparerId(mapper.GetBoxId(comparerType));
    1053 
    1054       box.TypeId = mapper.GetBoxId(type);
    1055       box.SetExtension(DictionaryBox.Dictionary, dictionaryBox.Build());
    1056     }
    1057     public override object ToObject(Box box, Mapper mapper) {
    1058       var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary);
    1059       return Activator.CreateInstance((Type)mapper.GetObject(box.TypeId), dictionaryBox.ValueIdsCount);
    1060     }
    1061     public override void FillFromBox(object obj, Box box, Mapper mapper) {
    1062       var type = obj.GetType();
    1063       var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary);
    1064       var comparerObj = mapper.GetObject(dictionaryBox.ComparerId);
    1065       var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
    1066 
    1067       var fieldInfo = type.GetField("comparer", BindingFlags.NonPublic | BindingFlags.Instance);
    1068       fieldInfo.SetValue(obj, comparer);
    1069 
    1070 
    1071       var addMethod = type.GetMethod("Add");
    1072       for (int i = 0; i < dictionaryBox.KeyIdsCount; i++) {
    1073         var key = mapper.GetObject(dictionaryBox.GetKeyIds(i));
    1074         var value = mapper.GetObject(dictionaryBox.GetValueIds(i));
    1075         addMethod.Invoke(obj, new[] { key, value });
     1014
     1015      if (lastDict.Any())
     1016        throw new PersistenceException(string.Format("Invalid conversion method. The following members are undefined in type {0} version {1}: {2}",
     1017          typeGuid, typeInfo.StorableTypeAttribute.Version,
     1018          string.Join(", ", lastDict.Keys)));
     1019
     1020      var emptyArgs = new object[0];
     1021      foreach (var hook in typeInfo.AfterDeserializationHooks) {
     1022        hook.Invoke(obj, emptyArgs);
    10761023      }
    10771024    }
Note: See TracChangeset for help on using the changeset viewer.