C语言,基于单向链表实现,变长动态数据缓冲区(线程安全) ---- 类似java的StringBuffer --- 亲测OK
参考:https://blog.csdn.net/aiwangtingyun/article/details/79705042
参考:https://baike.baidu.com/item/realloc/659993?fr=aladdin
C语言,基于单向链表实现,变长动态数据缓冲区(线程安全) ---- 类似java的StringBuffer
0、我的实现与realloc、环形数组的区别
0.1 realloc原理
-
如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。
-
如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。
0.2 我的原理
我的是一个buffer,不能像realloc那样可扩大、可缩小,我的只能扩大,类似于流的缓存
原理是:
数据追加——不再顾虑原来分配的空间,而是重新分配出要扩大的空间,将指令以节点方式挂在单向表的尾部
数据读取——从头节点中读出数据,如果头节点被读完,则删除并释放头节点对应的内存
0.3 要不要使用我的方式
如果你的内存够用,大可不必像我这样实现,直接调用realloc即可
有的同学说使用环形数组,环形数组是定长的缓冲区,并且数据接收是可控的范围时使用。
如果你的内存很紧缺,或者接收的数据不可控——另一个模块在不断的塞给你数据,你又不得不接,环形数组分配太大浪费内存,分配太小不够用,给的数据不存就丢了,这种场景可以以用我的方式,内存用多少开多少,随时用随时申请,请往下看。
1、就4个接口:
1 void *BytesBuffer_create(void); // 缓冲区句柄创建 2 void BytesBuffer_delete(IN void *p_head); // 缓冲区销毁 3 int BytesBuffer_read(IN void *p_head, OUT unsigned char *out_buf, IN unsigned int expected_read_len); // 缓冲区读 4 int BytesBuffer_append(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len); // 缓冲区写
2、直接上代码,两个缓冲区文件,一个测试文件
1 //LIB_bytes_buffer.c 2 /** 3 * Copyright © XXXX Technologies Co., Ltd. All Rights Reserved. 4 * @Date 2020年08月01日,下午16:00:00 5 */ 6 7 /********************************************************************************************** 8 * 文件描述: 该文件为带头结点的单链表库函数中,部分功能函数的实现 9 * 日期: 2020.08.01 16:00:00 10 * 作者: XXXX 11 **********************************************************************************************/ 12 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include <string.h> 16 17 #include "LIB_bytes_buffer.h" 18 19 /********************************************************************************************** 20 单向链表 : 遍历打印链表所有数据 21 22 23 日期: 2020.08.01 16:00:00 24 作者: XXXX 25 26 参数: h:链表头结点的地址 27 28 返回值: 无 29 30 **********************************************************************************************/ 31 void XXXX_SINGLELIST_print(IN const Node_head_t *h) 32 { 33 Node_t *i = NULL; 34 int index = 0; 35 36 /* 检查是否为空链表 */ 37 if (NULL == h || NULL == h->next) 38 { 39 XXXX_print_ln_E("Empty list."); 40 return; 41 } 42 43 /* 遍历链表 */ 44 for (index = 0, i = h->next; i != NULL; index++, i = i->next) 45 { 46 XXXX_print_ln_I("[%d]= %d/%d:%p", index, i->data.len_used, i->data.len_data, i->data.data); 47 } 48 } 49 50 /********************************************************************************************** 51 单向链表 : 删除链表头节点后的第一个节点 52 53 54 日期: 2020.08.01 16:00:00 55 作者: XXXX 56 57 参数: h:链表头结点的地址 58 59 返回值: 成功返回0, 空链表返回-1 60 61 **********************************************************************************************/ 62 int XXXX_SINGLELIST_delete_first(IN Node_head_t *h) 63 { 64 Node_t *fast = NULL; // 快指针 65 66 // 获取锁 67 if (NULL != h->lock) { 68 XXXX_mutex_take(h->lock); 69 } 70 71 /* 检查是否为空链表 */ 72 if (NULL == h || NULL == h->next) 73 { 74 XXXX_print_ln_E("Empty list."); 75 // 释放锁 76 if (NULL != h->lock) { 77 XXXX_mutex_give(h->lock); 78 } 79 80 return -1; 81 } 82 83 fast = h->next; // 快指针 84 85 h->next = fast->next; // 通过摘掉节点 86 87 fast->next = NULL; 88 fast->data.len_used = 0; 89 fast->data.len_data = 0; 90 if (NULL != fast->data.data) { 91 XXXX_free(fast->data.data); 92 fast->data.data = NULL; 93 } 94 95 XXXX_free(fast); // 和释放节点空间达到删除目的 96 fast = NULL; 97 98 // 释放锁 99 if (NULL != h->lock) { 100 XXXX_mutex_give(h->lock); 101 } 102 103 return 0; 104 } 105 106 /********************************************************************************************** 107 单向链表 : 删除链表的所有节点(除了头节点) 108 109 110 日期: 2020.08.01 16:00:00 111 作者: XXXX 112 113 参数: h:链表头结点的地址 114 115 返回值: 无 116 117 **********************************************************************************************/ 118 void XXXX_SINGLELIST_delete(IN Node_head_t *h) 119 { 120 int ret = 0; 121 122 /* 检查是否为空链表 */ 123 if (NULL == h || NULL == h->next) 124 { 125 XXXX_print_ln_E("Empty list."); 126 return; 127 } 128 129 /* 遍历链表 */ 130 for (; 0 == ret; ) 131 { 132 ret = XXXX_SINGLELIST_delete_first(h); 133 } 134 } 135 136 /********************************************************************************************** 137 单向链表 : 创建一个节点 138 139 140 日期: 2020.08.01 16:00:00 141 作者: XXXX 142 143 参数: 无 144 145 返回值: 成功返回新节点指针,失败返回NULL 146 147 **********************************************************************************************/ 148 Node_t *XXXX_SINGLELIST_create_node(void) 149 { 150 Node_t *newNode = NULL; 151 152 /* 第一步:分配新节点空间 */ 153 newNode = XXXX_malloc(sizeof(Node_t)); 154 if (NULL == newNode) 155 { 156 XXXX_print_ln_E("malloc Failed(size=%u).", (unsigned int)sizeof(Node_t)); 157 return NULL; 158 } 159 160 memset((void *)newNode, 0, sizeof(Node_t)); 161 162 return newNode; 163 } 164 165 /********************************************************************************************** 166 单向链表 : 插入节点到链表尾 167 168 **** 注意: 调用完毕此函数后, 请自行维护 node_data 对应的实参 *** 169 170 日期: 2020.08.01 16:00:00 171 作者: XXXX 172 173 参数: h:链表头结点的地址, node_data:待插入的节点 174 175 返回值: 成功返回0,失败返回-1 176 177 **********************************************************************************************/ 178 179 int XXXX_SINGLELIST_append_tail(IN Node_head_t *h, IN Node_data_t *node_data) 180 { 181 Node_t *newNode = NULL; 182 Node_t *i = (Node_t *)h; 183 184 // 获取锁 185 if (NULL != h->lock) { 186 XXXX_mutex_take(h->lock); 187 } 188 189 /* 参数检查 */ 190 if (NULL == h || NULL == node_data) 191 { 192 XXXX_print_ln_E("wrong para1."); 193 194 // 释放锁 195 if (NULL != h->lock) { 196 XXXX_mutex_give(h->lock); 197 } 198 return -1; 199 } 200 201 /* 第一步:分配新节点空间 */ 202 newNode = XXXX_SINGLELIST_create_node(); 203 if (NULL == newNode) 204 { 205 XXXX_print_ln_E("create_node Failed."); 206 207 // 释放锁 208 if (NULL != h->lock) { 209 XXXX_mutex_give(h->lock); 210 } 211 return -1; 212 } 213 214 /* 第二步:赋值给新节点 */ 215 memcpy((void *)&newNode->data, (void *)node_data, sizeof(Node_data_t)); 216 217 /* 第三步:找到链表尾 */ 218 while (i->next != NULL) 219 { 220 i = i->next; 221 } 222 223 /* 第四步:把新节点插入到链表尾 */ 224 i->next = newNode; // 尾节点指向新节点 225 newNode->next = NULL; // 新节点指向NULL,作为链表尾 226 227 // 释放锁 228 if (NULL != h->lock) { 229 XXXX_mutex_give(h->lock); 230 } 231 232 return 0; // 成功返回0 233 } 234 235 /********************************************************************************************** 236 单向链表 : 插入节点到链表头 237 238 **** 注意: 调用完毕此函数后, 请自行维护 node_data 对应的实参 *** 239 240 日期: 2020.08.01 16:00:00 241 作者: XXXX 242 243 参数: h:链表头结点的地址, node_data:待插入的节点 244 245 返回值: 成功返回0,失败返回-1 246 247 **********************************************************************************************/ 248 249 int XXXX_SINGLELIST_append_head(IN Node_head_t *h, IN Node_data_t *node_data) 250 { 251 Node_t *p_next = NULL; 252 Node_t *newNode = NULL; 253 Node_t *i = (Node_t *)h; 254 255 // 获取锁 256 if (NULL != h->lock) { 257 XXXX_mutex_take(h->lock); 258 } 259 260 /* 参数检查 */ 261 if (NULL == h || NULL == node_data) 262 { 263 XXXX_print_ln_E("wrong para1."); 264 265 // 释放锁 266 if (NULL != h->lock) { 267 XXXX_mutex_give(h->lock); 268 } 269 return -1; 270 } 271 272 /* 第一步:分配新节点空间 */ 273 newNode = XXXX_SINGLELIST_create_node(); 274 if (NULL == newNode) 275 { 276 XXXX_print_ln_E("create_node Failed."); 277 278 // 释放锁 279 if (NULL != h->lock) { 280 XXXX_mutex_give(h->lock); 281 } 282 return -1; 283 } 284 285 /* 第二步:赋值给新节点 */ 286 memcpy((void *)&newNode->data, (void *)node_data, sizeof(Node_data_t)); 287 288 /* 第三步:找到链表尾 */ 289 p_next = i->next; 290 291 292 /* 第四步:把新节点插入到链表头 */ 293 i->next = newNode; // 头节点连接新节点 294 newNode->next = p_next; // 新节点连接原第一节点 295 296 // 释放锁 297 if (NULL != h->lock) { 298 XXXX_mutex_give(h->lock); 299 } 300 301 return 0; // 成功返回0 302 } 303 304 /********************************************************************************************** 305 字节缓存区 : 创建对象 306 307 308 日期: 2020.08.01 16:00:00 309 作者: XXXX 310 311 参数: 无 312 313 返回值: NULL: 失败 314 非NULL: 成功, 返回对象 315 316 **********************************************************************************************/ 317 void *BytesBuffer_create(void) 318 { 319 Node_head_t *headNode = NULL; 320 321 /* 第一步:分配新节点空间 */ 322 headNode = XXXX_malloc(sizeof(Node_head_t)); 323 if (NULL == headNode) 324 { 325 XXXX_print_ln_E("malloc Failed(size=%u).", (unsigned int)sizeof(Node_head_t)); 326 return NULL; 327 } 328 329 memset((void *)headNode, 0, sizeof(Node_head_t)); 330 331 headNode->lock = XXXX_mutex_init(); 332 if ( NULL == headNode->lock ) { 333 XXXX_print_ln_E(" mutex create failed.\n"); 334 } 335 336 return (void *)headNode; 337 } 338 339 /********************************************************************************************** 340 字节缓存区 : 销毁对象 341 342 343 日期: 2020.08.01 16:00:00 344 作者: XXXX 345 346 参数: p_head, 待销毁对象 347 348 返回值: 无 349 350 **********************************************************************************************/ 351 void BytesBuffer_delete(IN void *p_head) 352 { 353 Node_head_t *h = (Node_head_t *)p_head; 354 355 /* 检查是否为空链表 */ 356 if (NULL == h || NULL == h->next) 357 { 358 XXXX_print_ln_E("Empty list."); 359 return; 360 } 361 362 XXXX_SINGLELIST_delete((Node_head_t *)p_head); 363 364 XXXX_free(p_head); 365 p_head = NULL; 366 } 367 368 /********************************************************************************************** 369 字节缓存区 : 读取 370 371 372 日期: 2020.08.01 16:00:00 373 作者: XXXX 374 375 参数: p_head, 字节缓存区对象 376 out_buf, 字节输出 377 expected_read_len, 期望读取字节个数 378 379 返回值: >=0: 成功读取字节个数 380 381 **********************************************************************************************/ 382 int BytesBuffer_read(IN void *p_head, OUT unsigned char *out_buf, IN unsigned int expected_read_len) 383 { 384 Node_t *i = NULL; 385 unsigned int curr_copy_len = 0; 386 unsigned int curr_node_bytes = 0; 387 unsigned int already_copy_len = 0; 388 unsigned int left_copy_len = expected_read_len; 389 Node_head_t *h = (Node_head_t *)p_head; 390 391 /* 检查是否为空链表 */ 392 if (NULL == h || NULL == out_buf) 393 { 394 XXXX_print_ln_E("wrong para."); 395 return -1; 396 } 397 398 if (NULL == h->next || 0 == expected_read_len) 399 { 400 //XXXX_print_ln_I("Empty list,h=%x,h->next=%x,ex_r=%u", (unsigned int)h, (unsigned int)h->next, expected_read_len); // 0的时候就不打印了 401 return 0; 402 } 403 404 /* 遍历链表 */ 405 for (i = h->next; i != NULL; ) 406 { 407 if (i->data.len_data <= i->data.len_used) 408 { 409 i = i->next; // 即将删除i节点, 准备好下一点节指令 410 XXXX_SINGLELIST_delete_first(h); 411 continue; 412 } 413 414 left_copy_len = expected_read_len - already_copy_len; 415 416 curr_node_bytes = (i->data.len_data - i->data.len_used); 417 curr_copy_len = (curr_node_bytes > left_copy_len) ? left_copy_len : curr_node_bytes; 418 419 memcpy((void *)(out_buf + already_copy_len), i->data.data + i->data.len_used, curr_copy_len); 420 421 i->data.len_used += curr_copy_len; 422 if (i->data.len_data <= i->data.len_used) 423 { 424 i = i->next; // 即将删除i节点, 准备好下一点节指令 425 XXXX_SINGLELIST_delete_first(h); 426 } 427 428 already_copy_len += curr_copy_len; 429 430 if (already_copy_len >= expected_read_len) { 431 break; 432 } 433 434 } 435 436 return already_copy_len; 437 } 438 439 /********************************************************************************************** 440 字节缓存区 : 追加 441 442 443 **** 注意: 调用完毕此函数后, 调用者请不要释放 in_buf 对应的缓冲区 *** 444 445 日期: 2020.08.01 16:00:00 446 作者: XXXX 447 448 参数: p_head, 字节缓存区对象 449 in_buf, 待追加的字节流, 调用者请在堆中分配 450 expected_append_len, 待追加的字节流字节个数 451 452 返回值: 成功返回0,失败返回-1 453 454 **********************************************************************************************/ 455 int BytesBuffer_append_tail(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len) 456 { 457 Node_data_t node_data; 458 Node_head_t *h = (Node_head_t *)p_head; 459 int ret = -1; 460 461 /* 参数检查 */ 462 if (NULL == h || NULL == in_buf || 0 == expected_append_len) 463 { 464 XXXX_print_ln_E("wrong para."); 465 return -1; 466 } 467 468 memset((void *)&node_data, 0, sizeof(Node_data_t)); 469 470 node_data.len_used = 0; 471 node_data.len_data = expected_append_len; 472 node_data.data = in_buf; 473 474 475 ret = XXXX_SINGLELIST_append_tail(h, &node_data); 476 477 memset((void *)&node_data, 0, sizeof(Node_data_t)); 478 479 return ret; 480 } 481 482 /********************************************************************************************** 483 字节缓存区 : 追加 - 放在头部 484 485 486 **** 注意: 调用完毕此函数后, 调用者请不要释放 in_buf 对应的缓冲区 *** 487 488 日期: 2020.08.01 16:00:00 489 作者: XXXX 490 491 参数: p_head, 字节缓存区对象 492 in_buf, 待追加的字节流, 调用者请在堆中分配 493 expected_append_len, 待追加的字节流字节个数 494 495 返回值: 成功返回0,失败返回-1 496 497 **********************************************************************************************/ 498 int BytesBuffer_append_head(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len) 499 { 500 Node_data_t node_data; 501 Node_head_t *h = (Node_head_t *)p_head; 502 int ret = -1; 503 504 /* 参数检查 */ 505 if (NULL == h || NULL == in_buf || 0 == expected_append_len) 506 { 507 XXXX_print_ln_E("wrong para."); 508 return -1; 509 } 510 511 memset((void *)&node_data, 0, sizeof(Node_data_t)); 512 513 node_data.len_used = 0; 514 node_data.len_data = expected_append_len; 515 node_data.data = in_buf; 516 517 518 ret = XXXX_SINGLELIST_append_head(h, &node_data); 519 520 memset((void *)&node_data, 0, sizeof(Node_data_t)); 521 522 return ret; 523 } 524 525 /********************************************************************************************** 526 字节缓存区 : 在头部 或 尾部添加数据 527 528 529 **** 注意: 调用完毕此函数后, 调用者必须释放 in_buf 对应的缓冲区 *** 530 531 日期: 2020.08.01 16:00:00 532 作者: XXXX 533 534 参数: p_head, 字节缓存区对象 535 in_buf, 待追加的字节流, 调用者请在堆中分配 536 expected_append_len, 待追加的字节流字节个数 537 is_put_to_tail, 放置尾部 538 539 返回值: 成功返回0,失败返回-1 540 541 **********************************************************************************************/ 542 int BytesBuffer_add(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len, IN int is_put_to_tail) 543 { 544 int ret = -1; 545 unsigned char *p_in = NULL; 546 547 /* 参数检查 */ 548 if (NULL == p_head || NULL == in_buf || 0 == expected_append_len) 549 { 550 XXXX_print_ln_E("wrong para."); 551 return -1; 552 } 553 554 p_in = (unsigned char *)XXXX_malloc(expected_append_len); 555 if (NULL == p_in) { 556 XXXX_print_ln_E("return Failed"); 557 return -1; 558 } 559 560 memset(p_in, 0, expected_append_len); 561 memcpy(p_in, in_buf, expected_append_len); 562 563 // p_in 已挂载到缓冲区链表中, 不要释放 p_in 564 if (0 == is_put_to_tail) { 565 ret = BytesBuffer_append_head(p_head, p_in, expected_append_len); 566 } else { 567 ret = BytesBuffer_append_tail(p_head, p_in, expected_append_len); 568 } 569 570 return ret; 571 572 }
1 // LIB_bytes_buffer.h 2 /** 3 * Copyright © XXXX Technologies Co., Ltd. All Rights Reserved. 4 * @Date 2020年08月01日,下午16:00:00 5 */ 6 7 /********************************************************************************************** 8 * 文件描述: 该文件为带头结点的单链表库函数中,部分功能函数的实现 9 * 日期: 2020.08.01 16:00:00 10 * 作者: XXXX 11 **********************************************************************************************/ 12 13 #ifndef _NODELIST_H_ 14 #define _NODELIST_H_ 15 16 #include "LIB_bytes_buffer_port.h" 17 typedef struct node_data 18 { 19 unsigned int len_used; // 节点数据已使用长度 20 unsigned int len_data; // 节点数据长度 21 unsigned char *data; // 节点数据指定为整型 22 }Node_data_t; 23 24 /* 封装链表节点 */ 25 typedef struct node 26 { 27 Node_data_t data; // 节点数据 28 struct node *next; // 下一个节点 29 } Node_t; 30 31 /* 封装链表头节点 */ 32 typedef struct _node_head 33 { 34 Node_data_t data; // 节点数据 35 struct node *next; // 下一个节点 36 void *lock; // 锁 37 } Node_head_t; 38 39 /** 40 * @函数名: XXXX_SINGLELIST_append_tail 41 * @函数功能: 插入节点到链表尾 42 * @参数: h:链表头结点的地址 data:待插入的数据 43 * @返回值:插入成功返回0,失败返回非零 44 */ 45 int XXXX_SINGLELIST_append_tail(IN Node_head_t *h, IN Node_data_t *node_data); 46 47 /** 48 * @函数名: XXXX_SINGLELIST_print 49 * @函数功能: 遍历链表所有数据 50 * @参数: h:链表头结点的地址 51 * @返回值: void 52 */ 53 void XXXX_SINGLELIST_print(IN const Node_head_t *h); 54 55 /** 56 * @函数名: XXXX_SINGLELIST_delete 57 * @函数功能: 在链表中删除指定值的节点,如果有多个匹配则删除全部 58 * @参数: h:链表头结点的地址 data:待删除的数据 59 * @返回值: void 60 */ 61 void XXXX_SINGLELIST_delete(IN Node_head_t *h); 62 63 void *BytesBuffer_create(void); 64 void BytesBuffer_delete(IN void *p_head); 65 int BytesBuffer_read(IN void *p_head, OUT unsigned char *out_buf, IN unsigned int expected_read_len); 66 int BytesBuffer_append_tail(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len); 67 int BytesBuffer_append_head(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len); 68 int BytesBuffer_add(IN void *p_head, IN unsigned char *in_buf, IN unsigned int expected_append_len, IN int is_put_to_tail); 69 70 #endif //_NODELIST_H
1 // LIB_bytes_buffer_port.c 2 3 #include <pthread.h> 4 #include "LIB_bytes_buffer_port.h" 5 6 /********************************************************************************************** 7 锁初始化 8 9 10 日期: 2019.09.20 10:36:00 11 作者: XXXX 12 13 参数: 无 14 15 返回值: 锁指针 16 17 **********************************************************************************************/ 18 void *XXXX_mutex_init( void ) 19 { 20 static pthread_mutex_t g_mutex_lock; 21 int ret = 0; 22 23 ret = pthread_mutex_init(&g_mutex_lock, NULL); 24 if (ret != 0) { 25 XXXX_print_ln_E("mutex init failed\n"); 26 return NULL; 27 } 28 29 return (void *)&g_mutex_lock; 30 } 31 32 /********************************************************************************************** 33 锁获取 34 35 36 日期: 2019.09.20 10:36:00 37 作者: XXXX 38 39 参数: mutex, 锁指针 40 41 返回值: 无 42 43 **********************************************************************************************/ 44 void XXXX_mutex_take( void *mutex ) 45 { 46 pthread_mutex_lock(mutex); 47 48 return; 49 } 50 51 /********************************************************************************************** 52 锁释放 53 54 55 日期: 2019.09.20 10:36:00 56 作者: XXXX 57 58 参数: mutex, 锁指针 59 60 返回值: 无 61 62 **********************************************************************************************/ 63 void XXXX_mutex_give( void *mutex ) 64 { 65 pthread_mutex_unlock(mutex); 66 return; 67 }
1 // LIB_bytes_buffer_port.h 2 3 // 移植请实现以下接口 或 宏 4 #if 1 5 #include <stdlib.h> 6 #include <unistd.h> 7 8 void *XXXX_mutex_init( void ); 9 void XXXX_mutex_take( void *mutex ); 10 void XXXX_mutex_give( void *mutex ); 11 12 #define XXXX_malloc malloc 13 #define XXXX_free free 14 #define XXXX_print_ln_E(fmt, arg...) { printf("(%s|%d)"fmt"\r\n", __func__, __LINE__, ##arg); } 15 #define XXXX_print_ln_W(fmt, arg...) { printf("(%s|%d)"fmt"\r\n", __func__, __LINE__, ##arg); } 16 #define XXXX_print_ln_I(fmt, arg...) { printf("(%s|%d)"fmt"\r\n", __func__, __LINE__, ##arg); } 17 #define XXXX_print_ln_D(fmt, arg...) { printf("(%s|%d)"fmt"\r\n", __func__, __LINE__, ##arg); } 18 #define XXXX_sleep_ms(a) usleep(a * 1000) 19 20 #define XXXX_MIN(a, b) ( ( (a) < (b) ) ? (a) : (b) ) 21 22 // 输入参数标识 23 #define IN 24 25 // 输出参数标识 26 #define OUT 27 28 // 输入输出参数标识 29 #define INOUT 30 31 typedef enum _ERRCODE_E 32 { 33 ERRCODE_FAILED = -1, 34 ERRCODE_SUCCESS = 0, 35 }ERRCODE_E; 36 37 #endif
// LIB_bytes_buffer_apply.c /** * Copyright © XXXX Technologies Co., Ltd. All Rights Reserved. * @Date 2020年08月01日,下午16:00:00 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "LIB_bytes_buffer.h" static const char *g_match_str[] = { "+SKTRPT=", "+OK", "+ERR", }; extern int give_me_more_data(void); static int XXXX_memcmp(const void *cs, const void *ct, unsigned long count) { const unsigned char *su1, *su2; int res = 0; // XXXX add begin if (NULL == cs && NULL == ct) { return 0; // 相等 } if (NULL == cs || NULL == ct) { return 1; // 不相等 } // XXXX add end for (su1 = (const unsigned char *)cs, su2 = (const unsigned char *)ct; 0 < count; ++su1, ++su2, count--) if ((res = *su1 - *su2) != 0) break; return res; } //static char *XXXX_strstr(const char *s1, int l1, const char *s2, int l2) { if (!l2) return (char *)s1; while (l1 >= l2) { l1--; if (!XXXX_memcmp(s1, s2, l2)) return (char *)s1; s1++; } return NULL; } /********************************************************************************************** 字节缓存区 : 检查是否含有关键字 日期: 2020.08.01 16:00:00 作者: XXXX 参数: p_head, 字节缓存区对象 out_buf, 待检查缓冲区 already_read_len, 已读取长度 返回值: ERRCODE_SUCCESS: 找到了关键字, 并成功放回队列 ERRCODE_FAILED: 未找到关键字 **********************************************************************************************/ static int is_contain_key(IN void *p_head, IN unsigned char *out_buff, IN unsigned int already_read_len) { unsigned char *p_key = NULL; unsigned char *p_key_min = NULL; int jndex = 0; int ret = 0; /* 参数检查 */ if (NULL == p_head || NULL == out_buff || 2 >= already_read_len) // 第一字节是+ { XXXX_print_ln_E("wrong para."); return -1; } for (jndex = 0; jndex < sizeof(g_match_str) / sizeof(char *); jndex++) { p_key = XXXX_strstr(out_buff + 1, already_read_len - 1, g_match_str[jndex], strlen(g_match_str[jndex])); if (NULL != p_key) { XXXX_print_ln_W("###read_next_item=%d:[%x-%x]%s", already_read_len, out_buff, p_key, p_key); p_key_min = (NULL == p_key_min) ? p_key : XXXX_MIN(p_key_min, p_key); } } if (NULL != p_key_min) { unsigned short putback_len = 0; putback_len = out_buff + already_read_len - p_key_min; XXXX_print_ln_W("###read_next_item=%d:[%x-%x][L=%u]%s", already_read_len, out_buff, p_key_min, putback_len, p_key_min); ret = BytesBuffer_add(p_head, p_key_min, putback_len, 0); XXXX_print_ln_W(",h=%x,BYTESBUFFER_putback_ret=%d,putback_size=%u", p_head, ret, putback_len); return ERRCODE_SUCCESS; } return ERRCODE_FAILED; } /********************************************************************************************** 字节缓存区 : 读取一条数据 ***** 注意: 本函数与BytesBuffer_read互斥 *************************** ***** 同一对象要么当纯缓存区使用, 要么当一条一条数据使用 ***************** ***** item 又叫包 ***************** ***** 分为几种: "+OK" ***************** ***** "+ERR" ***************** ***** "+SKTRPT=2,4,180.97.81.180,30281\r\n\r\n" ***************** ***** 只要数据不够, 就在这里阻塞住, 如果是+OK之类的后面不确定会不会有=1, 通过指定超时来返回 日期: 2020.08.01 16:00:00 作者: XXXX 参数: p_head, 字节缓存区对象 out_buf, 字节输出 timeout_ms, 超时时间(ms) 返回值: >=0: 成功读取字节个数 -1: 失败 **********************************************************************************************/ int XXXX_LIB_BYTESBUFFER_read_next_item(IN void *p_head, OUT unsigned char *out_buff, IN unsigned int out_buff_len, IN unsigned int timeout_ms) { #define INTERVAL_TIMEOUT (10) static unsigned char last_char = '\0'; unsigned int already_read_len = 0; unsigned int stream_read_len = 0; int ret = 0; int head_find_state = 0; // 0未找到+, 1找到+, 2找到头, int index = 0; int jndex = 0; int match_str_index = 0; unsigned int len_you_told_me = 0; unsigned int is_read_stream_begin = 0; int is_calc_timeout = 0; int stand_by_count = 0; int is_print_begin = 0; int for_counter = 0; unsigned char burr_each_byte[40] = {'\0'}; /* 参数检查 */ if (NULL == p_head || NULL == out_buff || 0 == out_buff_len) { XXXX_print_ln_E("wrong para."); return -1; } for (for_counter = 0; ; for_counter++) { if (0 == index) { memset((void *)burr_each_byte, 0, sizeof(burr_each_byte)); } if ('+' == last_char) { ret = 1; burr_each_byte[0] = last_char; last_char = '\0'; } else { if (index >= sizeof(burr_each_byte) - 10) { memcpy((void *)burr_each_byte, &burr_each_byte[20], sizeof(burr_each_byte) - 20); memset((void *)(burr_each_byte + sizeof(burr_each_byte) - 20), 0, 20); index -= 20; } ret = BytesBuffer_read(p_head, &burr_each_byte[index], 1); } if (0 > ret) { return -1; } else if (0 == ret) { //XXXX_sleep_ms(INTERVAL_TIMEOUT); give_me_more_data(); stand_by_count++; if (0 < is_calc_timeout) { if (0 != timeout_ms && stand_by_count * INTERVAL_TIMEOUT > timeout_ms) { return already_read_len; } } continue; } stand_by_count = 0; if (1 != ret) { XXXX_print_ln_W("for_ctr=%d,r_ret=%u,h_f_sta=%d,idx=[%d],brr_ech_b=%s", for_counter, ret, head_find_state, index, burr_each_byte); } if (0 == for_counter % 300 ) { XXXX_print_ln_W("for_ctr=%d,r_ret=%u,h_f_sta=%d,idx=[%d],brr_ech_b=%s", for_counter, ret, head_find_state, index, burr_each_byte); } if (0 == for_counter % 100 ) { //XXXX_sleep_ms(10); } if (0 == head_find_state) { if ('+' == burr_each_byte[0]) { head_find_state = 1; index = 1; XXXX_print_ln_W("found +, head_find_state=%d", head_find_state); } else { index = 0; } continue; } else if (1 == head_find_state) { int is_matched = 0; if ('+' == burr_each_byte[index]) { memset((void *)burr_each_byte, 0, sizeof(burr_each_byte)); burr_each_byte[0] = '+'; index = 1; XXXX_print_ln_W("found +, head_find_state=%d", head_find_state); continue; } for (jndex = 0; jndex < sizeof(g_match_str) / sizeof(char *); jndex++) { if (0 == memcmp((void *)burr_each_byte, g_match_str[jndex], strlen(g_match_str[jndex]))) { head_find_state = 2; match_str_index = jndex; already_read_len = index + 1; memcpy((void *)out_buff, burr_each_byte, already_read_len); XXXX_print_ln_W("already_read_len=%u, out_buff=%s", already_read_len, out_buff); index = 0; is_matched = 1; break; } } if (0 == is_matched) { index++; } continue; } else if (2 == head_find_state) { if (out_buff_len > already_read_len) { memcpy((void *)(out_buff + already_read_len), burr_each_byte, ret); // ret 一定为1 already_read_len += ret; } else { XXXX_print_ln_W("read buff reach max, now return, al_r=%u, max=%u", already_read_len, out_buff_len); return already_read_len; } if (0 == already_read_len % 300 ) { XXXX_print_ln_W("already_read_len=%u, out_buff=%s", already_read_len, out_buff); } //XXXX_print_ln_D("already_read_len=%u, out_buff=%s", already_read_len, out_buff); // 查找每一个关键字第一次出现的位置 if (0 == strncmp("+SKTRPT=", g_match_str[match_str_index], strlen(g_match_str[match_str_index]))) { if (0 == is_read_stream_begin) { if (0 == already_read_len % 10) { XXXX_print_ln_W("to find len_u_t_me,out=%s", out_buff); } if ( NULL == strstr((char *)out_buff, "\r\n\r\n")) { continue; } else { sscanf((char *)out_buff, "+SKTRPT=%*[^,],%d,", &len_you_told_me); XXXX_print_ln_W("find len_u_t_me[%u]:%s", len_you_told_me, out_buff); is_read_stream_begin = 1; stream_read_len = 0; if (1024 == len_you_told_me) { is_print_begin = 1; } } } else { if (ERRCODE_SUCCESS == is_contain_key(p_head, out_buff, already_read_len)) { XXXX_print_ln_W(",h=%x,len_u_t_me=%u,contain key,already putback to BYTESBUFFER.", p_head, len_you_told_me); return 0; } stream_read_len++; if (stream_read_len >= len_you_told_me) { XXXX_print_ln_W("stream_read_len=%u,len_u_t_me=%u", stream_read_len, len_you_told_me); return already_read_len; } } } else if (0 == strncmp("+OK", g_match_str[match_str_index], strlen(g_match_str[match_str_index])) || 0 == strncmp("+ERR", g_match_str[match_str_index], strlen(g_match_str[match_str_index]))) { is_calc_timeout = 1; // 可以计时了 if ( burr_each_byte[0] == '+') { last_char = '+'; // 最后一个"+", 删了吧 out_buff[already_read_len - 1] = '\0'; return already_read_len - 1; } else { continue; } } index = 0; continue; } } return -1; }
// LIB_bytes_buffer_apply.h #ifndef __APPLY_H__ #define __APPLY_H__ int XXXX_LIB_BYTESBUFFER_read_next_item(IN void *p_head, OUT unsigned char *out_buff, IN unsigned int out_buff_len, IN unsigned int timeout_ms); #endif /* __APPLY_H__ */
1 // test1.c 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <pthread.h> 6 #include <string.h> 7 #include <sys/types.h> 8 #include <unistd.h> 9 #include "LIB_bytes_buffer.h" 10 11 12 #include <fcntl.h> 13 14 15 unsigned char rand_byte() 16 { 17 // return rand() % 26 + 0x41; 18 return rand() % 0xff; 19 } 20 21 int rand_bytes(unsigned char **p_in_buf, int *p_rand_len) 22 { 23 int index = 0; 24 int rand_len = 0; 25 unsigned char *p = NULL; 26 27 rand_len = rand() % 1024 + 1; 28 p = XXXX_malloc(rand_len + 1); 29 if (NULL == p) 30 { 31 return -1; 32 } 33 34 memset((void *)p, 0, rand_len + 1); 35 36 for (index = 0; index < rand_len; index++) { 37 p[index] = rand_byte(); 38 } 39 40 *p_in_buf = p; 41 *p_rand_len = rand_len; 42 return 0; 43 } 44 45 void *bb = NULL; 46 47 #define char_file (0) 48 49 void *thr_fn(void *arg) 50 { 51 int ret = 0; 52 int rand_len = 0; 53 unsigned char *out_buf = NULL; 54 55 #if char_file 56 FILE * fp_r; 57 fp_r = fopen ("test1_r.txt", "w+"); 58 #else 59 60 int fp_r = open("./test1_r.txt", O_RDWR | O_CREAT | O_TRUNC); 61 XXXX_print_ln_I("fp_r=%d%s", fp_r, "./test1_r.txt"); 62 63 #endif 64 65 for (; ;) 66 { 67 if (NULL == bb) { 68 usleep(1000 * 200); 69 continue; 70 } 71 72 rand_len = rand() % 1024 + 1; 73 out_buf = XXXX_malloc(rand_len + 1); 74 if (NULL == out_buf) 75 { 76 return ((void *)0); 77 } 78 79 memset((void *)out_buf, 0, rand_len + 1); 80 81 ret = BytesBuffer_read(bb, out_buf, rand_len); 82 // XXXX_print_ln_I("\t\tr_ret=%d/%d:%s", ret, rand_len, out_buf); 83 84 #if char_file 85 fprintf(fp_r, "%s", out_buf); 86 #else 87 if (0 < ret) { 88 write(fp_r, out_buf, ret); 89 } 90 #endif 91 XXXX_free(out_buf); 92 93 // usleep(1000 * 50); 94 95 } 96 97 #if char_file 98 fclose(fp_r); 99 #else 100 close(fp_r); 101 #endif 102 103 return ((void *)0); 104 } 105 106 107 int main(int argc, char *argv[]) 108 { 109 int ret = 0; 110 unsigned char *in_buf = NULL; 111 int rand_len = 0; 112 pthread_t ntid; 113 int err = 0; 114 115 bb = BytesBuffer_create(); 116 if (NULL == bb) { 117 XXXX_print_ln_I("BytesBuffer_create Failed."); 118 return -1; 119 } 120 121 err = pthread_create(&ntid, NULL, thr_fn, NULL); 122 if(err != 0){ 123 XXXX_print_ln_I("can't create thread: %s",strerror(err)); 124 } 125 #if char_file 126 FILE * fp_w; 127 fp_w = fopen ("test1_w.txt", "w+"); 128 #else 129 int fp_w = open("./test1_w.txt", O_RDWR | O_CREAT | O_TRUNC); 130 XXXX_print_ln_I("fp_w=%d%s", fp_w, "./test1_w.txt"); 131 #endif 132 133 134 for (; ;) 135 { 136 ret = rand_bytes(&in_buf, &rand_len); 137 if (0 != ret) { 138 return -1; 139 } 140 141 ret = BytesBuffer_append_tail(bb, in_buf, rand_len); 142 143 //XXXX_print_ln_I("w_ret=%d/%d:%s", ret, rand_len, in_buf); 144 #if char_file 145 fprintf(fp_w, "%s", in_buf); 146 #else 147 write(fp_w, in_buf, rand_len); 148 #endif 149 150 // XXXX_free(in_buf); 不要释放 151 152 // XXXX_SINGLELIST_print((const Node_head_t *)bb); 153 154 // usleep(1000 * 50); 155 156 } 157 158 #if char_file 159 fclose(fp_w); 160 #else 161 close(fp_w); 162 #endif 163 164 return 0; 165 }
1 // test2.c 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <pthread.h> 6 #include <string.h> 7 #include <sys/types.h> 8 #include <unistd.h> 9 #include "LIB_bytes_buffer.h" 10 11 12 #include <fcntl.h> 13 14 #include "LIB_bytes_buffer_apply.h" 15 16 17 static void *g_uart_buffer_handler = NULL; 18 static void *g_uart_buffer_handler2 = NULL; 19 20 // return 0成功, -1失败 21 static int XXXX_task_init(void) 22 { 23 24 g_uart_buffer_handler = BytesBuffer_create(); // 创建缓冲区对象 25 XXXX_print_ln_I("BYTESBUFFER_create,h=%x.", g_uart_buffer_handler); 26 if (NULL == g_uart_buffer_handler) 27 { 28 XXXX_print_ln_E("BYTESBUFFER_create Failed."); 29 } 30 31 32 g_uart_buffer_handler2 = BytesBuffer_create(); // 创建缓冲区对象 33 34 return 0; 35 } 36 37 int give_me_more_data(void) 38 { 39 unsigned char buff[1024] = {'\0'}; 40 int ret_read = 0; 41 int ret_append = 0; 42 43 memset((void *)buff, 0, sizeof(buff)); 44 ret_read = BytesBuffer_read(g_uart_buffer_handler2, buff, sizeof(buff) - 1); 45 if (0 >= ret_read) { 46 return ret_read; 47 } 48 XXXX_print_ln_W(",h=%x,BYTESBUFFER_read_ret=%d,expect_read_len=%u", g_uart_buffer_handler2, ret_read, sizeof(buff) - 1); 49 50 ret_append = BytesBuffer_add(g_uart_buffer_handler, buff, ret_read, 1); 51 XXXX_print_ln_W(",h=%x,BYTESBUFFER_append_ret=%d,append_size=%u", g_uart_buffer_handler, ret_append, ret_read); 52 53 return ret_read; 54 } 55 56 int XXXX_task_buffer_append(void *buffer, unsigned short size) 57 { 58 int ret = -1; 59 60 /* 参数检查 */ 61 if (NULL == buffer || 0 == size) 62 { 63 XXXX_print_ln_E("wrong para."); 64 return -1; 65 } 66 67 ret = BytesBuffer_add(g_uart_buffer_handler2, buffer, (unsigned int)size, 1); 68 XXXX_print_ln_W(",h=%x,BYTESBUFFER_append_ret=%d,append_size=%u, buffer=%s", g_uart_buffer_handler2, ret, (unsigned int)size, buffer); 69 70 return ret; 71 } 72 73 int file_w(unsigned char *in_buf, unsigned int len) 74 { 75 static int fp_w = -1; 76 77 if (-1 == fp_w) 78 { 79 fp_w = open("./test2_w.txt", O_RDWR|O_CREAT|O_TRUNC); 80 XXXX_print_ln_I("fp_w=%d%s", fp_w, "./test2_w.txt"); 81 } 82 83 write(fp_w, in_buf, len); 84 85 return 0; 86 } 87 88 int file_r(unsigned char *in_buf, unsigned int len) 89 { 90 static int fp_r = -1; 91 92 if (-1 == fp_r) 93 { 94 fp_r = open("./test2_r.txt", O_RDWR|O_CREAT|O_TRUNC); 95 XXXX_print_ln_I("fp_r=%d%s", fp_r, "./test2_r.txt"); 96 } 97 98 if (0 < len) { 99 write(fp_r, in_buf, len); 100 } 101 102 return 0; 103 } 104 105 106 107 void *thr_fn2(void *arg) 108 109 { 110 int ret_next_item = 0; 111 int ret_parser_each = 0; 112 unsigned char buff[2048] = {'\0'}; 113 114 for ( ; ; ) 115 { 116 //XXXX_sleep_ms(30); 117 118 119 give_me_more_data(); 120 121 memset((void *)buff, 0, sizeof(buff)); 122 ret_next_item = XXXX_LIB_BYTESBUFFER_read_next_item(g_uart_buffer_handler, buff, sizeof(buff), 50); 123 124 if (0 >= ret_next_item) { 125 continue; 126 } 127 128 129 XXXX_print_ln_W("\t\t\t\t\t\trecv[uart0]<####[L=%u]=%s", ret_next_item, buff); 130 ret_parser_each = 0; 131 XXXX_print_ln_W("each_ret=%d:%s", ret_parser_each, buff); 132 133 file_r(buff, ret_next_item); 134 } 135 136 } 137 138 void XXXX_MINORNETHELPER_AT_PARSER_parser(char *buff, int len) 139 { 140 XXXX_task_buffer_append(buff, len); 141 file_w(buff, len); 142 // usleep(1000 * 50); 143 } 144 145 void test0(void) 146 { 147 148 char *buff6 = "+SKTRPT=1,6,1.1.1.1,3333\r\n\r\nqwert+OK+ERR5"; // 长度不够的测试用例 149 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, strlen(buff6)); 150 } 151 152 void test1(void) 153 { 154 char *buff = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE"; 155 156 XXXX_MINORNETHELPER_AT_PARSER_parser(buff, strlen(buff)); 157 } 158 159 void test2(void) 160 { 161 char *buff = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF"; 162 163 XXXX_MINORNETHELPER_AT_PARSER_parser(buff, strlen(buff)); 164 } 165 166 void test3(void) 167 { 168 char *buff = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeAB"; 169 170 XXXX_MINORNETHELPER_AT_PARSER_parser(buff, strlen(buff)); 171 } 172 173 174 175 void test4(void) 176 { 177 char *buff1 = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeAB"; 178 char *buff2 = "liuy"; 179 180 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 181 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 182 } 183 184 void test5(void) 185 { 186 char *buff1 = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeAB"; 187 char *buff2 = "liuy+SKTRPT=1,13,1.1.1.1,3333\r\n\r\nabcdeABCDEFG"; 188 189 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 190 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 191 } 192 193 194 void test6(void) 195 { 196 char *buff1 = "go+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDQ+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeAB"; 197 char *buff2 = "liuy+SKTRPT=1,13,1.1.1.1,3333\r\n\r\nabcdeABCDEFG"; 198 199 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 200 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 201 } 202 203 void test7(void) 204 { 205 char *buff1 = "go+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeAB"; 206 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 207 208 char *buff2 = "liuy+SKTRPT=1,13,1.1.1.1,3333\r\n\r\nabcdeABCDEFG+OK1"; 209 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 210 211 char *buff3 = "+SKTRPT=1,4,1.1.1.1,3333\r\n\r\nqwer+OK2"; 212 XXXX_MINORNETHELPER_AT_PARSER_parser(buff3, strlen(buff3)); 213 214 char *buff4 = "+ERR3+SKTRPT=1,5,1.1.1.1,3333\r\n\r\nqwert+OK4"; 215 XXXX_MINORNETHELPER_AT_PARSER_parser(buff4, strlen(buff4)); 216 217 char *buff5 = "+SKTRPT=1,5,1.1.1.1,3333\r\n\r\nqwert"; 218 XXXX_MINORNETHELPER_AT_PARSER_parser(buff5, strlen(buff5)); 219 220 char *buff6 = "+SKTRPT=1,6,1.1.1.1,3333\r\n\r\nqwerty+OK+ERR5"; 221 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, strlen(buff6)); 222 223 char *buff7 = "+OK6+ERR7"; 224 XXXX_MINORNETHELPER_AT_PARSER_parser(buff7, strlen(buff7)); 225 226 char *buff8 = "+OK8"; 227 XXXX_MINORNETHELPER_AT_PARSER_parser(buff8, strlen(buff8)); 228 } 229 230 void test8(void) 231 { 232 char *buff1 = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,360,1.1.1.1,3333\r\n\r\nabcdeAB"; 233 char *buff2 = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklllll"; 234 char *buff3 = "liuy"; 235 236 char *buff4 = "AAaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklllll"; 237 char *buff5 = "YYYY"; 238 char *buff6 = "BBaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklOVER"; 239 240 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 241 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 242 XXXX_MINORNETHELPER_AT_PARSER_parser(buff3, strlen(buff3)); 243 XXXX_MINORNETHELPER_AT_PARSER_parser(buff4, strlen(buff4)); 244 XXXX_MINORNETHELPER_AT_PARSER_parser(buff5, strlen(buff5)); 245 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, strlen(buff6)); 246 } 247 248 void test9(void) 249 { 250 char *buff1 = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,360,1.1.1.1,3333\r\n\r\nabcdeAB"; 251 char *buff2 = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklllll"; 252 char *buff3 = "liuy"; 253 254 char *buff4 = "AAaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklllll"; 255 char *buff5 = "YYYY"; 256 char *buff6 = "BBaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklOVER+SKTR"; 257 char *buff7 = "PT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE"; 258 259 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 260 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 261 XXXX_MINORNETHELPER_AT_PARSER_parser(buff3, strlen(buff3)); 262 XXXX_MINORNETHELPER_AT_PARSER_parser(buff4, strlen(buff4)); 263 XXXX_MINORNETHELPER_AT_PARSER_parser(buff5, strlen(buff5)); 264 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, strlen(buff6)); 265 XXXX_MINORNETHELPER_AT_PARSER_parser(buff7, strlen(buff7)); 266 } 267 268 void test10(void) 269 { 270 char *buff1 = "+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE+SKTRPT=1,11,1.1.1.1,3333\r\n\r\nabcdeABCDEF+SKTRPT=1,360,1.1.1.1,3333\r\n\r\nabcdeAB"; 271 char *buff2 = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklllll"; 272 char *buff3 = "liuy"; 273 274 char *buff4 = "AAaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklllll"; 275 char *buff5 = "YYYY"; 276 char *buff6 = "BBaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkklOVER+SKTR"; 277 char *buff7 = "PT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDV"; 278 279 XXXX_MINORNETHELPER_AT_PARSER_parser(buff1, strlen(buff1)); 280 XXXX_MINORNETHELPER_AT_PARSER_parser(buff2, strlen(buff2)); 281 XXXX_MINORNETHELPER_AT_PARSER_parser(buff3, strlen(buff3)); 282 XXXX_MINORNETHELPER_AT_PARSER_parser(buff4, strlen(buff4)); 283 XXXX_MINORNETHELPER_AT_PARSER_parser(buff5, strlen(buff5)); 284 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, strlen(buff6)); 285 286 sleep(2); 287 XXXX_MINORNETHELPER_AT_PARSER_parser(buff7, strlen(buff7)); 288 } 289 290 void test11_pressure(void) 291 { 292 char *buff[] = {"+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE", 293 "+OK", 294 "+OK=1", 295 "+OK=22", 296 "+ERR"}; 297 unsigned int count = 0; 298 unsigned int rand_str = 0; 299 300 count = sizeof(buff) / sizeof(char *); 301 302 for (; ; ) { 303 rand_str = rand() % count; 304 XXXX_MINORNETHELPER_AT_PARSER_parser(buff[rand_str], strlen(buff[rand_str])); 305 sleep(1); 306 } 307 308 } 309 310 void test12_pressure_normal(void) 311 { 312 char *buff[] = {"+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCDE", 313 "+OK", 314 "+OK=1", 315 "+OK=22", 316 "+ERR"}; 317 unsigned int count = 0; 318 unsigned int rand_str = 0; 319 unsigned int bf_len = 0; 320 unsigned int already_set_len = 0; 321 unsigned int will_cpy_len = 0; 322 int is_full = 0; 323 int youbiao = 0; 324 int index = 0; 325 char bf[17] = {'\0'}; 326 327 count = sizeof(buff) / sizeof(char *); 328 bf_len = sizeof(bf); 329 already_set_len = 0; 330 331 for (index = 0; ; index++) { // index < 20 332 if (0 == is_full) { 333 rand_str = rand() % count; 334 335 will_cpy_len = XXXX_MIN(bf_len - already_set_len, strlen(buff[rand_str])); 336 memcpy(bf + already_set_len, buff[rand_str], will_cpy_len); 337 youbiao = will_cpy_len; 338 } else { 339 already_set_len = 0; 340 is_full = 0; 341 memset(bf, 0, bf_len); 342 343 if (youbiao >= strlen(buff[rand_str])) { 344 continue; 345 } else { 346 will_cpy_len = XXXX_MIN(bf_len - already_set_len, strlen(buff[rand_str]) - youbiao); 347 memcpy(bf + already_set_len, buff[rand_str] + youbiao, will_cpy_len); 348 youbiao += will_cpy_len; 349 } 350 351 } 352 already_set_len += will_cpy_len; 353 354 if (already_set_len >= bf_len) 355 { 356 XXXX_MINORNETHELPER_AT_PARSER_parser(bf, bf_len); 357 is_full = 1; 358 } 359 360 } 361 } 362 363 void test13_pressure_abnormal(void) 364 { 365 char *buff[] = {"+SKTRPT=1,10,1.1.1.1,3333\r\n\r\nabcdeABCD", // 本条消息字节丢失 366 "+OK", 367 "+OK=1", 368 "+OK=22", 369 "+ERR"}; 370 unsigned int count = 0; 371 unsigned int rand_str = 0; 372 unsigned int bf_len = 0; 373 unsigned int already_set_len = 0; 374 unsigned int will_cpy_len = 0; 375 int is_full = 0; 376 int youbiao = 0; 377 int index = 0; 378 char bf[17] = {'\0'}; 379 380 count = sizeof(buff) / sizeof(char *); 381 bf_len = sizeof(bf); 382 already_set_len = 0; 383 384 srand((unsigned int)time(NULL)); 385 386 for (index = 0; ; index++) { // index < 10 387 if (0 == is_full) { 388 rand_str = rand() % count; 389 390 will_cpy_len = XXXX_MIN(bf_len - already_set_len, strlen(buff[rand_str])); 391 memcpy(bf + already_set_len, buff[rand_str], will_cpy_len); 392 youbiao = will_cpy_len; 393 } else { 394 already_set_len = 0; 395 is_full = 0; 396 memset(bf, 0, bf_len); 397 398 if (youbiao >= strlen(buff[rand_str])) { 399 continue; 400 } else { 401 will_cpy_len = XXXX_MIN(bf_len - already_set_len, strlen(buff[rand_str]) - youbiao); 402 memcpy(bf + already_set_len, buff[rand_str] + youbiao, will_cpy_len); 403 youbiao += will_cpy_len; 404 } 405 406 } 407 already_set_len += will_cpy_len; 408 409 if (already_set_len >= bf_len) 410 { 411 XXXX_MINORNETHELPER_AT_PARSER_parser(bf, bf_len); 412 is_full = 1; 413 } 414 415 } 416 } 417 418 void test14(void) 419 { 420 421 char *buff6 = "+SKTRPT=1,6,1.1.1.1,3333\r\n\r\n\t\r\t\t\tA+OK+ERR5"; // 不可见字符测试 422 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, 42); 423 424 } 425 426 void test15(void) 427 { 428 429 char *buff6 = "+SKTRPT=1,6,1.1.1.1,3333\r\n\r\naaaaabAAAAAAAAA11111111112222222222333333333344444444445555+5555556666666666777777777788888888889999999999000000000011111111112222222222333333333344444444445555+55555566666666667777777777888888888899999999990000000000+OK+ERR5"; // 多出来的数据里有+ 430 XXXX_MINORNETHELPER_AT_PARSER_parser(buff6, strlen(buff6)); 431 432 } 433 434 int main(int argc, char *argv[]) 435 { 436 437 pthread_t ntid; 438 int err = 0; 439 440 XXXX_task_init(); 441 442 err = pthread_create(&ntid, NULL, thr_fn2, NULL); 443 if(err != 0){ 444 XXXX_print_ln_I("can't create thread: %s",strerror(err)); 445 } 446 447 // test1(); 448 test12_pressure_normal(); 449 450 for (; ;) 451 { 452 usleep(1000 * 1000); 453 printf("..."); 454 continue; 455 } 456 457 return 0; 458 }
makefile:
test1: LIB_bytes_buffer.c LIB_bytes_buffer_port.c test1.c rm test1 -f ; gcc $^ -o test1 -Wall -lpthread -g test2: LIB_bytes_buffer.c LIB_bytes_buffer_apply.c LIB_bytes_buffer_port.c test2.c rm test2 -f ; gcc $^ -o test2 -Wall -lpthread -g clean: rm test1 test2 -f