Msg DisPatch
一天写了个Carlife 协议数据分流器
#include <stdio.h>
#include <string.h> typedef unsigned char uint8_t;
typedef unsigned int uint32_t; void print_array_data(uint8_t* data, size_t len)
{
int i;
char log_buffer[];
strcpy(log_buffer," ");
for(i=;i<len;i++)
{
char num_buffer[];
sprintf(num_buffer,"%02x ",data[i]);
strncat(log_buffer,num_buffer,);
if(strlen(log_buffer) > ) break;
}
printf("%s\n",log_buffer);
} class MsgReceiver
{
public:
void processData(uint8_t channel, uint8_t* buf, size_t size)
{
printf("channel %d, data is ", channel);
print_array_data(buf,size);
}
}; class MsgDispatch
{
public:
MsgDispatch(){
itsBufferData = new uint8_t[*];
itsCachedBufferSize = ;
itsMode = eParseHeader;
itsChannel = ;
itsCachedHeaderSize = ;
itsHeaderData = new uint8_t[MSG_HEADER_SIZE];
itsMsgRecv = new MsgReceiver;
}
~MsgDispatch(){
delete [] itsBufferData;
delete [] itsHeaderData;
delete itsMsgRecv;
}
void dispatch(uint8_t* buf, size_t size)
{
uint32_t curProcessIndex = ;
//printf("dispatch mode = %d, buffer size %lu, buffer data is ",itsMode,size);
//print_array_data(buf,size);
if(itsMode == eParseHeader)
{
if(size >= MSG_HEADER_SIZE) /* we can process header size */
{
if(isValidHeader(buf))
{
uint8_t channel = buf[];
uint32_t dataLen = readBig32(buf + ); curProcessIndex += MSG_HEADER_SIZE;
if (curProcessIndex + dataLen <= size)
{
itsMsgRecv -> processData(channel, buf + curProcessIndex, dataLen);
curProcessIndex += dataLen;
}
else /* we need to cache data */
{
cacheData(buf + curProcessIndex, size - curProcessIndex, dataLen, channel);
itsMode = eReadData;
curProcessIndex = size;
}
}
else /* header is not correct, shift one byte */
{
curProcessIndex++;
}
}
else /* process data is less than header size, cache header */
{
memcpy(itsHeaderData,buf,size);
itsCachedHeaderSize = size;
curProcessIndex = size;
itsMode = eReadHeader;
}
}
else if (itsMode == eReadData) /* read data */
{
if(size >= itsNeedReadSize) /* we can read all data from current buf */
{
memcpy(itsBufferData + itsCachedBufferSize, buf, itsNeedReadSize);
itsCachedBufferSize += itsNeedReadSize;
itsMsgRecv -> processData(itsChannel, itsBufferData, itsCachedBufferSize);
itsMode = eParseHeader;
curProcessIndex = itsNeedReadSize;
}
else /* can't read all data from current buffer, put all data to cache buffer */
{
memcpy(itsBufferData + itsCachedBufferSize, buf, size);
itsCachedBufferSize += size;
itsNeedReadSize -= size;
curProcessIndex = size;
}
}
else /* read header */
{
uint8_t needReadHeaderSize = MSG_HEADER_SIZE - itsCachedHeaderSize;
if(needReadHeaderSize < size) /* we can read header from current buffer */
{
memcpy(itsHeaderData+itsCachedHeaderSize,buf,needReadHeaderSize);
if(isValidHeader(itsHeaderData))
{
uint8_t channel = itsHeaderData[];
uint32_t dataLen = readBig32(itsHeaderData+); curProcessIndex = needReadHeaderSize;
if (curProcessIndex + dataLen <= size) /* we read data from current buffer */
{ itsMsgRecv -> processData(channel, buf + curProcessIndex, dataLen);
itsMode = eParseHeader;
curProcessIndex += dataLen;
}
else /* we need to cache data */
{
cacheData(buf + curProcessIndex, size - curProcessIndex, dataLen, channel);
curProcessIndex = size;
itsMode = eReadData;
}
}
else /* error header, shift one byte */
{
memcpy(itsHeaderData,itsHeaderData + ,MSG_HEADER_SIZE - );
itsCachedHeaderSize = MSG_HEADER_SIZE - ;
curProcessIndex = needReadHeaderSize;
}
}
else /* can't fill a header size */
{
memcpy(itsHeaderData+itsCachedHeaderSize,buf,size);
itsCachedHeaderSize += size;
curProcessIndex = size;
}
}
if(curProcessIndex < size)
{
this->dispatch(buf+curProcessIndex,size-curProcessIndex);
}
else { } /* data process Done */
}
private:
uint32_t readBig32(uint8_t* ptr)
{
return ( (uint32_t)( \
( ( (uint32_t)( (uint8_t *)(ptr))[ ] ) << ) | \
( ( (uint32_t)( (uint8_t *)(ptr))[ ] ) << ) | \
( ( (uint32_t)( (uint8_t *)(ptr))[ ] ) << ) | \
( (uint32_t)( (uint8_t *)(ptr))[ ] ) ) );
} bool isValidHeader(uint8_t* buf)
{
return (buf[] == 0x00 && buf[] == 0x00 && buf[] == 0x00 && buf[] < 0x07);
} void cacheData(uint8_t* buf, size_t cachedSize, size_t totalDataLen, uint8_t channel)
{
memcpy(itsBufferData,buf,cachedSize);
itsCachedBufferSize = cachedSize;
itsNeedReadSize = totalDataLen - itsCachedBufferSize;
itsChannel = channel;
} enum {
MSG_HEADER_SIZE = ,
};
enum {
eParseHeader,
eReadHeader,
eReadData,
};
uint8_t itsChannel;
uint8_t* itsBufferData;
size_t itsCachedBufferSize;
size_t itsNeedReadSize;
uint8_t itsMode; uint8_t* itsHeaderData;
uint8_t itsCachedHeaderSize;
MsgReceiver* itsMsgRecv;
}; int main()
{
uint8_t muti_msg_buf[] = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x04, 0x01,0x02,0x03,0x04, \
0x00,0x00,0x00,0x02, 0x00,0x00,0x00,0x02, 0x02,0x02,\
0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x03, 0x05,0x06,0x07};
uint8_t small_msg_buf_1[] = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x05, 0x09,0x08,0x07,0x06};
uint8_t small_msg_buf_2[] = {0x05, 0x00,0x00,0x00,0x02, 0x00,0x00,0x00,0x02, 0x01,0x01};
uint8_t small_msg_buf_3[] = {0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x0A, 0x01,0x02,0x03};
uint8_t small_msg_buf_4[] = {0x04,0x05,0x06};
uint8_t small_msg_buf_5[] = {0x07,0x08,0x09,0x0A,0x00};
uint8_t small_msg_buf_6[] = {0x00,0x00,0x04, 0x00,0x00,0x00,0x03, 0x07,0x07,0x07, 0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x03};
uint8_t small_msg_buf_7[] = {0x09,0x09,0x09};
uint8_t error_msg_buf_1[] = {0x01,0x00,0x00,0x00,0x06, 0x00,0x00,0x00,0x01, 0x01,0x02};
uint8_t error_msg_buf_2[] = {0x00,0x00,0x00,0x05, 0x00,0x00,0x00,0x02, 0x02,0x03};
uint8_t error_msg_buf_3[] = {0x00,0x00,0x00,0x04, 0x00,0x00,0x00,0x01, 0x04,0x05,0x05};
uint8_t error_msg_buf_4[] = {0x00,0x00,0x00,0x03, 0x00,0x00,0x00,0x02, 0x05,0x06};
uint8_t error_msg_buf_5[] = {0x00,0x00,0x00,0x02, 0x00,0x00,0x00,0x01, 0x07,0x06,0x05,0x06,0x08,0x00,0x00,0x00};
uint8_t error_msg_buf_6[] = {0x01, 0x00,0x00,0x00,0x03, 0x08,0x09,0x0A, 0x10,0x11};
uint8_t error_msg_buf_7[] = {0x01, 0x04,0x00,0x00,0x00,0x03, 0x00,0x00,0x00,0x04, 0x0B,0x0C,0x0D,0x0E};
uint8_t header_msg_buf_1[] = {0x01,0x00,0x00,0x00,0x06, 0x00,0x00,0x00,0x01, 0x01,0x00};
uint8_t header_msg_buf_2[] = {0x00, 0x00, 0x01, 0x00, 0x00};
uint8_t header_msg_buf_3[] = {0x00, 0x03, 0x01, 0x02, 0x03, 0x01,0x00,0x00,0x00,0x06, 0x00,0x00,0x00,0x01, 0x11}; MsgDispatch mds;
printf("test muti\n");
mds.dispatch(muti_msg_buf,sizeof(muti_msg_buf)); printf("test small\n");
mds.dispatch(small_msg_buf_1,sizeof(small_msg_buf_1));
mds.dispatch(small_msg_buf_2,sizeof(small_msg_buf_2));
mds.dispatch(small_msg_buf_3,sizeof(small_msg_buf_3));
mds.dispatch(small_msg_buf_4,sizeof(small_msg_buf_4));
mds.dispatch(small_msg_buf_5,sizeof(small_msg_buf_5));
mds.dispatch(small_msg_buf_6,sizeof(small_msg_buf_6));
mds.dispatch(small_msg_buf_7,sizeof(small_msg_buf_7)); printf("test error\n");
mds.dispatch(error_msg_buf_1,sizeof(error_msg_buf_1));
mds.dispatch(error_msg_buf_2,sizeof(error_msg_buf_2));
mds.dispatch(error_msg_buf_3,sizeof(error_msg_buf_3));
mds.dispatch(error_msg_buf_4,sizeof(error_msg_buf_4));
mds.dispatch(error_msg_buf_5,sizeof(error_msg_buf_5));
mds.dispatch(error_msg_buf_6,sizeof(error_msg_buf_6));
mds.dispatch(error_msg_buf_7,sizeof(error_msg_buf_7));
printf("test header\n");
mds.dispatch(header_msg_buf_1,sizeof(header_msg_buf_1));
mds.dispatch(header_msg_buf_2,sizeof(header_msg_buf_2));
mds.dispatch(header_msg_buf_3,sizeof(header_msg_buf_3));
return ;
}
输出:
test muti
channel 1, data is 01 02 03 04
channel 2, data is 02 02
channel 1, data is 05 06 07
test small
channel 1, data is 09 08 07 06 05
channel 2, data is 01 01
channel 5, data is 01 02 03 04 05 06 07 08 09 0a
channel 4, data is 07 07 07
channel 5, data is 09 09 09
test error
channel 6, data is 01
channel 5, data is 02 03
channel 4, data is 04
channel 3, data is 05 06
channel 2, data is 07
channel 1, data is 08 09 0a
channel 3, data is 0b 0c 0d 0e
test header
channel 6, data is 01
channel 1, data is 01 02 03
channel 6, data is 11
Msg DisPatch的更多相关文章
- 【单页应用之通信机制】view之间应该如何通信
前言 在单页应用中,view与view之间的通信机制一直是一个重点,因为单页应用的所有操作以及状态管理全部发生在一个页面上 没有很好的组织的话很容易就乱了,就算表面上看起来没有问题,事实上会有各种隐忧 ...
- 开源免费跨平台opengl opencv webgl gtk blender, opengl贴图程序
三维图形的这是opengl的强项,大型3D游戏都会把它作为首选.图像处理,是opencv的锁定的目标,大多都是C的api,也有少部分是C++的,工业图像表现,图像识别,都会考虑opencv的.webg ...
- unity 3D + Google Play In-app Billing (IAB)(转) 热度 3
最近由于工作需要,研究unity如何接入Google Play以实现游戏内购买.目前IAB的实现,prime31做的插件比较好,各平台的IAB均有,但费用相对过高(几乎都是70刀左右,可怜穷小子).在 ...
- [译]NeHe教程 - 创建一个OpenGL窗体
原文: Setting Up An OpenGL Window 欢迎阅读我的OpenGL教程.我是一个热爱OpenGL的普通码农!我第一次听到OpenGL是在3Dfx刚发布他们给Voodoo I显卡的 ...
- opengl加载多个3ds模型失败记
VC6 下载 http://blog.csdn.net/bcbobo21cn/article/details/44200205 opengl环境配置 http://blog.csdn.net/bcbo ...
- OPENGL4_变换
几种变换的几何意义说明 http://blog.csdn.net/onafioo/article/details/22094247 变换的执行顺序问题 正常顺序 1 视图(观察)变换 2 模型变换 3 ...
- OPENGL2_基本框架
一些概念 HDC:设备描述句柄(窗口着色描述表句柄),是WINDOWS的一种数据类型,HDC定义的变量指向一块内存,这块内存用来描述一个设备的相关的内容(设备描述表). HGLRC:OpenGL渲染环 ...
- Nehe OpenGL教程第一课-创建一个OpenGL窗口(Win32)
原文英文地址为:Creating an OpenGL Window (Win32),翻译的chm中文格式文档下载地址为:OpenGL教程电子书(chm格式)中文版,源代码在官网上也可以下载到,每 ...
- mosquitto/openssl 在RK3288上的编译以及MQTT客户端的代码示例
1,依赖库openssl 的交叉编译 (1)配置编译器信息 setarch i386 ./config no-asm shared --cross-compile-prefix=arm-linux-a ...
随机推荐
- ZOJ 2850和ZOJ 1414
下午上数据结构,结果竟然没有新题.T T果断上OJ来水一发 ZOJ 2850 Beautiful Meadow 传送门http://acm.zju.edu.cn/onlinejudge/showP ...
- 【习题 5-7 UVA - 12100】Printer Queue
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用队列和multiset就能完成模拟 [代码] #include <bits/stdc++.h> using names ...
- 【z02】选择客栈
(hotel.cpp/c/pas) [问题描述] 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照 某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示) ...
- SQL日期时间函数
一.Sql Server中的日期与时间函数 1. 当前系统日期.时间 select getdate() 2. dateadd 在向指定日期加上一段时间的基础上,返回新的 datetime 值 例如 ...
- 34、uevent机制说明
class_device_create(4.3.2内核是device_create->device_create_vargs->device_register->device_add ...
- CImage将图片转为指定像素大小
CFileDialog fDlg(true, "jpg", "", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, &q ...
- Perl遍历查找文件
Perl遍历查找文件 使用Perl查找当前目录下的所有PDF文件 ******************************************************************* ...
- c#编程:给定一个正整数求出是几位数并逆序输出
<span style="color:#FF0000;">第一步:把输入的数字转为字符串n.ToString() 第二步:求出字符串的长度即为正整数的位数 第三步:从后 ...
- 编译pano13的一些注意事项
作者:朱金灿 来源:error C2037: "jmpbuf"的左侧部分指定未定义的结构/联合"png_struct_def"e:\src\Test\libpa ...
- 特殊类型数据:IP地址字段(IPv4)
人们经常使用varchar(15)来存储ip地址,然而,它们实际上是32位无符号整数,不是字符串. MySQL提供INET_ATON()和INET_NTOA()函数将ip地址在整数和四段表示形式之间进 ...