| File: FrameworkFork\Microsoft.Xml\Xml\XPath\Internal\NumberFunctions.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 System.Text; using FT = MS.Internal.Xml.XPath.Function.FunctionType; internal sealed class NumberFunctions : ValueQuery { private Query _arg = null; private FT _ftype; public NumberFunctions(FT ftype, Query arg) { _arg = arg; _ftype = ftype; } private NumberFunctions(NumberFunctions other) : base(other) { _arg = Clone(other._arg); _ftype = other._ftype; } public override void SetXsltContext(XsltContext context) { if (_arg != null) { _arg.SetXsltContext(context); } } internal static double Number(bool arg) { return arg ? 1.0 : 0.0; } internal static double Number(string arg) { return XmlConvert.ToXPathDouble(arg); } public override object Evaluate(XPathNodeIterator nodeIterator) { switch (_ftype) { case FT.FuncNumber: return Number(nodeIterator); case FT.FuncSum: return Sum(nodeIterator); case FT.FuncFloor: return Floor(nodeIterator); case FT.FuncCeiling: return Ceiling(nodeIterator); case FT.FuncRound: return Round(nodeIterator); } return null; } private double Number(XPathNodeIterator nodeIterator) { if (_arg == null) { return XmlConvert.ToXPathDouble(nodeIterator.Current.Value); } object argVal = _arg.Evaluate(nodeIterator); switch (GetXPathType(argVal)) { case XPathResultType.NodeSet: XPathNavigator value = _arg.Advance(); if (value != null) { return Number(value.Value); } break; case XPathResultType.String: return Number((string)argVal); case XPathResultType.Boolean: return Number((bool)argVal); case XPathResultType.Number: return (double)argVal; case XPathResultType_Navigator: return Number(((XPathNavigator)argVal).Value); } return double.NaN; } private double Sum(XPathNodeIterator nodeIterator) { double sum = 0; _arg.Evaluate(nodeIterator); XPathNavigator nav; while ((nav = _arg.Advance()) != null) { sum += Number(nav.Value); } return sum; } private double Floor(XPathNodeIterator nodeIterator) { return Math.Floor((double)_arg.Evaluate(nodeIterator)); } private double Ceiling(XPathNodeIterator nodeIterator) { return Math.Ceiling((double)_arg.Evaluate(nodeIterator)); } private double Round(XPathNodeIterator nodeIterator) { double n = XmlConvert.ToXPathDouble(_arg.Evaluate(nodeIterator)); return XmlConvert.XPathRound(n); } public override XPathResultType StaticType { get { return XPathResultType.Number; } } public override XPathNodeIterator Clone() { return new NumberFunctions(this); } public override void PrintQuery(XmlWriter w) { w.WriteStartElement(this.GetType().Name); w.WriteAttributeString("name", _ftype.ToString()); if (_arg != null) { _arg.PrintQuery(w); } w.WriteEndElement(); } } }