LogicalExpr.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / XPath / Internal / LogicalExpr.cs / 1305376 / LogicalExpr.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace MS.Internal.Xml.XPath { 
    using System;
    using System.Xml; 
    using System.Xml.XPath;
    using System.Diagnostics;
    using System.Globalization;
    using System.Xml.Xsl; 

    internal sealed class LogicalExpr : ValueQuery { 
        Operator.Op op; 
        Query opnd1;
        Query opnd2; 

        public LogicalExpr(Operator.Op op, Query  opnd1, Query  opnd2) {
            Debug.Assert(
                Operator.Op.LT == op || Operator.Op.GT == op || 
                Operator.Op.LE == op || Operator.Op.GE == op ||
                Operator.Op.EQ == op || Operator.Op.NE == op 
            ); 
            this.op    = op;
            this.opnd1 = opnd1; 
            this.opnd2 = opnd2;
        }
        private LogicalExpr(LogicalExpr other) : base (other) {
            this.op    = other.op; 
            this.opnd1 = Clone(other.opnd1);
            this.opnd2 = Clone(other.opnd2); 
        } 

        public override void SetXsltContext(XsltContext context){ 
            opnd1.SetXsltContext(context);
            opnd2.SetXsltContext(context);
        }
 
        public override object Evaluate(XPathNodeIterator nodeIterator) {
            Operator.Op op = this.op; 
            object val1 = this.opnd1.Evaluate(nodeIterator); 
            object val2 = this.opnd2.Evaluate(nodeIterator);
            int type1 = (int)GetXPathType(val1); 
            int type2 = (int)GetXPathType(val2);
            if (type1 < type2) {
                op = Operator.InvertOperator(op);
                object valTemp = val1; 
                val1 = val2;
                val2 = valTemp; 
                int typeTmp = type1; 
                type1 = type2;
                type2 = typeTmp; 
            }

            if (op == Operator.Op.EQ || op == Operator.Op.NE) {
                return CompXsltE[type1][type2](op, val1, val2); 
            } else {
                return CompXsltO[type1][type2](op, val1, val2); 
            } 
        }
 
        delegate bool cmpXslt(Operator.Op op, object val1, object val2);

        //                              Number,                       String,                        Boolean,                     NodeSet,                      Navigator
        private static readonly cmpXslt[][] CompXsltE = { 
            new cmpXslt[] { new cmpXslt(cmpNumberNumber), null                         , null                       , null                        , null                    },
            new cmpXslt[] { new cmpXslt(cmpStringNumber), new cmpXslt(cmpStringStringE), null                       , null                        , null                    }, 
            new cmpXslt[] { new cmpXslt(cmpBoolNumberE ), new cmpXslt(cmpBoolStringE  ), new cmpXslt(cmpBoolBoolE  ), null                        , null                    }, 
            new cmpXslt[] { new cmpXslt(cmpQueryNumber ), new cmpXslt(cmpQueryStringE ), new cmpXslt(cmpQueryBoolE ), new cmpXslt(cmpQueryQueryE ), null                    },
            new cmpXslt[] { new cmpXslt(cmpRtfNumber   ), new cmpXslt(cmpRtfStringE   ), new cmpXslt(cmpRtfBoolE   ), new cmpXslt(cmpRtfQueryE   ), new cmpXslt(cmpRtfRtfE) }, 
        };
        private static readonly cmpXslt[][] CompXsltO = {
            new cmpXslt[] { new cmpXslt(cmpNumberNumber), null                         , null                       , null                        , null                    },
            new cmpXslt[] { new cmpXslt(cmpStringNumber), new cmpXslt(cmpStringStringO), null                       , null                        , null                    }, 
            new cmpXslt[] { new cmpXslt(cmpBoolNumberO ), new cmpXslt(cmpBoolStringO  ), new cmpXslt(cmpBoolBoolO  ), null                        , null                    },
            new cmpXslt[] { new cmpXslt(cmpQueryNumber ), new cmpXslt(cmpQueryStringO ), new cmpXslt(cmpQueryBoolO ), new cmpXslt(cmpQueryQueryO ), null                    }, 
            new cmpXslt[] { new cmpXslt(cmpRtfNumber   ), new cmpXslt(cmpRtfStringO   ), new cmpXslt(cmpRtfBoolO   ), new cmpXslt(cmpRtfQueryO   ), new cmpXslt(cmpRtfRtfO) }, 
        };
 
        /*cmpXslt:*/
        static bool cmpQueryQueryE(Operator.Op op, object val1, object val2) {
            Debug.Assert(op == Operator.Op.EQ || op == Operator.Op.NE);
            bool isEQ = (op == Operator.Op.EQ); 

            NodeSet n1 = new NodeSet(val1); 
            NodeSet n2 = new NodeSet(val2); 

            while (true) { 
                if (! n1.MoveNext()) {
                    return false;
                }
                if (! n2.MoveNext()) { 
                    return false;
                } 
 
                string str1 = n1.Value;
 
                do {
                    if ((str1 == n2.Value) == isEQ) {
                        return true;
                    } 
                }while (n2.MoveNext());
                n2.Reset(); 
            } 
        }
 
        /*cmpXslt:*/
        static bool cmpQueryQueryO(Operator.Op op, object val1, object val2) {
            Debug.Assert(
                op == Operator.Op.LT || op == Operator.Op.GT || 
                op == Operator.Op.LE || op == Operator.Op.GE
            ); 
 
            NodeSet n1 = new NodeSet(val1);
            NodeSet n2 = new NodeSet(val2); 

            while (true) {
                if (!n1.MoveNext()) {
                    return false; 
                }
                if (!n2.MoveNext()) { 
                    return false; 
                }
 
                double num1 = NumberFunctions.Number(n1.Value);

                do {
                    if (cmpNumberNumber(op, num1, NumberFunctions.Number(n2.Value))) { 
                        return true;
                    } 
                } while (n2.MoveNext()); 
                n2.Reset();
            } 
        }
        static bool cmpQueryNumber(Operator.Op op, object val1, object val2) {
            NodeSet n1 = new NodeSet(val1);
            double n2 = (double) val2; 

            while (n1.MoveNext()) { 
                if (cmpNumberNumber(op, NumberFunctions.Number(n1.Value), n2)) { 
                    return true;
                } 
            }
            return false;
        }
 
        static bool cmpQueryStringE(Operator.Op op, object val1, object val2) {
            NodeSet n1 = new NodeSet(val1); 
            string n2 = (string) val2; 

            while (n1.MoveNext()) { 
                if (cmpStringStringE(op, n1.Value, n2)) {
                    return true;
                }
            } 
            return false;
        } 
 
        static bool cmpQueryStringO(Operator.Op op, object val1, object val2) {
            NodeSet n1 = new NodeSet(val1); 
            double n2 = NumberFunctions.Number((string) val2);

            while (n1.MoveNext()) {
                if (cmpNumberNumberO(op, NumberFunctions.Number(n1.Value), n2)) { 
                    return true;
                } 
            } 
            return false;
        } 

        static bool cmpRtfQueryE(Operator.Op op, object val1, object val2) {
            string n1 = Rtf(val1);
            NodeSet n2 = new NodeSet(val2); 

            while (n2.MoveNext()) { 
                if (cmpStringStringE(op, n1, n2.Value)) { 
                    return true;
                } 
            }
            return false;
        }
 
        static bool cmpRtfQueryO(Operator.Op op, object val1, object val2) {
            double n1 = NumberFunctions.Number(Rtf(val1)); 
            NodeSet n2 = new NodeSet(val2); 

            while (n2.MoveNext()) { 
                if (cmpNumberNumberO(op, n1, NumberFunctions.Number(n2.Value))) {
                    return true;
                }
            } 
            return false;
        } 
 
        static bool cmpQueryBoolE(Operator.Op op, object val1, object val2) {
            NodeSet n1 = new NodeSet(val1); 
            bool b1 = n1.MoveNext();
            bool b2 = (bool)val2;
            return cmpBoolBoolE(op, b1, b2);
        } 

        static bool cmpQueryBoolO(Operator.Op op, object val1, object val2) { 
            NodeSet n1 = new NodeSet(val1); 
            double d1 = n1.MoveNext() ? 1.0 : 0;
            double d2 = NumberFunctions.Number((bool)val2); 
            return cmpNumberNumberO(op, d1, d2);
        }

        static bool cmpBoolBoolE(Operator.Op op, bool n1, bool n2) { 
            Debug.Assert( op == Operator.Op.EQ || op == Operator.Op.NE,
                "Unexpected Operator.op code in cmpBoolBoolE()" 
            ); 
            return (op == Operator.Op.EQ) == (n1 == n2);
        } 
        static bool cmpBoolBoolE(Operator.Op op, object val1, object val2) {
            bool n1 = (bool)val1;
            bool n2 = (bool)val2;
            return cmpBoolBoolE(op, n1, n2); 
        }
 
        static bool cmpBoolBoolO(Operator.Op op, object val1, object val2) { 
            double n1 = NumberFunctions.Number((bool)val1);
            double n2 = NumberFunctions.Number((bool)val2); 
            return cmpNumberNumberO(op, n1, n2);
        }

        static bool cmpBoolNumberE(Operator.Op op, object val1, object val2) { 
            bool n1 = (bool)val1;
            bool n2 = BooleanFunctions.toBoolean((double)val2); 
            return cmpBoolBoolE(op, n1, n2); 
        }
 
        static bool cmpBoolNumberO(Operator.Op op, object val1, object val2) {
            double n1 = NumberFunctions.Number((bool)val1);
            double n2 = (double)val2;
            return cmpNumberNumberO(op, n1, n2); 
        }
 
        static bool cmpBoolStringE(Operator.Op op, object val1, object val2) { 
            bool n1 = (bool)val1;
            bool n2 = BooleanFunctions.toBoolean((string) val2); 
            return cmpBoolBoolE(op, n1, n2);
        }

        static bool cmpRtfBoolE(Operator.Op op, object val1, object val2) { 
            bool n1 = BooleanFunctions.toBoolean(Rtf(val1));
            bool n2 = (bool)val2; 
            return cmpBoolBoolE(op, n1, n2); 
        }
 
        static bool cmpBoolStringO(Operator.Op op, object val1, object val2) {
            return cmpNumberNumberO(op,
                NumberFunctions.Number((bool)val1),
                NumberFunctions.Number((string) val2) 
            );
        } 
 
        static bool cmpRtfBoolO(Operator.Op op, object val1, object val2) {
            return cmpNumberNumberO(op, 
                NumberFunctions.Number(Rtf(val1)),
                NumberFunctions.Number((bool)val2)
            );
        } 

        static bool cmpNumberNumber(Operator.Op op, double n1, double n2) { 
            switch (op) { 
            case Operator.Op.LT : return( n1 <  n2 ) ;
            case Operator.Op.GT : return( n1 >  n2 ) ; 
            case Operator.Op.LE : return( n1 <= n2 ) ;
            case Operator.Op.GE : return( n1 >= n2 ) ;
            case Operator.Op.EQ : return( n1 == n2 ) ;
            case Operator.Op.NE : return( n1 != n2 ) ; 
            }
            Debug.Fail("Unexpected Operator.op code in cmpNumberNumber()"); 
            return false; 
        }
        static bool cmpNumberNumberO(Operator.Op op, double n1, double n2) { 
            switch (op) {
            case Operator.Op.LT : return( n1 <  n2 ) ;
            case Operator.Op.GT : return( n1 >  n2 ) ;
            case Operator.Op.LE : return( n1 <= n2 ) ; 
            case Operator.Op.GE : return( n1 >= n2 ) ;
            } 
            Debug.Fail("Unexpected Operator.op code in cmpNumberNumberO()"); 
            return false;
        } 
        static bool cmpNumberNumber(Operator.Op op, object val1, object val2) {
            double n1 = (double)val1;
            double n2 = (double)val2;
            return cmpNumberNumber(op, n1, n2); 
        }
 
        static bool cmpStringNumber(Operator.Op op, object val1, object val2) { 
            double n2 = (double)val2;
            double n1 = NumberFunctions.Number((string) val1); 
            return cmpNumberNumber(op, n1, n2);
        }

        static bool cmpRtfNumber(Operator.Op op, object val1, object val2) { 
            double n2 = (double)val2;
            double n1 = NumberFunctions.Number(Rtf(val1)); 
            return cmpNumberNumber(op, n1, n2); 
        }
 
        static bool cmpStringStringE(Operator.Op op, string n1, string n2) {
            Debug.Assert( op == Operator.Op.EQ || op == Operator.Op.NE,
                "Unexpected Operator.op code in cmpStringStringE()"
            ); 
            return (op == Operator.Op.EQ) == (n1 == n2);
        } 
        static bool cmpStringStringE(Operator.Op op, object val1, object val2) { 
            string n1 = (string) val1;
            string n2 = (string) val2; 
            return cmpStringStringE(op, n1, n2);
        }
        static bool cmpRtfStringE(Operator.Op op, object val1, object val2) {
            string n1 = Rtf(val1); 
            string n2 = (string) val2;
            return cmpStringStringE(op, n1, n2); 
        } 
        static bool cmpRtfRtfE(Operator.Op op, object val1, object val2) {
            string n1 = Rtf(val1); 
            string n2 = Rtf(val2);
            return cmpStringStringE(op, n1, n2);
        }
 
        static bool cmpStringStringO(Operator.Op op, object val1, object val2) {
            double n1 = NumberFunctions.Number((string) val1); 
            double n2 = NumberFunctions.Number((string) val2); 
            return cmpNumberNumberO(op, n1, n2);
        } 

        static bool cmpRtfStringO(Operator.Op op, object val1, object val2) {
            double n1 = NumberFunctions.Number(Rtf(val1));
            double n2 = NumberFunctions.Number((string)val2); 
            return cmpNumberNumberO(op, n1, n2);
        } 
 
        static bool cmpRtfRtfO(Operator.Op op, object val1, object val2) {
            double n1 = NumberFunctions.Number(Rtf(val1)); 
            double n2 = NumberFunctions.Number(Rtf(val2));
            return cmpNumberNumberO(op, n1, n2);
        }
 
        public override XPathNodeIterator Clone() { return new LogicalExpr(this); }
 
        private struct NodeSet { 
            private Query opnd;
            private XPathNavigator current; 

            public NodeSet(object opnd) {
                this.opnd = (Query) opnd;
                current = null; 
            }
            public bool MoveNext() { 
                current = opnd.Advance(); 
                return current != null;
            } 

            public void Reset() {
                opnd.Reset();
            } 

            public string Value { get { return this.current.Value; } } 
        } 

        private static string Rtf(    object o) { return ((XPathNavigator)o).Value; } 

        public override XPathResultType StaticType { get { return XPathResultType.Boolean; } }

        public override void PrintQuery(XmlWriter w) { 
            w.WriteStartElement(this.GetType().Name);
            w.WriteAttributeString("op", op.ToString()); 
            opnd1.PrintQuery(w); 
            opnd2.PrintQuery(w);
            w.WriteEndElement(); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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