TmplBlockBuffer.tlh 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. //
  2. #pragma once
  3. #include <memory>
  4. #define __TmplBlockBuffer__
  5. ////////////////////////////////////////////////////////////////////////////////
  6. // TmplBuffer - 定义一个连续的内存块
  7. //
  8. // Copyright (c) 1997-2013 E-COM Technology Ltd.
  9. //
  10. // V1.0 ?? - Initial Version
  11. // V2.0 2019-10-31 - Use std::shared_ptr & std::unique_ptr
  12. // V2.1 2019-11-08 - Define TmplBuffer_Base as the base class
  13. // V2.2 2020-06-17 - add TmplSharedBuffer (TmplUniqueBuffer <T> && from)
  14. // V2.3 2022-06-02 - add TmplUniqueBuffer::Resize (int count)
  15. // V2.4 2022-08-01 - pass the compiler option /permissive
  16. // V2.3 2023-04-23 - add TmplBuffer_view
  17. namespace ECOM
  18. {
  19. namespace Utility
  20. {
  21. //-----------------------------------------------------------------------------
  22. // TmplBuffer_Base
  23. // 基本类
  24. //-----------------------------------------------------------------------------
  25. template <typename T, typename PTR>
  26. class TmplBuffer_Base
  27. {
  28. protected:
  29. int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!!
  30. PTR m_Data;
  31. public:
  32. TmplBuffer_Base ()
  33. {
  34. m_nCount = 0;
  35. }
  36. TmplBuffer_Base (TmplBuffer_Base && from)
  37. {
  38. m_Data = std::move (from.m_Data);
  39. m_nCount = from.m_nCount;
  40. from.m_nCount = 0;
  41. }
  42. void Attach (T * object, int count)
  43. {
  44. if (! object)
  45. {
  46. m_Data.reset ();
  47. m_nCount = 0;
  48. return;
  49. }
  50. m_Data.reset (object);
  51. m_nCount = count;
  52. }
  53. public:
  54. // operator bool () const { return ! IsEmpty (); }
  55. operator T * () { return m_Data.get (); }
  56. operator const T * () const { return m_Data.get (); }
  57. public:
  58. // Allow usage as a pointer
  59. T * operator -> ()
  60. {
  61. return m_Data.get ();
  62. }
  63. const T * operator -> () const
  64. {
  65. return m_Data.get ();
  66. }
  67. T * As ()
  68. {
  69. return m_Data.get ();
  70. }
  71. const T * As () const
  72. {
  73. return m_Data.get ();
  74. }
  75. public:
  76. int GetCount () const
  77. {
  78. return m_nCount;
  79. }
  80. int GetNbOfBytes () const
  81. {
  82. return m_nCount * sizeof (T);
  83. }
  84. bool IsEmpty () const { return (m_Data.get () == nullptr); }
  85. public:
  86. void Release () { m_Data.reset (); m_nCount = 0; }
  87. public:
  88. TmplBuffer_Base & operator = (const TmplBuffer_Base & from) = delete;
  89. TmplBuffer_Base & operator = (TmplBuffer_Base && from) = delete;
  90. public:
  91. // MemCpy
  92. void MemCopyFrom (const T * from, int count);
  93. void MemCopyTo (T * to, int count) const;
  94. protected:
  95. T * _GetBufferSetCount (int count);
  96. void MoveAssign (TmplBuffer_Base & from)
  97. {
  98. m_Data = std::move (from.m_Data);
  99. m_nCount = from.m_nCount;
  100. from.m_nCount = 0;
  101. }
  102. // make a real copy
  103. void MemCopyTo (TmplBuffer_Base & To) const;
  104. void ResizeTo (int count, TmplBuffer_Base & To) const;
  105. };
  106. template <typename T>
  107. class TmplUniqueBuffer;
  108. template <typename T>
  109. class TmplSharedBuffer;
  110. //-----------------------------------------------------------------------------
  111. // TmplSharedBuffer
  112. //
  113. // 定义一个连续的内存块, 用 shared_ptr 定义, 因此可以在多个模块之间共享
  114. //-----------------------------------------------------------------------------
  115. template <typename T>
  116. class TmplSharedBuffer : public TmplBuffer_Base <T, std::shared_ptr <T>>
  117. {
  118. typedef TmplBuffer_Base <T, std::shared_ptr <T>> inherited;
  119. public:
  120. TmplSharedBuffer ()
  121. {
  122. }
  123. #if 1
  124. explicit TmplSharedBuffer (T * from, int count)
  125. {
  126. this->m_Data.reset (from);
  127. this->m_nCount = count;
  128. }
  129. #endif
  130. TmplSharedBuffer (const TmplSharedBuffer & from)
  131. {
  132. this->m_Data = from.m_Data;
  133. this->m_nCount = from.m_nCount;
  134. }
  135. TmplSharedBuffer (TmplSharedBuffer && from) : inherited (std::move (from))
  136. {
  137. }
  138. TmplSharedBuffer (TmplUniqueBuffer <T> && from);
  139. TmplSharedBuffer & operator = (const TmplSharedBuffer & from)
  140. {
  141. this->m_Data = from.m_Data;
  142. this->m_nCount = from.m_nCount;
  143. return *this;
  144. }
  145. TmplSharedBuffer & operator = (TmplSharedBuffer && from)
  146. {
  147. inherited::MoveAssign (from);
  148. return (*this);
  149. }
  150. TmplSharedBuffer & operator = (TmplUniqueBuffer <T> && from);
  151. public:
  152. T * GetBufferSetCount (int count)
  153. {
  154. return inherited::_GetBufferSetCount (count);
  155. }
  156. // return real copy
  157. TmplSharedBuffer Clone () const
  158. {
  159. TmplSharedBuffer <T> To;
  160. inherited::MemCopyTo (To);
  161. return std::move (To);
  162. }
  163. // 调整大小, 只要前面的 count 个对象
  164. // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定
  165. TmplSharedBuffer Resize (int count) const
  166. {
  167. TmplSharedBuffer <T> To;
  168. inherited::ResizeTo (count, To);
  169. return std::move (To);
  170. }
  171. };
  172. //-----------------------------------------------------------------------------
  173. // TmplUniqueBuffer
  174. // 用 unique_ptr 定义, 不能共享, 但是可以转移
  175. //-----------------------------------------------------------------------------
  176. template <typename T>
  177. class TmplUniqueBuffer : public TmplBuffer_Base <T, std::unique_ptr <T>>
  178. {
  179. typedef TmplBuffer_Base <T, std::unique_ptr <T>> inherited;
  180. public:
  181. TmplUniqueBuffer ()
  182. {
  183. this->m_nCount = 0;
  184. }
  185. explicit TmplUniqueBuffer (T * from, int count)
  186. {
  187. this->m_Data.reset (from);
  188. this->m_nCount = count;
  189. }
  190. TmplUniqueBuffer (TmplUniqueBuffer && from) : inherited (std::move (from))
  191. {
  192. }
  193. TmplUniqueBuffer (const TmplUniqueBuffer & from) = delete;
  194. TmplUniqueBuffer & operator = (const TmplUniqueBuffer & from) = delete;
  195. TmplUniqueBuffer & operator = (TmplUniqueBuffer && from)
  196. {
  197. inherited::MoveAssign (from);
  198. return (*this);
  199. }
  200. public:
  201. T * GetBufferSetCount (int count)
  202. {
  203. return this->_GetBufferSetCount (count);
  204. }
  205. // return real copy
  206. TmplUniqueBuffer Clone () const
  207. {
  208. TmplUniqueBuffer <T> To;
  209. inherited::MemCopyTo (To);
  210. return std::move (To);
  211. }
  212. // 调整大小, 只要前面的 count 个对象
  213. // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定
  214. void Resize (int count)
  215. {
  216. // 如果要的很少, 只需要修改 m_nCount
  217. if (count <= this->m_nCount)
  218. {
  219. this->m_nCount = count;
  220. }
  221. else
  222. // 如果要的太多了, 重新分配, 然后 memcpy
  223. {
  224. auto tmp = std::move (*this);
  225. auto pDst = this->_GetBufferSetCount (count);
  226. auto pSrc = tmp.As ();
  227. memcpy (pDst, pSrc, sizeof (T) * tmp.m_nCount);
  228. }
  229. }
  230. public:
  231. T * Detach ()
  232. {
  233. this->m_nCount = 0;
  234. auto pc = this->m_Data.release ();
  235. ASSERT (pc);
  236. return pc;
  237. }
  238. };
  239. //-----------------------------------------------------------------------------
  240. // TmplBuffer_View
  241. // 是 TmplUniqueBuffer 或 TmplSharedBuffer 的只读视图
  242. // 某些类或 API 的参数, 既可以用 TmplUniqueBuffer 也可以用 TmplSharedBuffer,
  243. // 但是如果想让这些函数适用于两种情况, 就必须写成 template.
  244. // 为避免 template, 参数类型可改用 TmplBuffer_View.
  245. // 典型的场景是 Compress/Decompress
  246. //-----------------------------------------------------------------------------
  247. template <typename T>
  248. class TmplBuffer_View
  249. {
  250. protected:
  251. int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!!
  252. const T * m_Data;
  253. public:
  254. TmplBuffer_View () : m_nCount{ 0 } {}
  255. TmplBuffer_View (const TmplUniqueBuffer <T> & from) :
  256. m_Data { from.As () },
  257. m_nCount { from.GetCount () }
  258. {
  259. }
  260. TmplBuffer_View (const TmplSharedBuffer <T> & from) :
  261. m_Data{ from.As () },
  262. m_nCount{ from.GetCount () }
  263. {
  264. }
  265. TmplBuffer_View (const TmplBuffer_View & from) :
  266. m_Data { from.m_Data },
  267. m_nCount { from.m_nCount }
  268. {
  269. }
  270. TmplBuffer_View (TmplBuffer_View && from):
  271. m_Data { from.m_Data },
  272. m_nCount { from.m_nCount }
  273. {
  274. }
  275. public:
  276. TmplBuffer_View & operator = (const TmplBuffer_View & from)
  277. {
  278. m_Data = from.m_Data;
  279. m_nCount = from.m_nCount;
  280. }
  281. TmplBuffer_View & operator = (TmplBuffer_View && from)
  282. {
  283. m_Data = from.m_Data;
  284. m_nCount = from.m_nCount;
  285. return (*this);
  286. }
  287. public:
  288. const T * As () const
  289. {
  290. return m_Data;
  291. }
  292. public:
  293. int GetCount () const
  294. {
  295. return m_nCount;
  296. }
  297. int GetNbOfBytes () const
  298. {
  299. return m_nCount * sizeof (T);
  300. }
  301. };
  302. }
  303. }
  304. // 共享版本
  305. // 为像素数据定义一个专用的类型
  306. using BlockBuffer = ECOM::Utility::TmplSharedBuffer <unsigned char>;
  307. // 非共享版本
  308. using UniqueBuffer = ECOM::Utility::TmplUniqueBuffer <unsigned char> ;
  309. using IBlockBuffer = UniqueBuffer;
  310. using OBlockBuffer = UniqueBuffer;
  311. using Buffer_View = ECOM::Utility::TmplBuffer_View <unsigned char>;