C++实现的Buffer类

转自 http://blog.csdn.net/athlong0564/article/details/5942351

写C#的同志一定觉得Byte []比C++的 BYTE * 加 Length的方式好的多。一来,只需要一个对象就可以是表示一段字节流,另一方面,由于C#的特性,不需要象C++那样还要记得删除指针。由于我工作中,需要频繁地试用C#和C++,所以写了个C++的类,以便方便地管理字节流。

  很简单,先定义一个类:CMemoryBuffer。字节流内部可以用std::vector<BYTE>来保存,当然,考虑到效率,有些地方处理还是要考虑下。先把代码贴出来,然后解释为什么这么做。

  头文件:

#include <vector>
#include <queue>
#include <afxmt.h>

using namespace std;


class  CMemoryBuffer
{
public:
    CMemoryBuffer(void);
    CMemoryBuffer(const CMemoryBuffer &other);
    CMemoryBuffer(const BYTE *tpBytes ,int tiLength);
    virtual ~CMemoryBuffer(void);

    //得到内部指针——const
    const BYTE * c_Bytes() const;
    //从内部拷贝数据到数据中
    BYTE * CopyOut(int &tiLength) const;
    //确保tppBytes指向的数据足够大
    void CopyTo(const BYTE ** tppBytes, int &tiLenth) const;
    //从外部数据拷贝数据
    void CopyFrom(const BYTE * tpBytes , int tiLength);
    //从外部数据拷贝数据,添加
    void Append(const BYTE * tpBytes , int tiLength);
    void Append(const BYTE & tByte);
    //从外部数据拷贝数据,插入
    void Insert(int tiStartIndex,const BYTE * tpBytes , int tiLength);


    CMemoryBuffer & operator = (const CMemoryBuffer &other);

    CMemoryBuffer & operator += (const CMemoryBuffer &other);

    const std::vector<BYTE> &GetBuffer() const { return m_vctBuffer; }

    void Clear() ;

    int GetLength() const { return (int)m_vctBuffer.size(); }

    bool IsEmpty() const { return m_vctBuffer.size() == 0; }
    
public:
    vector<BYTE> m_vctBuffer;
};
#include "StdAfx.h"
#include "MemoryBuffer.h"



CMemoryBuffer::CMemoryBuffer(void)
{
}

CMemoryBuffer::~CMemoryBuffer(void)
{
    this->Clear();
}

CMemoryBuffer::CMemoryBuffer(const CMemoryBuffer &other)
{
    *this = other;
}

CMemoryBuffer::CMemoryBuffer(const BYTE *tpBytes ,int tiLength)
{
    this->CopyFrom(tpBytes,tiLength);
}

void CMemoryBuffer::Clear()
{
    vector<BYTE>().swap(this->m_vctBuffer); 
}


const BYTE * CMemoryBuffer::c_Bytes() const
{
    if(this->IsEmpty()) return NULL;
    return &m_vctBuffer[0];
}

BYTE * CMemoryBuffer::CopyOut(int &tiLength) const
{
    tiLength = this->GetLength();
    if(this->IsEmpty()) return NULL;
    BYTE *pBytes = new BYTE[tiLength];
    memcpy(pBytes,&m_vctBuffer[0],tiLength);
    return pBytes;
}

void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)
{
    this->Clear();
    if(tpBytes == NULL || tiLength == 0) return;
    m_vctBuffer.resize(tiLength,0);
    memcpy(&m_vctBuffer[0],tpBytes,tiLength);

}

void CMemoryBuffer::Append(const BYTE * tpBytes , int tiLength)
{
    if(tpBytes == NULL || tiLength == 0) return;
    m_vctBuffer.resize(this->GetLength() + tiLength,0);
    memcpy(&m_vctBuffer[0] + this->GetLength() - tiLength,tpBytes,tiLength);
}

void CMemoryBuffer::Append(const BYTE & tByte)
{
    m_vctBuffer.push_back(tByte);

}

void CMemoryBuffer::Insert(int tiStartIndex,const BYTE * tpBytes , int tiLength)
{
    if(tpBytes == NULL || tiLength == 0) return;
    int iBufferSize = this->GetLength();
    if(tiStartIndex > iBufferSize) return;
    if(tiStartIndex == iBufferSize)
    {
        this->Append(tpBytes,tiLength);
    }
    else if((tiStartIndex + tiLength) < iBufferSize)
    {
        memcpy(&m_vctBuffer[0] + tiStartIndex,tpBytes,tiLength);
    }
    else
    {
        m_vctBuffer.resize(tiStartIndex + tiLength ,0);
        memcpy(&m_vctBuffer[0] + tiStartIndex,tpBytes,tiLength);
    }

}

void CMemoryBuffer::CopyTo(const BYTE ** tppBytes, int &tiLength)const
{
    if(tppBytes == NULL || *tppBytes == NULL || this->IsEmpty()) return;
    tiLength = this->GetLength();
    memcpy(tppBytes,&m_vctBuffer[0],tiLength);

}



CMemoryBuffer & CMemoryBuffer::operator = (const CMemoryBuffer &other)
{
    this->Clear();
    if (!other.IsEmpty())
    {
        m_vctBuffer.insert(m_vctBuffer.begin(),other.GetBuffer().begin(),other.GetBuffer().end());
    }
    return *this;
}

CMemoryBuffer & CMemoryBuffer::operator += (const CMemoryBuffer &other)
{
    if (!other.IsEmpty())
    {
        m_vctBuffer.insert(m_vctBuffer.end(),other.GetBuffer().begin(),other.GetBuffer().end());
    }
    return *this;
}

解释下几点:

1、void CMemoryBuffer::Clear()
    {
     vector<BYTE>().swap(this->m_vctBuffer); 
    }

    这地方之所以要这么写,是因为vector有个毛病,clear后内存空间还不释放,需要对象释放后才释放,如果频繁操作一个大的字节流,怕影响   内存性能.

2、void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)
{
 this->Clear();
 if(tpBytes == NULL || tiLength == 0) return;
 m_vctBuffer.resize(tiLength,0);
 memcpy(&m_vctBuffer[0],tpBytes,tiLength);

}

    很多人可能会写成一个循环语句:

    for(int i = 0; i < tiLength; i ++)

{

    m_vctBuffer.push_back(tpBytes[i]);

}

 这样写效率太低.

原文地址:https://www.cnblogs.com/AquaGot/p/7241962.html