You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			592 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			592 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //---------------------------------------------------------------------
 | |
| // <copyright file="Helper.cs" company="Microsoft">
 | |
| //      Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| //
 | |
| // @owner       Microsoft
 | |
| // @backupOwner Microsoft
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| namespace System.Data.Metadata.Edm
 | |
| {
 | |
|     using System.Collections;
 | |
|     using System.Collections.Generic;
 | |
|     using System.Diagnostics;
 | |
|     using System.Linq;
 | |
|     using System.Text;
 | |
|     using System.Xml;
 | |
|     using System.Xml.XPath;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Helper Class for EDM Metadata - this class contains all the helper methods
 | |
|     /// which only accesses public methods/properties. The other partial class contains all 
 | |
|     /// helper methods which just uses internal methods/properties. The reason why we 
 | |
|     /// did this for allowing view gen to happen at compile time - all the helper
 | |
|     /// methods that view gen or mapping uses are in this class. Rest of the
 | |
|     /// methods are in this class
 | |
|     /// </summary>
 | |
|     internal static partial class Helper
 | |
|     {
 | |
|         #region Fields
 | |
|         internal static readonly EdmMember[] EmptyArrayEdmProperty = new EdmMember[0];
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Methods
 | |
|         /// <summary>
 | |
|         /// The method wraps the GetAttribute method on XPathNavigator.
 | |
|         /// The problem with using the method directly is that the 
 | |
|         /// Get Attribute method does not differentiate the absence of an attribute and
 | |
|         /// having an attribute with Empty string value. In both cases the value returned is an empty string.
 | |
|         /// So in case of optional attributes, it becomes hard to distinguish the case whether the 
 | |
|         /// xml contains the attribute with empty string or doesn't contain the attribute
 | |
|         /// This method will return null if the attribute is not present and otherwise will return the
 | |
|         /// attribute value.
 | |
|         /// </summary>
 | |
|         /// <param name="nav"></param>
 | |
|         /// <param name="attributeName">name of the attribute</param>
 | |
|         /// <returns></returns>
 | |
|         static internal string GetAttributeValue(XPathNavigator nav, 
 | |
|                                                  string attributeName)
 | |
|         {
 | |
|             //Clone the navigator so that there wont be any sideeffects on the passed in Navigator
 | |
|             nav = nav.Clone();
 | |
|             string attributeValue = null;
 | |
|             if (nav.MoveToAttribute(attributeName, string.Empty))
 | |
|             {
 | |
|                 attributeValue = nav.Value;
 | |
|             }
 | |
|             return attributeValue;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The method returns typed attribute value of the specified xml attribute.
 | |
|         /// The method does not do any specific casting but uses the methods on XPathNavigator.
 | |
|         /// </summary>
 | |
|         /// <param name="nav"></param>
 | |
|         /// <param name="attributeName"></param>
 | |
|         /// <param name="clrType"></param>
 | |
|         /// <returns></returns>
 | |
|         internal static object GetTypedAttributeValue(XPathNavigator nav, 
 | |
|                                                      string attributeName,
 | |
|                                                      Type clrType) 
 | |
|         {
 | |
|             //Clone the navigator so that there wont be any sideeffects on the passed in Navigator
 | |
|             nav = nav.Clone();
 | |
|             object attributeValue = null;
 | |
|             if (nav.MoveToAttribute(attributeName, string.Empty))
 | |
|             {
 | |
|                 attributeValue = nav.ValueAs(clrType);
 | |
|             }
 | |
|             return attributeValue;
 | |
|         }
 | |
|         
 | |
|         /// <summary>
 | |
|         /// Searches for Facet Description with the name specified. 
 | |
|         /// </summary>
 | |
|         /// <param name="facetCollection">Collection of facet description</param>
 | |
|         /// <param name="facetName">name of the facet</param>
 | |
|         /// <returns></returns>
 | |
|         internal static FacetDescription GetFacet(IEnumerable<FacetDescription> facetCollection, string facetName)
 | |
|         {
 | |
|             foreach (FacetDescription facetDescription in facetCollection)
 | |
|             {
 | |
|                 if (facetDescription.FacetName == facetName)
 | |
|                 {
 | |
|                     return facetDescription;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         // requires: firstType is not null
 | |
|         // effects: Returns true iff firstType is assignable from secondType
 | |
|         internal static bool IsAssignableFrom(EdmType firstType, EdmType secondType)
 | |
|         {
 | |
|             Debug.Assert(firstType != null, "firstType should not be not null");
 | |
|             if (secondType == null)
 | |
|             {
 | |
|                 return false;
 | |
|             }
 | |
|             return firstType.Equals(secondType) || IsSubtypeOf(secondType, firstType);
 | |
|         }
 | |
| 
 | |
|         // requires: firstType is not null
 | |
|         // effects: if otherType is among the base types, return true, 
 | |
|         // otherwise returns false.
 | |
|         // when othertype is same as the current type, return false.
 | |
|         internal static bool IsSubtypeOf(EdmType firstType, EdmType secondType)
 | |
|         {
 | |
|             Debug.Assert(firstType != null, "firstType should not be not null");
 | |
|             if (secondType == null)
 | |
|             {
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|             // walk up my type hierarchy list
 | |
|             for (EdmType t = firstType.BaseType; t != null; t = t.BaseType)
 | |
|             {
 | |
|                 if (t == secondType)
 | |
|                     return true;
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         internal static IList GetAllStructuralMembers(EdmType edmType)
 | |
|         {
 | |
|             switch (edmType.BuiltInTypeKind)
 | |
|             {
 | |
|                 case BuiltInTypeKind.AssociationType:
 | |
|                     return ((AssociationType)edmType).AssociationEndMembers;
 | |
|                 case BuiltInTypeKind.ComplexType:
 | |
|                     return ((ComplexType)edmType).Properties;
 | |
|                 case BuiltInTypeKind.EntityType:
 | |
|                     return ((EntityType)edmType).Properties;
 | |
|                 case BuiltInTypeKind.RowType:
 | |
|                     return ((RowType)edmType).Properties;
 | |
|                 default:
 | |
|                     return EmptyArrayEdmProperty;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal static AssociationEndMember GetEndThatShouldBeMappedToKey(AssociationType associationType)
 | |
|         {
 | |
|             //For 1:* and 1:0..1 associations, the end other than 1 i.e. either * or 0..1 ends need to be 
 | |
|             //mapped to key columns
 | |
|             if (associationType.AssociationEndMembers.Any( it =>
 | |
|                 it.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One)))
 | |
|             {
 | |
|                 {
 | |
|                     return associationType.AssociationEndMembers.SingleOrDefault(it =>
 | |
|                         ((it.RelationshipMultiplicity.Equals(RelationshipMultiplicity.Many))
 | |
|                          || (it.RelationshipMultiplicity.Equals(RelationshipMultiplicity.ZeroOrOne))));
 | |
|                 }
 | |
|             }
 | |
|             //For 0..1:* associations, * end must be mapped to key.
 | |
|             else if (associationType.AssociationEndMembers.Any(it => 
 | |
|                 (it.RelationshipMultiplicity.Equals(RelationshipMultiplicity.ZeroOrOne))))
 | |
|             {
 | |
|                 {
 | |
|                     return associationType.AssociationEndMembers.SingleOrDefault(it =>
 | |
|                         ((it.RelationshipMultiplicity.Equals(RelationshipMultiplicity.Many))));
 | |
|                 }
 | |
|             }                
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a single comma delimited string given a list of strings
 | |
|         /// </summary>
 | |
|         /// <param name="stringList"></param>
 | |
|         /// <returns></returns>
 | |
|         internal static String GetCommaDelimitedString(IEnumerable<string> stringList)
 | |
|         {
 | |
|             Debug.Assert(stringList != null , "Expecting a non null list");
 | |
|             StringBuilder sb = new StringBuilder();
 | |
|             bool first = true;
 | |
|             foreach (string part in stringList)
 | |
|             {
 | |
|                 if (!first)
 | |
|                 {
 | |
|                     sb.Append(", ");
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     first = false;
 | |
|                 }
 | |
|                 
 | |
|                 sb.Append(part);
 | |
|             }
 | |
|             return sb.ToString();
 | |
|         }
 | |
| 
 | |
|         
 | |
|         // effects: concatenates all given enumerations
 | |
|         internal static IEnumerable<T> Concat<T>(params IEnumerable<T>[] sources)
 | |
|         {
 | |
|             foreach (IEnumerable<T> source in sources)
 | |
|             {
 | |
|                 if (null != source)
 | |
|                 {
 | |
|                     foreach (T element in source)
 | |
|                     {
 | |
|                         yield return element;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal static void DisposeXmlReaders(IEnumerable<XmlReader> xmlReaders)
 | |
|         {
 | |
|             Debug.Assert(xmlReaders != null);
 | |
| 
 | |
|             foreach (XmlReader xmlReader in xmlReaders)
 | |
|             {
 | |
|                 ((IDisposable)xmlReader).Dispose();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region IsXXXType Methods
 | |
|         internal static bool IsStructuralType(EdmType type)
 | |
|         {
 | |
|             return (IsComplexType(type) || IsEntityType(type) || IsRelationshipType(type) || IsRowType(type));
 | |
|         }
 | |
| 
 | |
|         internal static bool IsCollectionType(GlobalItem item)
 | |
|         {
 | |
|             return (BuiltInTypeKind.CollectionType == item.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEntityType(EdmType type)
 | |
|         {
 | |
|             return (BuiltInTypeKind.EntityType == type.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsComplexType(EdmType type)
 | |
|         {
 | |
|             return (BuiltInTypeKind.ComplexType == type.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsPrimitiveType(EdmType type)
 | |
|         {
 | |
|             return (BuiltInTypeKind.PrimitiveType == type.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsRefType(GlobalItem item)
 | |
|         {
 | |
|             return (BuiltInTypeKind.RefType == item.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsRowType(GlobalItem item)
 | |
|         {
 | |
|             return (BuiltInTypeKind.RowType == item.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsAssociationType(EdmType type)
 | |
|         {
 | |
|             return (BuiltInTypeKind.AssociationType == type.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsRelationshipType(EdmType type)
 | |
|         {
 | |
|             return (BuiltInTypeKind.AssociationType == type.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEdmProperty(EdmMember member)
 | |
|         {
 | |
|             return (BuiltInTypeKind.EdmProperty == member.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsRelationshipEndMember(EdmMember member)
 | |
|         {
 | |
|             return (BuiltInTypeKind.AssociationEndMember == member.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsAssociationEndMember(EdmMember member)
 | |
|         {
 | |
|             return (BuiltInTypeKind.AssociationEndMember == member.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsNavigationProperty(EdmMember member)
 | |
|         {
 | |
|             return (BuiltInTypeKind.NavigationProperty == member.BuiltInTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEntityTypeBase(EdmType edmType)
 | |
|         {
 | |
|             return Helper.IsEntityType(edmType) ||
 | |
|                    Helper.IsRelationshipType(edmType);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsTransientType(EdmType edmType)
 | |
|         {
 | |
|             return Helper.IsCollectionType(edmType) ||
 | |
|                    Helper.IsRefType(edmType) ||
 | |
|                    Helper.IsRowType(edmType);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEntitySet(EntitySetBase entitySetBase)
 | |
|         {
 | |
|             return BuiltInTypeKind.EntitySet == entitySetBase.BuiltInTypeKind;
 | |
|         }
 | |
| 
 | |
|         internal static bool IsRelationshipSet(EntitySetBase entitySetBase)
 | |
|         {
 | |
|             return BuiltInTypeKind.AssociationSet == entitySetBase.BuiltInTypeKind;
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEntityContainer(GlobalItem item)
 | |
|         {
 | |
|             return BuiltInTypeKind.EntityContainer == item.BuiltInTypeKind;
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEdmFunction(GlobalItem item)
 | |
|         {
 | |
|             return BuiltInTypeKind.EdmFunction == item.BuiltInTypeKind;
 | |
|         }
 | |
|                
 | |
|         internal static string GetFileNameFromUri(Uri uri)
 | |
|         {
 | |
|             if ( uri == null )
 | |
|                 throw new ArgumentNullException("uri");
 | |
|             if ( uri.IsFile )
 | |
|                 return uri.LocalPath;
 | |
| 
 | |
|             if ( uri.IsAbsoluteUri )
 | |
|                 return uri.AbsolutePath;
 | |
| 
 | |
|             throw new ArgumentException(System.Data.Entity.Strings.UnacceptableUri(uri),"uri");
 | |
|         }
 | |
| 
 | |
|         internal static bool IsEnumType(EdmType edmType)
 | |
|         {
 | |
|             Debug.Assert(edmType != null, "edmType != null");
 | |
|             return BuiltInTypeKind.EnumType == edmType.BuiltInTypeKind;
 | |
|         }
 | |
| 
 | |
|         internal static bool IsUnboundedFacetValue(Facet facet)
 | |
|         {
 | |
|             return object.ReferenceEquals(facet.Value, EdmConstants.UnboundedValue);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsVariableFacetValue(Facet facet)
 | |
|         {
 | |
|             return object.ReferenceEquals(facet.Value, EdmConstants.VariableValue);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsScalarType(EdmType edmType)
 | |
|         {
 | |
|             return IsEnumType(edmType) || IsPrimitiveType(edmType);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsSpatialType(PrimitiveType type)
 | |
|         {
 | |
|             return IsGeographicType(type) || IsGeometricType(type);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsSpatialType(EdmType type, out bool isGeographic)
 | |
|         {
 | |
|             PrimitiveType pt = type as PrimitiveType;
 | |
|             if (pt == null)
 | |
|             {
 | |
|                 isGeographic = false;
 | |
|                 return false;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 isGeographic = IsGeographicType(pt);
 | |
|                 return isGeographic || IsGeometricType(pt);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal static bool IsGeographicType(PrimitiveType type)
 | |
|         {
 | |
|             return IsGeographicTypeKind(type.PrimitiveTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool AreSameSpatialUnionType(PrimitiveType firstType, PrimitiveType secondType)
 | |
|         {
 | |
|             // for the purposes of type checking all geographic types should be treated as if they were the Geography union type.
 | |
|             if (Helper.IsGeographicTypeKind(firstType.PrimitiveTypeKind) && Helper.IsGeographicTypeKind(secondType.PrimitiveTypeKind))
 | |
|             {
 | |
|                 return true;
 | |
|             }
 | |
| 
 | |
|             // for the purposes of type checking all geometric types should be treated as if they were the Geometry union type.
 | |
|             if (Helper.IsGeometricTypeKind(firstType.PrimitiveTypeKind) && Helper.IsGeometricTypeKind(secondType.PrimitiveTypeKind))
 | |
|             {
 | |
|                 return true;
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         internal static bool IsGeographicTypeKind(PrimitiveTypeKind kind)
 | |
|         {
 | |
|             return kind == PrimitiveTypeKind.Geography || IsStrongGeographicTypeKind(kind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsGeometricType(PrimitiveType type)
 | |
|         {
 | |
|             return IsGeometricTypeKind(type.PrimitiveTypeKind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsGeometricTypeKind(PrimitiveTypeKind kind)
 | |
|         {
 | |
|             return kind == PrimitiveTypeKind.Geometry || IsStrongGeometricTypeKind(kind);
 | |
|         }
 | |
| 
 | |
|         internal static bool IsStrongSpatialTypeKind(PrimitiveTypeKind kind)
 | |
|         {
 | |
|             return IsStrongGeometricTypeKind(kind) || IsStrongGeographicTypeKind(kind);
 | |
|         }
 | |
| 
 | |
|         static bool IsStrongGeometricTypeKind(PrimitiveTypeKind kind)
 | |
|         {
 | |
|             return kind >= PrimitiveTypeKind.GeometryPoint && kind <= PrimitiveTypeKind.GeometryCollection;
 | |
|         }
 | |
| 
 | |
|         static bool IsStrongGeographicTypeKind(PrimitiveTypeKind kind)
 | |
|         {
 | |
|             return kind >= PrimitiveTypeKind.GeographyPoint && kind <= PrimitiveTypeKind.GeographyCollection;
 | |
|         }
 | |
| 
 | |
|         internal static bool IsSpatialType(TypeUsage type)
 | |
|         {
 | |
|             return (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType && IsSpatialType((PrimitiveType)type.EdmType));
 | |
|         }
 | |
| 
 | |
|         internal static bool IsSpatialType(TypeUsage type, out PrimitiveTypeKind spatialType)
 | |
|         {
 | |
|             if (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
 | |
|             {
 | |
|                 PrimitiveType primitiveType = (PrimitiveType)type.EdmType;
 | |
|                 if (IsGeographicTypeKind(primitiveType.PrimitiveTypeKind) || IsGeometricTypeKind(primitiveType.PrimitiveTypeKind))
 | |
|                 {
 | |
|                     spatialType = primitiveType.PrimitiveTypeKind;
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             spatialType = default(PrimitiveTypeKind);
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         #endregion /// IsXXXType region
 | |
| 
 | |
|         /// <remarks>Performance of Enum.ToString() is slow and we use this value in building Identity</remarks>
 | |
|         internal static string ToString(System.Data.ParameterDirection value)
 | |
|         {
 | |
|             switch (value)
 | |
|             {
 | |
|                 case ParameterDirection.Input:
 | |
|                     return "Input";
 | |
|                 case ParameterDirection.Output:
 | |
|                     return "Output";
 | |
|                 case ParameterDirection.InputOutput:
 | |
|                     return "InputOutput";
 | |
|                 case ParameterDirection.ReturnValue:
 | |
|                     return "ReturnValue";
 | |
|                 default:
 | |
|                     Debug.Assert(false, "which ParameterDirection.ToString() is missing?");
 | |
|                     return value.ToString();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <remarks>Performance of Enum.ToString() is slow and we use this value in building Identity</remarks>
 | |
|         internal static string ToString(System.Data.Metadata.Edm.ParameterMode value)
 | |
|         {
 | |
|             switch (value)
 | |
|             {
 | |
|                 case ParameterMode.In:
 | |
|                     return EdmConstants.In;
 | |
|                 case ParameterMode.Out:
 | |
|                     return EdmConstants.Out;
 | |
|                 case ParameterMode.InOut:
 | |
|                     return EdmConstants.InOut;
 | |
|                 case ParameterMode.ReturnValue:
 | |
|                     return "ReturnValue";
 | |
|                 default:
 | |
|                     Debug.Assert(false, "which ParameterMode.ToString() is missing?");
 | |
|                     return value.ToString();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Verifies whether the given <paramref name="typeKind"/> is a valid underlying type for an enumeration type.
 | |
|         /// </summary>
 | |
|         /// <param name="typeKind">
 | |
|         /// <see cref="PrimitiveTypeKind"/> to verifiy.
 | |
|         /// </param>
 | |
|         /// <returns>
 | |
|         /// <c>true</c> if the <paramref name="typeKind"/> is a valid underlying type for an enumeration type. Otherwise <c>false</c>.
 | |
|         /// </returns>
 | |
|         internal static bool IsSupportedEnumUnderlyingType(PrimitiveTypeKind typeKind)
 | |
|         {
 | |
|             return typeKind == PrimitiveTypeKind.Byte ||
 | |
|                    typeKind == PrimitiveTypeKind.SByte ||
 | |
|                    typeKind == PrimitiveTypeKind.Int16 ||
 | |
|                    typeKind == PrimitiveTypeKind.Int32 ||
 | |
|                    typeKind == PrimitiveTypeKind.Int64;
 | |
|         }
 | |
| 
 | |
|         private static readonly Dictionary<PrimitiveTypeKind, long[]> _enumUnderlyingTypeRanges =
 | |
|             new Dictionary<PrimitiveTypeKind, long[]>
 | |
|             {
 | |
|                 { PrimitiveTypeKind.Byte,  new long[] { Byte.MinValue,  Byte.MaxValue  } },
 | |
|                 { PrimitiveTypeKind.SByte, new long[] { SByte.MinValue, SByte.MaxValue } },
 | |
|                 { PrimitiveTypeKind.Int16, new long[] { Int16.MinValue, Int16.MaxValue } },
 | |
|                 { PrimitiveTypeKind.Int32, new long[] { Int32.MinValue, Int32.MaxValue } },
 | |
|                 { PrimitiveTypeKind.Int64, new long[] { Int64.MinValue, Int64.MaxValue } },
 | |
|             };
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Verifies whether a value of a member of an enumeration type is in range according to underlying type of the enumeration type.
 | |
|         /// </summary>
 | |
|         /// <param name="underlyingTypeKind">Underlying type of the enumeration type.</param>
 | |
|         /// <param name="value">Value to check.</param>
 | |
|         /// <returns>
 | |
|         /// <c>true</c> if the <paramref name="value"/> is in range of the <paramref name="underlyingTypeKind"/>. <c>false</c> otherwise.
 | |
|         /// </returns>
 | |
|         internal static bool IsEnumMemberValueInRange(PrimitiveTypeKind underlyingTypeKind, long value)
 | |
|         {
 | |
|             Debug.Assert(IsSupportedEnumUnderlyingType(underlyingTypeKind), "Unsupported underlying type.");
 | |
| 
 | |
|             return value >= _enumUnderlyingTypeRanges[underlyingTypeKind][0] && value <= _enumUnderlyingTypeRanges[underlyingTypeKind][1];
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Checks whether the <paramref name="type"/> is enum type and if this is the case returns its underlying type. Otherwise 
 | |
|         /// returns <paramref name="type"/> after casting it to PrimitiveType.
 | |
|         /// </summary>
 | |
|         /// <param name="type">Type to convert to primitive type.</param>
 | |
|         /// <returns>Underlying type if <paramref name="type"/> is enumeration type. Otherwise <paramref name="type"/> itself.</returns>
 | |
|         /// <remarks>This method should be called only for primitive or enumeration types.</remarks>
 | |
|         internal static PrimitiveType AsPrimitive(EdmType type)
 | |
|         {
 | |
|             Debug.Assert(type != null, "type != null");
 | |
|             Debug.Assert(IsScalarType(type), "This method must not be called for types that are neither primitive nor enums.");
 | |
| 
 | |
|             return Helper.IsEnumType(type) ?
 | |
|                 GetUnderlyingEdmTypeForEnumType(type) : 
 | |
|                 (PrimitiveType)type;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Returns underlying EDM type of a given enum <paramref name="type"/>.
 | |
|         /// </summary>
 | |
|         /// <param name="type">Enum type whose underlying EDM type needs to be returned. Must not be null.</param>
 | |
|         /// <returns>The underlying EDM type of a given enum <paramref name="type"/>.</returns>
 | |
|         internal static PrimitiveType GetUnderlyingEdmTypeForEnumType(EdmType type)
 | |
|         {
 | |
|             Debug.Assert(type != null, "type != null");
 | |
|             Debug.Assert(IsEnumType(type), "This method can be called only for enums.");
 | |
| 
 | |
|             return ((EnumType)type).UnderlyingType;
 | |
|         }
 | |
| 
 | |
|         internal static PrimitiveType GetSpatialNormalizedPrimitiveType(EdmType type)
 | |
|         {
 | |
|             Debug.Assert(type != null, "type != null");
 | |
|             Debug.Assert(IsPrimitiveType(type), "This method can be called only for enums.");
 | |
|             PrimitiveType primitiveType = (PrimitiveType)type;
 | |
| 
 | |
|             if (IsGeographicType(primitiveType) && primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Geography)
 | |
|             {
 | |
|                 return PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Geography);
 | |
|             }
 | |
|             else if (IsGeometricType(primitiveType) && primitiveType.PrimitiveTypeKind != PrimitiveTypeKind.Geometry)
 | |
|             {
 | |
|                 return PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Geometry);
 | |
|             }
 | |
|             else 
 | |
|             {
 | |
|                 return primitiveType;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 |