CMCore/inc/hgl/thread/RingBufferWrite.cpp
2019-08-19 19:19:58 +08:00

182 lines
3.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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