ring-buffer(C 语言实现)
来源:互联网 发布:索尼z3c安全软件 编辑:程序博客网 时间:2024/06/14 19:57
下面是一个 ring-buffer 的 C 语言实现,采用 Mirroring 方式实现空、满判断。通过 void 指针模拟泛型,可以在初始化时灵活定义 ring-buffer 中的元素类型(例如 char 类型,int 类型,数组类型,结构体类型等)。
首先给出头文件定义:
/** * File: ring_buf.h * * Description: * Header file for ring-buffer. * Implemented according to the 'Mirroring' solution: * http://en.wikipedia.org/wiki/Circular_buffer#Mirroring * * Change Logs: * Date Author Notes * 2013-12-16 Glen first implementation */#ifndef _RING_BUF_H_#define _RING_BUF_H_#include <stdint.h>#include <stdbool.h>#include <stddef.h>#define IDX_MASK (SIZE_MAX>>1)#define MSB_MASK (~IDX_MASK) /* also the maximum value of the buffer depth *//* ring buffer structure */struct ring_buf{ size_t depth ; /* maximum element number */ size_t width ; /* sizeof each element */ size_t rd_idx; /* MSB is used for the 'mirror' flag */ size_t wr_idx; /* MSB is used for the 'mirror' flag */ void *buf ;};typedef struct ring_buf ring_buf_t;typedef struct ring_buf* ring_buf_p;bool ring_buf_init (ring_buf_p rbuf, size_t depth, size_t width);void ring_buf_free (ring_buf_p rbuf);void ring_buf_clear(ring_buf_p rbuf);bool ring_buf_full (ring_buf_p rbuf);bool ring_buf_empty(ring_buf_p rbuf);bool ring_buf_write(ring_buf_p rbuf, void *wr_data);bool ring_buf_read (ring_buf_p rbuf, void *rd_data);#endif
下面是对应的 C 文件:
/** * File: ring_buf.c * * Description: * Ring-buffer implemented according to the 'Mirroring' solution: * http://en.wikipedia.org/wiki/Circular_buffer#Mirroring * * Change Logs: * Date Author Notes * 2013-12-16 Glen first implementation */#include "ring_buf.h"#include <stdlib.h>#include <string.h>#include <assert.h>/** * @brief Initialize the ring-buffer. Allocate necessary memory for the buffer. * * @param rbuf : Pointer to the ring-buffer object * @param depth: Maximum element number of the buffer * @param width: sizeof each element * * @return true : Succeeded * false: Failed */bool ring_buf_init(ring_buf_p rbuf, size_t depth, size_t width){ assert(depth > 0 && depth < MSB_MASK && width > 0); rbuf->depth = depth; rbuf->width = width; rbuf->rd_idx = 0; rbuf->wr_idx = 0; rbuf->buf = calloc(depth, width); return rbuf->buf != NULL;}/** * @brief Release the ring-buffer object. Deallocate the buffer memory. * * @param rbuf: Pointer to the ring-buffer object */void ring_buf_free(ring_buf_p rbuf){ free(rbuf->buf); rbuf->buf = NULL;}/** * @brief Clear the ring-buffer object. * * @param rbuf: Pointer to the ring-buffer object */void ring_buf_clear(ring_buf_p rbuf){ rbuf->rd_idx = 0; rbuf->wr_idx = 0;}/** * @brief Whether the ring-buffer is empty or not. * * @param rbuf: Pointer to the ring-buffer * * @return true : Empty. There's no elements stored in the buffer. * false: Not empty */bool ring_buf_is_empty(ring_buf_p rbuf){ return rbuf->rd_idx == rbuf->wr_idx;}/** * @brief Whether the ring-buffer is full or not. * * @param rbuf: Pointer to the ring-buffer * * @return true : Full * false: Not full */bool ring_buf_is_full(ring_buf_p rbuf){ return (rbuf->rd_idx & IDX_MASK) == (rbuf->wr_idx & IDX_MASK) && (rbuf->rd_idx & MSB_MASK) != (rbuf->wr_idx & MSB_MASK);}/** * @brief Increase the buffer index while writing or reading the ring-buffer. * This is implemented according to the 'mirroring' solution: * http://en.wikipedia.org/wiki/Circular_buffer#Mirroring * * @param rbuf : Pointer to the ring-buffer * @param p_idx: Pointer to the buffer index to be increased */inline void ring_buf_incr(ring_buf_p rbuf, size_t *p_idx){ size_t idx = *p_idx & IDX_MASK; size_t msb = *p_idx & MSB_MASK; if (++idx == rbuf->depth) { msb ^= MSB_MASK; idx = 0; } *p_idx = msb | idx;}/** * @brief Write new element to the ring-buffer. * * @param rbuf : Pointer to the ring-buffer object * @param wr_data: Pointer of the new element to be written to the buffer * * @return true : Succeeded * false: Failed */bool ring_buf_write(ring_buf_p rbuf, void *wr_data){ if (ring_buf_is_full(rbuf)) return false; else { memcpy(rbuf->buf + rbuf->wr_idx * rbuf->width, wr_data, rbuf->width); ring_buf_incr(rbuf, &rbuf->wr_idx); return true; }}/** * @brief Read from the ring-buffer * * @param rbuf : Pointer to the ring-buffer object * @param rd_data: Pointer to the read result * * @return true : Succeeded * false: Failed */bool ring_buf_read(ring_buf_p rbuf, void *rd_data){ if (ring_buf_is_empty(rbuf)) return false; else {memcpy(rd_data, rbuf->buf + rbuf->rd_idx * rbuf->width, rbuf->width); ring_buf_incr(rbuf, &rbuf->rd_idx); return true; }}
最后给出一个简单的应用示例,将字符数组写入 ring-buffer,然后读出、显示:
int main(){ ring_buf_t rbuf; char str[10]; ring_buf_init(&rbuf, 8, sizeof(str)); ring_buf_write(&rbuf, "str 0"); ring_buf_write(&rbuf, "str 1"); ring_buf_write(&rbuf, "str 2"); ring_buf_write(&rbuf, "str 3"); int k = 0; for (k = 0; k < 8; k++) if (ring_buf_read(&rbuf, str)) printf("%s\n", str); ring_buf_free(&rbuf); return 0;}
0 0
- ring-buffer(C 语言实现)
- c印记(八): ring buffer实现
- Ring buffer basics 环形缓冲基础(C语言实现) 二
- Ring Buffer 实现原理
- Ring Buffer 实现原理
- (转载)环形缓冲区的实现原理(ring buffer)
- (转载)环形缓冲区的实现原理(ring buffer) .
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- 环形缓冲区的实现原理(ring buffer)
- A Macro Defined Ring Buffer(C Language)
- Ring Buffer
- Ring Buffer实现 -- 可以参考其思想
- 用dpkg命令制作deb包方法总结
- Android基于XMPP Smack Openfire开发IM(3)建立好友列表
- LeetCode(19) Remove Nth Node From End of List
- go语言string遍历细节
- Android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )
- ring-buffer(C 语言实现)
- Qt Creator快捷键
- FW-binary - tree - with id and sibling connected - java version 2013年12月18日1:21
- java.lang.OutOfMemoryError:PermGen space的一种解决办法
- VisualNet某广电机房管理介绍
- ANT命令总结
- FLEX画面练习
- 组内分享
- 浏览器兼容