Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
5.5 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FILE
  4. //
  5. // Tokens.h
  6. //
  7. // SYNOPSIS
  8. //
  9. // This file defines the various boolean token classes.
  10. //
  11. // MODIFICATION HISTORY
  12. //
  13. // 02/04/1998 Original version.
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. #ifndef _TOKENS_H_
  17. #define _TOKENS_H_
  18. #include <algorithm>
  19. #include <nap.h>
  20. #include <nocopy.h>
  21. //////////
  22. // An abstract token.
  23. //////////
  24. class Token :
  25. public ICondition, NonCopyable
  26. {
  27. public:
  28. Token() throw ()
  29. : refCount(0)
  30. { }
  31. virtual ~Token() throw ()
  32. { }
  33. //////////
  34. // IUnknown implementation.
  35. //////////
  36. STDMETHOD_(ULONG, AddRef)()
  37. {
  38. return InterlockedIncrement(&refCount);
  39. }
  40. STDMETHOD_(ULONG, Release)()
  41. {
  42. LONG l = InterlockedDecrement(&refCount);
  43. if (l == 0) { delete this; }
  44. return l;
  45. }
  46. STDMETHOD(QueryInterface)(const IID& iid, void** ppv)
  47. {
  48. if (iid == __uuidof(IUnknown))
  49. {
  50. *ppv = static_cast<IUnknown*>(this);
  51. }
  52. else if (iid == __uuidof(ICondition))
  53. {
  54. *ppv = static_cast<ICondition*>(this);
  55. }
  56. else
  57. {
  58. return E_NOINTERFACE;
  59. }
  60. InterlockedIncrement(&refCount);
  61. return S_OK;
  62. }
  63. protected:
  64. LONG refCount;
  65. };
  66. //////////
  67. // A Boolean constant.
  68. //////////
  69. template <VARIANT_BOOL Value>
  70. class ConstantCondition : public Token
  71. {
  72. public:
  73. STDMETHOD(IsTrue)(/*[in]*/ IRequest*,
  74. /*[out, retval]*/ VARIANT_BOOL *pVal)
  75. {
  76. *pVal = Value;
  77. return S_OK;
  78. }
  79. };
  80. //////////
  81. // A unary operator in the logic tree.
  82. //////////
  83. class UnaryOperator : public Token
  84. {
  85. public:
  86. UnaryOperator(ICondition* cond)
  87. : operand(cond)
  88. {
  89. if (operand)
  90. {
  91. operand->AddRef();
  92. }
  93. else
  94. {
  95. _com_issue_error(E_POINTER);
  96. }
  97. }
  98. ~UnaryOperator() throw ()
  99. {
  100. operand->Release();
  101. }
  102. protected:
  103. ICondition* operand;
  104. };
  105. //////////
  106. // A binary operator in the logic tree.
  107. //////////
  108. class BinaryOperator : public Token
  109. {
  110. public:
  111. BinaryOperator(ICondition* left, ICondition* right)
  112. : left_operand(left), right_operand(right)
  113. {
  114. if (left_operand && right_operand)
  115. {
  116. left_operand->AddRef();
  117. right_operand->AddRef();
  118. }
  119. else
  120. {
  121. _com_issue_error(E_POINTER);
  122. }
  123. }
  124. ~BinaryOperator() throw ()
  125. {
  126. left_operand->Release();
  127. right_operand->Release();
  128. }
  129. protected:
  130. ICondition *left_operand, *right_operand;
  131. };
  132. //////////
  133. // AND Operator
  134. //////////
  135. class AndOperator : public BinaryOperator
  136. {
  137. public:
  138. AndOperator(ICondition* left, ICondition* right)
  139. : BinaryOperator(left, right)
  140. { }
  141. STDMETHOD(IsTrue)(/*[in]*/ IRequest* pRequest,
  142. /*[out, retval]*/ VARIANT_BOOL *pVal)
  143. {
  144. HRESULT hr = left_operand->IsTrue(pRequest, pVal);
  145. if (SUCCEEDED(hr) && *pVal != VARIANT_FALSE)
  146. {
  147. hr = right_operand->IsTrue(pRequest, pVal);
  148. if (*pVal == VARIANT_FALSE)
  149. {
  150. // We should have tried the right operand first, so let's swap
  151. // them and maybe we'll get lucky next time.
  152. std::swap(left_operand, right_operand);
  153. }
  154. }
  155. return hr;
  156. }
  157. };
  158. //////////
  159. // OR Operator
  160. //////////
  161. class OrOperator : public BinaryOperator
  162. {
  163. public:
  164. OrOperator(ICondition* left, ICondition* right)
  165. : BinaryOperator(left, right)
  166. { }
  167. STDMETHOD(IsTrue)(/*[in]*/ IRequest* pRequest,
  168. /*[out, retval]*/ VARIANT_BOOL *pVal)
  169. {
  170. HRESULT hr = left_operand->IsTrue(pRequest, pVal);
  171. if (SUCCEEDED(hr) && *pVal == VARIANT_FALSE)
  172. {
  173. hr = right_operand->IsTrue(pRequest, pVal);
  174. if (*pVal != VARIANT_FALSE)
  175. {
  176. // We should have tried the right operand first, so let's swap
  177. // them and maybe we'll get lucky next time.
  178. std::swap(left_operand, right_operand);
  179. }
  180. }
  181. return hr;
  182. }
  183. };
  184. //////////
  185. // XOR Operator
  186. //////////
  187. class XorOperator : public BinaryOperator
  188. {
  189. public:
  190. XorOperator(ICondition* left, ICondition* right)
  191. : BinaryOperator(left, right)
  192. { }
  193. STDMETHOD(IsTrue)(/*[in]*/ IRequest* pRequest,
  194. /*[out, retval]*/ VARIANT_BOOL *pVal)
  195. {
  196. HRESULT hr = left_operand->IsTrue(pRequest, pVal);
  197. if (SUCCEEDED(hr))
  198. {
  199. BOOL b1 = (*pVal != VARIANT_FALSE);
  200. hr = right_operand->IsTrue(pRequest, pVal);
  201. if (SUCCEEDED(hr))
  202. {
  203. BOOL b2 = (*pVal != VARIANT_FALSE);
  204. *pVal = ((b1 && !b2) || (!b1 && b2)) ? VARIANT_TRUE
  205. : VARIANT_FALSE;
  206. }
  207. }
  208. return hr;
  209. }
  210. };
  211. //////////
  212. // NOT Operator
  213. //////////
  214. class NotOperator : public UnaryOperator
  215. {
  216. public:
  217. NotOperator(ICondition* cond)
  218. : UnaryOperator(cond)
  219. { }
  220. STDMETHOD(IsTrue)(/*[in]*/ IRequest* pRequest,
  221. /*[out, retval]*/ VARIANT_BOOL *pVal)
  222. {
  223. HRESULT hr = operand->IsTrue(pRequest, pVal);
  224. if (SUCCEEDED(hr))
  225. {
  226. *pVal = (*pVal != VARIANT_FALSE) ? VARIANT_FALSE : VARIANT_TRUE;
  227. }
  228. return hr;
  229. }
  230. };
  231. #endif //_TOKENS_H_