#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using Google.ProtocolBuffers;
using HeuristicLab.Persistence.Core;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
namespace HeuristicLab.Persistence {
public abstract class BoxTransformer : Transformer {
public override bool CanTransformType(Type type) {
return type == typeof(T);
}
public override Box ToBox(object o, Mapper mapper) {
var box = Box.CreateBuilder();
box.TransformerId = mapper.GetTransformerId(this);
box.TypeId = mapper.GetBoxId(o.GetType());
Populate(box, (T)o, mapper);
return box.Build();
}
public override object ToObject(Box box, Mapper mapper) {
return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
}
protected abstract void Populate(Box.Builder box, T value, Mapper mapper);
protected abstract T Extract(Box box, Type type, Mapper mapper);
}
#region Scalar Box Transformers
public abstract class BoolBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = BoolBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(BoolBox.Bool, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(BoolBox.Bool).Value, type, mapper);
}
protected abstract bool ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(bool value, Type type, Mapper mapper);
}
public abstract class IntBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = IntBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(IntBox.Int, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(IntBox.Int).Value, type, mapper);
}
protected abstract int ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(int value, Type type, Mapper mapper);
}
public abstract class LongBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = LongBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(LongBox.Long, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(LongBox.Long).Value, type, mapper);
}
protected abstract long ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(long value, Type type, Mapper mapper);
}
public abstract class UnsignedIntBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = UnsignedIntBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(UnsignedIntBox.UnsignedInt, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(UnsignedIntBox.UnsignedInt).Value, type, mapper);
}
protected abstract uint ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(uint value, Type type, Mapper mapper);
}
public abstract class UnsignedLongBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = UnsignedLongBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(UnsignedLongBox.UnsignedLong, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(UnsignedLongBox.UnsignedLong).Value, type, mapper);
}
protected abstract ulong ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(ulong value, Type type, Mapper mapper);
}
public abstract class FloatBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = FloatBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(FloatBox.Float, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(FloatBox.Float).Value, type, mapper);
}
protected abstract float ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(float value, Type type, Mapper mapper);
}
public abstract class DoubleBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = DoubleBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(DoubleBox.Double, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(DoubleBox.Double).Value, type, mapper);
}
protected abstract double ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(double value, Type type, Mapper mapper);
}
public abstract class StringBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = StringBox.CreateBuilder();
b.Value = ToBoxType(value, mapper);
box.SetExtension(StringBox.String, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(StringBox.String).Value, type, mapper);
}
protected abstract string ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(string value, Type type, Mapper mapper);
}
public abstract class BytesBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = BytesBox.CreateBuilder();
b.Value = ByteString.CopyFrom(ToBoxType(value, mapper));
box.SetExtension(BytesBox.Bytes, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(BytesBox.Bytes).Value.ToByteArray(), type, mapper);
}
protected abstract byte[] ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(byte[] value, Type type, Mapper mapper);
}
#endregion
#region Array Box Transformers
public abstract class ByteArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = ByteArrayBox.CreateBuilder();
b.SetValues(ToByteString(value));
box.SetExtension(ByteArrayBox.ByteArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return FromByteString(box.GetExtension(ByteArrayBox.ByteArray).Values);
}
protected abstract ByteString ToByteString(T value);
protected abstract T FromByteString(ByteString byteString);
}
public abstract class BoolArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = BoolArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(BoolArrayBox.BoolArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(BoolArrayBox.BoolArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class IntArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = IntArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(IntArrayBox.IntArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(IntArrayBox.IntArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class LongArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = LongArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(LongArrayBox.LongArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(LongArrayBox.LongArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class UnsignedIntArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = UnsignedIntArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class UnsignedLongArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = UnsignedLongArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(UnsignedLongArrayBox.UnsignedLongArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(UnsignedLongArrayBox.UnsignedLongArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class FloatArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = FloatArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(FloatArrayBox.FloatArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(FloatArrayBox.FloatArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class DoubleArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = DoubleArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(DoubleArrayBox.DoubleArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(DoubleArrayBox.DoubleArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
public abstract class StringArrayBoxTransformer : BoxTransformer {
protected override void Populate(Box.Builder box, T value, Mapper mapper) {
var b = StringArrayBox.CreateBuilder();
b.AddRangeValues(ToBoxType(value, mapper));
box.SetExtension(StringArrayBox.StringArray, b.Build());
}
protected override T Extract(Box box, Type type, Mapper mapper) {
return ToValueType(box.GetExtension(StringArrayBox.StringArray).ValuesList, type, mapper);
}
protected abstract IEnumerable ToBoxType(T value, Mapper mapper);
protected abstract T ToValueType(IEnumerable value, Type type, Mapper mapper);
}
#endregion
[Transformer("11B822C9-46A0-4B65-AE4A-D12F63DDE9F6", 50)]
internal sealed class TypeTransformer : Transformer {
public override bool CanTransformType(Type type) {
return typeof(Type).IsAssignableFrom(type);
}
public override Box ToBox(object o, Mapper mapper) {
var box = Box.CreateBuilder();
box.TransformerId = mapper.GetTransformerId(this);
Populate(box, o, mapper);
return box.Build();
}
private void Populate(Box.Builder box, object value, Mapper mapper) {
var type = (Type)value;
var typeBox = TypeBox.CreateBuilder();
if (type.IsGenericType) {
box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition());
typeBox.AddRangeGenericTypeIds(type.GetGenericArguments().Select(t => mapper.GetBoxId(t)));
} else if (type.IsArray) {
box.TypeId = mapper.GetTypeId(typeof(Array));
typeBox.AddGenericTypeIds(mapper.GetBoxId(type.GetElementType()));
} else {
box.TypeId = mapper.GetTypeId(type);
}
if (StorableTypeAttribute.IsStorableType(type))
typeBox.Version = StorableTypeAttribute.GetStorableTypeAttribute(type).Version;
box.SetExtension(TypeBox.Type, typeBox.Build());
}
public override object ToObject(Box box, Mapper mapper) {
return Extract(box, mapper.GetType(box.TypeId), mapper);
}
private object Extract(Box box, Type type, Mapper mapper) {
var b = box.GetExtension(TypeBox.Type);
if (type.IsGenericType) {
return type.MakeGenericType(b.GenericTypeIdsList.Select(id => (Type)mapper.GetObject(id)).ToArray());
} else if (type == typeof(Array)) {
return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType();
} else {
return type;
}
}
}
#region Primitive Value Types
[Transformer("268617FE-3F0F-4029-8248-EDA420901FB6", 10000)]
internal sealed class ObjectTransformer : BoxTransformer