- Timestamp:
- 12/11/17 17:46:11 (7 years ago)
- 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 26 26 [NonDiscoverableType] 27 27 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; 30 30 private uint nextIndex; 31 31 … … 35 35 nextIndex = 1; 36 36 } 37 public Index(IEnumerable<T> values) 38 37 38 public Index(IEnumerable<T> values) : this() { 39 39 foreach (var value in values) { 40 40 this.indexes.Add(value, nextIndex); … … 54 54 return index; 55 55 } 56 56 57 public T GetValue(uint index) { 57 58 return index == 0 ? null : values[index]; 58 59 } 60 59 61 public IEnumerable<T> GetValues() { 60 62 return values.Values; -
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/Mapper.cs
r15020 r15509 23 23 using System.Collections.Generic; 24 24 using System.Linq; 25 using Google.Proto colBuffers;25 using Google.Protobuf; 26 26 27 27 namespace HeuristicLab.Persistence { … … 43 43 } 44 44 45 private static StaticCache staticCache = null;45 private static StaticCache staticCache; 46 46 private static object locker = new object(); 47 47 public static StaticCache StaticCache { … … 56 56 private Index<ITransformer> transformers; 57 57 private Index<Type> types; 58 private Index<string> strings; 58 59 59 private Dictionary<uint, Box> boxId2Box; 60 60 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; 62 76 63 77 public uint BoxCount { get; private set; } 78 64 79 65 80 public Mapper() { 66 81 transformers = new Index<ITransformer>(); 67 82 types = new Index<Type>(); 68 strings = new Index<string>(); 83 69 84 boxId2Box = new Dictionary<uint, Box>(); 70 85 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>(); 72 101 73 102 BoxCount = 0; 74 103 } 75 104 105 #region Transformers 76 106 public uint GetTransformerId(ITransformer transformer) { 77 107 return transformers.GetIndex(transformer); 78 108 } 109 79 110 public ITransformer GetTransformer(uint transformerId) { 80 111 return transformers.GetValue(transformerId); 81 112 } 82 113 #endregion 114 115 #region Types 83 116 public uint GetTypeId(Type type) { 84 117 return types.GetIndex(type); 85 118 } 119 86 120 public Type GetType(uint typeId) { 87 121 return types.GetValue(typeId); 88 122 } 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 100 126 public uint GetBoxId(object o) { 101 127 uint boxId; … … 115 141 return boxId; 116 142 } 143 144 public Box GetBox(uint boxId) { 145 return boxId2Box[boxId]; 146 } 147 117 148 public object GetObject(uint boxId) { 118 149 object o; 119 if (boxId2 object.TryGetValue(boxId, out o)) return o;150 if (boxId2Object.TryGetValue(boxId, out o)) return o; 120 151 121 152 Box box; … … 127 158 var transformer = transformers.GetValue(box.TransformerId); 128 159 o = transformer.ToObject(box, this); 129 boxId2 object.Add(boxId, o);160 boxId2Object.Add(boxId, o); 130 161 transformer.FillFromBox(o, box, this); 131 162 } 163 132 164 return o; 133 165 } 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 134 228 135 229 public object CreateInstance(Type type) { … … 143 237 public static Bundle ToBundle(object o) { 144 238 var mapper = new Mapper(); 145 var bundle = Bundle.CreateBuilder(); 239 var bundle = new Bundle(); 240 146 241 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; 152 261 } 153 262 public static object ToObject(Bundle bundle) { 154 263 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 159 284 return mapper.GetObject(bundle.RootBoxId); 160 285 } -
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/ProtoBufSerializer.cs
r13367 r15509 21 21 22 22 using System.IO; 23 using Google.Protobuf; 23 24 24 25 namespace HeuristicLab.Persistence { 25 26 public sealed class ProtoBufSerializer : Serializer { 26 27 protected override void SerializeBundle(Bundle bundle, Stream stream) { 27 bundle.WriteTo(stream); 28 using (var outputStream = new CodedOutputStream(stream)) 29 bundle.WriteTo(outputStream); 28 30 } 29 31 30 32 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); 32 35 } 33 36 } -
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StaticCache.cs
r15020 r15509 25 25 using System.Drawing; 26 26 using System.Linq; 27 using Google.ProtocolBuffers;28 27 using HeuristicLab.PluginInfrastructure; 29 28 30 29 namespace HeuristicLab.Persistence { 31 30 public sealed class StaticCache { 32 private static object locker = new object();31 private static readonly object locker = new object(); 33 32 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; 40 38 41 39 internal StaticCache() { … … 45 43 type2Guid = new Dictionary<Type, Guid>(); 46 44 typeInfos = new Dictionary<Type, TypeInfo>(); 47 extensionRegistry = ExtensionRegistry.CreateInstance();48 45 49 46 foreach (var transformer in ApplicationManager.Manager.GetInstances<ITransformer>()) … … 82 79 RegisterType(new Guid("E84C326A-7E14-4F28-AEFF-BC16CC671655"), typeof(KeyValuePair<,>)); 83 80 RegisterType(new Guid("F0280B55-25E8-4981-B309-D675D081402A"), typeof(string)); 84 // 81 85 82 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));101 83 RegisterType(new Guid("B7313EE2-045F-41C9-AEC9-7B1A8CDBF90F"), typeof(IEnumerable)); 102 84 RegisterType(new Guid("D5265599-7380-4A28-AB0D-9F336EF290C5"), typeof(IEnumerable<>)); 85 RegisterType(new Guid("E451A99B-0CFD-48E6-9BEF-0AE9D1E73628"), typeof(IList)); 103 86 RegisterType(new Guid("DB2A785C-5803-42C7-A01F-E1FD845A83A1"), typeof(List<>)); 104 87 RegisterType(new Guid("EB98A564-BEDC-458A-9E9B-4BF3CDAFB9BE"), typeof(Stack<>)); … … 129 112 } 130 113 } 114 131 115 RegisterType(new Guid("67C35B3B-DC23-4929-9BA9-0A0CD5FE17F5"), allTypes["System.StringComparer"]); 132 116 RegisterType(new Guid("C7FDE8F0-EF3F-4A4D-8D87-5559C32A8B90"), allTypes["System.CultureAwareComparer"]); … … 151 135 RegisterType(new Guid("00C8C940-63D9-43FF-99BA-9C69301BF043"), allTypes["System.Collections.Generic.RandomizedObjectEqualityComparer"]); 152 136 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);183 137 } 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 //}195 138 196 139 public void RegisterTransformer(ITransformer transformer) { … … 206 149 } 207 150 } 151 208 152 // mainly for testing 209 153 public void DeregisterType(Guid guid) { … … 213 157 } 214 158 } 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 }229 159 230 160 public ITransformer GetTransformer(Guid guid) { 231 161 return guid2Transformer[guid]; 232 162 } 163 233 164 public Guid GetGuid(ITransformer transformer) { 234 165 return transformer2Guid[transformer]; 235 166 } 167 236 168 public Type GetType(Guid guid) { 237 169 return guid2Type[guid]; 238 170 } 171 239 172 public Guid GetGuid(Type type) { 240 173 return type2Guid[type]; 241 174 } 175 242 176 public TypeInfo GetTypeInfo(Type type) { 243 177 lock (locker) { … … 245 179 if (!typeInfos.TryGetValue(type, out typeInfo)) { 246 180 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); 248 182 typeInfo = new TypeInfo(type, transformer); 249 183 typeInfos.Add(type, typeInfo); … … 252 186 } 253 187 } 254 public ExtensionRegistry GetExtensionRegistry() {255 return extensionRegistry;256 }257 188 } 258 189 } -
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/HeuristicLab.Persistence-4.0.csproj
r15501 r15509 73 73 <Compile Include="Properties\AssemblyInfo.cs" /> 74 74 <Compile Include="Protos\PersistenceMessages.cs" /> 75 <Compile Include="Transformers\StorableClassTransformer.cs" />76 75 <Compile Include="Transformers\Transformers.cs" /> 77 76 </ItemGroup> -
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Protos/PersistenceMessages.proto
r15501 r15509 9 9 uint32 root_box_id = 10; 10 10 repeated Box boxes = 20; 11 repeated TypeBox type_boxes = 30; 11 12 12 13 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;21 14 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; 38 25 } 39 26 message Box { … … 41 28 uint32 type_id = 2; 42 29 uint32 box_id = 3; 30 43 31 bool bool = 10; 44 32 int32 int = 11; 45 33 int64 long = 12; 46 uint32 u int = 13;47 uint64 u long = 14;34 uint32 u_int = 13; 35 uint64 u_long = 14; 48 36 float float = 15; 49 37 double double = 16; 38 bytes bytes = 17; 50 39 } 51 40 message TypeBox { … … 63 52 message FloatArrayBox { repeated float values = 1; } 64 53 message DoubleArrayBox { repeated double values = 1; } 65 message ByteArrayBox { bytes values = 1; }66 54 67 55 // matrix boxes -
branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
r15034 r15509 23 23 using System.Collections; 24 24 using System.Collections.Generic; 25 using System.ComponentModel;26 25 using System.Drawing; 27 26 using System.Drawing.Imaging; … … 30 29 using System.Linq; 31 30 using System.Reflection; 32 using Google.Proto colBuffers;31 using Google.Protobuf; 33 32 34 33 namespace HeuristicLab.Persistence { … … 40 39 41 40 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 }; 45 45 Populate(box, (T)o, mapper); 46 return box.Build(); 47 } 46 return box; 47 } 48 48 49 public override object ToObject(Box box, Mapper mapper) { 49 50 return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper); 50 51 } 51 protected abstract void Populate(Box.Builder box, T value, Mapper mapper); 52 53 protected abstract void Populate(Box box, T value, Mapper mapper); 52 54 protected abstract T Extract(Box box, Type type, Mapper mapper); 53 55 } 54 56 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")] 297 59 internal sealed class TypeTransformer : Transformer { 298 60 public override bool CanTransformType(Type type) { 299 61 return typeof(Type).IsAssignableFrom(type); 300 62 } 63 301 64 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 }; 304 68 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) { 308 73 var type = (Type)value; 309 var typeBox = TypeBox.CreateBuilder(); 74 var typeBox = new TypeBox(); 75 310 76 if (type.IsGenericType) { 311 77 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)); 313 79 } else if (type.IsArray) { 314 80 box.TypeId = mapper.GetTypeId(typeof(Array)); 315 typeBox. AddGenericTypeIds(mapper.GetBoxId(type.GetElementType()));81 typeBox.GenericTypeIds.Add(mapper.GetBoxId(type.GetElementType())); 316 82 } else { 317 83 box.TypeId = mapper.GetTypeId(type); … … 320 86 if (StorableTypeAttribute.IsStorableType(type)) 321 87 typeBox.Version = StorableTypeAttribute.GetStorableTypeAttribute(type).Version; 322 box.SetExtension(TypeBox.Type, typeBox.Build()); 323 } 88 89 box.BoxId = mapper.GetTypeBoxId(typeBox); 90 } 91 324 92 public override object ToObject(Box box, Mapper mapper) { 325 93 return Extract(box, mapper.GetType(box.TypeId), mapper); 326 94 } 95 327 96 private object Extract(Box box, Type type, Mapper mapper) { 328 var b = box.GetExtension(TypeBox.Type); 97 var typeBox = mapper.GetTypeBox(box.BoxId); 98 329 99 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()); 331 101 } else if (type == typeof(Array)) { 332 return ((Type)mapper.GetObject( b.GetGenericTypeIds(0))).MakeArrayType();102 return ((Type)mapper.GetObject(typeBox.GenericTypeIds[0])).MakeArrayType(); 333 103 } else { 334 104 335 105 return type; 336 106 } … … 338 108 } 339 109 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> { 456 413 public override bool CanTransformType(Type type) { 457 return type.Is GenericType && (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) { 461 418 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 468 465 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 478 531 protected override object Extract(Box box, Type type, Mapper mapper) { 479 532 return Activator.CreateInstance(type); 480 533 } 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 493 653 private static decimal ParseG30(string s) { 494 654 decimal d; … … 501 661 string.Format("Invalid decimal G30 number format \"{0}\" could not be parsed", s)); 502 662 } 663 503 664 private static string FormatG30(decimal d) { 504 665 return d.ToString("g30", CultureInfo.InvariantCulture); 505 666 } 506 667 } 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> { 522 777 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> { 549 850 public override bool CanTransformType(Type type) { 550 851 return type.IsValueType && !type.IsPrimitive && !type.IsEnum && type.IsSealed; 551 852 } 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(); 563 856 var type = value.GetType(); 564 857 … … 569 862 } 570 863 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); 579 873 var obj = Activator.CreateInstance(type); 580 874 581 875 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); 584 878 } 585 879 … … 600 894 return obj; 601 895 } 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> { 613 902 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(); 623 909 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 639 941 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); 642 943 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; 660 976 } 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; 900 1005 } 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; 943 1012 } 944 1013 } 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); 1076 1023 } 1077 1024 }
Note: See TracChangeset
for help on using the changeset viewer.