/*
* MMORPG Server
* Copyright (C) 2013
*
*/
#include "CircularBuffer.h"
/** Constructor
*/
CircularBuffer::CircularBuffer()
{
m_buffer = m_bufferEnd = m_regionAPointer = m_regionBPointer = nullptr;
m_regionASize = m_regionBSize = 0;
}
/** Destructor
*/
CircularBuffer::~CircularBuffer()
{
free(m_buffer);
}
/** Read bytes from the buffer
* @param destination pointer to destination where bytes will be written
* @param bytes number of bytes to read
* @return true if there was enough data, false otherwise
*/
bool CircularBuffer::Read(void * destination, size_t bytes)
{
// copy as much out of region a
uint8* ptr = (uint8*)destination;
size_t read_count = 0;
if ((m_regionASize + m_regionBSize) < bytes)
return false;
// If we have both region A and region B, always "finish" off region A first, as
// this will contain the "oldest" data
if (bytes > 0 && m_regionASize > 0)
{
read_count = std::min(bytes, m_regionASize);
memcpy(ptr, m_regionAPointer, read_count);
m_regionASize -= read_count;
m_regionAPointer += read_count;
ptr += read_count;
bytes -= read_count;
}
// Data left over? read the data from buffer B
if (bytes > 0)
{
memcpy(ptr, m_regionBPointer, bytes);
m_regionBSize -= bytes;
m_regionBPointer += bytes;
}
// Is buffer A empty?, move buffer B to buffer A, to increase future per formance
if (m_regionASize == 0)
{
if (m_regionBSize > 0 && m_regionBPointer != m_buffer)
memmove(m_buffer, m_regionBPointer, m_regionBSize);
m_regionAPointer = m_buffer;
m_regionASize = m_regionBSize;
m_regionBPointer = NULL;
m_regionBSize = 0;
}
return true;
}
/** Write bytes to the buffer
* @param data pointer to the data to be written
* @param bytes number of bytes to be written
* @return true if was successful, otherwise false
*/
bool CircularBuffer::Write(const void * data, size_t bytes)
{
// If buffer B exists, write to it.
if (m_regionBPointer != NULL)
{
if (GetBFreeSpace() < bytes)
return false;
memcpy(&m_regionBPointer[m_regionBSize], data, bytes);
m_regionBSize += bytes;
return true;
}
// Otherwise, write to buffer A, or initialize buffer B depending on which has more space.
if (GetAFreeSpace() < GetSpaceBeforeA())
{
AllocateB();
if (GetBFreeSpace() < bytes)
return false;
memcpy(&m_regionBPointer[m_regionBSize], data, bytes);
m_regionBSize += bytes;
return true;
}
else
{
if (GetAFreeSpace() < bytes)
return false;
memcpy(&m_regionAPointer[m_regionASize], data, bytes);
m_regionASize += bytes;
return true;
}
}
/** Returns the number of available bytes left.
*/
size_t CircularBuffer::GetSpace()
{
if( m_regionBPointer != NULL )
return GetBFreeSpace();
else
{
// would allocating buffer B get us more data?
if( GetAFreeSpace() < GetSpaceBeforeA() )
{
AllocateB();
return GetBFreeSpace();
}
// or not?
return GetAFreeSpace();
}
}
/** Removes len bytes from the front of the buffer
* @param len the number of bytes to "cut"
*/
void CircularBuffer::Remove(size_t len)
{
// remove from A first before we remove from b
size_t remove_count = 0;
// If we have both region A and region B, always "finish" off region A first, as
// this will contain the "oldest" data
if (len > 0 && m_regionASize > 0)
{
remove_count = std::min(len, m_regionASize);
m_regionASize -= remove_count;
m_regionAPointer += remove_count;
len -= remove_count;
}
// Data left over? cut the data from buffer B
if (len > 0 && m_regionBSize > 0)
{
remove_count = std::min(len, m_regionBSize);
m_regionBSize -= remove_count;
m_regionBPointer += remove_count;
len -= remove_count;
}
// is buffer A empty? move buffer B to buffer A, to increase future performance
if (m_regionASize == 0)
{
if (m_regionBSize > 0 && m_regionBPointer != m_buffer)
memmove(m_buffer, m_regionBPointer, m_regionBSize);
m_regionAPointer = m_buffer;
m_regionASize = m_regionBSize;
m_regionBPointer = NULL;
m_regionBSize = 0;
}
}
/** Allocate the buffer with room for size bytes
* @param size the number of bytes to allocate
*/
void CircularBuffer::Allocate(size_t size)
{
m_buffer = (uint8*)malloc(size);
m_bufferEnd = m_buffer + size;
m_regionAPointer = m_buffer; // reset A to the start
}
/** Increments the "writen" pointer forward len bytes
* @param len number of bytes to step
*/
void CircularBuffer::IncrementWritten(size_t len) // known as "commit"
{
if( m_regionBPointer != nullptr )
m_regionBSize += len;
else
m_regionASize += len;
}
/** Returns a pointer at the "beginning" of the buffer, where data can be pulled from
*/
void * CircularBuffer::GetBufferStart()
{
if( m_regionASize > 0 )
return m_regionAPointer;
else
return m_regionBPointer;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
boost_asio.rar (14个子文件)
asioTest
asioTest
asioTest.vcxproj 4KB
asioTest.vcxproj.filters 2KB
asioTest.vcxproj.user 164B
src
SocketMgr.h 766B
ListenSocket.h 1KB
CircularBuffer.cpp 5KB
asioTest.cpp 1KB
Socket.cpp 2KB
SocketMgr.cpp 930B
GameSocket.cpp 465B
Common.h 20KB
Socket.h 878B
GameSocket.h 269B
CircularBuffer.h 3KB
共 14 条
- 1
资源评论
进梦叶
- 粉丝: 3
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Three.js介绍.zip
- Android14 CTS Verifier测试手册.pdf
- NC65 UAP65 流程开发 – 业务流 – 推单 详细笔记
- 两种计算CDF累加分布函数的Matlab程序,可以选择使用 .rar
- Windows操作系统介绍.zip
- 汉森的广义t分布的matlab程序(金融)cdf.zip
- Three.js介绍.zip0002
- 人工智能BBSO算法,MATLAB实现,很基本的人工智能算法,里面有很多源程序
- 高端大气科技互联网项目融资商业计划书产品公司品牌介绍PPT模板.pptx
- Sora AI文字生成视频实操教程、由给定的图片生成视频的教程说明书,祝你一臂之力 轻松上手Sora
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功