QuerySetOp.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System.Runtime;
  7. class OrdinalOpcode : Opcode
  8. {
  9. internal OrdinalOpcode()
  10. : base(OpcodeID.Ordinal)
  11. {
  12. }
  13. internal override Opcode Eval(ProcessingContext context)
  14. {
  15. StackFrame sequences = context.TopSequenceArg;
  16. StackFrame ordinals = context.TopArg;
  17. Value[] sequenceBuffer = context.Sequences;
  18. for (int seqIndex = sequences.basePtr, ordinalIndex = ordinals.basePtr; seqIndex <= sequences.endPtr; ++seqIndex)
  19. {
  20. NodeSequence sequence = sequenceBuffer[seqIndex].Sequence;
  21. for (int item = 0; item < sequence.Count; ++item)
  22. {
  23. context.Values[ordinalIndex].Boolean = (sequence[item].Position == context.Values[ordinalIndex].Double);
  24. ordinalIndex++;
  25. }
  26. }
  27. return this.next;
  28. }
  29. }
  30. internal class LiteralOrdinalOpcode : Opcode
  31. {
  32. int ordinal; // 1 based
  33. internal LiteralOrdinalOpcode(int ordinal)
  34. : base(OpcodeID.LiteralOrdinal)
  35. {
  36. Fx.Assert(ordinal > 0, "");
  37. this.ordinal = ordinal;
  38. }
  39. #if NO
  40. // Never used for inverse query, so don't need this
  41. internal override bool Equals(Opcode op)
  42. {
  43. if (base.Equals (op))
  44. {
  45. return (this.ordinal == ((LiteralOrdinalOpcode) op).ordinal);
  46. }
  47. return false;
  48. }
  49. #endif
  50. internal override Opcode Eval(ProcessingContext context)
  51. {
  52. StackFrame sequences = context.TopSequenceArg;
  53. Value[] sequenceBuffer = context.Sequences;
  54. context.PushFrame();
  55. for (int i = sequences.basePtr; i <= sequences.endPtr; ++i)
  56. {
  57. NodeSequence sequence = sequenceBuffer[i].Sequence;
  58. for (int item = 0; item < sequence.Count; ++item)
  59. {
  60. context.Push(sequence[item].Position == this.ordinal);
  61. }
  62. }
  63. return this.next;
  64. }
  65. #if DEBUG_FILTER
  66. public override string ToString()
  67. {
  68. return string.Format("{0} {1}", base.ToString(), this.ordinal);
  69. }
  70. #endif
  71. }
  72. // Filters context sequences using the results of the last executed predicate
  73. // Does pop result values
  74. internal class ApplyFilterOpcode : Opcode
  75. {
  76. internal ApplyFilterOpcode()
  77. : base(OpcodeID.Filter)
  78. {
  79. }
  80. internal override Opcode Eval(ProcessingContext context)
  81. {
  82. StackFrame sequences = context.TopSequenceArg;
  83. StackFrame results = context.TopArg;
  84. NodeSequenceBuilder sequenceBuilder = new NodeSequenceBuilder(context);
  85. Value[] sequenceBuffer = context.Sequences;
  86. for (int seqIndex = sequences.basePtr, resultIndex = results.basePtr; seqIndex <= sequences.endPtr; ++seqIndex)
  87. {
  88. NodeSequence sourceSequence = sequenceBuffer[seqIndex].Sequence;
  89. if (sourceSequence.Count > 0)
  90. {
  91. NodesetIterator nodesetIterator = new NodesetIterator(sourceSequence);
  92. while (nodesetIterator.NextNodeset())
  93. {
  94. sequenceBuilder.StartNodeset();
  95. while (nodesetIterator.NextItem())
  96. {
  97. Fx.Assert(context.Values[resultIndex].IsType(ValueDataType.Boolean), "");
  98. if (context.Values[resultIndex].Boolean)
  99. {
  100. sequenceBuilder.Add(ref sourceSequence.Items[nodesetIterator.Index]);
  101. }
  102. ++resultIndex;
  103. }
  104. sequenceBuilder.EndNodeset();
  105. }
  106. context.ReplaceSequenceAt(seqIndex, sequenceBuilder.Sequence);
  107. context.ReleaseSequence(sourceSequence);
  108. sequenceBuilder.Sequence = null;
  109. }
  110. }
  111. context.PopFrame();
  112. return this.next;
  113. }
  114. }
  115. /// <summary>
  116. /// Union the sequences found in the top two frames of the value stack
  117. /// The unionized sequence
  118. /// </summary>
  119. internal class UnionOpcode : Opcode
  120. {
  121. internal UnionOpcode()
  122. : base(OpcodeID.Union)
  123. {
  124. }
  125. internal override Opcode Eval(ProcessingContext context)
  126. {
  127. StackFrame topArg = context.TopArg;
  128. StackFrame secondArg = context.SecondArg;
  129. Fx.Assert(topArg.Count == secondArg.Count, "");
  130. for (int x = topArg.basePtr, y = secondArg.basePtr; x <= topArg.endPtr; ++x, ++y)
  131. {
  132. NodeSequence seqX = context.Values[x].Sequence;
  133. NodeSequence seqY = context.Values[y].Sequence;
  134. // Replace with a new sequence that is the union of the two
  135. context.SetValue(context, y, seqY.Union(context, seqX));
  136. }
  137. context.PopFrame();
  138. return this.next;
  139. }
  140. }
  141. internal class MergeOpcode : Opcode
  142. {
  143. internal MergeOpcode()
  144. : base(OpcodeID.Merge)
  145. {
  146. }
  147. internal override Opcode Eval(ProcessingContext context)
  148. {
  149. Value[] values = context.Values;
  150. StackFrame arg = context.TopArg;
  151. for (int i = arg.basePtr; i <= arg.endPtr; ++i)
  152. {
  153. Fx.Assert(ValueDataType.Sequence == values[i].Type, "");
  154. NodeSequence seq = values[i].Sequence;
  155. NodeSequence newSeq = context.CreateSequence();
  156. for (int j = 0; j < seq.Count; ++j)
  157. {
  158. NodeSequenceItem item = seq[j];
  159. newSeq.AddCopy(ref item);
  160. }
  161. newSeq.Merge();
  162. context.SetValue(context, i, newSeq);
  163. }
  164. return this.next;
  165. }
  166. }
  167. }