TmplBlockBuffer.tlh 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //
  2. #pragma once
  3. #include <memory>
  4. ////////////////////////////////////////////////////////////////////////////////
  5. // TmplBuffer - 定义一个连续的内存块
  6. //
  7. // Copyright (c) 1997-2019 E-COM Technology Ltd.
  8. //
  9. // V1.0 ?? - Initial Version
  10. // V2.0 2019-10-31 - Use std::shared_ptr & std::unique_ptr
  11. // V2.1 2019-11-08 - Define TmplBuffer_Base as the base class
  12. // V2.2 2020-06-17 - add TmplSharedBuffer (TmplUniqueBuffer <T> && from)
  13. namespace ECOM
  14. {
  15. namespace Utility
  16. {
  17. //-----------------------------------------------------------------------------
  18. // TmplBuffer_Base
  19. // 基本类
  20. //-----------------------------------------------------------------------------
  21. template <typename T, typename PTR>
  22. class TmplBuffer_Base
  23. {
  24. protected:
  25. int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!!
  26. PTR m_Data;
  27. public:
  28. TmplBuffer_Base ()
  29. {
  30. m_nCount = 0;
  31. }
  32. TmplBuffer_Base (TmplBuffer_Base && from)
  33. {
  34. m_Data = std::move (from.m_Data);
  35. m_nCount = from.m_nCount;
  36. from.m_nCount = 0;
  37. }
  38. void Attach (T * object, int count)
  39. {
  40. if (! object)
  41. {
  42. m_Data.reset ();
  43. m_nCount = 0;
  44. return;
  45. }
  46. m_Data.reset (object);
  47. m_nCount = count;
  48. }
  49. public:
  50. // operator bool () const { return ! IsEmpty (); }
  51. operator T * () { return m_Data.get (); }
  52. operator const T * () const { return m_Data.get (); }
  53. public:
  54. // Allow usage as a pointer
  55. T * operator -> ()
  56. {
  57. return m_Data.get ();
  58. }
  59. const T * operator -> () const
  60. {
  61. return m_Data.get ();
  62. }
  63. T * As ()
  64. {
  65. return m_Data.get ();
  66. }
  67. const T * As () const
  68. {
  69. return m_Data.get ();
  70. }
  71. public:
  72. int GetCount () const
  73. {
  74. return m_nCount;
  75. }
  76. int GetNbOfBytes () const
  77. {
  78. return m_nCount * sizeof (T);
  79. }
  80. bool IsEmpty () const { return (m_Data.get () == nullptr); }
  81. public:
  82. void Release () { m_Data.reset (); m_nCount = 0; }
  83. public:
  84. TmplBuffer_Base & operator = (const TmplBuffer_Base & from) = delete;
  85. TmplBuffer_Base & operator = (TmplBuffer_Base && from) = delete;
  86. public:
  87. // MemCpy
  88. void MemCopyFrom (const T * from, int count);
  89. void MemCopyTo (T * to, int count) const;
  90. protected:
  91. T * _GetBufferSetCount (int count);
  92. void MoveAssign (TmplBuffer_Base & from)
  93. {
  94. m_Data = std::move (from.m_Data);
  95. m_nCount = from.m_nCount;
  96. from.m_nCount = 0;
  97. }
  98. // make a real copy
  99. void MemCopyTo (TmplBuffer_Base & To) const;
  100. void ResizeTo (int count, TmplBuffer_Base & To) const;
  101. };
  102. template <typename T>
  103. class TmplUniqueBuffer;
  104. template <typename T>
  105. class TmplSharedBuffer;
  106. //-----------------------------------------------------------------------------
  107. // TmplSharedBuffer
  108. //
  109. // 定义一个连续的内存块, 用 shared_ptr 定义, 因此可以在多个模块之间共享
  110. //-----------------------------------------------------------------------------
  111. template <typename T>
  112. class TmplSharedBuffer : public TmplBuffer_Base <T, std::shared_ptr <T>>
  113. {
  114. typedef TmplBuffer_Base <T, std::shared_ptr <T>> inherited;
  115. public:
  116. TmplSharedBuffer ()
  117. {
  118. }
  119. #if 1
  120. explicit TmplSharedBuffer (T * from, int count)
  121. {
  122. m_Data.reset (from);
  123. m_nCount = count;
  124. }
  125. #endif
  126. TmplSharedBuffer (const TmplSharedBuffer & from)
  127. {
  128. m_Data = from.m_Data;
  129. m_nCount = from.m_nCount;
  130. }
  131. TmplSharedBuffer (TmplSharedBuffer && from) : inherited (std::move (from))
  132. {
  133. }
  134. TmplSharedBuffer (TmplUniqueBuffer <T> && from);
  135. TmplSharedBuffer & operator = (const TmplSharedBuffer & from)
  136. {
  137. m_Data = from.m_Data;
  138. m_nCount = from.m_nCount;
  139. return *this;
  140. }
  141. TmplSharedBuffer & operator = (TmplSharedBuffer && from)
  142. {
  143. MoveAssign (from);
  144. return (*this);
  145. }
  146. TmplSharedBuffer & operator = (TmplUniqueBuffer <T> && from);
  147. public:
  148. T * GetBufferSetCount (int count)
  149. {
  150. return inherited::_GetBufferSetCount (count);
  151. }
  152. // return real copy
  153. TmplSharedBuffer Clone () const
  154. {
  155. TmplSharedBuffer <T> To;
  156. inherited::MemCopyTo (To);
  157. return std::move (To);
  158. }
  159. // 调整大小, 只要前面的 count 个对象
  160. // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定
  161. TmplSharedBuffer Resize (int count) const
  162. {
  163. TmplSharedBuffer <T> To;
  164. inherited::ResizeTo (count, To);
  165. return std::move (To);
  166. }
  167. };
  168. //-----------------------------------------------------------------------------
  169. // TmplUniqueBuffer
  170. // 用 unique_ptr 定义, 不能共享, 但是可以转移
  171. //-----------------------------------------------------------------------------
  172. template <typename T>
  173. class TmplUniqueBuffer : public TmplBuffer_Base <T, std::unique_ptr <T>>
  174. {
  175. typedef TmplBuffer_Base <T, std::unique_ptr <T>> inherited;
  176. public:
  177. TmplUniqueBuffer ()
  178. {
  179. m_nCount = 0;
  180. }
  181. explicit TmplUniqueBuffer (T * from, int count)
  182. {
  183. m_Data.reset (from);
  184. m_nCount = count;
  185. }
  186. TmplUniqueBuffer (TmplUniqueBuffer && from) : inherited (std::move (from))
  187. {
  188. }
  189. TmplUniqueBuffer (const TmplUniqueBuffer & from) = delete;
  190. TmplUniqueBuffer & operator = (const TmplUniqueBuffer & from) = delete;
  191. TmplUniqueBuffer & operator = (TmplUniqueBuffer && from)
  192. {
  193. MoveAssign (from);
  194. return (*this);
  195. }
  196. public:
  197. T * GetBufferSetCount (int count)
  198. {
  199. return inherited::_GetBufferSetCount (count);
  200. }
  201. // return real copy
  202. TmplUniqueBuffer Clone () const
  203. {
  204. TmplUniqueBuffer <T> To;
  205. inherited::MemCopyTo (To);
  206. return std::move (To);
  207. }
  208. public:
  209. T * Detach () { m_nCount = 0; auto pc = m_Data.release (); ASSERT (pc); return pc; }
  210. };
  211. }
  212. }
  213. // 共享版本
  214. // 为像素数据定义一个专用的类型
  215. typedef ECOM::Utility::TmplSharedBuffer <unsigned char> BlockBuffer;
  216. // 非共享版本
  217. typedef ECOM::Utility::TmplUniqueBuffer <unsigned char> UniqueBuffer;
  218. typedef UniqueBuffer IBlockBuffer;
  219. typedef UniqueBuffer OBlockBuffer;