182 lines
3.8 KiB
C++
182 lines
3.8 KiB
C++
|
#ifndef HGL_THREAD_RING_BUFFER_WRITE_SOURCE
|
|||
|
#define HGL_THREAD_RING_BUFFER_WRITE_SOURCE
|
|||
|
#include<string.h>
|
|||
|
|
|||
|
namespace hgl
|
|||
|
{
|
|||
|
/**
|
|||
|
* 安全取得可写入数据长度
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::SafeGetWriteSize()
|
|||
|
{
|
|||
|
Lock();
|
|||
|
|
|||
|
const int result=_GetWriteSize();
|
|||
|
|
|||
|
Unlock();
|
|||
|
|
|||
|
return(result);
|
|||
|
}
|
|||
|
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::WriteStart()
|
|||
|
{
|
|||
|
ClampPosition();
|
|||
|
|
|||
|
read_off=read_pos%buffer_size;
|
|||
|
|
|||
|
write_max=_GetWriteSize();
|
|||
|
|
|||
|
write_count=0;
|
|||
|
write_cur=write_pos;
|
|||
|
|
|||
|
return write_max;
|
|||
|
}
|
|||
|
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::_SafeWriteStart()
|
|||
|
{
|
|||
|
WriteStart();
|
|||
|
|
|||
|
if(write_max<=0)
|
|||
|
Unlock();
|
|||
|
|
|||
|
return write_max;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 尝试开始写入
|
|||
|
* @return >0 成功开始,可写入的数据长度
|
|||
|
* @return =0 没有可以写入的空间
|
|||
|
* @return <0 暂时不可写入
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::SafeTryWriteStart()
|
|||
|
{
|
|||
|
if(!TryLock())
|
|||
|
return(-1);
|
|||
|
|
|||
|
return _SafeWriteStart();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 开始写入数据,如果没有空间会立即关闭缓冲区,不必再次调用SafeWriteEnd
|
|||
|
* @return 可写入的数据长度
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::SafeWriteStart()
|
|||
|
{
|
|||
|
Lock();
|
|||
|
|
|||
|
return _SafeWriteStart();
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 结束写入数据
|
|||
|
* @param data 要写入的数据
|
|||
|
* @param size 要写入的数据长度
|
|||
|
* @return 实际写入的数据长度
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::Write(const T *data,int size)
|
|||
|
{
|
|||
|
if(!data||size<=0)return(-1);
|
|||
|
|
|||
|
const int result=_Write(data,size);
|
|||
|
|
|||
|
write_count+=result;
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 写入结束
|
|||
|
* @return 返回写入的数据长度
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::WriteEnd()
|
|||
|
{
|
|||
|
const int result=write_count;
|
|||
|
|
|||
|
if(result)
|
|||
|
write_pos=write_cur;
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 安全写入结束
|
|||
|
* @return 返回写入的数据长度
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::SafeWriteEnd()
|
|||
|
{
|
|||
|
const int result=WriteEnd();
|
|||
|
|
|||
|
Unlock();
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 安全写入数据,此函数会直接开锁解锁,用于少量的一次性处理。如大量的数据要分次写入,请使用SafeWriteStart/SafeWriteEnd
|
|||
|
* @param data 要写入的数据
|
|||
|
* @param size 要写入的数据长度
|
|||
|
* @return 实际写入的数据长度
|
|||
|
* @return -1 出错
|
|||
|
*/
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::SafeWrite(const T *data,int size)
|
|||
|
{
|
|||
|
if(!data||size<=0)return(-1);
|
|||
|
|
|||
|
if(SafeWriteStart()<=0)
|
|||
|
return(-1);
|
|||
|
|
|||
|
Write(data,size);
|
|||
|
|
|||
|
return SafeWriteEnd();
|
|||
|
}
|
|||
|
|
|||
|
template<typename T>
|
|||
|
int RingBuffer<T>::_Write(const T *data,int size)
|
|||
|
{
|
|||
|
if(size<=0||write_max<=0)return(0);
|
|||
|
|
|||
|
if(size>write_max)
|
|||
|
size=write_max;
|
|||
|
|
|||
|
if(size>0)
|
|||
|
{
|
|||
|
const int temp_write=write_cur%buffer_size;
|
|||
|
|
|||
|
if(read_off<=temp_write)
|
|||
|
{
|
|||
|
int temp=buffer_size-temp_write;
|
|||
|
|
|||
|
if(size>temp)
|
|||
|
{
|
|||
|
memcpy(buffer+temp_write,data,temp*sizeof(T));
|
|||
|
|
|||
|
memcpy(buffer,(char *)(data+temp),(size-temp)*sizeof(T));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
memcpy(buffer+temp_write,data,size*sizeof(T));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
memcpy(buffer+temp_write,data,size*sizeof(T));
|
|||
|
}
|
|||
|
|
|||
|
write_cur+=size;
|
|||
|
write_max-=size;
|
|||
|
}
|
|||
|
|
|||
|
return size;
|
|||
|
}
|
|||
|
}//namespace hgl
|
|||
|
#endif//HGL_THREAD_RING_BUFFER_WRITE_SOURCE
|