| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Dispatcher
- {
- using System.Collections.Generic;
- using System.Runtime;
- internal enum RelationOperator
- {
- None,
- Eq,
- Ne,
- Gt,
- Ge,
- Lt,
- Le
- }
- /// <summary>
- /// General relation opcode: compares any two values on the value stack
- /// </summary>
- internal class RelationOpcode : Opcode
- {
- protected RelationOperator op;
- internal RelationOpcode(RelationOperator op)
- : this(OpcodeID.Relation, op)
- {
- }
- protected RelationOpcode(OpcodeID id, RelationOperator op)
- : base(id)
- {
- this.op = op;
- }
- internal override bool Equals(Opcode op)
- {
- if (base.Equals(op))
- {
- return (this.op == ((RelationOpcode)op).op);
- }
- return false;
- }
- internal override Opcode Eval(ProcessingContext context)
- {
- StackFrame argX = context.TopArg;
- StackFrame argY = context.SecondArg;
- Fx.Assert(argX.Count == argY.Count, "");
- Value[] values = context.Values;
- while (argX.basePtr <= argX.endPtr)
- {
- values[argY.basePtr].Update(context, values[argY.basePtr].CompareTo(ref values[argX.basePtr], op));
- argX.basePtr++;
- argY.basePtr++;
- }
- context.PopFrame();
- return this.next;
- }
- #if DEBUG_FILTER
- public override string ToString()
- {
- return string.Format("{0} {1}", base.ToString(), this.op.ToString());
- }
- #endif
- }
- internal abstract class LiteralRelationOpcode : Opcode
- {
- internal LiteralRelationOpcode(OpcodeID id)
- : base(id)
- {
- this.flags |= OpcodeFlags.Literal;
- }
- #if NO
- internal abstract ValueDataType DataType
- {
- get;
- }
- #endif
- internal abstract object Literal
- {
- get;
- }
- #if DEBUG_FILTER
- public override string ToString()
- {
- return string.Format("{0} '{1}'", base.ToString(), this.Literal);
- }
- #endif
- }
- internal class StringEqualsOpcode : LiteralRelationOpcode
- {
- string literal;
- internal StringEqualsOpcode(string literal)
- : base(OpcodeID.StringEquals)
- {
- Fx.Assert(null != literal, "");
- this.literal = literal;
- }
- #if NO
- internal override ValueDataType DataType
- {
- get
- {
- return ValueDataType.String;
- }
- }
- #endif
- internal override object Literal
- {
- get
- {
- return this.literal;
- }
- }
- internal override void Add(Opcode op)
- {
- StringEqualsOpcode strEqOp = op as StringEqualsOpcode;
- if (null == strEqOp)
- {
- base.Add(op);
- return;
- }
- Fx.Assert(null != this.prev, "");
- StringEqualsBranchOpcode branch = new StringEqualsBranchOpcode();
- this.prev.Replace(this, branch);
- branch.Add(this);
- branch.Add(strEqOp);
- }
- internal override bool Equals(Opcode op)
- {
- if (base.Equals(op))
- {
- StringEqualsOpcode strEqOp = (StringEqualsOpcode)op;
- return (strEqOp.literal == this.literal);
- }
- return false;
- }
- internal override Opcode Eval(ProcessingContext context)
- {
- Value[] values = context.Values;
- StackFrame arg = context.TopArg;
- if (1 == arg.Count)
- {
- values[arg.basePtr].Update(context, values[arg.basePtr].Equals(this.literal));
- }
- else
- {
- for (int i = arg.basePtr; i <= arg.endPtr; ++i)
- {
- values[i].Update(context, values[i].Equals(this.literal));
- }
- }
- return this.next;
- }
- }
- internal class NumberEqualsOpcode : LiteralRelationOpcode
- {
- double literal;
- internal NumberEqualsOpcode(double literal)
- : base(OpcodeID.NumberEquals)
- {
- this.literal = literal;
- }
- #if NO
- internal override ValueDataType DataType
- {
- get
- {
- return ValueDataType.Double;
- }
- }
- #endif
- internal override object Literal
- {
- get
- {
- return this.literal;
- }
- }
- internal override void Add(Opcode op)
- {
- NumberEqualsOpcode numEqOp = op as NumberEqualsOpcode;
- if (null == numEqOp)
- {
- base.Add(op);
- return;
- }
- Fx.Assert(null != this.prev, "");
- NumberEqualsBranchOpcode branch = new NumberEqualsBranchOpcode();
- this.prev.Replace(this, branch);
- branch.Add(this);
- branch.Add(numEqOp);
- }
- internal override bool Equals(Opcode op)
- {
- if (base.Equals(op))
- {
- NumberEqualsOpcode numEqOp = (NumberEqualsOpcode)op;
- return (numEqOp.literal == this.literal);
- }
- return false;
- }
- internal override Opcode Eval(ProcessingContext context)
- {
- Value[] values = context.Values;
- StackFrame arg = context.TopArg;
- if (1 == arg.Count)
- {
- values[arg.basePtr].Update(context, values[arg.basePtr].Equals(this.literal));
- }
- else
- {
- for (int i = arg.basePtr; i <= arg.endPtr; ++i)
- {
- values[i].Update(context, values[i].Equals(this.literal));
- }
- }
- return this.next;
- }
- }
- internal abstract class HashBranchIndex : QueryBranchIndex
- {
- Dictionary<object, QueryBranch> literals;
- internal HashBranchIndex()
- {
- this.literals = new Dictionary<object, QueryBranch>();
- }
- internal override int Count
- {
- get
- {
- return this.literals.Count;
- }
- }
- internal override QueryBranch this[object literal]
- {
- get
- {
- QueryBranch result;
- if (this.literals.TryGetValue(literal, out result))
- {
- return result;
- }
- return null;
- }
- set
- {
- this.literals[literal] = value;
- }
- }
- internal override void CollectXPathFilters(ICollection<MessageFilter> filters)
- {
- foreach (QueryBranch branch in this.literals.Values)
- {
- branch.Branch.CollectXPathFilters(filters);
- }
- }
- #if NO
- internal override IEnumerator GetEnumerator()
- {
- return this.literals.GetEnumerator();
- }
- #endif
- internal override void Remove(object key)
- {
- this.literals.Remove(key);
- }
- internal override void Trim()
- {
- // Can't compact Hashtable
- }
- }
- internal class StringBranchIndex : HashBranchIndex
- {
- internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results)
- {
- QueryBranch branch = null;
- if (ValueDataType.Sequence == val.Type)
- {
- NodeSequence sequence = val.Sequence;
- for (int i = 0; i < sequence.Count; ++i)
- {
- branch = this[sequence.Items[i].StringValue()];
- if (null != branch)
- {
- results.Add(branch, valIndex);
- }
- }
- }
- else
- {
- Fx.Assert(val.Type == ValueDataType.String, "");
- branch = this[val.String];
- if (null != branch)
- {
- results.Add(branch, valIndex);
- }
- }
- }
- }
- internal class StringEqualsBranchOpcode : QueryConditionalBranchOpcode
- {
- internal StringEqualsBranchOpcode()
- : base(OpcodeID.StringEqualsBranch, new StringBranchIndex())
- {
- }
- internal override LiteralRelationOpcode ValidateOpcode(Opcode opcode)
- {
- StringEqualsOpcode numOp = opcode as StringEqualsOpcode;
- if (null != numOp)
- {
- return numOp;
- }
- return null;
- }
- }
- internal class NumberBranchIndex : HashBranchIndex
- {
- internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results)
- {
- QueryBranch branch = null;
- if (ValueDataType.Sequence == val.Type)
- {
- NodeSequence sequence = val.Sequence;
- for (int i = 0; i < sequence.Count; ++i)
- {
- branch = this[sequence.Items[i].NumberValue()];
- if (null != branch)
- {
- results.Add(branch, valIndex);
- }
- }
- }
- else
- {
- branch = this[val.ToDouble()];
- if (null != branch)
- {
- results.Add(branch, valIndex);
- }
- }
- }
- }
- internal class NumberEqualsBranchOpcode : QueryConditionalBranchOpcode
- {
- internal NumberEqualsBranchOpcode()
- : base(OpcodeID.NumberEqualsBranch, new NumberBranchIndex())
- {
- }
- internal override LiteralRelationOpcode ValidateOpcode(Opcode opcode)
- {
- NumberEqualsOpcode numOp = opcode as NumberEqualsOpcode;
- if (null != numOp)
- {
- return numOp;
- }
- return null;
- }
- }
- }
|