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

 

posted @ 2020-08-01 21:35  LiuYanYGZ  阅读(883)  评论(0编辑  收藏  举报