IECPropStorage.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. // Interface for writing and reading properties to disk (which does the actual transfer and save)
  18. //
  19. // Strategy is to load most of the small (ie not much data) properties at load-time. This saves
  20. // a lot of overhead if the properties were to be acquired one-by-one over the network. However, a
  21. // complete list of properties is also read through HrReadProps(), so the local system also knows
  22. // about larger properties. These properties are read through HrLoadProp().
  23. //
  24. // When a save is done, only the *changes* to the properties are propagated, by using HrDeleteProps
  25. // and HrWriteProps. HrWriteProps changes and/or adds any new or modified properties, while HrDeleteProps
  26. // removes any properties that have been completely removed.
  27. //
  28. // This keeps the overall performance high, by having relatively low latency problems as most message
  29. // accesses will be kept down to about 1 to 5 network accesses, and have low bandwidth requirements as
  30. // large data is only loaded on demand.
  31. //
  32. #ifndef IECPROPSTORAGE_H
  33. #define IECPROPSTORAGE_H
  34. #include <kopano/IECUnknown.h>
  35. #include <mapi.h>
  36. #include <mapispi.h>
  37. #include <list>
  38. #include <set>
  39. #include "ECPropertyEntry.h"
  40. #include "kcore.hpp"
  41. #include <kopano/Util.h>
  42. struct MAPIOBJECT {
  43. MAPIOBJECT() {
  44. /* see AllocNewMapiObject :: Mem.cpp */
  45. };
  46. MAPIOBJECT(unsigned int ulType, unsigned int ulId) : ulUniqueId(ulId), ulObjType(ulType) {
  47. }
  48. bool operator < (const MAPIOBJECT &other) const {
  49. std::pair<unsigned int, unsigned int> me(ulObjType, ulUniqueId), him(other.ulObjType, other.ulUniqueId);
  50. return me < him;
  51. };
  52. struct CompareMAPIOBJECT {
  53. bool operator()(const MAPIOBJECT *a, const MAPIOBJECT *b) const
  54. {
  55. return *a < *b;
  56. }
  57. };
  58. MAPIOBJECT(const MAPIOBJECT *lpSource)
  59. {
  60. this->bChanged = lpSource->bChanged;
  61. this->bChangedInstance = lpSource->bChangedInstance;
  62. this->bDelete = lpSource->bDelete;
  63. this->ulUniqueId = lpSource->ulUniqueId;
  64. this->ulObjId = lpSource->ulObjId;
  65. this->ulObjType = lpSource->ulObjType;
  66. Util::HrCopyEntryId(lpSource->cbInstanceID, (LPENTRYID)lpSource->lpInstanceID,
  67. &this->cbInstanceID, (LPENTRYID *)&this->lpInstanceID);
  68. this->lstDeleted = lpSource->lstDeleted;
  69. this->lstModified = lpSource->lstModified;
  70. this->lstProperties = lpSource->lstProperties;
  71. this->lstAvailable = lpSource->lstAvailable;
  72. for (const auto &i : lpSource->lstChildren)
  73. this->lstChildren.insert(new MAPIOBJECT(i));
  74. };
  75. /* data */
  76. std::set<MAPIOBJECT *, CompareMAPIOBJECT> lstChildren; /* ECSavedObjects */
  77. std::list<ULONG> lstDeleted; /* proptags client->server only */
  78. std::list<ULONG> lstAvailable; /* proptags server->client only */
  79. std::list<ECProperty> lstModified; /* propval client->server only */
  80. std::list<ECProperty> lstProperties; /* propval client->server but not serialized and server->client */
  81. LPSIEID lpInstanceID = nullptr; /* Single Instance ID */
  82. ULONG cbInstanceID = 0; /* Single Instance ID length */
  83. BOOL bChangedInstance = false; /* Single Instance ID changed */
  84. BOOL bChanged = false; /* this is a saved child, otherwise only loaded */
  85. BOOL bDelete = false; /* delete this object completely */
  86. ULONG ulUniqueId = 0; /* PR_ROWID (recipients) or PR_ATTACH_NUM (attachments) only */
  87. ULONG ulObjId = 0; /* hierarchy id of recipients and attachments */
  88. ULONG ulObjType = 0;
  89. };
  90. typedef std::set<MAPIOBJECT*, MAPIOBJECT::CompareMAPIOBJECT> ECMapiObjects;
  91. class IECPropStorage : public IECUnknown {
  92. public:
  93. // Get a list of the properties
  94. virtual HRESULT HrReadProps(LPSPropTagArray *lppPropTags,ULONG *cValues, LPSPropValue *ppValues) = 0;
  95. // Get a single (large) property from an object
  96. virtual HRESULT HrLoadProp(ULONG ulObjId, ULONG ulPropTag, LPSPropValue *lppsPropValue) = 0;
  97. // Write all properties to disk (overwrites a property if it already exists)
  98. virtual HRESULT HrWriteProps(ULONG cValues, LPSPropValue pValues, ULONG ulFlags = 0) = 0;
  99. // Delete properties from file
  100. virtual HRESULT HrDeleteProps(const SPropTagArray *lpsPropTagArray) = 0;
  101. // Save a complete object to the server
  102. virtual HRESULT HrSaveObject(ULONG ulFlags, MAPIOBJECT *lpSavedObjects) = 0;
  103. // Load a complete object from the server
  104. virtual HRESULT HrLoadObject(MAPIOBJECT **lppSavedObjects) = 0;
  105. // Returns the correct storage which can connect to the server
  106. virtual IECPropStorage* GetServerStorage() = 0;
  107. };
  108. #endif