コード例 #1
0
        public static object ConvertToClrType(this Value wireValue, V1.Type spannerType, System.Type targetClrType)
        {
            if (wireValue.KindCase == Value.KindOneofCase.NullValue)
            {
                if (targetClrType.GetTypeInfo().IsValueType)
                {
                    //Returns default(T) for targetClrType
                    return(Activator.CreateInstance(targetClrType));
                }
                return(null);
            }
            if (targetClrType == typeof(object))
            {
                //then we decide the type for you
                targetClrType = spannerType?.Code.GetDefaultClrTypeFromSpannerType();
            }
            var possibleUnderlyingType = Nullable.GetUnderlyingType(targetClrType);

            if (possibleUnderlyingType != null)
            {
                targetClrType = possibleUnderlyingType;
            }
            //extra supported conversions that are modifications of the "core" versions but may have loss of precision.
            //we call the spannerType with the known supported version and cast it down to lose precision.
            if (targetClrType == typeof(int))
            {
                return(Convert.ToInt32((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(long))));
            }

            if (targetClrType == typeof(uint))
            {
                return(Convert.ToUInt32((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(long))));
            }

            if (targetClrType == typeof(short))
            {
                return(Convert.ToInt16((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(long))));
            }

            if (targetClrType == typeof(ushort))
            {
                return(Convert.ToUInt16((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(long))));
            }

            if (targetClrType == typeof(char))
            {
                return(Convert.ToChar((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(long))));
            }

            if (targetClrType == typeof(byte))
            {
                return(Convert.ToByte((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(long))));
            }

            if (targetClrType == typeof(decimal))
            {
                return(Convert.ToDecimal((long)ConvertToClrTypeImpl(wireValue, spannerType, typeof(decimal))));
            }

            if (targetClrType == typeof(float))
            {
                return(Convert.ToSingle((double)ConvertToClrTypeImpl(wireValue, spannerType, typeof(double))));
            }

            if (targetClrType == typeof(Guid))
            {
                return(Guid.Parse((string)ConvertToClrTypeImpl(wireValue, spannerType, typeof(string))));
            }

            return(ConvertToClrTypeImpl(wireValue, spannerType, targetClrType));
        }
コード例 #2
0
 public static T ConvertToClrType <T>(
     this Value wireValue,
     V1.Type spannerType) => (T)ConvertToClrType(wireValue, spannerType, typeof(T));
コード例 #3
0
        private static object ConvertToClrTypeImpl(Value wireValue, V1.Type spannerType, System.Type targetClrType)
        {
            //If the wireValue itself is assignable to the target type, just return it
            //This covers both typeof(Value) and typeof(object).
            if (wireValue == null || targetClrType == null || targetClrType == typeof(Value))
            {
                return(wireValue);
            }

            //targetClrType should be one of the values returned by GetDefaultClrTypeFromSpannerType
            if (targetClrType == typeof(bool))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(default(bool));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToBoolean(wireValue.StringValue));

                case Value.KindOneofCase.BoolValue:
                    return(wireValue.BoolValue);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(long))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NumberValue:
                    return(Convert.ToInt64(wireValue.NumberValue));

                case Value.KindOneofCase.NullValue:
                    return(default(long));

                case Value.KindOneofCase.StringValue:
                    return(Convert.ToInt64(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(double))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(default(double));

                case Value.KindOneofCase.NumberValue:
                    return(wireValue.NumberValue);

                case Value.KindOneofCase.StringValue:
                    if (string.Compare(wireValue.StringValue, "NaN", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.NaN);
                    }

                    if (string.Compare(wireValue.StringValue, "Infinity", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.PositiveInfinity);
                    }

                    if (string.Compare(wireValue.StringValue, "-Infinity", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return(double.NegativeInfinity);
                    }

                    return(Convert.ToDouble(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(DateTime))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(XmlConvert.ToDateTime(wireValue.StringValue, XmlDateTimeSerializationMode.Utc));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(Timestamp))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(Timestamp.Parser.ParseJson(wireValue.StringValue));

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }

            if (targetClrType == typeof(string))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.NumberValue:
                    return(wireValue.NumberValue.ToString(CultureInfo.CurrentCulture));

                case Value.KindOneofCase.StringValue:
                    return(wireValue.StringValue);

                case Value.KindOneofCase.BoolValue:
                    return(wireValue.BoolValue.ToString());

                default:
                    return(wireValue.ToString());
                }
            }

            if (targetClrType == typeof(byte[]))
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue:
                    return(null);

                case Value.KindOneofCase.StringValue:
                    return(Convert.FromBase64String(wireValue.StringValue));

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            if (typeof(IDictionary).IsAssignableFrom(targetClrType))
            {
                if (targetClrType == typeof(IDictionary))
                {
                    targetClrType = typeof(Hashtable);
                }
                //a bit of recursion here...
                IDictionary dictionary = (IDictionary)Activator.CreateInstance(targetClrType);
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.StructValue:
                    foreach (var structField in spannerType.StructType.Fields)
                    {
                        dictionary[structField.Name] =
                            wireValue.StructValue.Fields[structField.Name]
                            .ConvertToClrType(structField.Type);
                    }

                    return(dictionary);

                case Value.KindOneofCase.ListValue:
                    if (spannerType.Code == TypeCode.Struct)
                    {
                        for (var i = 0; i < spannerType.StructType.Fields.Count; i++)
                        {
                            dictionary[spannerType.StructType.Fields[i].Name] = wireValue
                                                                                .ListValue.Values[i]
                                                                                .ConvertToClrType(spannerType.StructType.Fields[i].Type);
                        }
                    }
                    else
                    {
                        var i = 0;
                        foreach (var listItemValue in wireValue.ListValue.Values)
                        {
                            dictionary[i] =
                                listItemValue.ConvertToClrType(spannerType.ArrayElementType);
                            i++;
                        }
                    }
                    return(dictionary);

                default:
                    throw new ArgumentException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (targetClrType.IsArray)
            {
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue: return(null);

                case Value.KindOneofCase.ListValue:
                    var newArray = Array.CreateInstance(
                        targetClrType.GetElementType(),
                        wireValue.ListValue.Values.Count);

                    var i = 0;
                    foreach (var obj in wireValue.ListValue.Values.Select(
                                 x => x.ConvertToClrType(spannerType.ArrayElementType, targetClrType.GetElementType())))
                    {
                        newArray.SetValue(obj, i);
                        i++;
                    }
                    return(newArray);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            if (typeof(IList).IsAssignableFrom(targetClrType))
            {
                if (targetClrType == typeof(IList))
                {
                    targetClrType = typeof(ArrayList);
                }
                switch (wireValue.KindCase)
                {
                case Value.KindOneofCase.NullValue: return(null);

                case Value.KindOneofCase.ListValue:
                    var newList = (IList)Activator.CreateInstance(targetClrType);
                    foreach (var obj in wireValue.ListValue.Values.Select(
                                 x => x.ConvertToClrType(spannerType.ArrayElementType)))
                    {
                        newList.Add(obj);
                    }
                    return(newList);

                default:
                    throw new InvalidOperationException(
                              $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
                }
            }
            throw new ArgumentException(
                      $"Invalid Type conversion from {wireValue.KindCase} to {targetClrType.FullName}");
        }
コード例 #4
0
 public static object ConvertToClrType(this Value wireValue, V1.Type spannerType) => ConvertToClrType(
     wireValue, spannerType, typeof(object));
コード例 #5
0
ファイル: ValueConversion.cs プロジェクト: greggaba/GCDotNet
 private static T ConvertToClrTypeImpl <T>(Value wireValue, V1.Type spannerType) =>
 (T)ConvertToClrTypeImpl(wireValue, spannerType, typeof(T));