object ScalarToObject(YamlScalar node, Type type)
{
if (type == null)
{
throw new FormatException("Could not find a type '{0}'.".DoFormat(node.Tag));
}
// To accommodate the !!int and !!float encoding, all "_"s in integer and floating point values
// are simply neglected.
if (type == typeof(byte) || type == typeof(sbyte) || type == typeof(short) || type == typeof(ushort) ||
type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) ||
type == typeof(float) || type == typeof(decimal))
{
return(config.TypeConverter.ConvertFromString(node.Value.Replace("_", ""), type));
}
if (type.IsEnum || type.IsPrimitive || type == typeof(char) || type == typeof(bool) ||
type == typeof(string) || EasyTypeConverter.IsTypeConverterSpecified(type))
{
return(config.TypeConverter.ConvertFromString(node.Value, type));
}
if (type.IsArray)
{
// Split dimension from base64 strings
var s = node.Value;
var regex = new Regex(@" *\[([0-9 ,]+)\][\r\n]+((.+|[\r\n])+)");
int[] dimension;
byte[] binary;
var elementSize = Marshal.SizeOf(type.GetElementType());
if (type.GetArrayRank() == 1)
{
binary = System.Convert.FromBase64CharArray(s.ToCharArray(), 0, s.Length);
var arrayLength = binary.Length / elementSize;
dimension = new int[] { arrayLength };
}
else
{
var m = regex.Match(s);
if (!m.Success)
{
throw new FormatException("Irregal binary array");
}
// Create array from dimension
dimension = m.Groups[1].Value.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
if (type.GetArrayRank() != dimension.Length)
{
throw new FormatException("Irregal binary array");
}
// Fill values
s = m.Groups[2].Value;
binary = System.Convert.FromBase64CharArray(s.ToCharArray(), 0, s.Length);
}
var paramType = dimension.Select(n => typeof(int) /* n.GetType() */).ToArray();
var array = (Array)type.GetConstructor(paramType).Invoke(dimension.Cast <object>().ToArray());
if (binary.Length != array.Length * elementSize)
{
throw new FormatException("Irregal binary: data size does not match to array dimension");
}
int j = 0;
for (int i = 0; i < array.Length; i++)
{
var p = Marshal.UnsafeAddrOfPinnedArrayElement(array, i);
Marshal.Copy(binary, j, p, elementSize);
j += elementSize;
}
return(array);
}
if (node.Value == "")
{
return(config.Activator.Activate(type));
}
else
{
return(TypeDescriptor.GetConverter(type).ConvertFromString(node.Value));
}
}