C++实现的Buffer类
写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() == ; } public:
vector<BYTE> m_vctBuffer;
};
CPP文件:
#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[];
} BYTE * CMemoryBuffer::CopyOut(int &tiLength) const
{
tiLength = this->GetLength();
if(this->IsEmpty()) return NULL;
BYTE *pBytes = new BYTE[tiLength];
memcpy(pBytes,&m_vctBuffer[],tiLength);
return pBytes;
} void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)
{
this->Clear();
if(tpBytes == NULL || tiLength == ) return;
m_vctBuffer.resize(tiLength,);
memcpy(&m_vctBuffer[],tpBytes,tiLength); } void CMemoryBuffer::Append(const BYTE * tpBytes , int tiLength)
{
if(tpBytes == NULL || tiLength == ) return;
m_vctBuffer.resize(this->GetLength() + tiLength,);
memcpy(&m_vctBuffer[] + 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 == ) return;
int iBufferSize = this->GetLength();
if(tiStartIndex > iBufferSize) return;
if(tiStartIndex == iBufferSize)
{
this->Append(tpBytes,tiLength);
}
else if((tiStartIndex + tiLength) < iBufferSize)
{
memcpy(&m_vctBuffer[] + tiStartIndex,tpBytes,tiLength);
}
else
{
m_vctBuffer.resize(tiStartIndex + tiLength ,);
memcpy(&m_vctBuffer[] + 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[],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]);
}
这样写效率太低。
转自 :
C++实现的Buffer类
C++实现的CMemoryStream类
C++实现的Buffer类的更多相关文章
- Node.js权威指南 (5) - 使用Buffer类处理二进制数据
		
5.1 创建Buffer对象 / 705.2 字符串的长度与缓存区的长度 / 725.3 Buffer对象与字符串对象之间的相互转换 / 74 5.3.1 Buffer对象的toString方法 / ...
 - Node.js系列:Buffer类的使用
		
客户端JavaScript中没有对二进制数据提供很好的支持.但是在处理TCP流或文件流时,必须要处理二进制数据.Node.js定义了一个Buffer类,用来创建一个专门存放二进制数据的缓存区. Buf ...
 - Node.js之使用Buffer类处理二进制数据
		
Node.js之使用Buffer类处理二进制数据 Buffer类可以在处理TCP流或文件流时处理二进制数据,该类用来创建一个专门存放二进制数据的缓存区. 1. 创建Buffer对象 1.1 直接创建: ...
 - 浅析nodejs的buffer类(转)
		
最近翻阅了node v0.10.4的buffer类的源代码,收获不少,也很久没有在cnode上发表文章了,想把一些收获分享给大家,有什么错误的地方希望大牛们指正啊. 前阵子有位rrestjs框架的使用 ...
 - node.js—Buffer类(二进制数据处理模块)
		
Buffer类概述 一个用于更好的操作二进制数据的类 我们在操作文件或者网络数据的时候,其实操作的就是二进制数据流 Node为我们提供了一个更加方便的去操作这种数据流的类 Buffer,他是一个全局的 ...
 - nodeJS-使用buffer类处理二进制数据
		
使用buffer类处理二进制数据 在客户端javascript脚本代码中,对于二进制数据并没有提供一个很好的支持.然后在nodejs中需要处理像TCP流或文件流时,必须要处理二进制数据.因此在node ...
 - Buffer类的详解(转)
		
Buffer 类是 java.nio 的构造基础.一个 Buffer 对象是固定数量的数据的容器,其作用是一个存储器,或者分段运输区,在这里,数据可被存储并在之后用于检索.缓冲区可以被写满或释放.对于 ...
 - Java NIO中的Buffer类
		
Buffer 缓冲,用于批量读写数据 Buffer是一个抽象类,基本数据类型都有实现类:XxxBuffer,比如ByteBuffer.CharBuffer.IntBuffer.DoubleBu ...
 - 浅析nodejs的buffer类
		
1.什么时候该用buffer,什么时候不该用 看一下如下的测试代码,分别是拼接各种不同长度的字符串,最后直接拼接了10MB的字符串 var string,string2,string3; var bu ...
 
随机推荐
- 阿里云、青云、腾讯云服务器,Mysql数据库,Redis等产品性能对比
			
阿里云.青云.腾讯云服务器,Mysql数据库,Redis等产品都使用过,对比维度很多就不一一放出.直接放结论吧:买的腾讯(金融专区)服务器,Mysql(TDSql)把所有项目转到腾讯云,但是没有用腾讯 ...
 - SpringMVC国际化配置
			
一.什么是国际化: 国际化是设计软件应用的过程中应用被使用与不同语言和地区 国际化通常采用多属性文件的方式解决,每个属性文件保存一种语言的文字信息, 不同语言的用户看到的是不同的内容 二.spr ...
 - cocos-creator 脚本逻辑-1
			
1.节点 编辑组件的脚本文件时.可以通过以下语句获得节点 this 就是当前组件 this.node 拿到组件依附的节点 This.node.parent 拿到组件依附的节点 的父节点 This.no ...
 - 你必须知道的get与post的真正区别
			
我们会经常看到有人问:http协议中GET请求和POST请求有什么区别~? 这个问题看似很简单,但是不同程度的人会回答出不同的结果.在公司的面试中,也会经常的问及类似这样的问题,看似很简单,但是不同层 ...
 - jquery文本框textarea自适应高度
			
浏览器中默认的文本框是不能根据内容的增多变高,只能固定高度有滚动条,体验不是很好,找了很多方法兼容都不行,总算找到个兼容良好的方法: <body> <textarea id=&quo ...
 - 纯CSS实现立方体旋转
			
下面为通过CSS动画实现的立方体旋转,可以改变CSS代码中关键帧定义(@keyframes)来改变立方体的旋转方式 HTML部分: <body class="body"> ...
 - Web前端面试指导(十九):CSS样式-如何清除元素浮动?
			
题目点评 本题属于比较常问的题目,也是在网页设计中经常遇到的问题,面试官希望通过这样的面试题来了解你对网页设计的基本功底,如果这样的题目答不出来,必会让面试官大失所望,面试成功的概率是非常小的. 答题 ...
 - sqoop简单介绍
			
一简介 Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS ...
 - Android Timer和TimerTask
			
以下内容根据 The JavaTM Tutorial 和相关API doc翻译整理,以供日后参考: 1.概览 Timer是一种定时器工具,用来在一个后台线程计划执行指定任务.它可以计划执行一个任务一次 ...
 - Log4Net使用教程
			
简介 为方便跟踪程序运行情况,我们可以记录系统运行异常日志,winform和web都可以通过继承异常或者try来实现. 官方网站:http://logging.apache.org/log4net/ ...