diff options
Diffstat (limited to 'src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs')
-rw-r--r-- | src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs | 210 |
1 files changed, 130 insertions, 80 deletions
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs index b7dad17a6b..aa0f3ba056 100644 --- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs +++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs @@ -25,9 +25,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime _data = data; } - private static Tuple<Type, PropertyType>[] NumericScalarTypes { - get { - if (s_numericScalarTypes == null) { + private static Tuple<Type, PropertyType>[] NumericScalarTypes + { + get + { + if (s_numericScalarTypes == null) + { Tuple<Type, PropertyType>[] numericScalarTypes = new Tuple<Type, PropertyType>[] { new Tuple<Type, PropertyType>(typeof(Byte), PropertyType.UInt8), new Tuple<Type, PropertyType>(typeof(Int16), PropertyType.Int16), @@ -47,14 +50,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime } } - public PropertyType Type { + public PropertyType Type + { [Pure] get { return _type; } } - public bool IsNumericScalar { + public bool IsNumericScalar + { [Pure] - get { + get + { return IsNumericScalarImpl(_type, _data); } } @@ -128,7 +134,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public char GetChar16() { if (this.Type != PropertyType.Char16) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Char16"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Char16"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (char)_data; } @@ -137,7 +143,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Boolean GetBoolean() { if (this.Type != PropertyType.Boolean) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Boolean"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Boolean"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (bool)_data; } @@ -160,7 +166,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public DateTimeOffset GetDateTime() { if (this.Type != PropertyType.DateTime) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "DateTime"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "DateTime"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (DateTimeOffset)_data; } @@ -169,7 +175,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public TimeSpan GetTimeSpan() { if (this.Type != PropertyType.TimeSpan) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "TimeSpan"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "TimeSpan"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (TimeSpan)_data; } @@ -178,7 +184,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Point GetPoint() { if (this.Type != PropertyType.Point) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Point"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Point"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return Unbox<Point>(IReferenceFactory.s_pointType); @@ -188,9 +194,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Size GetSize() { if (this.Type != PropertyType.Size) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Size"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Size"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); - + return Unbox<Size>(IReferenceFactory.s_sizeType); } @@ -198,9 +204,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Rect GetRect() { if (this.Type != PropertyType.Rect) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Rect"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Rect"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); - + return Unbox<Rect>(IReferenceFactory.s_rectType); } @@ -262,7 +268,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public char[] GetChar16Array() { if (this.Type != PropertyType.Char16Array) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Char16[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Char16[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (char[])_data; } @@ -271,7 +277,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Boolean[] GetBooleanArray() { if (this.Type != PropertyType.BooleanArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Boolean[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Boolean[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (bool[])_data; } @@ -286,7 +292,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Object[] GetInspectableArray() { if (this.Type != PropertyType.InspectableArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Inspectable[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Inspectable[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (Object[])_data; } @@ -301,7 +307,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public DateTimeOffset[] GetDateTimeArray() { if (this.Type != PropertyType.DateTimeArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "DateTimeOffset[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "DateTimeOffset[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (DateTimeOffset[])_data; } @@ -310,7 +316,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public TimeSpan[] GetTimeSpanArray() { if (this.Type != PropertyType.TimeSpanArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "TimeSpan[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "TimeSpan[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return (TimeSpan[])_data; } @@ -319,9 +325,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Point[] GetPointArray() { if (this.Type != PropertyType.PointArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Point[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Point[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); - + return UnboxArray<Point>(IReferenceFactory.s_pointType); } @@ -329,7 +335,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Size[] GetSizeArray() { if (this.Type != PropertyType.SizeArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Size[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Size[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); @@ -340,22 +346,25 @@ namespace System.Runtime.InteropServices.WindowsRuntime public Rect[] GetRectArray() { if (this.Type != PropertyType.RectArray) - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Rect[]"), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Rect[]"), __HResults.TYPE_E_TYPEMISMATCH); Contract.EndContractBlock(); return UnboxArray<Rect>(IReferenceFactory.s_rectType); } - private T[] CoerceArrayValue<T>(PropertyType unboxType) { + private T[] CoerceArrayValue<T>(PropertyType unboxType) + { // If we contain the type being looked for directly, then take the fast-path - if (Type == unboxType) { + if (Type == unboxType) + { return (T[])_data; } // Make sure we have an array to begin with Array dataArray = _data as Array; - if (dataArray == null) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, typeof(T).MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH); + if (dataArray == null) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, typeof (T).MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH); } // Array types are 1024 larger than their equivilent scalar counterpart @@ -365,11 +374,15 @@ namespace System.Runtime.InteropServices.WindowsRuntime // If we do not have the correct array type, then we need to convert the array element-by-element // to a new array of the requested type T[] coercedArray = new T[dataArray.Length]; - for (int i = 0; i < dataArray.Length; ++i) { - try { + for (int i = 0; i < dataArray.Length; ++i) + { + try + { coercedArray[i] = CoerceScalarValue<T>(scalarType, dataArray.GetValue(i)); - } catch (InvalidCastException elementCastException) { - Exception e = new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueArrayCoersion", this.Type, typeof(T).MakeArrayType().Name, i, elementCastException.Message), elementCastException); + } + catch (InvalidCastException elementCastException) + { + Exception e = new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, this.Type, typeof (T).MakeArrayType().Name, i, elementCastException.Message), elementCastException); e.SetErrorCode(elementCastException._HResult); throw e; } @@ -381,92 +394,117 @@ namespace System.Runtime.InteropServices.WindowsRuntime private T CoerceScalarValue<T>(PropertyType unboxType) { // If we are just a boxed version of the requested type, then take the fast path out - if (Type == unboxType) { + if (Type == unboxType) + { return (T)_data; } return CoerceScalarValue<T>(Type, _data); } - private static T CoerceScalarValue<T>(PropertyType type, object value) { + private static T CoerceScalarValue<T>(PropertyType type, object value) + { // If the property type is neither one of the coercable numeric types nor IInspectable, we // should not attempt coersion, even if the underlying value is technically convertable - if (!IsCoercable(type, value) && type != PropertyType.Inspectable) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH); + if (!IsCoercable(type, value) && type != PropertyType.Inspectable) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH); } - try { + try + { // Try to coerce: // * String <--> Guid // * Numeric scalars - if (type == PropertyType.String && typeof(T) == typeof(Guid)) { + if (type == PropertyType.String && typeof(T) == typeof(Guid)) + { return (T)(object)Guid.Parse((string)value); } - else if (type == PropertyType.Guid && typeof(T) == typeof(String)) { - return (T)(object)((Guid)value).ToString("D", System.Globalization.CultureInfo.InvariantCulture); + else if (type == PropertyType.Guid && typeof(T) == typeof(String)) + { + return (T)(object)((Guid)value).ToString("D", System.Globalization.CultureInfo.InvariantCulture); } - else { + else + { // Iterate over the numeric scalars, to see if we have a match for one of the known conversions - foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes) { - if (numericScalar.Item1 == typeof(T)) { + foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes) + { + if (numericScalar.Item1 == typeof(T)) + { return (T)Convert.ChangeType(value, typeof(T), System.Globalization.CultureInfo.InvariantCulture); } } } } - catch (FormatException) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH); + catch (FormatException) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH); } - catch (InvalidCastException) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH); + catch (InvalidCastException) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH); } - catch (OverflowException) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueCoersion", type, value, typeof(T).Name), __HResults.DISP_E_OVERFLOW); + catch (OverflowException) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueCoersion, type, value, typeof (T).Name), __HResults.DISP_E_OVERFLOW); } // If the property type is IInspectable, and we have a nested IPropertyValue, then we need // to pass along the request to coerce the value. IPropertyValue ipv = value as IPropertyValue; - if (type == PropertyType.Inspectable && ipv != null) { - if (typeof(T) == typeof(Byte)) { + if (type == PropertyType.Inspectable && ipv != null) + { + if (typeof(T) == typeof(Byte)) + { return (T)(object)ipv.GetUInt8(); } - else if (typeof(T) == typeof(Int16)) { + else if (typeof(T) == typeof(Int16)) + { return (T)(object)ipv.GetInt16(); } - else if (typeof(T) == typeof(UInt16)) { + else if (typeof(T) == typeof(UInt16)) + { return (T)(object)ipv.GetUInt16(); } - else if (typeof(T) == typeof(Int32)) { + else if (typeof(T) == typeof(Int32)) + { return (T)(object)ipv.GetUInt32(); } - else if (typeof(T) == typeof(UInt32)) { + else if (typeof(T) == typeof(UInt32)) + { return (T)(object)ipv.GetUInt32(); } - else if (typeof(T) == typeof(Int64)) { + else if (typeof(T) == typeof(Int64)) + { return (T)(object)ipv.GetInt64(); } - else if (typeof(T) == typeof(UInt64)) { + else if (typeof(T) == typeof(UInt64)) + { return (T)(object)ipv.GetUInt64(); } - else if (typeof(T) == typeof(Single)) { + else if (typeof(T) == typeof(Single)) + { return (T)(object)ipv.GetSingle(); } - else if (typeof(T) == typeof(Double)) { + else if (typeof(T) == typeof(Double)) + { return (T)(object)ipv.GetDouble(); } - else { + else + { BCLDebug.Assert(false, "T in coersion function wasn't understood as a type that can be coerced - make sure that CoerceScalarValue and NumericScalarTypes are in sync"); } } // Otherwise, this is an invalid coersion - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH); + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH); } - private static bool IsCoercable(PropertyType type, object data) { + private static bool IsCoercable(PropertyType type, object data) + { // String <--> Guid is allowed - if (type == PropertyType.Guid || type == PropertyType.String) { + if (type == PropertyType.Guid || type == PropertyType.String) + { return true; } @@ -474,13 +512,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime return IsNumericScalarImpl(type, data); } - private static bool IsNumericScalarImpl(PropertyType type, object data) { - if (data.GetType().IsEnum) { + private static bool IsNumericScalarImpl(PropertyType type, object data) + { + if (data.GetType().IsEnum) + { return true; } - foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes) { - if (numericScalar.Item2 == type) { + foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes) + { + if (numericScalar.Item2 == type) + { return true; } } @@ -490,42 +532,50 @@ namespace System.Runtime.InteropServices.WindowsRuntime // Unbox the data stored in the property value to a structurally equivilent type [Pure] - private unsafe T Unbox<T>(Type expectedBoxedType) where T : struct { + private unsafe T Unbox<T>(Type expectedBoxedType) where T : struct + { Contract.Requires(expectedBoxedType != null); Contract.Requires(Marshal.SizeOf(expectedBoxedType) == Marshal.SizeOf(typeof(T))); - if (_data.GetType() != expectedBoxedType) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", _data.GetType(), expectedBoxedType.Name), __HResults.TYPE_E_TYPEMISMATCH); + if (_data.GetType() != expectedBoxedType) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, _data.GetType(), expectedBoxedType.Name), __HResults.TYPE_E_TYPEMISMATCH); } T unboxed = new T(); - fixed (byte *pData = &JitHelpers.GetPinningHelper(_data).m_data) { + fixed (byte* pData = &JitHelpers.GetPinningHelper(_data).m_data) + { byte* pUnboxed = (byte*)JitHelpers.UnsafeCastToStackPointer(ref unboxed); Buffer.Memcpy(pUnboxed, pData, Marshal.SizeOf(unboxed)); } - + return unboxed; } // Convert the array stored in the property value to a structurally equivilent array type [Pure] - private unsafe T[] UnboxArray<T>(Type expectedArrayElementType) where T : struct { + private unsafe T[] UnboxArray<T>(Type expectedArrayElementType) where T : struct + { Contract.Requires(expectedArrayElementType != null); Contract.Requires(Marshal.SizeOf(expectedArrayElementType) == Marshal.SizeOf(typeof(T))); Array dataArray = _data as Array; - if (dataArray == null || _data.GetType().GetElementType() != expectedArrayElementType) { - throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", _data.GetType(), expectedArrayElementType.MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH); + if (dataArray == null || _data.GetType().GetElementType() != expectedArrayElementType) + { + throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, _data.GetType(), expectedArrayElementType.MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH); } T[] converted = new T[dataArray.Length]; - if (converted.Length > 0) { - fixed (byte * dataPin = &JitHelpers.GetPinningHelper(dataArray).m_data) { - fixed (byte * convertedPin = &JitHelpers.GetPinningHelper(converted).m_data) { - byte *pData = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(dataArray, 0); - byte *pConverted = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(converted, 0); + if (converted.Length > 0) + { + fixed (byte* dataPin = &JitHelpers.GetPinningHelper(dataArray).m_data) + { + fixed (byte* convertedPin = &JitHelpers.GetPinningHelper(converted).m_data) + { + byte* pData = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(dataArray, 0); + byte* pConverted = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(converted, 0); Buffer.Memcpy(pConverted, pData, checked(Marshal.SizeOf(typeof(T)) * converted.Length)); } |