ClientConvert.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ClientConvert.cs / 1305376 / ClientConvert.cs

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

namespace System.Data.Services.Client 
{
    #region Namespaces.

    using System; 
    using System.Collections.Generic;
    using System.Diagnostics; 
    using System.Linq; 
    using System.Xml;
 
    #endregion Namespaces.

    /// 
    /// 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=" + FXAssembly.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);
        } 

        /// 
        /// 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 an xml payload string. 
        /// NOTE: We need to pay special attention to DateTimes - if the converted value is going to be used as a content of 
        /// atom:updated or atom:published element we have to ensure it contains information about time zone. At the same time we
        /// must not touch datetime values that in content or are mapped to custom elements. 
        /// 
        /// incoming object value
        /// whether the converted value is going to be used as a content of an atom
        /// element of atomDateConstruct type (e.g. atom:updated or atom:published) 
        /// converted value
        internal static string ToString(object propertyValue, bool atomDateConstruct) 
        { 
            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:
                    DateTime dt = (DateTime)propertyValue; 
                    /* If the dt.Kind == DateTimeKind.Unspecified XmlConvert will not add information about timezone to the resulting datetime
                       string. For atom:published and atom:updated elements information about timezone is required otherwise the message is not 
                       a valid atom message. To get the information about timezone we need to make datetimes of Unspecified kind become UniversalTime. 
                       We do it the same way as we do it in JsonWriter class.
                       WE MUST NOT TOUCH THE DATE IF IT IS NOT GOING TO BE USED FOR atom:updated OR atom:published ELEMENTS (i.e. isForAtomElement == false). */ 
                    return XmlConvert.ToString(dt.Kind == DateTimeKind.Unspecified && atomDateConstruct ? new DateTime(dt.Ticks, DateTimeKind.Utc) : dt, 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 known primitive type or a nullable based on a primitive type (including string,byte[],uri) 
        /// 
        /// type to analyze, possibly nullable 
        /// true if known primitive type or a nullable based on a primitive type
        internal static bool IsKnownNullableType(Type type)
        {
            return IsKnownType(Nullable.GetUnderlyingType(type) ?? 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(EqualityComparer.Default);

            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 
{
    #region Namespaces.

    using System; 
    using System.Collections.Generic;
    using System.Diagnostics; 
    using System.Linq; 
    using System.Xml;
 
    #endregion Namespaces.

    /// 
    /// 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=" + FXAssembly.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);
        } 

        /// 
        /// 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 an xml payload string. 
        /// NOTE: We need to pay special attention to DateTimes - if the converted value is going to be used as a content of 
        /// atom:updated or atom:published element we have to ensure it contains information about time zone. At the same time we
        /// must not touch datetime values that in content or are mapped to custom elements. 
        /// 
        /// incoming object value
        /// whether the converted value is going to be used as a content of an atom
        /// element of atomDateConstruct type (e.g. atom:updated or atom:published) 
        /// converted value
        internal static string ToString(object propertyValue, bool atomDateConstruct) 
        { 
            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:
                    DateTime dt = (DateTime)propertyValue; 
                    /* If the dt.Kind == DateTimeKind.Unspecified XmlConvert will not add information about timezone to the resulting datetime
                       string. For atom:published and atom:updated elements information about timezone is required otherwise the message is not 
                       a valid atom message. To get the information about timezone we need to make datetimes of Unspecified kind become UniversalTime. 
                       We do it the same way as we do it in JsonWriter class.
                       WE MUST NOT TOUCH THE DATE IF IT IS NOT GOING TO BE USED FOR atom:updated OR atom:published ELEMENTS (i.e. isForAtomElement == false). */ 
                    return XmlConvert.ToString(dt.Kind == DateTimeKind.Unspecified && atomDateConstruct ? new DateTime(dt.Ticks, DateTimeKind.Utc) : dt, 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 known primitive type or a nullable based on a primitive type (including string,byte[],uri) 
        /// 
        /// type to analyze, possibly nullable 
        /// true if known primitive type or a nullable based on a primitive type
        internal static bool IsKnownNullableType(Type type)
        {
            return IsKnownType(Nullable.GetUnderlyingType(type) ?? 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(EqualityComparer.Default);

            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