// #pragma once #include #define __TmplBlockBuffer__ //////////////////////////////////////////////////////////////////////////////// // TmplBuffer - 定义一个连续的内存块 // // Copyright (c) 1997-2013 E-COM Technology Ltd. // // V1.0 ?? - Initial Version // V2.0 2019-10-31 - Use std::shared_ptr & std::unique_ptr // V2.1 2019-11-08 - Define TmplBuffer_Base as the base class // V2.2 2020-06-17 - add TmplSharedBuffer (TmplUniqueBuffer && from) // V2.3 2022-06-02 - add TmplUniqueBuffer::Resize (int count) // V2.4 2022-08-01 - pass the compiler option /permissive // V2.3 2023-04-23 - add TmplBuffer_view namespace ECOM { namespace Utility { //----------------------------------------------------------------------------- // TmplBuffer_Base // 基本类 //----------------------------------------------------------------------------- template class TmplBuffer_Base { protected: int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!! PTR m_Data; public: TmplBuffer_Base () { m_nCount = 0; } TmplBuffer_Base (TmplBuffer_Base && from) { m_Data = std::move (from.m_Data); m_nCount = from.m_nCount; from.m_nCount = 0; } void Attach (T * object, int count) { if (! object) { m_Data.reset (); m_nCount = 0; return; } m_Data.reset (object); m_nCount = count; } public: // operator bool () const { return ! IsEmpty (); } operator T * () { return m_Data.get (); } operator const T * () const { return m_Data.get (); } public: // Allow usage as a pointer T * operator -> () { return m_Data.get (); } const T * operator -> () const { return m_Data.get (); } T * As () { return m_Data.get (); } const T * As () const { return m_Data.get (); } public: int GetCount () const { return m_nCount; } int GetNbOfBytes () const { return m_nCount * sizeof (T); } bool IsEmpty () const { return (m_Data.get () == nullptr); } public: void Release () { m_Data.reset (); m_nCount = 0; } public: TmplBuffer_Base & operator = (const TmplBuffer_Base & from) = delete; TmplBuffer_Base & operator = (TmplBuffer_Base && from) = delete; public: // MemCpy void MemCopyFrom (const T * from, int count); void MemCopyTo (T * to, int count) const; protected: T * _GetBufferSetCount (int count); void MoveAssign (TmplBuffer_Base & from) { m_Data = std::move (from.m_Data); m_nCount = from.m_nCount; from.m_nCount = 0; } // make a real copy void MemCopyTo (TmplBuffer_Base & To) const; void ResizeTo (int count, TmplBuffer_Base & To) const; }; template class TmplUniqueBuffer; template class TmplSharedBuffer; //----------------------------------------------------------------------------- // TmplSharedBuffer // // 定义一个连续的内存块, 用 shared_ptr 定义, 因此可以在多个模块之间共享 //----------------------------------------------------------------------------- template class TmplSharedBuffer : public TmplBuffer_Base > { typedef TmplBuffer_Base > inherited; public: TmplSharedBuffer () { } #if 1 explicit TmplSharedBuffer (T * from, int count) { this->m_Data.reset (from); this->m_nCount = count; } #endif TmplSharedBuffer (const TmplSharedBuffer & from) { this->m_Data = from.m_Data; this->m_nCount = from.m_nCount; } TmplSharedBuffer (TmplSharedBuffer && from) : inherited (std::move (from)) { } TmplSharedBuffer (TmplUniqueBuffer && from); TmplSharedBuffer & operator = (const TmplSharedBuffer & from) { this->m_Data = from.m_Data; this->m_nCount = from.m_nCount; return *this; } TmplSharedBuffer & operator = (TmplSharedBuffer && from) { inherited::MoveAssign (from); return (*this); } TmplSharedBuffer & operator = (TmplUniqueBuffer && from); public: T * GetBufferSetCount (int count) { return inherited::_GetBufferSetCount (count); } // return real copy TmplSharedBuffer Clone () const { TmplSharedBuffer To; inherited::MemCopyTo (To); return std::move (To); } // 调整大小, 只要前面的 count 个对象 // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定 TmplSharedBuffer Resize (int count) const { TmplSharedBuffer To; inherited::ResizeTo (count, To); return std::move (To); } }; //----------------------------------------------------------------------------- // TmplUniqueBuffer // 用 unique_ptr 定义, 不能共享, 但是可以转移 //----------------------------------------------------------------------------- template class TmplUniqueBuffer : public TmplBuffer_Base > { typedef TmplBuffer_Base > inherited; public: TmplUniqueBuffer () { this->m_nCount = 0; } explicit TmplUniqueBuffer (T * from, int count) { this->m_Data.reset (from); this->m_nCount = count; } TmplUniqueBuffer (TmplUniqueBuffer && from) : inherited (std::move (from)) { } TmplUniqueBuffer (const TmplUniqueBuffer & from) = delete; TmplUniqueBuffer & operator = (const TmplUniqueBuffer & from) = delete; TmplUniqueBuffer & operator = (TmplUniqueBuffer && from) { inherited::MoveAssign (from); return (*this); } public: T * GetBufferSetCount (int count) { return this->_GetBufferSetCount (count); } // return real copy TmplUniqueBuffer Clone () const { TmplUniqueBuffer To; inherited::MemCopyTo (To); return std::move (To); } // 调整大小, 只要前面的 count 个对象 // 如果要的数量比我现有的数量 (m_nCount) 多,就重新分配,然后memcpy,但填充值由上层自行决定 void Resize (int count) { // 如果要的很少, 只需要修改 m_nCount if (count <= this->m_nCount) { this->m_nCount = count; } else // 如果要的太多了, 重新分配, 然后 memcpy { auto tmp = std::move (*this); auto pDst = this->_GetBufferSetCount (count); auto pSrc = tmp.As (); memcpy (pDst, pSrc, sizeof (T) * tmp.m_nCount); } } public: T * Detach () { this->m_nCount = 0; auto pc = this->m_Data.release (); ASSERT (pc); return pc; } }; //----------------------------------------------------------------------------- // TmplBuffer_View // 是 TmplUniqueBuffer 或 TmplSharedBuffer 的只读视图 // 某些类或 API 的参数, 既可以用 TmplUniqueBuffer 也可以用 TmplSharedBuffer, // 但是如果想让这些函数适用于两种情况, 就必须写成 template. // 为避免 template, 参数类型可改用 TmplBuffer_View. // 典型的场景是 Compress/Decompress //----------------------------------------------------------------------------- template class TmplBuffer_View { protected: int m_nCount; // count of data, 注意是 数量 而不是 字节 长度 !!! const T * m_Data; public: TmplBuffer_View () : m_nCount{ 0 } {} TmplBuffer_View (const TmplUniqueBuffer & from) : m_Data { from.As () }, m_nCount { from.GetCount () } { } TmplBuffer_View (const TmplSharedBuffer & from) : m_Data{ from.As () }, m_nCount{ from.GetCount () } { } TmplBuffer_View (const TmplBuffer_View & from) : m_Data { from.m_Data }, m_nCount { from.m_nCount } { } TmplBuffer_View (TmplBuffer_View && from): m_Data { from.m_Data }, m_nCount { from.m_nCount } { } public: TmplBuffer_View & operator = (const TmplBuffer_View & from) { m_Data = from.m_Data; m_nCount = from.m_nCount; } TmplBuffer_View & operator = (TmplBuffer_View && from) { m_Data = from.m_Data; m_nCount = from.m_nCount; return (*this); } public: const T * As () const { return m_Data; } public: int GetCount () const { return m_nCount; } int GetNbOfBytes () const { return m_nCount * sizeof (T); } }; } } // 共享版本 // 为像素数据定义一个专用的类型 using BlockBuffer = ECOM::Utility::TmplSharedBuffer ; // 非共享版本 using UniqueBuffer = ECOM::Utility::TmplUniqueBuffer ; using IBlockBuffer = UniqueBuffer; using OBlockBuffer = UniqueBuffer; using Buffer_View = ECOM::Utility::TmplBuffer_View ;