199 lines
4.7 KiB
C++
199 lines
4.7 KiB
C++
/*
|
|
* Copyright: JessMA Open Source (ldcsaa@gmail.com)
|
|
*
|
|
* Author : Bruce Liang
|
|
* Website : https://github.com/ldcsaa
|
|
* Project : https://github.com/ldcsaa/HP-Socket
|
|
* Blog : http://www.cnblogs.com/ldcsaa
|
|
* Wiki : http://www.oschina.net/p/hp-socket
|
|
* QQ Group : 44636872, 75375912
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "../hpsocket/GlobalDef.h"
|
|
|
|
#include <memory.h>
|
|
#include <malloc.h>
|
|
|
|
template<class T, size_t MAX_CACHE_SIZE = 0>
|
|
class CBufferPtrT
|
|
{
|
|
public:
|
|
explicit CBufferPtrT(size_t size = 0, bool zero = false) {Reset(); Malloc(size, zero);}
|
|
explicit CBufferPtrT(const T* pch, size_t size) {Reset(); Copy(pch, size);}
|
|
CBufferPtrT(const CBufferPtrT& other) {Reset(); Copy(other);}
|
|
template<size_t S> CBufferPtrT(const CBufferPtrT<T, S>& other) {Reset(); Copy(other);}
|
|
|
|
~CBufferPtrT() {Free();}
|
|
|
|
T* Malloc(size_t size = 1, bool zero = false)
|
|
{
|
|
Free();
|
|
return Alloc(size, zero, false);
|
|
}
|
|
|
|
T* Realloc(size_t size, bool zero = false)
|
|
{
|
|
return Alloc(size, zero, true);
|
|
}
|
|
|
|
void Free()
|
|
{
|
|
if(m_pch)
|
|
{
|
|
free(m_pch);
|
|
Reset();
|
|
}
|
|
}
|
|
|
|
template<size_t S> CBufferPtrT& Copy(const CBufferPtrT<T, S>& other)
|
|
{
|
|
if((void*)&other != (void*)this)
|
|
Copy(other.Ptr(), other.Size());
|
|
|
|
return *this;
|
|
}
|
|
|
|
CBufferPtrT& Copy(const T* pch, size_t size)
|
|
{
|
|
Malloc(size);
|
|
|
|
if(m_pch)
|
|
memcpy(m_pch, pch, size * sizeof(T));
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<size_t S> CBufferPtrT& Cat(const CBufferPtrT<T, S>& other)
|
|
{
|
|
if((void*)&other != (void*)this)
|
|
Cat(other.Ptr(), other.Size());
|
|
|
|
return *this;
|
|
}
|
|
|
|
CBufferPtrT& Cat(const T* pch, size_t size = 1)
|
|
{
|
|
size_t pre_size = m_size;
|
|
Realloc(m_size + size);
|
|
|
|
if(m_pch)
|
|
memcpy(m_pch + pre_size, pch, size * sizeof(T));
|
|
|
|
return *this;
|
|
}
|
|
|
|
template<size_t S> bool Equal(const CBufferPtrT<T, S>& other) const
|
|
{
|
|
if((void*)&other == (void*)this)
|
|
return true;
|
|
else if(m_size != other.Size())
|
|
return false;
|
|
else if(m_size == 0)
|
|
return true;
|
|
else
|
|
return (memcmp(m_pch, other.Ptr(), m_size * sizeof(T)) == 0);
|
|
}
|
|
|
|
bool Equal(T* pch) const
|
|
{
|
|
if(m_pch == pch)
|
|
return true;
|
|
else if(!m_pch || !pch)
|
|
return false;
|
|
else
|
|
return (memcmp(m_pch, pch, m_size * sizeof(T)) == 0);
|
|
}
|
|
|
|
size_t SetSize(size_t size)
|
|
{
|
|
if(size < 0 || size > m_capacity)
|
|
size = m_capacity;
|
|
|
|
return (m_size = size);
|
|
}
|
|
|
|
T* Ptr() {return m_pch;}
|
|
const T* Ptr() const {return m_pch;}
|
|
T& Get(int i) {return *(m_pch + i);}
|
|
const T& Get(int i) const {return *(m_pch + i);}
|
|
size_t Size() const {return m_size;}
|
|
size_t Capacity() const {return m_capacity;}
|
|
bool IsValid() const {return m_pch != 0;}
|
|
|
|
operator T* () {return Ptr();}
|
|
operator const T* () const {return Ptr();}
|
|
T& operator [] (int i) {return Get(i);}
|
|
const T& operator [] (int i) const {return Get(i);}
|
|
bool operator == (T* pv) const {return Equal(pv);}
|
|
template<size_t S> bool operator == (const CBufferPtrT<T, S>& other) {return Equal(other);}
|
|
CBufferPtrT& operator = (const CBufferPtrT& other) {return Copy(other);}
|
|
template<size_t S> CBufferPtrT& operator = (const CBufferPtrT<T, S>& other) {return Copy(other);}
|
|
|
|
private:
|
|
void Reset() {m_pch = 0; m_size = 0; m_capacity = 0;}
|
|
size_t GetAllocSize(size_t size) {return MAX(size, MIN(size * 2, m_size + MAX_CACHE_SIZE));}
|
|
|
|
T* Alloc(size_t size, bool zero = false, bool is_realloc = false)
|
|
{
|
|
if(size != m_size)
|
|
{
|
|
size_t rsize = GetAllocSize(size);
|
|
if(size > m_capacity || rsize < m_size)
|
|
{
|
|
T* pch = is_realloc ?
|
|
(T*)realloc(m_pch, rsize * sizeof(T)) :
|
|
(T*)malloc(rsize * sizeof(T)) ;
|
|
|
|
if(pch || rsize == 0)
|
|
{
|
|
m_pch = pch;
|
|
m_size = size;
|
|
m_capacity = rsize;
|
|
}
|
|
else
|
|
{
|
|
Free();
|
|
throw std::bad_alloc();
|
|
}
|
|
}
|
|
else
|
|
m_size = size;
|
|
}
|
|
|
|
if(zero && m_pch)
|
|
memset(m_pch, 0, m_size * sizeof(T));
|
|
|
|
return m_pch;
|
|
}
|
|
|
|
private:
|
|
T* m_pch;
|
|
size_t m_size;
|
|
size_t m_capacity;
|
|
};
|
|
|
|
typedef CBufferPtrT<char> CCharBufferPtr;
|
|
typedef CBufferPtrT<wchar_t> CWCharBufferPtr;
|
|
typedef CBufferPtrT<unsigned char> CByteBufferPtr;
|
|
typedef CByteBufferPtr CBufferPtr;
|
|
|
|
#ifdef _UNICODE
|
|
typedef CWCharBufferPtr CTCharBufferPtr;
|
|
#else
|
|
typedef CCharBufferPtr CTCharBufferPtr;
|
|
#endif
|