IStreamAdapter.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 <algorithm>
  19. #include <mapicode.h>
  20. #include <mapidefs.h>
  21. #include <mapiguid.h>
  22. #include "IStreamAdapter.h"
  23. namespace KC {
  24. IStreamAdapter::IStreamAdapter(std::string &str) : m_str(str)
  25. {}
  26. HRESULT IStreamAdapter::QueryInterface(REFIID iid, void **pv){
  27. if(iid == IID_IStream || iid == IID_ISequentialStream || iid == IID_IUnknown) {
  28. *pv = this;
  29. return hrSuccess;
  30. }
  31. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  32. }
  33. HRESULT IStreamAdapter::Read(void *pv, ULONG cb, ULONG *pcbRead)
  34. {
  35. size_t toread = std::min(cb, (ULONG)(m_str.size() - m_pos));
  36. memcpy(pv, m_str.data() + m_pos, toread);
  37. m_pos += toread;
  38. if(pcbRead)
  39. *pcbRead = toread;
  40. return hrSuccess;
  41. }
  42. HRESULT IStreamAdapter::Write(const void *pv, ULONG cb, ULONG *pcbWritten)
  43. {
  44. if(m_pos + cb > m_str.size()) {
  45. m_str.resize(m_pos+cb);
  46. }
  47. memcpy(const_cast<char *>(m_str.data() + m_pos), pv, cb);
  48. m_pos += cb;
  49. if(pcbWritten)
  50. *pcbWritten = cb;
  51. return hrSuccess;
  52. }
  53. HRESULT IStreamAdapter::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
  54. {
  55. if(dwOrigin == SEEK_SET) {
  56. if (dlibMove.QuadPart < 0)
  57. m_pos = 0;
  58. else
  59. m_pos = dlibMove.QuadPart;
  60. }
  61. else if(dwOrigin == SEEK_CUR) {
  62. if (dlibMove.QuadPart < 0 &&
  63. m_pos < static_cast<ULONGLONG>(-dlibMove.QuadPart))
  64. m_pos = 0;
  65. else
  66. m_pos += dlibMove.QuadPart;
  67. }
  68. else if(dwOrigin == SEEK_END) {
  69. if (dlibMove.QuadPart < 0 &&
  70. m_str.size() < static_cast<ULONGLONG>(-dlibMove.QuadPart))
  71. m_pos = 0;
  72. else
  73. m_pos = m_str.size() + dlibMove.QuadPart;
  74. }
  75. // Fix overflow
  76. if (m_pos > m_str.size())
  77. m_pos = m_str.size();
  78. if (plibNewPosition)
  79. plibNewPosition->QuadPart = m_pos;
  80. return hrSuccess;
  81. }
  82. HRESULT IStreamAdapter::SetSize(ULARGE_INTEGER libNewSize)
  83. {
  84. LARGE_INTEGER zero = { { 0 } };
  85. m_str.resize(libNewSize.QuadPart);
  86. return Seek(zero, 0, NULL);
  87. }
  88. HRESULT IStreamAdapter::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
  89. {
  90. HRESULT hr = hrSuccess;
  91. char buf[4096];
  92. ULONG len = 0;
  93. while(1) {
  94. hr = Read(buf, sizeof(buf), &len);
  95. if(hr != hrSuccess)
  96. return hr;
  97. if(len == 0)
  98. break;
  99. hr = pstm->Write(buf, len, NULL);
  100. if(hr != hrSuccess)
  101. return hr;
  102. }
  103. return hr;
  104. }
  105. HRESULT IStreamAdapter::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
  106. {
  107. memset(pstatstg, 0, sizeof(STATSTG));
  108. pstatstg->cbSize.QuadPart = m_str.size();
  109. return hrSuccess;
  110. }
  111. } /* namespace */