ECRestriction.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. * Copyright 2016 Kopano and its licensors
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License, version 3,
  7. * as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Affero General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Affero General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. */
  18. #ifndef ECRestrictionBuilder_INCLUDED
  19. #define ECRestrictionBuilder_INCLUDED
  20. #include <memory>
  21. #include <utility>
  22. #include <kopano/zcdefs.h>
  23. #include <mapidefs.h>
  24. #include <list>
  25. namespace KC {
  26. /*
  27. * Caution. Since ECXXRestriction(ECXXRestriction &&) will be defined in
  28. * classes for the purpose of clone_and_move, that constructor cannot be used
  29. * to create nested restrictions. The three affected cases are:
  30. *
  31. * - ECAndRestriction(ECAndRestriction(expr)) is redundant and equal to
  32. * just writing ECAndRestriction(expr).
  33. * - Same goes for ECOrRestriction.
  34. * - ECNotRestriction(ECNotRestriction(expr)) is silly to write; just use expr.
  35. */
  36. class ECRestrictionList;
  37. /**
  38. * Base class for all other ECxxxRestriction classes.
  39. * It defines the interface needed to hook the various restrictions together.
  40. */
  41. class _kc_export ECRestriction {
  42. public:
  43. enum {
  44. Full = 0,
  45. Cheap = 1, // Stores the passed LPSPropValue pointer.
  46. Shallow = 2 // Creates a new SPropValue, but point to the embedded data from the original structure.
  47. };
  48. _kc_hidden virtual ~ECRestriction(void) _kc_impdtor;
  49. /**
  50. * Create an LPSRestiction object that represents the restriction on which CreateMAPIRestriction was called.
  51. * @param[in] lppRestriction Pointer to an LPSRestriction pointer, that will be set to the address
  52. * of the newly allocated restriction. This memory must be freed with
  53. * MAPIFreeBuffer.
  54. * @param[in] ulFlags When set to ECRestriction::Cheap, not all data will be copied to the
  55. * new MAPI restriction. This is useful if the ECRestriction will outlive
  56. * the MAPI restriction.
  57. */
  58. HRESULT CreateMAPIRestriction(LPSRestriction *lppRestriction, ULONG ulFlags) const;
  59. /**
  60. * Apply the restriction on a table.
  61. * @param[in] lpTable The table on which to apply the restriction.
  62. */
  63. HRESULT RestrictTable(IMAPITable *, unsigned int flags = TBL_BATCH) const;
  64. /**
  65. * Use the restriction to perform a FindRow on the passed table.
  66. * @param[in] lpTable The table on which to perform the FindRow.
  67. * @param[in] BkOrigin The location to start searching from. Directly passed to FindRow.
  68. * @param[in] ulFlags Flags controlling search behaviour. Directly passed to FindRow.
  69. */
  70. _kc_export HRESULT FindRowIn(LPMAPITABLE, BOOKMARK origin, ULONG flags) const;
  71. /**
  72. * Populate an SRestriction structure based on the objects state.
  73. * @param[in] lpBase Base pointer used for allocating additional memory.
  74. * @param[in,out] lpRestriction Pointer to the SRestriction object that is to be populated.
  75. */
  76. _kc_hidden virtual HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction, ULONG flags = 0) const = 0;
  77. /**
  78. * Create a new ECRestriction derived class of the same type of the object on which this
  79. * method is invoked.
  80. * @return A copy of the current object.
  81. */
  82. _kc_hidden virtual ECRestriction *Clone(void) const _kc_lvqual = 0;
  83. #ifdef HAVE_MF_QUAL
  84. _kc_hidden virtual ECRestriction *Clone(void) && = 0;
  85. _kc_hidden ECRestrictionList operator+(ECRestriction &&) &&;
  86. #endif
  87. _kc_hidden ECRestrictionList operator+(const ECRestriction &) const;
  88. protected:
  89. typedef std::shared_ptr<SPropValue> PropPtr;
  90. typedef std::shared_ptr<ECRestriction> ResPtr;
  91. typedef std::list<ResPtr> ResList;
  92. _kc_hidden ECRestriction(void) = default;
  93. _kc_hidden static HRESULT CopyProp(SPropValue *src, void *base, ULONG flags, SPropValue **dst);
  94. _kc_hidden static HRESULT CopyPropArray(ULONG nvals, SPropValue *src, void *base, ULONG flags, SPropValue **dst);
  95. _kc_hidden static void DummyFree(LPVOID);
  96. };
  97. /**
  98. * An ECRestrictionList is a list of ECRestriction objects.
  99. * This class is used to allow a list of restrictions to be passed in the
  100. * constructors of the ECAndRestriction and the ECOrRestriction classes.
  101. * It's implicitly created by +-ing multiple ECRestriction objects.
  102. */
  103. class ECRestrictionList _kc_final {
  104. public:
  105. ECRestrictionList(const ECRestriction &res1, const ECRestriction &res2) {
  106. m_list.push_back(ResPtr(res1.Clone()));
  107. m_list.push_back(ResPtr(res2.Clone()));
  108. }
  109. ECRestrictionList(ECRestriction &&o1, ECRestriction &&o2)
  110. {
  111. m_list.push_back(ResPtr(std::move(o1).Clone()));
  112. m_list.push_back(ResPtr(std::move(o2).Clone()));
  113. }
  114. ECRestrictionList& operator+(const ECRestriction &restriction) {
  115. m_list.push_back(ResPtr(restriction.Clone()));
  116. return *this;
  117. }
  118. ECRestrictionList &operator+(ECRestriction &&o)
  119. {
  120. m_list.push_back(ResPtr(std::move(o).Clone()));
  121. return *this;
  122. }
  123. private:
  124. typedef std::shared_ptr<ECRestriction> ResPtr;
  125. typedef std::list<ResPtr> ResList;
  126. ResList m_list;
  127. friend class ECAndRestriction;
  128. friend class ECOrRestriction;
  129. };
  130. /**
  131. * Add two restrictions together and create an ECRestrictionList.
  132. * @param[in] restriction The restriction to add with the current.
  133. * @return The ECRestrictionList with the two entries.
  134. */
  135. inline ECRestrictionList ECRestriction::operator+ (const ECRestriction &other) const {
  136. return ECRestrictionList(*this, other);
  137. }
  138. #ifdef HAVE_MF_QUAL
  139. inline ECRestrictionList ECRestriction::operator+(ECRestriction &&other) &&
  140. {
  141. return ECRestrictionList(std::move(*this), std::move(other));
  142. }
  143. #endif
  144. class IRestrictionPush : public ECRestriction {
  145. public:
  146. virtual ECRestriction *operator+=(const ECRestriction &) = 0;
  147. virtual ECRestriction *operator+=(ECRestriction &&) = 0;
  148. };
  149. class _kc_export ECAndRestriction _kc_final : public IRestrictionPush {
  150. public:
  151. _kc_hidden ECAndRestriction(void) {}
  152. ECAndRestriction(const ECRestrictionList &list);
  153. _kc_hidden ECAndRestriction(ECRestrictionList &&o) :
  154. m_lstRestrictions(std::move(o.m_list))
  155. {}
  156. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction res, ULONG flags) const _kc_override;
  157. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  158. #ifdef HAVE_MF_QUAL
  159. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECAndRestriction(std::move(*this)); }
  160. #endif
  161. ECRestriction *operator+=(const ECRestriction &restriction)
  162. {
  163. m_lstRestrictions.push_back(ResPtr(restriction.Clone()));
  164. return m_lstRestrictions.rbegin()->get();
  165. }
  166. ECRestriction *operator+=(ECRestriction &&o)
  167. {
  168. m_lstRestrictions.push_back(ResPtr(std::move(o).Clone()));
  169. return m_lstRestrictions.rbegin()->get();
  170. }
  171. void operator+=(const ECRestrictionList &list);
  172. void operator+=(ECRestrictionList &&);
  173. private:
  174. ResList m_lstRestrictions;
  175. };
  176. class _kc_export ECOrRestriction _kc_final : public IRestrictionPush {
  177. public:
  178. _kc_hidden ECOrRestriction(void) {}
  179. ECOrRestriction(const ECRestrictionList &list);
  180. _kc_hidden ECOrRestriction(ECRestrictionList &&o) :
  181. m_lstRestrictions(std::move(o.m_list))
  182. {}
  183. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  184. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  185. #ifdef HAVE_MF_QUAL
  186. ECRestriction *Clone(void) && _kc_override { return new ECOrRestriction(std::move(*this)); }
  187. #endif
  188. ECRestriction *operator+=(const ECRestriction &restriction)
  189. {
  190. m_lstRestrictions.push_back(ResPtr(restriction.Clone()));
  191. return m_lstRestrictions.rbegin()->get();
  192. }
  193. ECRestriction *operator+=(ECRestriction &&o)
  194. {
  195. m_lstRestrictions.push_back(ResPtr(std::move(o).Clone()));
  196. return m_lstRestrictions.rbegin()->get();
  197. }
  198. void operator+=(const ECRestrictionList &list);
  199. void operator+=(ECRestrictionList &&);
  200. private:
  201. ResList m_lstRestrictions;
  202. };
  203. class _kc_export ECNotRestriction _kc_final : public IRestrictionPush {
  204. public:
  205. _kc_hidden ECNotRestriction(const ECRestriction &restriction)
  206. : m_ptrRestriction(ResPtr(restriction.Clone()))
  207. { }
  208. _kc_hidden ECNotRestriction(ECRestriction &&o) :
  209. m_ptrRestriction(std::move(o).Clone())
  210. {}
  211. ECNotRestriction(std::nullptr_t) {}
  212. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  213. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  214. #ifdef HAVE_MF_QUAL
  215. ECRestriction *Clone(void) && _kc_override { return new ECNotRestriction(std::move(*this)); }
  216. #endif
  217. ECRestriction *operator+=(const ECRestriction &r)
  218. {
  219. m_ptrRestriction.reset(r.Clone());
  220. return m_ptrRestriction.get();
  221. }
  222. ECRestriction *operator+=(ECRestriction &&r)
  223. {
  224. m_ptrRestriction.reset(std::move(r).Clone());
  225. return m_ptrRestriction.get();
  226. }
  227. private:
  228. _kc_hidden ECNotRestriction(ResPtr restriction);
  229. ResPtr m_ptrRestriction;
  230. };
  231. class _kc_export ECContentRestriction _kc_final : public ECRestriction {
  232. public:
  233. ECContentRestriction(ULONG fuzzy_lvl, ULONG tag, const SPropValue *, ULONG flags);
  234. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  235. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  236. #ifdef HAVE_MF_QUAL
  237. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECContentRestriction(std::move(*this)); }
  238. #endif
  239. private:
  240. _kc_hidden ECContentRestriction(ULONG fuzzy_level, ULONG tag, PropPtr prop);
  241. private:
  242. ULONG m_ulFuzzyLevel;
  243. ULONG m_ulPropTag;
  244. PropPtr m_ptrProp;
  245. };
  246. class _kc_export ECBitMaskRestriction _kc_final : public ECRestriction {
  247. public:
  248. _kc_hidden ECBitMaskRestriction(ULONG relBMR, ULONG ulPropTag, ULONG ulMask)
  249. : m_relBMR(relBMR)
  250. , m_ulPropTag(ulPropTag)
  251. , m_ulMask(ulMask)
  252. { }
  253. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  254. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  255. #ifdef HAVE_MF_QUAL
  256. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECBitMaskRestriction(std::move(*this)); }
  257. #endif
  258. private:
  259. ULONG m_relBMR;
  260. ULONG m_ulPropTag;
  261. ULONG m_ulMask;
  262. };
  263. class _kc_export ECPropertyRestriction _kc_final : public ECRestriction {
  264. public:
  265. ECPropertyRestriction(ULONG relop, ULONG tag, const SPropValue *, ULONG flags);
  266. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  267. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  268. #ifdef HAVE_MF_QUAL
  269. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECPropertyRestriction(std::move(*this)); }
  270. #endif
  271. private:
  272. _kc_hidden ECPropertyRestriction(ULONG relop, ULONG proptag, PropPtr prop);
  273. ULONG m_relop;
  274. ULONG m_ulPropTag;
  275. PropPtr m_ptrProp;
  276. };
  277. class _kc_export ECComparePropsRestriction _kc_final : public ECRestriction {
  278. public:
  279. _kc_hidden ECComparePropsRestriction(ULONG relop, ULONG ulPropTag1, ULONG ulPropTag2)
  280. : m_relop(relop)
  281. , m_ulPropTag1(ulPropTag1)
  282. , m_ulPropTag2(ulPropTag2)
  283. { }
  284. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  285. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  286. #ifdef HAVE_MF_QUAL
  287. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECComparePropsRestriction(std::move(*this)); }
  288. #endif
  289. private:
  290. ULONG m_relop;
  291. ULONG m_ulPropTag1;
  292. ULONG m_ulPropTag2;
  293. };
  294. class _kc_export ECExistRestriction _kc_final : public ECRestriction {
  295. public:
  296. _kc_hidden ECExistRestriction(ULONG ulPropTag)
  297. : m_ulPropTag(ulPropTag)
  298. { }
  299. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  300. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  301. #ifdef HAVE_MF_QUAL
  302. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECExistRestriction(std::move(*this)); }
  303. #endif
  304. private:
  305. ULONG m_ulPropTag;
  306. };
  307. /**
  308. * This is a special class, which encapsulates a raw SRestriction structure to allow
  309. * prebuild or obtained restriction structures to be used in the ECRestriction model.
  310. */
  311. class _kc_export ECRawRestriction _kc_final : public ECRestriction {
  312. public:
  313. ECRawRestriction(const SRestriction *, ULONG flags);
  314. _kc_hidden HRESULT GetMAPIRestriction(LPVOID base, LPSRestriction r, ULONG flags) const _kc_override;
  315. ECRestriction *Clone(void) const _kc_lvqual _kc_override;
  316. #ifdef HAVE_MF_QUAL
  317. _kc_hidden ECRestriction *Clone(void) && _kc_override { return new ECRawRestriction(std::move(*this)); }
  318. #endif
  319. private:
  320. typedef std::shared_ptr<SRestriction> RawResPtr;
  321. _kc_hidden ECRawRestriction(RawResPtr restriction);
  322. RawResPtr m_ptrRestriction;
  323. };
  324. } /* namespace */
  325. #endif // ndef ECRestrictionBuilder_INCLUDED