QueryModel.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / QueryModel.cs / 1 / QueryModel.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System.Diagnostics;
    using System.Collections; 
    using System.Xml; 
    using System.Xml.XPath;
    using System.Globalization; 

    internal enum AxisDirection : byte
    {
        Forward, 
        Reverse
    } 
 
    internal enum QueryNodeType : byte
    { 
        Any         = 0x00,
        Root        = 0x01,
        Attribute   = 0x02,
        Element     = 0x04, 
        Text        = 0x08,
        Comment     = 0x10, 
        Processing  = 0x20, 
        Namespace   = 0x40,
        Multiple    = 0x80, 
        ChildNodes  = (QueryNodeType.Multiple | QueryNodeType.Element | QueryNodeType.Comment | QueryNodeType.Text | QueryNodeType.Processing),
        Ancestor    = (QueryNodeType.Multiple | QueryNodeType.Element | QueryNodeType.Root),
        All         = (QueryNodeType.Multiple | QueryNodeType.Element | QueryNodeType.Attribute | QueryNodeType.Namespace | QueryNodeType.Root | QueryNodeType.Comment | QueryNodeType.Text | QueryNodeType.Processing)
    } 

    internal enum QueryAxisType : byte 
    { 
        None = 0,
        Ancestor = 1, 
        AncestorOrSelf = 2,
        Attribute = 3,
        Child = 4,
        Descendant = 5, 
        DescendantOrSelf = 6,
        Following = 7, 
        FollowingSibling = 8, 
        Namespace = 9,
        Parent = 10, 
        Preceding = 11,
        PrecedingSibling = 12,
        Self = 13
    } 

    // 4 bytes - each element is a byte 
    internal struct QueryAxis 
    {
        AxisDirection direction; 
        QueryNodeType principalNode;
        QueryAxisType type;
        QueryNodeType validNodeTypes;
 
        internal QueryAxis(QueryAxisType type, AxisDirection direction, QueryNodeType principalNode, QueryNodeType validNodeTypes)
        { 
            this.direction = direction; 
            this.principalNode = principalNode;
            this.type = type; 
            this.validNodeTypes = validNodeTypes;
        }
#if NO
        internal AxisDirection Direction 
        {
            get 
            { 
                return this.direction;
            } 
        }
#endif
        internal QueryNodeType PrincipalNodeType
        { 
            get
            { 
                return this.principalNode; 
            }
        } 

        internal QueryAxisType Type
        {
            get 
            {
                return this.type; 
            } 
        }
 
        internal QueryNodeType ValidNodeTypes
        {
            get
            { 
                return this.validNodeTypes;
            } 
        } 

        internal bool IsSupported() 
        {
            switch(this.type)
            {
                default: 
                    return false;
 
                case QueryAxisType.DescendantOrSelf: 
                case QueryAxisType.Descendant:
                case QueryAxisType.Attribute: 
                case QueryAxisType.Child:
                case QueryAxisType.Self:
                    break;
            } 

            return true; 
        } 
    }
 
    /// 
    /// Information about a qname
    /// 
    internal enum NodeQNameType : byte 
    {
        // QName has neither name nor namespace. Entirely empty 
        Empty               = 0x00, 
        // QName has a regular name
        Name                = 0x01, 
        // QName has regular namespace
        Namespace           = 0x02,
        // QName has both name and namespace
        Standard            = NodeQNameType.Name | NodeQNameType.Namespace, 
        // QName has a wildcard name
        NameWildcard        = 0x04, 
        // QName has a wildcard namespace 
        NamespaceWildcard   = 0x08,
        // QName is entirely wildcard 
        Wildcard            = NodeQNameType.NameWildcard | NodeQNameType.NamespaceWildcard
    }

    ///  
    /// We'll use our own class to store QNames instead of XmlQualifiedName because:
    /// 1. Our is a struct. No allocations required. We have to dynamically create QNames in several places and 
    /// and don't want to do allocations 
    /// 2. Our equality tests are frequently faster. XmlQualifiedName implements .Equal with the assumption that
    /// strings are atomized using a shared name table, which in the case of arbitrary object graphs, they almost 
    /// never will be.
    /// 
    internal struct NodeQName
    { 
        internal static NodeQName Empty = new NodeQName(string.Empty, string.Empty);
        internal string name; 
        internal string ns; 

        internal NodeQName(string name) 
            : this(name, string.Empty)
        {
        }
 
        internal NodeQName(string name, string ns)
        { 
            this.name = (null == name) ? string.Empty : name; 
            this.ns = (null == ns) ? string.Empty : ns;
        } 
#if NO
        internal NodeQName(string name, string ns, string defaultNS)
        {
            DiagnosticUtility.DebugAssert(null != defaultNS, ""); 
            this.name = (null == name) ? string.Empty : name;
            this.ns = (null == ns) ? defaultNS : ns; 
        } 

        internal NodeQName(XmlQualifiedName qname) 
        {
            this.name = qname.Name;
            this.ns = qname.Namespace;
        } 

        internal bool HasWildcard 
        { 
            get
            { 
                return (this.IsNameWildcard || this.IsNamespaceWildcard);
            }
        }
#endif 
        internal bool IsEmpty
        { 
            get 
            {
                return (this.name.Length == 0 && this.ns.Length == 0); 
            }
        }

        internal bool IsNameDefined 
        {
            get 
            { 
                return (this.name.Length > 0);
            } 
        }

        internal bool IsNameWildcard
        { 
            get
            { 
                return object.ReferenceEquals(this.name, QueryDataModel.Wildcard); 
            }
        } 

        internal bool IsNamespaceDefined
        {
            get 
            {
                return (this.ns.Length > 0); 
            } 
        }
 
        internal bool IsNamespaceWildcard
        {
            get
            { 
                return object.ReferenceEquals(this.ns, QueryDataModel.Wildcard);
            } 
        } 

        internal string Name 
        {
            get
            {
                return this.name; 
            }
#if NO 
            set 
            {
                DiagnosticUtility.DebugAssert(null != value, ""); 
                this.name = value;
            }
#endif
        } 

        internal string Namespace 
        { 
            get
            { 
                return this.ns;
            }
#if NO
            set 
            {
                DiagnosticUtility.DebugAssert(null != value, ""); 
                this.ns = value; 
            }
#endif 
        }

        /// 
        /// If this qname's strings are == to the constants defined in NodeQName, replace the strings with the 
        /// constants
        ///  
#if NO 
        internal bool Atomize()
        { 
            return false;
        }
#endif
        internal bool EqualsName(string name) 
        {
            return (name == this.name); 
        } 
#if NO
        internal bool Equals(string name) 
        {
            return this.EqualsName(name);
        }
 
        internal bool Equals(string name, string ns)
        { 
            return ( (name.Length == this.name.Length && name == this.name) && (ns.Length == this.ns.Length && ns == this.ns)); 
        }
#endif 
        internal bool Equals(NodeQName qname)
        {
            return ( (qname.name.Length == this.name.Length && qname.name == this.name)&& (qname.ns.Length == this.ns.Length && qname.ns == this.ns));
        } 
#if NO
        internal bool Equals(SeekableXPathNavigator navigator) 
        { 
            string str = navigator.LocalName;
            if (this.name.Length == str.Length && this.name == str) 
            {
                str = navigator.NamespaceURI;
                return (this.ns.Length == str.Length && this.ns == str);
            } 
            return false;
        } 
#endif 
        internal bool EqualsNamespace(string ns)
        { 
            return (ns == this.ns);
        }
#if NO
        internal bool EqualsReference(NodeQName qname) 
        {
            return (object.ReferenceEquals(qname.name, this.name) && object.ReferenceEquals(qname.ns, this.ns)); 
        } 

        internal string QName() 
        {
            return this.ns + ':' + this.name;
        }
#endif 
        /// 
        /// Return this qname's type - whether the name is defined, whether the name is a wildcard etc 
        ///  
        internal NodeQNameType GetQNameType()
        { 
            NodeQNameType type = NodeQNameType.Empty;

            if (this.IsNameDefined)
            { 
                if (this.IsNameWildcard)
                { 
                    type |= NodeQNameType.NameWildcard; 
                }
                else 
                {
                    type |= NodeQNameType.Name;
                }
            } 

            if (this.IsNamespaceDefined) 
            { 
                if (this.IsNamespaceWildcard)
                { 
                    type |= NodeQNameType.NamespaceWildcard;
                }
                else
                { 
                    type |= NodeQNameType.Namespace;
                } 
            } 

            return type; 
        }
    }

    internal static class QueryDataModel 
    {
        internal static QueryAxis[] axes; 
        internal static string Wildcard = "*"; 

        static QueryDataModel() 
        {
            // Init axes table
            QueryDataModel.axes = new QueryAxis [] {
                new QueryAxis(QueryAxisType.None, AxisDirection.Forward, QueryNodeType.Any, QueryNodeType.Any), 
                new QueryAxis(QueryAxisType.Ancestor, AxisDirection.Reverse, QueryNodeType.Element, QueryNodeType.Ancestor),
                new QueryAxis(QueryAxisType.AncestorOrSelf, AxisDirection.Reverse, QueryNodeType.Element, QueryNodeType.All), 
                new QueryAxis(QueryAxisType.Attribute, AxisDirection.Forward, QueryNodeType.Attribute, QueryNodeType.Attribute), 
                new QueryAxis(QueryAxisType.Child, AxisDirection.Forward, QueryNodeType.Element, QueryNodeType.ChildNodes),
                new QueryAxis(QueryAxisType.Descendant, AxisDirection.Forward, QueryNodeType.Element, QueryNodeType.ChildNodes), 
                new QueryAxis(QueryAxisType.DescendantOrSelf, AxisDirection.Forward, QueryNodeType.Element, QueryNodeType.All),
                new QueryAxis(QueryAxisType.Following, AxisDirection.Forward, QueryNodeType.Element, QueryNodeType.ChildNodes),
                new QueryAxis(QueryAxisType.FollowingSibling, AxisDirection.Forward, QueryNodeType.Element, QueryNodeType.ChildNodes),
                new QueryAxis(QueryAxisType.Namespace, AxisDirection.Forward, QueryNodeType.Namespace, QueryNodeType.Namespace), 
                new QueryAxis(QueryAxisType.Parent, AxisDirection.Reverse, QueryNodeType.Element, QueryNodeType.Ancestor),
                new QueryAxis(QueryAxisType.Preceding, AxisDirection.Reverse, QueryNodeType.Element, QueryNodeType.ChildNodes), 
                new QueryAxis(QueryAxisType.PrecedingSibling, AxisDirection.Reverse, QueryNodeType.Element, QueryNodeType.All), 
                new QueryAxis(QueryAxisType.Self, AxisDirection.Forward, QueryNodeType.Element, QueryNodeType.All),
            }; 
        }


        ///  
        /// XPath does not interpret namespace declarations as attributes
        /// Any attributes that not qualified by the XmlNamespaces namespaces is therefore kosher 
        ///  
        internal static bool IsAttribute(string ns)
        { 
            return (0 != string.CompareOrdinal("http://www.w3.org/2000/xmlns/", ns));
        }
#if NO
 
        internal static bool IsDigit(char ch)
        { 
            return char.IsDigit(ch); 
        }
 
        internal static bool IsLetter(char ch)
        {
            return char.IsLetter(ch);
        } 

        internal static bool IsLetterOrDigit(char ch) 
        { 
            return char.IsLetterOrDigit(ch);
        } 

        internal static bool IsWhitespace(char ch)
        {
            return char.IsWhiteSpace(ch); 
        }
#endif 
        internal static QueryAxis GetAxis(QueryAxisType type) 
        {
            return QueryDataModel.axes[(int) type]; 
        }
#if NO
        internal static QueryNodeType GetNodeType(XPathNodeType type)
        { 
            QueryNodeType nodeType;
 
            switch (type) 
            {
                default: 
                    nodeType = QueryNodeType.Any;
                    break;

                case XPathNodeType.Root: 
                    nodeType = QueryNodeType.Root;
                    break; 
 
                case XPathNodeType.Attribute:
                    nodeType = QueryNodeType.Attribute; 
                    break;

                case XPathNodeType.Element:
                    nodeType = QueryNodeType.Element; 
                    break;
 
                case XPathNodeType.Comment: 
                    nodeType = QueryNodeType.Comment;
                    break; 

                case XPathNodeType.Text:
                case XPathNodeType.Whitespace:
                case XPathNodeType.SignificantWhitespace: 
                    nodeType = QueryNodeType.Text;
                    break; 
 
                case XPathNodeType.ProcessingInstruction:
                    nodeType = QueryNodeType.Processing; 
                    break;
            }

            return nodeType; 
        }
 
        internal static XPathNodeType GetXPathNodeType(QueryNodeType type) 
        {
            XPathNodeType nodeType = XPathNodeType.All; 
            switch(type)
            {
                default:
                    break; 

                case QueryNodeType.Attribute: 
                    nodeType = XPathNodeType.Attribute; 
                    break;
 
                case QueryNodeType.Root:
                    nodeType = XPathNodeType.Root;
                    break;
 
                case QueryNodeType.Namespace:
                    nodeType = XPathNodeType.Namespace; 
                    break; 

                case QueryNodeType.Element: 
                    nodeType = XPathNodeType.Element;
                    break;

                case QueryNodeType.Comment: 
                    nodeType = XPathNodeType.Comment;
                    break; 
 
                case QueryNodeType.Text:
                    nodeType = XPathNodeType.Text; 
                    break;

                case QueryNodeType.Processing:
                    nodeType = XPathNodeType.ProcessingInstruction; 
                    break;
            } 
 
            return nodeType;
        } 

        // Is it possible to select nodes matching the given criteria from nodes of the given type
        internal static bool IsSelectPossible(QueryNodeType nodeType, NodeSelectCriteria desc)
        { 
            if (0 != (nodeType & QueryNodeType.Attribute))
            { 
                switch(desc.Axis.Type) 
                {
                    default: 
                        return false;

                        // Navigation is possible from attributes on these axes
                    case QueryAxisType.Self: 
                    case QueryAxisType.Ancestor:
                    case QueryAxisType.AncestorOrSelf: 
                    case QueryAxisType.Parent: 
                        return true;
                } 
            }
            else if (0 != (nodeType & QueryNodeType.Root))
            {
                if (AxisDirection.Reverse == desc.Axis.Direction) 
                {
                    return false; 
                } 

                switch(desc.Axis.Type) 
                {
                    default:
                        return true;
 
                        // Navigation is possible from attributes on these axes
                    case QueryAxisType.Attribute: 
                    case QueryAxisType.Namespace: 
                        return false;
                } 
            }

            return true;
        } 
#endif
    } 
 
    internal static class QueryValueModel
    { 

        /*
        Conversions
 
        The following EXACTLY follow the XPath 1.0 spec. Some conversions may seem irrational/inefficient, but
        we prefer to adhere to the spec and shall leave them be unless performance becomes an issue. 
        */ 

        internal static bool Boolean(string val) 
        {
            DiagnosticUtility.DebugAssert(null != val, "");
            return (val.Length > 0);
        } 

        internal static bool Boolean(double dblVal) 
        { 
            return (dblVal != 0 && !double.IsNaN(dblVal));
        } 

        internal static bool Boolean(NodeSequence sequence)
        {
            DiagnosticUtility.DebugAssert(null != sequence, ""); 
            return sequence.IsNotEmpty;
        } 
 
        internal static double Double(bool val)
        { 
            return (val ? 1 : 0);
        }

        internal static double Double(string val) 
        {
            // XPath does not convert numbers the same way .NET does. A string preceeded by + is actually converted 
            // to NAN! Go figure..  Anyway, we have to do this manually. 
            val = val.TrimStart();
            if (val.Length > 0 && val[0] != '+') 
            {
                double dblVal;
                if (double.TryParse(val,
                                    NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowTrailingWhite, 
                                    NumberFormatInfo.InvariantInfo,
                                    out dblVal)) 
                { 
                    return dblVal;
                } 
            }
            return double.NaN;
        }
 
        internal static double Double(NodeSequence sequence)
        { 
            DiagnosticUtility.DebugAssert(null != sequence, ""); 
            return QueryValueModel.Double(sequence.StringValue());
        } 

#if NO
        internal static string String(object val)
        { 
            return val.ToString();
        } 
#endif 
        internal static string String(bool val)
        { 
            return val ? "true" : "false";  // XPath requires all lower case. bool.ToString() returns 'False' and 'True'
        }

        internal static string String(double val) 
        {
            return val.ToString(CultureInfo.InvariantCulture); 
        } 

        internal static string String(NodeSequence sequence) 
        {
            DiagnosticUtility.DebugAssert(null != sequence, "");
            return sequence.StringValue();
        } 

        // OPTIMIZE Comparisons in general!! 
 
        internal static bool Compare(bool x, bool y, RelationOperator op)
        { 
            switch(op)
            {
                default:
                    return QueryValueModel.Compare(QueryValueModel.Double(x), QueryValueModel.Double(y), op); 
                case RelationOperator.Eq:
                    return (x == y); 
                case RelationOperator.Ne: 
                    return (x != y);
            } 
        }

        internal static bool Compare(bool x, double y, RelationOperator op)
        { 
            switch(op)
            { 
                default: 
                    return QueryValueModel.Compare(QueryValueModel.Double(x), y, op);
                case RelationOperator.Eq: 
                    return (x == QueryValueModel.Boolean(y));
                case RelationOperator.Ne:
                    return (x != QueryValueModel.Boolean(y));
            } 
        }
 
        internal static bool Compare(bool x, string y, RelationOperator op) 
        {
            DiagnosticUtility.DebugAssert(null != y, ""); 
            switch(op)
            {
                default:
                    return QueryValueModel.Compare(QueryValueModel.Double(x), QueryValueModel.Double(y), op); 
                case RelationOperator.Eq:
                    return (x == QueryValueModel.Boolean(y)); 
                case RelationOperator.Ne: 
                    return (x != QueryValueModel.Boolean(y));
            } 
        }

        internal static bool Compare(bool x, NodeSequence y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != y, "");
            return QueryValueModel.Compare(x, QueryValueModel.Boolean(y), op); 
        } 

        internal static bool Compare(double x, bool y, RelationOperator op) 
        {
            switch(op)
            {
                default: 
                    return QueryValueModel.Compare(x, QueryValueModel.Double(y), op);
                case RelationOperator.Eq: 
                    return (QueryValueModel.Boolean(x) == y); 
                case RelationOperator.Ne:
                    return (QueryValueModel.Boolean(x) != y); 
            }
        }

        internal static bool Compare(double x, double y, RelationOperator op) 
        {
            switch(op) 
            { 
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new QueryProcessingException(QueryProcessingError.TypeMismatch)); 

                case RelationOperator.Eq:
                    return (x == y);
                case RelationOperator.Ge: 
                    return (x >= y);
                case RelationOperator.Gt: 
                    return (x > y); 
                case RelationOperator.Le:
                    return (x <= y); 
                case RelationOperator.Lt:
                    return (x < y);
                case RelationOperator.Ne:
                    return(x != y); 
            }
        } 
 
        internal static bool Compare(double x, string y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != y, "");
            return QueryValueModel.Compare(x, QueryValueModel.Double(y), op);
        }
 
        internal static bool Compare(double x, NodeSequence y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != y, ""); 
            switch(op)
            { 
                default:
                    return y.Compare(x, op);
                case RelationOperator.Ge:
                    return y.Compare(x, RelationOperator.Le); 
                case RelationOperator.Gt:
                    return y.Compare(x, RelationOperator.Lt); 
                case RelationOperator.Le: 
                    return y.Compare(x, RelationOperator.Ge);
                case RelationOperator.Lt: 
                    return y.Compare(x, RelationOperator.Gt);
            }
        }
 
        internal static bool Compare(string x, bool y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != x, ""); 
            switch(op)
            { 
                default:
                    return QueryValueModel.Compare(QueryValueModel.Double(x), QueryValueModel.Double(y), op);
                case RelationOperator.Eq:
                    return (y == QueryValueModel.Boolean(x)); 
                case RelationOperator.Ne:
                    return (y != QueryValueModel.Boolean(x)); 
            } 
        }
 
        internal static bool Compare(string x, double y, RelationOperator op)
        {
            DiagnosticUtility.DebugAssert(null != x, "");
            return QueryValueModel.Compare(QueryValueModel.Double(x), y, op); 
        }
 
        internal static bool Compare(string x, string y, RelationOperator op) 
        {
            DiagnosticUtility.DebugAssert(null != x && null != y, ""); 
            switch(op)
            {
                default:
                    DiagnosticUtility.DebugAssert("Invalid RelationOperator"); 
                    break;
 
                case RelationOperator.Eq: 
                    return QueryValueModel.Equals(x, y);
                case RelationOperator.Ge: 
                case RelationOperator.Gt:
                case RelationOperator.Le:
                case RelationOperator.Lt:
                    return QueryValueModel.Compare(QueryValueModel.Double(x), QueryValueModel.Double(y), op); 
                case RelationOperator.Ne:
                    return(x.Length != y.Length || 0 != string.CompareOrdinal(x, y)); 
            } 

            return false; 
        }

        internal static bool Compare(string x, NodeSequence y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != y, "");
            switch(op) 
            { 
                default:
                    return y.Compare(x, op); 
                case RelationOperator.Ge:
                    return y.Compare(x, RelationOperator.Le);
                case RelationOperator.Gt:
                    return y.Compare(x, RelationOperator.Lt); 
                case RelationOperator.Le:
                    return y.Compare(x, RelationOperator.Ge); 
                case RelationOperator.Lt: 
                    return y.Compare(x, RelationOperator.Gt);
            } 
        }

        internal static bool Compare(NodeSequence x, bool y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != x, "");
            return QueryValueModel.Compare(QueryValueModel.Boolean(x), y, op); 
        } 

        internal static bool Compare(NodeSequence x, double y, RelationOperator op) 
        {
            DiagnosticUtility.DebugAssert(null != x, "");
            return x.Compare(y, op);
        } 

        internal static bool Compare(NodeSequence x, string y, RelationOperator op) 
        { 
            DiagnosticUtility.DebugAssert(null != x, "");
            return x.Compare(y, op); 
        }

        internal static bool Compare(NodeSequence x, NodeSequence y, RelationOperator op)
        { 
            DiagnosticUtility.DebugAssert(null != x, "");
            return x.Compare(y, op); 
        } 

        internal static bool CompileTimeCompare(object x, object y, RelationOperator op) 
        {
            DiagnosticUtility.DebugAssert(null != x && null != y, "");

            if (x is string) 
            {
                if (y is double) 
                { 
                    return QueryValueModel.Compare((string) x, (double) y, op);
                } 
                else if (y is string)
                {
                    return QueryValueModel.Compare((string) x, (string) y, op);
                } 
            }
            else if (x is double) 
            { 
                if (y is double)
                { 
                    return QueryValueModel.Compare((double) x, (double) y, op);
                }
                else if (y is string)
                { 
                    return QueryValueModel.Compare((double) x, (string) y, op);
                } 
            } 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.InvalidComparison));
        } 

        internal static bool Equals(bool x, string y)
        {
            return (x == QueryValueModel.Boolean(y)); 
        }
 
        internal static bool Equals(double x, string y) 
        {
            return (x == QueryValueModel.Double(y)); 
        }

        internal static bool Equals(string x, string y)
        { 
            return (x.Length == y.Length && x == y);
        } 
 
        internal static bool Equals(NodeSequence x, string y)
        { 
            return x.Equals(y);
        }

        internal static bool Equals(bool x, double y) 
        {
            return (x == QueryValueModel.Boolean(y)); 
        } 

        internal static bool Equals(double x, double y) 
        {
            return (x == y);
        }
 
        internal static bool Equals(NodeSequence x, double y)
        { 
            return x.Equals(y); 
        }
 
        internal static double Round(double val)
        {
            // Math.Round does bankers rounding, which is IEEE 754, section 4.
            // If a is halfway between two whole numbers, one of which by definition is even and the other odd, then 
            // the even number is returned. Thus Round(3.5) == Round(4.5) == 4.0
            // XPath has different rules.. which is Math.Floor(a + 0.5)... with two exceptions (see below) 
            // The round function returns the number that is closest to the argument and that is an integer. 
            // If there are two such numbers, then the one that is closest to positive infinity is returned.
            // If the argument is NaN, then NaN is returned. 
            // If the argument is positive infinity, then positive infinity is returned.
            // If the argument is negative infinity, then negative infinity is returned.
            // If the argument is positive zero, then positive zero is returned.
            // If the argument is negative zero, then negative zero is returned. 
            // If the argument is less than zero, but greater than or equal to -0.5, then negative zero is returned.
            // For these last two cases, the result of calling the round function is not the same as the result of 
            // adding 0.5 and then calling the floor function. 
            // Note: .NET has no positive or negative zero... so we give up and use Math.Round...
            // For all other cases, we use Floor to Round... 
            return (-0.5 <= val && val <= 0.0) ? Math.Round(val) : Math.Floor(val + 0.5);
        }
#if NO
        internal static XPathResultType ResultType(ValueDataType dataType) 
        {
            switch (dataType) 
            { 
                default:
                    break; 

                case ValueDataType.Boolean:
                    return XPathResultType.Boolean;
 
                case ValueDataType.Double:
                    return XPathResultType.Number; 
 
                case ValueDataType.Sequence:
                    return XPathResultType.NodeSet; 

                case ValueDataType.String:
                    return XPathResultType.String;
            } 

            return XPathResultType.Any; 
        } 
#endif
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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