Ejemplo n.º 1
0
        YamlNode ObjectToNodeSub(object obj, Type expect)
        {
            // !!null
            if (obj == null)
            {
                return(str("!!null", "null"));
            }

            YamlScalar node;

            if (config.TagResolver.Encode(obj, out node))
            {
                return(node);
            }

            var type = obj.GetType();

            if (obj is IntPtr || type.IsPointer)
            {
                throw new ArgumentException($"Pointer object '{obj.ToString()}' can not be serialized.");
            }

            if (obj is char)
            {
                // config.TypeConverter.ConvertToString("\0") does not show "\0"
                var n = str(TypeNameToYamlTag(type), obj.ToString());
                return(n);
            }

            // bool, byte, sbyte, decimal, double, float, int ,uint, long, ulong, short, ushort, string, enum
            if (type.IsPrimitive || type.IsEnum || type == typeof(decimal) || type == typeof(string))
            {
                var n = str(TypeNameToYamlTag(type), config.TypeConverter.ConvertToString(obj));
                return(n);
            }

            // TypeConverterAttribute
            if (EasyTypeConverter.IsTypeConverterSpecified(type))
            {
                return(str(TypeNameToYamlTag(type), config.TypeConverter.ConvertToString(obj)));
            }

            // array
            if (type.IsArray)
            {
                return(CreateArrayNode((Array)obj));
            }

            if (type == typeof(Dictionary <object, object>))
            {
                return(DictionaryToMap(obj));
            }

            // class / struct
            if (type.IsClass || type.IsValueType)
            {
                return(CreateMapping(TypeNameToYamlTag(type), obj));
            }

            throw new NotImplementedException($"Type '{type.FullName}' could not be written");
        }
Ejemplo n.º 2
0
        object ScalarToObject(YamlScalar node, Type type)
        {
            if (type == null)
            {
                throw new FormatException($"Could not find a type '{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;
                int[]  dimension;
                byte[] binary;
                var    elementSize = Marshal.SizeOf(type.GetElementType());
                if (type.GetArrayRank() == 1)
                {
                    binary = Convert.FromBase64CharArray(s.ToCharArray(), 0, s.Length);
                    var arrayLength = binary.Length / elementSize;
                    dimension = new int[] { arrayLength };
                }
                else
                {
                    var m = binaryArray.Match(s);
                    if (!m.Success)
                    {
                        throw new FormatException("Illegal 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("Illegal binary array");
                    }
                    // Fill values
                    s      = m.Groups[2].Value;
                    binary = 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("Illegal binary: data size does not match 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));
            }
        }