信号板拼包:数组方式(bug长度只是截短,并未清空,若之后拷贝数据长度小于之前数据长度,老数据会接在后面)
2016-11-30 16:31
351 查看
class SignalobardMsgReadHandler : public SessionVectChar::ReadHandler
{
public:
SignalobardMsgReadHandler() = delete;
SignalobardMsgReadHandler(SignalobardMsgReadHandler _in v) = delete;
SignalobardMsgReadHandler(sNetPack * _in data_ptr, size_t _in package_size = sizeof(sNetPack) )
: last_time_(bzrobot::Now())
, data_ptr_(data_ptr)
, package_size_one_(package_size)
, package_check_sum_(0)
, cache_buffer_size_(0)
, cache_buffer_()
{
}
virtual ~SignalobardMsgReadHandler()
{
}
inline int GetPackHeadFirstIndex( char buffer[], int one_package_size, unsigned char package_head_value )
{
int continue_equal_times = 0;
for ( int i = 0; i < one_package_size; ++i )
{
if ( (unsigned char)buffer[i] == package_head_value )
{
++continue_equal_times;
if ( continue_equal_times == PackageHeadByte_ )
{
return (i-(PackageHeadByte_-1));
}
}
else
{
continue_equal_times = 0;
}
}
return -1;
}
unsigned short CalculateCheckSum ( char buffer_[], int package_size )
{
unsigned short check_sum = 0;
for ( int i = 0; i < package_size-2; ++i )
{
check_sum += (unsigned char)buffer_[i];
}
return check_sum;
}
bzrobot::Duration _rt BlankTime() const
{
return bzrobot::Now() - last_time_;
}
protected:
bzrobot::Result _rt RunMain(typename SessionVectChar::ReadHandler::OutputType _ut output,
typename SessionVectChar::ReadHandler::InputType _in input,
typename SessionVectChar::ReadHandler::OptionType _in option) final
{
last_time_ = bzrobot::Now();
if(!data_ptr_)
{
return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
}
TO_2_BYTE WORDtemp;
const std::vector<char>& input_data = input;
//存包,然后根据包长决定是否取包,多包时取用最新包
memcpy ( &cache_buffer_[cache_buffer_size_], input_data.data(), input_data.size() );
cache_buffer_size_ = cache_buffer_size_ + input_data.size();
//只要缓存长度大于单个包长度,即循环进行取包,以防缓存数据堆积
while ( cache_buffer_size_ >= package_size_one_ )
{
//获取数据包头在缓存中的位置
int pack_head_index = GetPackHeadFirstIndex ( cache_buffer_, package_size_one_, PackageHeadValue_ );
//未找到包头,丢弃该部分,返回等待新的接收数据
if ( pack_head_index == -1 )
{
BZROBOT_WARNNING("SiganlBoardMsg: Not find pack head index");
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
}
//找到包头,且缓存长度足够取包
if ( pack_head_index + package_size_one_ <= cache_buffer_size_ )
{
memcpy( WORDtemp.b, &cache_buffer_[pack_head_index + package_size_one_ - 2], 2 );
//确认包校验和是否相等:相等取出数据,将取出的包段及其之前的部分丢弃
if ( CalculateCheckSum( cache_buffer_, package_size_one_ ) == WORDtemp.data16 )
{
memcpy(data_ptr_, &cache_buffer_[pack_head_index], package_size_one_);
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
}
//确认包校验和是否相等:不相等取出数据,将该包段及其之前的部分丢弃
else
{
BZROBOT_WARNNING("SiganlBoardMsg: Check sum not equal");
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
}
}
//找到包头,但缓存长度不够取包,丢弃包头之前的部分
else
{
BZROBOT_WARNNING("SiganlBoardMsg: Not whole package");
cache_buffer_size_ = cache_buffer_size_ - pack_head_index;
}
}
return BZROBOT_SIGNAL_BOARD_MSG_SUCCEED;
}
sNetPack * data_ptr_;
size_t package_size_one_;
size_t cache_buffer_size_;
const unsigned char PackageHeadValue_ = 0xA5;
const int PackageHeadByte_ = 4;
const static int CacheBufferMaxSize_ = 1024;
char cache_buffer_[CacheBufferMaxSize_];
unsigned short package_check_sum_;
bzrobot::Time last_time_;
};
{
public:
SignalobardMsgReadHandler() = delete;
SignalobardMsgReadHandler(SignalobardMsgReadHandler _in v) = delete;
SignalobardMsgReadHandler(sNetPack * _in data_ptr, size_t _in package_size = sizeof(sNetPack) )
: last_time_(bzrobot::Now())
, data_ptr_(data_ptr)
, package_size_one_(package_size)
, package_check_sum_(0)
, cache_buffer_size_(0)
, cache_buffer_()
{
}
virtual ~SignalobardMsgReadHandler()
{
}
inline int GetPackHeadFirstIndex( char buffer[], int one_package_size, unsigned char package_head_value )
{
int continue_equal_times = 0;
for ( int i = 0; i < one_package_size; ++i )
{
if ( (unsigned char)buffer[i] == package_head_value )
{
++continue_equal_times;
if ( continue_equal_times == PackageHeadByte_ )
{
return (i-(PackageHeadByte_-1));
}
}
else
{
continue_equal_times = 0;
}
}
return -1;
}
unsigned short CalculateCheckSum ( char buffer_[], int package_size )
{
unsigned short check_sum = 0;
for ( int i = 0; i < package_size-2; ++i )
{
check_sum += (unsigned char)buffer_[i];
}
return check_sum;
}
bzrobot::Duration _rt BlankTime() const
{
return bzrobot::Now() - last_time_;
}
protected:
bzrobot::Result _rt RunMain(typename SessionVectChar::ReadHandler::OutputType _ut output,
typename SessionVectChar::ReadHandler::InputType _in input,
typename SessionVectChar::ReadHandler::OptionType _in option) final
{
last_time_ = bzrobot::Now();
if(!data_ptr_)
{
return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
}
TO_2_BYTE WORDtemp;
const std::vector<char>& input_data = input;
//存包,然后根据包长决定是否取包,多包时取用最新包
memcpy ( &cache_buffer_[cache_buffer_size_], input_data.data(), input_data.size() );
cache_buffer_size_ = cache_buffer_size_ + input_data.size();
//只要缓存长度大于单个包长度,即循环进行取包,以防缓存数据堆积
while ( cache_buffer_size_ >= package_size_one_ )
{
//获取数据包头在缓存中的位置
int pack_head_index = GetPackHeadFirstIndex ( cache_buffer_, package_size_one_, PackageHeadValue_ );
//未找到包头,丢弃该部分,返回等待新的接收数据
if ( pack_head_index == -1 )
{
BZROBOT_WARNNING("SiganlBoardMsg: Not find pack head index");
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
}
//找到包头,且缓存长度足够取包
if ( pack_head_index + package_size_one_ <= cache_buffer_size_ )
{
memcpy( WORDtemp.b, &cache_buffer_[pack_head_index + package_size_one_ - 2], 2 );
//确认包校验和是否相等:相等取出数据,将取出的包段及其之前的部分丢弃
if ( CalculateCheckSum( cache_buffer_, package_size_one_ ) == WORDtemp.data16 )
{
memcpy(data_ptr_, &cache_buffer_[pack_head_index], package_size_one_);
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
}
//确认包校验和是否相等:不相等取出数据,将该包段及其之前的部分丢弃
else
{
BZROBOT_WARNNING("SiganlBoardMsg: Check sum not equal");
cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
}
}
//找到包头,但缓存长度不够取包,丢弃包头之前的部分
else
{
BZROBOT_WARNNING("SiganlBoardMsg: Not whole package");
cache_buffer_size_ = cache_buffer_size_ - pack_head_index;
}
}
return BZROBOT_SIGNAL_BOARD_MSG_SUCCEED;
}
sNetPack * data_ptr_;
size_t package_size_one_;
size_t cache_buffer_size_;
const unsigned char PackageHeadValue_ = 0xA5;
const int PackageHeadByte_ = 4;
const static int CacheBufferMaxSize_ = 1024;
char cache_buffer_[CacheBufferMaxSize_];
unsigned short package_check_sum_;
bzrobot::Time last_time_;
};
相关文章推荐
- 假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 而已」
- 假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 而已」
- 修正Firebird Net Provider 1.7“偏移和长度已超出数组界限”BUG(提供下载)
- 长度100的随机数组,单个随机数小于等于100
- mysql数据长度不足的bug
- WinSDK方式清空ListView数据和表头
- JavaScript清空数组的两种方式
- IPHONE 开发 6 -- Object C 02 常用数据类型[整型浮点型,短长整型],数组(固定长度,变长)
- WCF序列化反序列化数据数组超限 解决方式
- 我调用一个API得到数组之后想把这些数组的数据导入数据库当中。
- 一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
- 判断一个数组(有n个数据,数组的值大于等于1小于等于N)里面是否有两个一样的数据
- js数组清空的两种方式
- GLib中私有数据的表示 和 结构体最后的长度为0或者1的数组
- JavaScript中清空数组的三种方式
- VC++ TRACE Bug Trace所能接收的数据长度不能大于508字符
- 用数组方式快速导出MSFlexGrid表格数据到Excel表格中
- 清空数组的两种方式
- java笔记:关于复杂数据存储的问题--基础篇:数组以及浅拷贝与深拷贝的问题(上)
- java笔记:关于复杂数据存储的问题--基础篇:数组以及浅拷贝与深拷贝的问题(上)