File: FrameworkFork\Microsoft.Xml\Xml\XPath\Internal\BooleanFunctions.cs
Web Access
Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
namespace MS.Internal.Xml.XPath
{
    using System;
    using Microsoft.Xml;
    using Microsoft.Xml.XPath;
    using System.Diagnostics;
    using System.Globalization;
    using Microsoft.Xml.Xsl;
    using FT = MS.Internal.Xml.XPath.Function.FunctionType;
 
    internal sealed class BooleanFunctions : ValueQuery
    {
        private Query _arg;
        private FT _funcType;
 
        public BooleanFunctions(FT funcType, Query arg)
        {
            _arg = arg;
            _funcType = funcType;
        }
        private BooleanFunctions(BooleanFunctions other) : base(other)
        {
            _arg = Clone(other._arg);
            _funcType = other._funcType;
        }
 
        public override void SetXsltContext(XsltContext context)
        {
            if (_arg != null)
            {
                _arg.SetXsltContext(context);
            }
        }
 
        public override object Evaluate(XPathNodeIterator nodeIterator)
        {
            switch (_funcType)
            {
                case FT.FuncBoolean: return toBoolean(nodeIterator);
                case FT.FuncNot: return Not(nodeIterator);
                case FT.FuncTrue: return true;
                case FT.FuncFalse: return false;
                case FT.FuncLang: return Lang(nodeIterator);
            }
            return false;
        }
 
        internal static bool toBoolean(double number)
        {
            return number != 0 && !double.IsNaN(number);
        }
        internal static bool toBoolean(string str)
        {
            return str.Length > 0;
        }
 
        internal bool toBoolean(XPathNodeIterator nodeIterator)
        {
            object result = _arg.Evaluate(nodeIterator);
            if (result is XPathNodeIterator) return _arg.Advance() != null;
            if (result is string) return toBoolean((string)result);
            if (result is double) return toBoolean((double)result);
            if (result is bool) return (bool)result;
            Debug.Assert(result is XPathNavigator, "Unknown value type");
            return true;
        }
 
        public override XPathResultType StaticType { get { return XPathResultType.Boolean; } }
 
        private bool Not(XPathNodeIterator nodeIterator)
        {
            return !(bool)_arg.Evaluate(nodeIterator);
        }
 
        private bool Lang(XPathNodeIterator nodeIterator)
        {
            string str = _arg.Evaluate(nodeIterator).ToString();
            string lang = nodeIterator.Current.XmlLang;
            return (
               lang.StartsWith(str, StringComparison.OrdinalIgnoreCase) &&
               (lang.Length == str.Length || lang[str.Length] == '-')
            );
        }
 
        public override XPathNodeIterator Clone() { return new BooleanFunctions(this); }
 
        public override void PrintQuery(XmlWriter w)
        {
            w.WriteStartElement(this.GetType().Name);
            w.WriteAttributeString("name", _funcType.ToString());
            if (_arg != null)
            {
                _arg.PrintQuery(w);
            }
            w.WriteEndElement();
        }
    }
}