WSSerializedMessage.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. #include <kopano/platform.h>
  18. #include <kopano/Util.h>
  19. #include "WSSerializedMessage.h"
  20. /**
  21. * @param[in] lpSoap The gSoap object from which the MTOM attachments must be obtained.
  22. * @param[in] strStreamId The expected stream id. Used to validate the MTOM attachment obtained from gSoap.
  23. * @param[in] cbProps The amount of properties returned from the original soap call.
  24. * @param[in] lpProps The properties returned from the original soap call. Only the pointer is stored, no
  25. * copy is made since our parent object will stay alive for our complete lifetime.
  26. */
  27. WSSerializedMessage::WSSerializedMessage(soap *lpSoap, const std::string strStreamId, ULONG cbProps, LPSPropValue lpProps)
  28. : m_lpSoap(lpSoap)
  29. , m_strStreamId(strStreamId)
  30. , m_cbProps(cbProps)
  31. , m_lpProps(lpProps)
  32. {
  33. }
  34. /**
  35. * Get a copy of the properties stored with this object.
  36. * @param[out] lpcbProps The amount of properties returned.
  37. * @param[out] lppProps A copy of the properties. The caller is responsible for deleting them.
  38. */
  39. HRESULT WSSerializedMessage::GetProps(ULONG *lpcbProps, LPSPropValue *lppProps)
  40. {
  41. if (lpcbProps == NULL || lppProps == NULL)
  42. return MAPI_E_INVALID_PARAMETER;
  43. return Util::HrCopyPropertyArray(m_lpProps, m_cbProps, lppProps, lpcbProps);
  44. }
  45. /**
  46. * Copy the message stream to an IStream instance.
  47. * @param[in] lpDestStream The stream to write the data to.
  48. * @retval MAPI_E_INVALID_PARAMETER lpDestStream is NULL.
  49. */
  50. HRESULT WSSerializedMessage::CopyData(LPSTREAM lpDestStream)
  51. {
  52. HRESULT hr;
  53. if (lpDestStream == NULL)
  54. return MAPI_E_INVALID_PARAMETER;
  55. hr = DoCopyData(lpDestStream);
  56. if (hr != hrSuccess)
  57. return hr;
  58. return lpDestStream->Commit(0);
  59. }
  60. /**
  61. * Read the data from the gSoap MTOM attachment, but discard it immediately.
  62. */
  63. HRESULT WSSerializedMessage::DiscardData()
  64. {
  65. // The data must be read from the network.
  66. return DoCopyData(NULL);
  67. }
  68. /**
  69. * Copy the message stream to an IStream instance.
  70. * @param[in] lpDestStream The stream to write the data to. If lpDestStream is
  71. * NULL, the data will be discarded.
  72. */
  73. HRESULT WSSerializedMessage::DoCopyData(LPSTREAM lpDestStream)
  74. {
  75. if (m_bUsed)
  76. return MAPI_E_UNCONFIGURED;
  77. m_bUsed = true;
  78. m_hr = hrSuccess;
  79. m_ptrDestStream.reset(lpDestStream);
  80. m_lpSoap->fmimewriteopen = StaticMTOMWriteOpen;
  81. m_lpSoap->fmimewrite = StaticMTOMWrite;
  82. m_lpSoap->fmimewriteclose = StaticMTOMWriteClose;
  83. soap_get_mime_attachment(m_lpSoap, (void*)this);
  84. if (m_lpSoap->error != 0)
  85. return MAPI_E_NETWORK_ERROR;
  86. return m_hr;
  87. }
  88. void* WSSerializedMessage::StaticMTOMWriteOpen(struct soap *soap, void *handle, const char *id, const char *type, const char *description, enum soap_mime_encoding encoding)
  89. {
  90. return static_cast<WSSerializedMessage *>(handle)->MTOMWriteOpen(soap, handle, id, type, description, encoding);
  91. }
  92. int WSSerializedMessage::StaticMTOMWrite(struct soap *soap, void *handle, const char *buf, size_t len)
  93. {
  94. return static_cast<WSSerializedMessage *>(handle)->MTOMWrite(soap, handle, buf, len);
  95. }
  96. void WSSerializedMessage::StaticMTOMWriteClose(struct soap *soap, void *handle)
  97. {
  98. static_cast<WSSerializedMessage *>(handle)->MTOMWriteClose(soap, handle);
  99. }
  100. void* WSSerializedMessage::MTOMWriteOpen(struct soap *soap, void *handle, const char *id, const char* /*type*/, const char* /*description*/, enum soap_mime_encoding encoding)
  101. {
  102. if (encoding != SOAP_MIME_BINARY || id == NULL ||
  103. m_strStreamId.compare(id) != 0) {
  104. soap->error = SOAP_ERR;
  105. m_hr = MAPI_E_INVALID_TYPE;
  106. m_ptrDestStream.reset();
  107. }
  108. return handle;
  109. }
  110. int WSSerializedMessage::MTOMWrite(struct soap *soap, void* /*handle*/, const char *buf, size_t len)
  111. {
  112. HRESULT hr = hrSuccess;
  113. ULONG cbWritten = 0;
  114. if (!m_ptrDestStream)
  115. return SOAP_OK;
  116. hr = m_ptrDestStream->Write(buf, (ULONG)len, &cbWritten);
  117. if (hr != hrSuccess) {
  118. soap->error = SOAP_ERR;
  119. m_hr = hr;
  120. m_ptrDestStream.reset();
  121. }
  122. // @todo: Should we check if everything was written?
  123. return SOAP_OK;
  124. }
  125. void WSSerializedMessage::MTOMWriteClose(struct soap *soap, void *handle)
  126. {
  127. m_ptrDestStream.reset();
  128. }