Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SqlServices.cs
- TreeIterators.cs
- XmlnsDefinitionAttribute.cs
- categoryentry.cs
- SafeEventLogReadHandle.cs
- BoolExpression.cs
- ListViewCancelEventArgs.cs
- TripleDES.cs
- SequenceNumber.cs
- OdbcDataReader.cs
- XmlComment.cs
- ConfigurationManagerHelper.cs
- IFlowDocumentViewer.cs
- EventItfInfo.cs
- SamlAttributeStatement.cs
- CalendarDateRange.cs
- _SecureChannel.cs
- PolyLineSegment.cs
- FrameworkContentElement.cs
- XmlAttributes.cs
- SqlDependencyUtils.cs
- XmlSchemaFacet.cs
- ICollection.cs
- WebPartConnectionsConfigureVerb.cs
- HttpChannelBindingToken.cs
- XsdValidatingReader.cs
- WebPartMenuStyle.cs
- WindowsAuthenticationEventArgs.cs
- ExceptionUtil.cs
- RepeatButtonAutomationPeer.cs
- ListDesigner.cs
- HtmlInputButton.cs
- SelectionHighlightInfo.cs
- StylusSystemGestureEventArgs.cs
- MemoryFailPoint.cs
- SpecialNameAttribute.cs
- Attributes.cs
- _ContextAwareResult.cs
- HtmlTextArea.cs
- PersonalizationStateInfo.cs
- Selection.cs
- CopyOnWriteList.cs
- SQLInt64.cs
- ConcurrentDictionary.cs
- TextRangeAdaptor.cs
- EventToken.cs
- PathFigureCollection.cs
- NullPackagingPolicy.cs
- AuthenticationModulesSection.cs
- GlobalEventManager.cs
- MessageDesigner.cs
- WebPart.cs
- StatusStrip.cs
- QueryAsyncResult.cs
- SettingsBindableAttribute.cs
- QueryModel.cs
- TimestampInformation.cs
- FontDriver.cs
- WebUtil.cs
- DockingAttribute.cs
- XmlSchemaAnnotation.cs
- NegotiationTokenProvider.cs
- TextRange.cs
- SecurityCriticalDataForSet.cs
- WebPartDisplayMode.cs
- SqlGatherConsumedAliases.cs
- TemplateXamlParser.cs
- HttpChannelListener.cs
- WebPageTraceListener.cs
- ResponseBodyWriter.cs
- CodeLabeledStatement.cs
- SwitchLevelAttribute.cs
- SecurityTokenSpecification.cs
- ExtensionWindowHeader.cs
- FilteredAttributeCollection.cs
- InProcStateClientManager.cs
- PerformanceCounter.cs
- JsonObjectDataContract.cs
- HttpApplicationStateBase.cs
- EncryptedType.cs
- ScrollBarRenderer.cs
- HttpConfigurationContext.cs
- TypeUsage.cs
- VectorCollection.cs
- MergablePropertyAttribute.cs
- LayoutDump.cs
- XamlRtfConverter.cs
- InstanceStoreQueryResult.cs
- QueryableDataSourceHelper.cs
- RetriableClipboard.cs
- NamespaceList.cs
- QuotedPrintableStream.cs
- HttpResponseHeader.cs
- AffineTransform3D.cs
- RawStylusActions.cs
- DispatchChannelSink.cs
- ThreadInterruptedException.cs
- ColorTransform.cs
- ExpressionConverter.cs
- DateTimeOffset.cs