ClientConvert.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ClientConvert.cs / 1 / ClientConvert.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
// static utility functions for conversion
//  
//--------------------------------------------------------------------- 

namespace System.Data.Services.Client 
{
    using System;
    using System.Collections.Generic;
    using System.Linq; 
    using System.Diagnostics;
    using System.Xml; 
 
    /// 
    /// static utility functions for conversions 
    /// 
    internal static class ClientConvert
    {
#if !ASTORIA_LIGHT // System.Data.Linq not available 
        /// fullname for assembly
        private const string SystemDataLinq = "System.Data.Linq, Version=" + FX35Assembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken; 
#endif 

        /// list of known value (and reference) types 
        /// 
        /// examples of unsupported value types
        /// IntPtr, UIntPtr, byte*, char*
        ///  
        private static readonly Type[] knownTypes = CreateKnownPrimitives();
 
        /// mapping of type names to type 
        private static readonly Dictionary namedTypesMap = CreateKnownNamesMap();
 
#if !ASTORIA_LIGHT // System.Data.Linq not available
        /// has System.Data.Link.Binary not been delay loaded yet
        private static bool needSystemDataLinqBinary = true;
#endif 

        /// StorageType enum 
        internal enum StorageType 
        {
            /// Boolean 
            Boolean,

            /// Byte
            Byte, 

            /// ByteArray 
            ByteArray, 

            /// Char 
            Char,

            /// CharArray
            CharArray, 

            /// DateTime 
            DateTime, 

            /// DateTimeOffset 
            DateTimeOffset,

            /// Decimal
            Decimal, 

            /// Double 
            Double, 

            /// Guid 
            Guid,

            /// Int16
            Int16, 

            /// Int32 
            Int32, 

            /// Int64 
            Int64,

            /// Single
            Single, 

            /// String 
            String, 

            /// SByte 
            SByte,

            /// TimeSpan
            TimeSpan, 

            /// Type 
            Type, 

            /// UInt16 
            UInt16,

            /// UInt32
            UInt32, 

            /// UInt64 
            UInt64, 

            /// Uri 
            Uri,

            /// System.Xml.Linq.XDocument
            XDocument, 

            /// System.Xml.Linq.XElement 
            XElement, 

#if !ASTORIA_LIGHT // System.Data.Linq not available 
            /// System.Data.Linq.Binary
            Binary,
#endif
        } 

        ///  
        /// convert from string to the appropriate type 
        /// 
        /// incoming string value 
        /// type to convert to
        /// converted value
        internal static object ChangeType(string propertyValue, Type propertyType)
        { 
            Debug.Assert(null != propertyValue, "should never be passed null");
            try 
            { 
                switch ((StorageType)IndexOfStorage(propertyType))
                { 
                    case StorageType.Boolean:
                        return XmlConvert.ToBoolean(propertyValue);
                    case StorageType.Byte:
                        return XmlConvert.ToByte(propertyValue); 
                    case StorageType.ByteArray:
                        return Convert.FromBase64String(propertyValue); 
                    case StorageType.Char: 
                        return XmlConvert.ToChar(propertyValue);
                    case StorageType.CharArray: 
                        return propertyValue.ToCharArray();
                    case StorageType.DateTime:
                        return XmlConvert.ToDateTime(propertyValue, XmlDateTimeSerializationMode.RoundtripKind);
                    case StorageType.DateTimeOffset: 
                        return XmlConvert.ToDateTimeOffset(propertyValue);
                    case StorageType.Decimal: 
                        return XmlConvert.ToDecimal(propertyValue); 
                    case StorageType.Double:
                        return XmlConvert.ToDouble(propertyValue); 
                    case StorageType.Guid:
                        return new Guid(propertyValue);
                    case StorageType.Int16:
                        return XmlConvert.ToInt16(propertyValue); 
                    case StorageType.Int32:
                        return XmlConvert.ToInt32(propertyValue); 
                    case StorageType.Int64: 
                        return XmlConvert.ToInt64(propertyValue);
                    case StorageType.Single: 
                        return XmlConvert.ToSingle(propertyValue);
                    case StorageType.String:
                        return propertyValue;
                    case StorageType.SByte: 
                        return XmlConvert.ToSByte(propertyValue);
                    case StorageType.TimeSpan: 
                        return XmlConvert.ToTimeSpan(propertyValue); 
                    case StorageType.Type:
                        return Type.GetType(propertyValue, true); 
                    case StorageType.UInt16:
                        return XmlConvert.ToUInt16(propertyValue);
                    case StorageType.UInt32:
                        return XmlConvert.ToUInt32(propertyValue); 
                    case StorageType.UInt64:
                        return XmlConvert.ToUInt64(propertyValue); 
                    case StorageType.Uri: 
                        return Util.CreateUri(propertyValue, UriKind.RelativeOrAbsolute);
                    case StorageType.XDocument: 
                        return (0 < propertyValue.Length ? System.Xml.Linq.XDocument.Parse(propertyValue) : new System.Xml.Linq.XDocument());
                    case StorageType.XElement:
                        return System.Xml.Linq.XElement.Parse(propertyValue);
#if !ASTORIA_LIGHT // System.Data.Linq not available 
                    case StorageType.Binary:
                        Debug.Assert(null != knownTypes[(int)StorageType.Binary], "null typeof(System.Data.Linq.Binary)"); 
                        return Activator.CreateInstance(knownTypes[(int)StorageType.Binary], Convert.FromBase64String(propertyValue)); 
#endif
                    default: 
                        Debug.Assert(false, "new StorageType without update to knownTypes");
                        return propertyValue;
                }
            } 
            catch (FormatException ex)
            { 
                propertyValue = (0 == propertyValue.Length ? "String.Empty" : "String"); 
                throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex);
            } 
            catch (OverflowException ex)
            {
                propertyValue = (0 == propertyValue.Length ? "String.Empty" : "String");
                throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex); 
            }
        } 
 
#if !ASTORIA_LIGHT
        /// Determines whether the specified value is a System.Data.Linq.Binary value. 
        /// Value to check.
        /// true if the value is a System.Data.Linq.Binary value; false otherwise.
        internal static bool IsBinaryValue(object value)
        { 
            Debug.Assert(value != null, "value != null");
            return StorageType.Binary == (StorageType)IndexOfStorage(value.GetType()); 
        } 

        /// Converts the specified System.Data.Linq.Binary to a serializable string for URI key. 
        /// Non-null value to convert.
        /// out parameter for value converted to a serializable string for URI key.
        /// true/ false indicating success
        internal static bool TryKeyBinaryToString(object binaryValue, out string result) 
        {
            Debug.Assert(binaryValue != null, "binaryValue != null"); 
            Debug.Assert(IsBinaryValue(binaryValue), "IsBinaryValue(binaryValue) - otherwise TryKeyBinaryToString shouldn't have been called."); 
            const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod;
            byte[] bytes = (byte[])binaryValue.GetType().InvokeMember("ToArray", Flags, null, binaryValue, null, System.Globalization.CultureInfo.InvariantCulture); 
            return System.Data.Services.Parsing.WebConvert.TryKeyPrimitiveToString(bytes, out result);
        }
#endif
 
        /// Converts the specified value to a serializable string for URI key.
        /// Non-null value to convert. 
        /// out parameter for value converted to a serializable string for URI key. 
        /// true/ false indicating success
        ///  
        /// This is a version of WebConvert.TryKeyPrimitiveToString to be used on the client, to avoid
        /// referencing System.Data.Linq.Binary unless required.
        /// 
        internal static bool TryKeyPrimitiveToString(object value, out string result) 
        {
            Debug.Assert(value != null, "value != null"); 
#if !ASTORIA_LIGHT 
            if (IsBinaryValue(value))
            { 
                return TryKeyBinaryToString(value, out result);
            }
#endif
            return System.Data.Services.Parsing.WebConvert.TryKeyPrimitiveToString(value, out result); 
        }
 
        ///  
        /// cast value to expected type
        ///  
        /// expected type
        /// value to cast
        /// cast value
        /// when the value can't be cast 
        internal static object VerifyCast(Type type, object value)
        { 
            if (type.IsInstanceOfType(value) || 
                ((value == null) &&
                 (!type.IsValueType || 
                  (null != Nullable.GetUnderlyingType(type)))))
            {
                return value;
            } 

            throw Error.InvalidOperation(Strings.Deserialize_Current(type.ToString(), (null != value) ? value.GetType().ToString() : "null")); 
        } 

        ///  
        /// change primtive typeName into non-nullable type
        /// 
        /// like Edm.String or Edm.Binary
        /// the mapped output type 
        /// true if named
        internal static bool ToNamedType(string typeName, out Type type) 
        { 
            type = typeof(string);
            return String.IsNullOrEmpty(typeName) || ClientConvert.namedTypesMap.TryGetValue(typeName, out type); 
        }

        /// Change primitive type into a well-known type name.
        /// Primitive type to get well-known name for. 
        /// The well-known name for the specified .
        internal static string ToTypeName(Type type) 
        { 
            Debug.Assert(type != null, "type != null");
            foreach (var pair in ClientConvert.namedTypesMap) 
            {
                if (pair.Value == type)
                {
                    return pair.Key; 
                }
            } 
 
            // this should never happen because a prior call to IsSupportedPrimitiveTypeForUri
            return type.FullName; 
        }

        /// 
        /// convert from primitive value to a xml payload string 
        /// 
        /// incoming object value 
        /// converted value 
        internal static string ToString(object propertyValue)
        { 
            Debug.Assert(null != propertyValue, "null should be handled by caller");
            switch ((StorageType)IndexOfStorage(propertyValue.GetType()))
            {
                case StorageType.Boolean: 
                    return XmlConvert.ToString((bool)propertyValue);
                case StorageType.Byte: 
                    return XmlConvert.ToString((byte)propertyValue); 
                case StorageType.ByteArray:
                    return Convert.ToBase64String((byte[])propertyValue); 
                case StorageType.Char:
                    return XmlConvert.ToString((char)propertyValue);
                case StorageType.CharArray:
                    return new String((char[])propertyValue); 
                case StorageType.DateTime:
                    return XmlConvert.ToString((DateTime)propertyValue, XmlDateTimeSerializationMode.RoundtripKind); 
                case StorageType.DateTimeOffset: 
                    return XmlConvert.ToString((DateTimeOffset)propertyValue);
                case StorageType.Decimal: 
                    return XmlConvert.ToString((Decimal)propertyValue);
                case StorageType.Double:
                    return XmlConvert.ToString((Double)propertyValue);
                case StorageType.Guid: 
                    return ((Guid)propertyValue).ToString();
                case StorageType.Int16: 
                    return XmlConvert.ToString((Int16)propertyValue); 
                case StorageType.Int32:
                    return XmlConvert.ToString((Int32)propertyValue); 
                case StorageType.Int64:
                    return XmlConvert.ToString((Int64)propertyValue);
                case StorageType.Single:
                    return XmlConvert.ToString((Single)propertyValue); 
                case StorageType.String:
                    return (String)propertyValue; 
                case StorageType.SByte: 
                    return XmlConvert.ToString((SByte)propertyValue);
                case StorageType.TimeSpan: 
                    return XmlConvert.ToString((TimeSpan)propertyValue);
                case StorageType.Type:
                    return ((Type)propertyValue).AssemblyQualifiedName;
                case StorageType.UInt16: 
                    return XmlConvert.ToString((UInt16)propertyValue);
                case StorageType.UInt32: 
                    return XmlConvert.ToString((UInt32)propertyValue); 
                case StorageType.UInt64:
                    return XmlConvert.ToString((UInt64)propertyValue); 
                case StorageType.Uri:
                    return ((Uri)propertyValue).ToString();
                case StorageType.XDocument:
                    return ((System.Xml.Linq.XDocument)propertyValue).ToString(); 
                case StorageType.XElement:
                    return ((System.Xml.Linq.XElement)propertyValue).ToString(); 
#if !ASTORIA_LIGHT // System.Data.Linq not available 
                case StorageType.Binary:
                    Debug.Assert(null != knownTypes[(int)StorageType.Binary], "null typeof(System.Data.Linq.Binary)"); 
                    Debug.Assert(knownTypes[(int)StorageType.Binary].IsInstanceOfType(propertyValue), "not IsInstanceOfType System.Data.Linq.Binary");
                    return propertyValue.ToString();
#endif
                default: 
                    Debug.Assert(false, "new StorageType without update to knownTypes");
                    return propertyValue.ToString(); 
            } 
        }
 
        /// 
        /// Is this a known primitive type (including string,byte[],uri)
        /// 
        /// type to analyze 
        /// true if known primitive type
        internal static bool IsKnownType(Type type) 
        { 
            return (0 <= IndexOfStorage(type));
        } 

        /// 
        /// Is this a primitive type that can go in the URI
        ///  
        /// type to analyze
        /// true if known primitive type 
        internal static bool IsSupportedPrimitiveTypeForUri(Type type) 
        {
            // 
            return Util.ContainsReference(namedTypesMap.Values.ToArray(), type);
        }

        /// type edm type string for content 
        /// type to analyze
        /// edm type string for payload, null for string and unknown 
        internal static string GetEdmType(Type propertyType) 
        {
            switch ((StorageType)IndexOfStorage(propertyType)) 
            {
                case StorageType.Boolean:
                    return XmlConstants.EdmBooleanTypeName;
                case StorageType.Byte: 
                    return XmlConstants.EdmByteTypeName;
#if !ASTORIA_LIGHT // System.Data.Linq not available 
                case StorageType.Binary: 
#endif
                case StorageType.ByteArray: 
                    return XmlConstants.EdmBinaryTypeName;
                case StorageType.DateTime:
                    return XmlConstants.EdmDateTimeTypeName;
                case StorageType.Decimal: 
                    return XmlConstants.EdmDecimalTypeName;
                case StorageType.Double: 
                    return XmlConstants.EdmDoubleTypeName; 
                case StorageType.Guid:
                    return XmlConstants.EdmGuidTypeName; 
                case StorageType.Int16:
                    return XmlConstants.EdmInt16TypeName;
                case StorageType.Int32:
                    return XmlConstants.EdmInt32TypeName; 
                case StorageType.Int64:
                    return XmlConstants.EdmInt64TypeName; 
                case StorageType.Single: 
                    return XmlConstants.EdmSingleTypeName;
                case StorageType.SByte: 
                    return XmlConstants.EdmSByteTypeName;
                case StorageType.DateTimeOffset:
                case StorageType.TimeSpan:
                case StorageType.UInt16: 
                case StorageType.UInt32:
                case StorageType.UInt64: 
                    // don't support reverse mappings for these types in this version 
                    // allows us to add real server support in the future without a
                    // "breaking change" in the future client 
                    throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name));
                case StorageType.Char:
                case StorageType.CharArray:
                case StorageType.String: 
                case StorageType.Type:
                case StorageType.Uri: 
                case StorageType.XDocument: 
                case StorageType.XElement:
                    return null; // returning null which implies typeof(string) 
                default:
                    Debug.Assert(false, "knowntype without reverse mapping");
                    return null;
            } 
        }
 
        /// create list of known value (and reference) types 
        /// static list of known types matching StorageType enum
        private static Type[] CreateKnownPrimitives() 
        {
#if !ASTORIA_LIGHT // System.Data.Linq not available
            Type[] types = new Type[1 + (int)StorageType.Binary];
#else 
            Type[] types = new Type[1 + (int)StorageType.XElement];
#endif 
            types[(int)StorageType.Boolean] = typeof(Boolean); 
            types[(int)StorageType.Byte] = typeof(Byte);
            types[(int)StorageType.ByteArray] = typeof(Byte[]); 
            types[(int)StorageType.Char] = typeof(Char);
            types[(int)StorageType.CharArray] = typeof(Char[]);
            types[(int)StorageType.DateTime] = typeof(DateTime);
            types[(int)StorageType.DateTimeOffset] = typeof(DateTimeOffset); 
            types[(int)StorageType.Decimal] = typeof(Decimal);
            types[(int)StorageType.Double] = typeof(Double); 
            types[(int)StorageType.Guid] = typeof(Guid); 
            types[(int)StorageType.Int16] = typeof(Int16);
            types[(int)StorageType.Int32] = typeof(Int32); 
            types[(int)StorageType.Int64] = typeof(Int64);
            types[(int)StorageType.Single] = typeof(Single);
            types[(int)StorageType.String] = typeof(String);
            types[(int)StorageType.SByte] = typeof(SByte); 
            types[(int)StorageType.TimeSpan] = typeof(TimeSpan);
            types[(int)StorageType.Type] = typeof(Type); 
            types[(int)StorageType.UInt16] = typeof(UInt16); 
            types[(int)StorageType.UInt32] = typeof(UInt32);
            types[(int)StorageType.UInt64] = typeof(UInt64); 
            types[(int)StorageType.Uri] = typeof(Uri);
            types[(int)StorageType.XDocument] = typeof(System.Xml.Linq.XDocument);
            types[(int)StorageType.XElement] = typeof(System.Xml.Linq.XElement);
#if !ASTORIA_LIGHT // System.Data.Linq not available 
            types[(int)StorageType.Binary] = null; // delay populated
#endif 
            return types; 
        }
 
        /// generate mapping of primitive type names to type
        /// mapping of primitive type names to type
        private static Dictionary CreateKnownNamesMap()
        { 
            Dictionary named = new Dictionary();
 
            named.Add(XmlConstants.EdmStringTypeName, typeof(string)); 
            named.Add(XmlConstants.EdmBooleanTypeName, typeof(Boolean));
            named.Add(XmlConstants.EdmByteTypeName, typeof(Byte)); 
            named.Add(XmlConstants.EdmDateTimeTypeName, typeof(DateTime));
            named.Add(XmlConstants.EdmDecimalTypeName, typeof(Decimal));
            named.Add(XmlConstants.EdmDoubleTypeName, typeof(Double));
            named.Add(XmlConstants.EdmGuidTypeName, typeof(Guid)); 
            named.Add(XmlConstants.EdmInt16TypeName, typeof(Int16));
            named.Add(XmlConstants.EdmInt32TypeName, typeof(Int32)); 
            named.Add(XmlConstants.EdmInt64TypeName, typeof(Int64)); 
            named.Add(XmlConstants.EdmSByteTypeName, typeof(SByte));
            named.Add(XmlConstants.EdmSingleTypeName, typeof(Single)); 
            named.Add(XmlConstants.EdmBinaryTypeName, typeof(byte[]));
            return named;
        }
 
        /// get the StorageType for known types
        /// type being tested for known type 
        /// -1 or (int)StorageType 
        /// will validate System.Data.Linq.Binary on demand
        private static int IndexOfStorage(Type type) 
        {
            int index = Util.IndexOfReference(ClientConvert.knownTypes, type);
#if !ASTORIA_LIGHT // System.Data.Linq not available
            if ((index < 0) && needSystemDataLinqBinary && (type.Name == "Binary")) 
            {
                return LoadSystemDataLinqBinary(type); 
            } 
#endif
            return index; 
        }

#if !ASTORIA_LIGHT // System.Data.Linq not available
        /// validating type is System.Data.Linq.Binary 
        /// type to verify its System.Data.Linq.Binary
        /// -1 or (int)StorageType 
        private static int LoadSystemDataLinqBinary(Type type) 
        {
            if ((type.Namespace == "System.Data.Linq") && 
                (System.Reflection.AssemblyName.ReferenceMatchesDefinition(
                    type.Assembly.GetName(), new System.Reflection.AssemblyName(SystemDataLinq))))
            {
                ClientConvert.knownTypes[(int)StorageType.Binary] = type; 
                needSystemDataLinqBinary = false;
                return (int)StorageType.Binary; 
            } 

            return -1; 
        }
#endif
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
// static utility functions for conversion
//  
//--------------------------------------------------------------------- 

namespace System.Data.Services.Client 
{
    using System;
    using System.Collections.Generic;
    using System.Linq; 
    using System.Diagnostics;
    using System.Xml; 
 
    /// 
    /// static utility functions for conversions 
    /// 
    internal static class ClientConvert
    {
#if !ASTORIA_LIGHT // System.Data.Linq not available 
        /// fullname for assembly
        private const string SystemDataLinq = "System.Data.Linq, Version=" + FX35Assembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken; 
#endif 

        /// list of known value (and reference) types 
        /// 
        /// examples of unsupported value types
        /// IntPtr, UIntPtr, byte*, char*
        ///  
        private static readonly Type[] knownTypes = CreateKnownPrimitives();
 
        /// mapping of type names to type 
        private static readonly Dictionary namedTypesMap = CreateKnownNamesMap();
 
#if !ASTORIA_LIGHT // System.Data.Linq not available
        /// has System.Data.Link.Binary not been delay loaded yet
        private static bool needSystemDataLinqBinary = true;
#endif 

        /// StorageType enum 
        internal enum StorageType 
        {
            /// Boolean 
            Boolean,

            /// Byte
            Byte, 

            /// ByteArray 
            ByteArray, 

            /// Char 
            Char,

            /// CharArray
            CharArray, 

            /// DateTime 
            DateTime, 

            /// DateTimeOffset 
            DateTimeOffset,

            /// Decimal
            Decimal, 

            /// Double 
            Double, 

            /// Guid 
            Guid,

            /// Int16
            Int16, 

            /// Int32 
            Int32, 

            /// Int64 
            Int64,

            /// Single
            Single, 

            /// String 
            String, 

            /// SByte 
            SByte,

            /// TimeSpan
            TimeSpan, 

            /// Type 
            Type, 

            /// UInt16 
            UInt16,

            /// UInt32
            UInt32, 

            /// UInt64 
            UInt64, 

            /// Uri 
            Uri,

            /// System.Xml.Linq.XDocument
            XDocument, 

            /// System.Xml.Linq.XElement 
            XElement, 

#if !ASTORIA_LIGHT // System.Data.Linq not available 
            /// System.Data.Linq.Binary
            Binary,
#endif
        } 

        ///  
        /// convert from string to the appropriate type 
        /// 
        /// incoming string value 
        /// type to convert to
        /// converted value
        internal static object ChangeType(string propertyValue, Type propertyType)
        { 
            Debug.Assert(null != propertyValue, "should never be passed null");
            try 
            { 
                switch ((StorageType)IndexOfStorage(propertyType))
                { 
                    case StorageType.Boolean:
                        return XmlConvert.ToBoolean(propertyValue);
                    case StorageType.Byte:
                        return XmlConvert.ToByte(propertyValue); 
                    case StorageType.ByteArray:
                        return Convert.FromBase64String(propertyValue); 
                    case StorageType.Char: 
                        return XmlConvert.ToChar(propertyValue);
                    case StorageType.CharArray: 
                        return propertyValue.ToCharArray();
                    case StorageType.DateTime:
                        return XmlConvert.ToDateTime(propertyValue, XmlDateTimeSerializationMode.RoundtripKind);
                    case StorageType.DateTimeOffset: 
                        return XmlConvert.ToDateTimeOffset(propertyValue);
                    case StorageType.Decimal: 
                        return XmlConvert.ToDecimal(propertyValue); 
                    case StorageType.Double:
                        return XmlConvert.ToDouble(propertyValue); 
                    case StorageType.Guid:
                        return new Guid(propertyValue);
                    case StorageType.Int16:
                        return XmlConvert.ToInt16(propertyValue); 
                    case StorageType.Int32:
                        return XmlConvert.ToInt32(propertyValue); 
                    case StorageType.Int64: 
                        return XmlConvert.ToInt64(propertyValue);
                    case StorageType.Single: 
                        return XmlConvert.ToSingle(propertyValue);
                    case StorageType.String:
                        return propertyValue;
                    case StorageType.SByte: 
                        return XmlConvert.ToSByte(propertyValue);
                    case StorageType.TimeSpan: 
                        return XmlConvert.ToTimeSpan(propertyValue); 
                    case StorageType.Type:
                        return Type.GetType(propertyValue, true); 
                    case StorageType.UInt16:
                        return XmlConvert.ToUInt16(propertyValue);
                    case StorageType.UInt32:
                        return XmlConvert.ToUInt32(propertyValue); 
                    case StorageType.UInt64:
                        return XmlConvert.ToUInt64(propertyValue); 
                    case StorageType.Uri: 
                        return Util.CreateUri(propertyValue, UriKind.RelativeOrAbsolute);
                    case StorageType.XDocument: 
                        return (0 < propertyValue.Length ? System.Xml.Linq.XDocument.Parse(propertyValue) : new System.Xml.Linq.XDocument());
                    case StorageType.XElement:
                        return System.Xml.Linq.XElement.Parse(propertyValue);
#if !ASTORIA_LIGHT // System.Data.Linq not available 
                    case StorageType.Binary:
                        Debug.Assert(null != knownTypes[(int)StorageType.Binary], "null typeof(System.Data.Linq.Binary)"); 
                        return Activator.CreateInstance(knownTypes[(int)StorageType.Binary], Convert.FromBase64String(propertyValue)); 
#endif
                    default: 
                        Debug.Assert(false, "new StorageType without update to knownTypes");
                        return propertyValue;
                }
            } 
            catch (FormatException ex)
            { 
                propertyValue = (0 == propertyValue.Length ? "String.Empty" : "String"); 
                throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex);
            } 
            catch (OverflowException ex)
            {
                propertyValue = (0 == propertyValue.Length ? "String.Empty" : "String");
                throw Error.InvalidOperation(Strings.Deserialize_Current(propertyType.ToString(), propertyValue), ex); 
            }
        } 
 
#if !ASTORIA_LIGHT
        /// Determines whether the specified value is a System.Data.Linq.Binary value. 
        /// Value to check.
        /// true if the value is a System.Data.Linq.Binary value; false otherwise.
        internal static bool IsBinaryValue(object value)
        { 
            Debug.Assert(value != null, "value != null");
            return StorageType.Binary == (StorageType)IndexOfStorage(value.GetType()); 
        } 

        /// Converts the specified System.Data.Linq.Binary to a serializable string for URI key. 
        /// Non-null value to convert.
        /// out parameter for value converted to a serializable string for URI key.
        /// true/ false indicating success
        internal static bool TryKeyBinaryToString(object binaryValue, out string result) 
        {
            Debug.Assert(binaryValue != null, "binaryValue != null"); 
            Debug.Assert(IsBinaryValue(binaryValue), "IsBinaryValue(binaryValue) - otherwise TryKeyBinaryToString shouldn't have been called."); 
            const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod;
            byte[] bytes = (byte[])binaryValue.GetType().InvokeMember("ToArray", Flags, null, binaryValue, null, System.Globalization.CultureInfo.InvariantCulture); 
            return System.Data.Services.Parsing.WebConvert.TryKeyPrimitiveToString(bytes, out result);
        }
#endif
 
        /// Converts the specified value to a serializable string for URI key.
        /// Non-null value to convert. 
        /// out parameter for value converted to a serializable string for URI key. 
        /// true/ false indicating success
        ///  
        /// This is a version of WebConvert.TryKeyPrimitiveToString to be used on the client, to avoid
        /// referencing System.Data.Linq.Binary unless required.
        /// 
        internal static bool TryKeyPrimitiveToString(object value, out string result) 
        {
            Debug.Assert(value != null, "value != null"); 
#if !ASTORIA_LIGHT 
            if (IsBinaryValue(value))
            { 
                return TryKeyBinaryToString(value, out result);
            }
#endif
            return System.Data.Services.Parsing.WebConvert.TryKeyPrimitiveToString(value, out result); 
        }
 
        ///  
        /// cast value to expected type
        ///  
        /// expected type
        /// value to cast
        /// cast value
        /// when the value can't be cast 
        internal static object VerifyCast(Type type, object value)
        { 
            if (type.IsInstanceOfType(value) || 
                ((value == null) &&
                 (!type.IsValueType || 
                  (null != Nullable.GetUnderlyingType(type)))))
            {
                return value;
            } 

            throw Error.InvalidOperation(Strings.Deserialize_Current(type.ToString(), (null != value) ? value.GetType().ToString() : "null")); 
        } 

        ///  
        /// change primtive typeName into non-nullable type
        /// 
        /// like Edm.String or Edm.Binary
        /// the mapped output type 
        /// true if named
        internal static bool ToNamedType(string typeName, out Type type) 
        { 
            type = typeof(string);
            return String.IsNullOrEmpty(typeName) || ClientConvert.namedTypesMap.TryGetValue(typeName, out type); 
        }

        /// Change primitive type into a well-known type name.
        /// Primitive type to get well-known name for. 
        /// The well-known name for the specified .
        internal static string ToTypeName(Type type) 
        { 
            Debug.Assert(type != null, "type != null");
            foreach (var pair in ClientConvert.namedTypesMap) 
            {
                if (pair.Value == type)
                {
                    return pair.Key; 
                }
            } 
 
            // this should never happen because a prior call to IsSupportedPrimitiveTypeForUri
            return type.FullName; 
        }

        /// 
        /// convert from primitive value to a xml payload string 
        /// 
        /// incoming object value 
        /// converted value 
        internal static string ToString(object propertyValue)
        { 
            Debug.Assert(null != propertyValue, "null should be handled by caller");
            switch ((StorageType)IndexOfStorage(propertyValue.GetType()))
            {
                case StorageType.Boolean: 
                    return XmlConvert.ToString((bool)propertyValue);
                case StorageType.Byte: 
                    return XmlConvert.ToString((byte)propertyValue); 
                case StorageType.ByteArray:
                    return Convert.ToBase64String((byte[])propertyValue); 
                case StorageType.Char:
                    return XmlConvert.ToString((char)propertyValue);
                case StorageType.CharArray:
                    return new String((char[])propertyValue); 
                case StorageType.DateTime:
                    return XmlConvert.ToString((DateTime)propertyValue, XmlDateTimeSerializationMode.RoundtripKind); 
                case StorageType.DateTimeOffset: 
                    return XmlConvert.ToString((DateTimeOffset)propertyValue);
                case StorageType.Decimal: 
                    return XmlConvert.ToString((Decimal)propertyValue);
                case StorageType.Double:
                    return XmlConvert.ToString((Double)propertyValue);
                case StorageType.Guid: 
                    return ((Guid)propertyValue).ToString();
                case StorageType.Int16: 
                    return XmlConvert.ToString((Int16)propertyValue); 
                case StorageType.Int32:
                    return XmlConvert.ToString((Int32)propertyValue); 
                case StorageType.Int64:
                    return XmlConvert.ToString((Int64)propertyValue);
                case StorageType.Single:
                    return XmlConvert.ToString((Single)propertyValue); 
                case StorageType.String:
                    return (String)propertyValue; 
                case StorageType.SByte: 
                    return XmlConvert.ToString((SByte)propertyValue);
                case StorageType.TimeSpan: 
                    return XmlConvert.ToString((TimeSpan)propertyValue);
                case StorageType.Type:
                    return ((Type)propertyValue).AssemblyQualifiedName;
                case StorageType.UInt16: 
                    return XmlConvert.ToString((UInt16)propertyValue);
                case StorageType.UInt32: 
                    return XmlConvert.ToString((UInt32)propertyValue); 
                case StorageType.UInt64:
                    return XmlConvert.ToString((UInt64)propertyValue); 
                case StorageType.Uri:
                    return ((Uri)propertyValue).ToString();
                case StorageType.XDocument:
                    return ((System.Xml.Linq.XDocument)propertyValue).ToString(); 
                case StorageType.XElement:
                    return ((System.Xml.Linq.XElement)propertyValue).ToString(); 
#if !ASTORIA_LIGHT // System.Data.Linq not available 
                case StorageType.Binary:
                    Debug.Assert(null != knownTypes[(int)StorageType.Binary], "null typeof(System.Data.Linq.Binary)"); 
                    Debug.Assert(knownTypes[(int)StorageType.Binary].IsInstanceOfType(propertyValue), "not IsInstanceOfType System.Data.Linq.Binary");
                    return propertyValue.ToString();
#endif
                default: 
                    Debug.Assert(false, "new StorageType without update to knownTypes");
                    return propertyValue.ToString(); 
            } 
        }
 
        /// 
        /// Is this a known primitive type (including string,byte[],uri)
        /// 
        /// type to analyze 
        /// true if known primitive type
        internal static bool IsKnownType(Type type) 
        { 
            return (0 <= IndexOfStorage(type));
        } 

        /// 
        /// Is this a primitive type that can go in the URI
        ///  
        /// type to analyze
        /// true if known primitive type 
        internal static bool IsSupportedPrimitiveTypeForUri(Type type) 
        {
            // 
            return Util.ContainsReference(namedTypesMap.Values.ToArray(), type);
        }

        /// type edm type string for content 
        /// type to analyze
        /// edm type string for payload, null for string and unknown 
        internal static string GetEdmType(Type propertyType) 
        {
            switch ((StorageType)IndexOfStorage(propertyType)) 
            {
                case StorageType.Boolean:
                    return XmlConstants.EdmBooleanTypeName;
                case StorageType.Byte: 
                    return XmlConstants.EdmByteTypeName;
#if !ASTORIA_LIGHT // System.Data.Linq not available 
                case StorageType.Binary: 
#endif
                case StorageType.ByteArray: 
                    return XmlConstants.EdmBinaryTypeName;
                case StorageType.DateTime:
                    return XmlConstants.EdmDateTimeTypeName;
                case StorageType.Decimal: 
                    return XmlConstants.EdmDecimalTypeName;
                case StorageType.Double: 
                    return XmlConstants.EdmDoubleTypeName; 
                case StorageType.Guid:
                    return XmlConstants.EdmGuidTypeName; 
                case StorageType.Int16:
                    return XmlConstants.EdmInt16TypeName;
                case StorageType.Int32:
                    return XmlConstants.EdmInt32TypeName; 
                case StorageType.Int64:
                    return XmlConstants.EdmInt64TypeName; 
                case StorageType.Single: 
                    return XmlConstants.EdmSingleTypeName;
                case StorageType.SByte: 
                    return XmlConstants.EdmSByteTypeName;
                case StorageType.DateTimeOffset:
                case StorageType.TimeSpan:
                case StorageType.UInt16: 
                case StorageType.UInt32:
                case StorageType.UInt64: 
                    // don't support reverse mappings for these types in this version 
                    // allows us to add real server support in the future without a
                    // "breaking change" in the future client 
                    throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name));
                case StorageType.Char:
                case StorageType.CharArray:
                case StorageType.String: 
                case StorageType.Type:
                case StorageType.Uri: 
                case StorageType.XDocument: 
                case StorageType.XElement:
                    return null; // returning null which implies typeof(string) 
                default:
                    Debug.Assert(false, "knowntype without reverse mapping");
                    return null;
            } 
        }
 
        /// create list of known value (and reference) types 
        /// static list of known types matching StorageType enum
        private static Type[] CreateKnownPrimitives() 
        {
#if !ASTORIA_LIGHT // System.Data.Linq not available
            Type[] types = new Type[1 + (int)StorageType.Binary];
#else 
            Type[] types = new Type[1 + (int)StorageType.XElement];
#endif 
            types[(int)StorageType.Boolean] = typeof(Boolean); 
            types[(int)StorageType.Byte] = typeof(Byte);
            types[(int)StorageType.ByteArray] = typeof(Byte[]); 
            types[(int)StorageType.Char] = typeof(Char);
            types[(int)StorageType.CharArray] = typeof(Char[]);
            types[(int)StorageType.DateTime] = typeof(DateTime);
            types[(int)StorageType.DateTimeOffset] = typeof(DateTimeOffset); 
            types[(int)StorageType.Decimal] = typeof(Decimal);
            types[(int)StorageType.Double] = typeof(Double); 
            types[(int)StorageType.Guid] = typeof(Guid); 
            types[(int)StorageType.Int16] = typeof(Int16);
            types[(int)StorageType.Int32] = typeof(Int32); 
            types[(int)StorageType.Int64] = typeof(Int64);
            types[(int)StorageType.Single] = typeof(Single);
            types[(int)StorageType.String] = typeof(String);
            types[(int)StorageType.SByte] = typeof(SByte); 
            types[(int)StorageType.TimeSpan] = typeof(TimeSpan);
            types[(int)StorageType.Type] = typeof(Type); 
            types[(int)StorageType.UInt16] = typeof(UInt16); 
            types[(int)StorageType.UInt32] = typeof(UInt32);
            types[(int)StorageType.UInt64] = typeof(UInt64); 
            types[(int)StorageType.Uri] = typeof(Uri);
            types[(int)StorageType.XDocument] = typeof(System.Xml.Linq.XDocument);
            types[(int)StorageType.XElement] = typeof(System.Xml.Linq.XElement);
#if !ASTORIA_LIGHT // System.Data.Linq not available 
            types[(int)StorageType.Binary] = null; // delay populated
#endif 
            return types; 
        }
 
        /// generate mapping of primitive type names to type
        /// mapping of primitive type names to type
        private static Dictionary CreateKnownNamesMap()
        { 
            Dictionary named = new Dictionary();
 
            named.Add(XmlConstants.EdmStringTypeName, typeof(string)); 
            named.Add(XmlConstants.EdmBooleanTypeName, typeof(Boolean));
            named.Add(XmlConstants.EdmByteTypeName, typeof(Byte)); 
            named.Add(XmlConstants.EdmDateTimeTypeName, typeof(DateTime));
            named.Add(XmlConstants.EdmDecimalTypeName, typeof(Decimal));
            named.Add(XmlConstants.EdmDoubleTypeName, typeof(Double));
            named.Add(XmlConstants.EdmGuidTypeName, typeof(Guid)); 
            named.Add(XmlConstants.EdmInt16TypeName, typeof(Int16));
            named.Add(XmlConstants.EdmInt32TypeName, typeof(Int32)); 
            named.Add(XmlConstants.EdmInt64TypeName, typeof(Int64)); 
            named.Add(XmlConstants.EdmSByteTypeName, typeof(SByte));
            named.Add(XmlConstants.EdmSingleTypeName, typeof(Single)); 
            named.Add(XmlConstants.EdmBinaryTypeName, typeof(byte[]));
            return named;
        }
 
        /// get the StorageType for known types
        /// type being tested for known type 
        /// -1 or (int)StorageType 
        /// will validate System.Data.Linq.Binary on demand
        private static int IndexOfStorage(Type type) 
        {
            int index = Util.IndexOfReference(ClientConvert.knownTypes, type);
#if !ASTORIA_LIGHT // System.Data.Linq not available
            if ((index < 0) && needSystemDataLinqBinary && (type.Name == "Binary")) 
            {
                return LoadSystemDataLinqBinary(type); 
            } 
#endif
            return index; 
        }

#if !ASTORIA_LIGHT // System.Data.Linq not available
        /// validating type is System.Data.Linq.Binary 
        /// type to verify its System.Data.Linq.Binary
        /// -1 or (int)StorageType 
        private static int LoadSystemDataLinqBinary(Type type) 
        {
            if ((type.Namespace == "System.Data.Linq") && 
                (System.Reflection.AssemblyName.ReferenceMatchesDefinition(
                    type.Assembly.GetName(), new System.Reflection.AssemblyName(SystemDataLinq))))
            {
                ClientConvert.knownTypes[(int)StorageType.Binary] = type; 
                needSystemDataLinqBinary = false;
                return (int)StorageType.Binary; 
            } 

            return -1; 
        }
#endif
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK