QueryRelOp.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System.Collections.Generic;
  7. using System.Runtime;
  8. internal enum RelationOperator
  9. {
  10. None,
  11. Eq,
  12. Ne,
  13. Gt,
  14. Ge,
  15. Lt,
  16. Le
  17. }
  18. /// <summary>
  19. /// General relation opcode: compares any two values on the value stack
  20. /// </summary>
  21. internal class RelationOpcode : Opcode
  22. {
  23. protected RelationOperator op;
  24. internal RelationOpcode(RelationOperator op)
  25. : this(OpcodeID.Relation, op)
  26. {
  27. }
  28. protected RelationOpcode(OpcodeID id, RelationOperator op)
  29. : base(id)
  30. {
  31. this.op = op;
  32. }
  33. internal override bool Equals(Opcode op)
  34. {
  35. if (base.Equals(op))
  36. {
  37. return (this.op == ((RelationOpcode)op).op);
  38. }
  39. return false;
  40. }
  41. internal override Opcode Eval(ProcessingContext context)
  42. {
  43. StackFrame argX = context.TopArg;
  44. StackFrame argY = context.SecondArg;
  45. Fx.Assert(argX.Count == argY.Count, "");
  46. Value[] values = context.Values;
  47. while (argX.basePtr <= argX.endPtr)
  48. {
  49. values[argY.basePtr].Update(context, values[argY.basePtr].CompareTo(ref values[argX.basePtr], op));
  50. argX.basePtr++;
  51. argY.basePtr++;
  52. }
  53. context.PopFrame();
  54. return this.next;
  55. }
  56. #if DEBUG_FILTER
  57. public override string ToString()
  58. {
  59. return string.Format("{0} {1}", base.ToString(), this.op.ToString());
  60. }
  61. #endif
  62. }
  63. internal abstract class LiteralRelationOpcode : Opcode
  64. {
  65. internal LiteralRelationOpcode(OpcodeID id)
  66. : base(id)
  67. {
  68. this.flags |= OpcodeFlags.Literal;
  69. }
  70. #if NO
  71. internal abstract ValueDataType DataType
  72. {
  73. get;
  74. }
  75. #endif
  76. internal abstract object Literal
  77. {
  78. get;
  79. }
  80. #if DEBUG_FILTER
  81. public override string ToString()
  82. {
  83. return string.Format("{0} '{1}'", base.ToString(), this.Literal);
  84. }
  85. #endif
  86. }
  87. internal class StringEqualsOpcode : LiteralRelationOpcode
  88. {
  89. string literal;
  90. internal StringEqualsOpcode(string literal)
  91. : base(OpcodeID.StringEquals)
  92. {
  93. Fx.Assert(null != literal, "");
  94. this.literal = literal;
  95. }
  96. #if NO
  97. internal override ValueDataType DataType
  98. {
  99. get
  100. {
  101. return ValueDataType.String;
  102. }
  103. }
  104. #endif
  105. internal override object Literal
  106. {
  107. get
  108. {
  109. return this.literal;
  110. }
  111. }
  112. internal override void Add(Opcode op)
  113. {
  114. StringEqualsOpcode strEqOp = op as StringEqualsOpcode;
  115. if (null == strEqOp)
  116. {
  117. base.Add(op);
  118. return;
  119. }
  120. Fx.Assert(null != this.prev, "");
  121. StringEqualsBranchOpcode branch = new StringEqualsBranchOpcode();
  122. this.prev.Replace(this, branch);
  123. branch.Add(this);
  124. branch.Add(strEqOp);
  125. }
  126. internal override bool Equals(Opcode op)
  127. {
  128. if (base.Equals(op))
  129. {
  130. StringEqualsOpcode strEqOp = (StringEqualsOpcode)op;
  131. return (strEqOp.literal == this.literal);
  132. }
  133. return false;
  134. }
  135. internal override Opcode Eval(ProcessingContext context)
  136. {
  137. Value[] values = context.Values;
  138. StackFrame arg = context.TopArg;
  139. if (1 == arg.Count)
  140. {
  141. values[arg.basePtr].Update(context, values[arg.basePtr].Equals(this.literal));
  142. }
  143. else
  144. {
  145. for (int i = arg.basePtr; i <= arg.endPtr; ++i)
  146. {
  147. values[i].Update(context, values[i].Equals(this.literal));
  148. }
  149. }
  150. return this.next;
  151. }
  152. }
  153. internal class NumberEqualsOpcode : LiteralRelationOpcode
  154. {
  155. double literal;
  156. internal NumberEqualsOpcode(double literal)
  157. : base(OpcodeID.NumberEquals)
  158. {
  159. this.literal = literal;
  160. }
  161. #if NO
  162. internal override ValueDataType DataType
  163. {
  164. get
  165. {
  166. return ValueDataType.Double;
  167. }
  168. }
  169. #endif
  170. internal override object Literal
  171. {
  172. get
  173. {
  174. return this.literal;
  175. }
  176. }
  177. internal override void Add(Opcode op)
  178. {
  179. NumberEqualsOpcode numEqOp = op as NumberEqualsOpcode;
  180. if (null == numEqOp)
  181. {
  182. base.Add(op);
  183. return;
  184. }
  185. Fx.Assert(null != this.prev, "");
  186. NumberEqualsBranchOpcode branch = new NumberEqualsBranchOpcode();
  187. this.prev.Replace(this, branch);
  188. branch.Add(this);
  189. branch.Add(numEqOp);
  190. }
  191. internal override bool Equals(Opcode op)
  192. {
  193. if (base.Equals(op))
  194. {
  195. NumberEqualsOpcode numEqOp = (NumberEqualsOpcode)op;
  196. return (numEqOp.literal == this.literal);
  197. }
  198. return false;
  199. }
  200. internal override Opcode Eval(ProcessingContext context)
  201. {
  202. Value[] values = context.Values;
  203. StackFrame arg = context.TopArg;
  204. if (1 == arg.Count)
  205. {
  206. values[arg.basePtr].Update(context, values[arg.basePtr].Equals(this.literal));
  207. }
  208. else
  209. {
  210. for (int i = arg.basePtr; i <= arg.endPtr; ++i)
  211. {
  212. values[i].Update(context, values[i].Equals(this.literal));
  213. }
  214. }
  215. return this.next;
  216. }
  217. }
  218. internal abstract class HashBranchIndex : QueryBranchIndex
  219. {
  220. Dictionary<object, QueryBranch> literals;
  221. internal HashBranchIndex()
  222. {
  223. this.literals = new Dictionary<object, QueryBranch>();
  224. }
  225. internal override int Count
  226. {
  227. get
  228. {
  229. return this.literals.Count;
  230. }
  231. }
  232. internal override QueryBranch this[object literal]
  233. {
  234. get
  235. {
  236. QueryBranch result;
  237. if (this.literals.TryGetValue(literal, out result))
  238. {
  239. return result;
  240. }
  241. return null;
  242. }
  243. set
  244. {
  245. this.literals[literal] = value;
  246. }
  247. }
  248. internal override void CollectXPathFilters(ICollection<MessageFilter> filters)
  249. {
  250. foreach (QueryBranch branch in this.literals.Values)
  251. {
  252. branch.Branch.CollectXPathFilters(filters);
  253. }
  254. }
  255. #if NO
  256. internal override IEnumerator GetEnumerator()
  257. {
  258. return this.literals.GetEnumerator();
  259. }
  260. #endif
  261. internal override void Remove(object key)
  262. {
  263. this.literals.Remove(key);
  264. }
  265. internal override void Trim()
  266. {
  267. // Can't compact Hashtable
  268. }
  269. }
  270. internal class StringBranchIndex : HashBranchIndex
  271. {
  272. internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results)
  273. {
  274. QueryBranch branch = null;
  275. if (ValueDataType.Sequence == val.Type)
  276. {
  277. NodeSequence sequence = val.Sequence;
  278. for (int i = 0; i < sequence.Count; ++i)
  279. {
  280. branch = this[sequence.Items[i].StringValue()];
  281. if (null != branch)
  282. {
  283. results.Add(branch, valIndex);
  284. }
  285. }
  286. }
  287. else
  288. {
  289. Fx.Assert(val.Type == ValueDataType.String, "");
  290. branch = this[val.String];
  291. if (null != branch)
  292. {
  293. results.Add(branch, valIndex);
  294. }
  295. }
  296. }
  297. }
  298. internal class StringEqualsBranchOpcode : QueryConditionalBranchOpcode
  299. {
  300. internal StringEqualsBranchOpcode()
  301. : base(OpcodeID.StringEqualsBranch, new StringBranchIndex())
  302. {
  303. }
  304. internal override LiteralRelationOpcode ValidateOpcode(Opcode opcode)
  305. {
  306. StringEqualsOpcode numOp = opcode as StringEqualsOpcode;
  307. if (null != numOp)
  308. {
  309. return numOp;
  310. }
  311. return null;
  312. }
  313. }
  314. internal class NumberBranchIndex : HashBranchIndex
  315. {
  316. internal override void Match(int valIndex, ref Value val, QueryBranchResultSet results)
  317. {
  318. QueryBranch branch = null;
  319. if (ValueDataType.Sequence == val.Type)
  320. {
  321. NodeSequence sequence = val.Sequence;
  322. for (int i = 0; i < sequence.Count; ++i)
  323. {
  324. branch = this[sequence.Items[i].NumberValue()];
  325. if (null != branch)
  326. {
  327. results.Add(branch, valIndex);
  328. }
  329. }
  330. }
  331. else
  332. {
  333. branch = this[val.ToDouble()];
  334. if (null != branch)
  335. {
  336. results.Add(branch, valIndex);
  337. }
  338. }
  339. }
  340. }
  341. internal class NumberEqualsBranchOpcode : QueryConditionalBranchOpcode
  342. {
  343. internal NumberEqualsBranchOpcode()
  344. : base(OpcodeID.NumberEqualsBranch, new NumberBranchIndex())
  345. {
  346. }
  347. internal override LiteralRelationOpcode ValidateOpcode(Opcode opcode)
  348. {
  349. NumberEqualsOpcode numOp = opcode as NumberEqualsOpcode;
  350. if (null != numOp)
  351. {
  352. return numOp;
  353. }
  354. return null;
  355. }
  356. }
  357. }