当数据缓存区已经满了,但是数据还在不停的接收,怎么办? 溢出了,通常两种方法来处理而非解决,要么覆盖旧数据,要么丢掉新数据,本文决定使用丢掉新数据的模式(可怜)。
Given these features leads us to our first listing. Again, the 1st listing (Listing 1) is the main ring buffer header file. This file defines all the interfaces and attributes required for our very simple ring buffer implementation.
首先就是头文件中的接口与属性的定义,后面的程序部分就不翻译了。
Listing 1. The interfaces and attributes for a simple ring buffer object.
#ifndef __RINGBUFS_H
#define __RINGBUFS_H
#define RBUF_SIZE 256
typedef struct ringBufS
{
unsigned char buf[RBUF_SIZE];
int head;
int tail;
int count;
} ringBufS;
#ifdef __cplusplus
extern "C" {
#endif
void ringBufS_init (ringBufS *_this);
int ringBufS_empty (ringBufS *_this);
int ringBufS_full (ringBufS *_this);
int ringBufS_get (ringBufS *_this);
void ringBufS_put (ringBufS *_this, const unsigned char c);
void ringBufS_flush (ringBufS *_this, const int clearBuffer);
#ifdef __cplusplus
}
#endif
#endif
The simple ring buffer record
buf[]缓存区
This is the managed buffer. The size of this buffer is set by the RBUF_SIZE macro. In our case, we are managing a 256 byte buffer of unsigned characters.
head头指示
This is the head index. The incoming bytes get written to the managed buffer using this index. The arithmetic for this index is in modulo-256. This is because the RBUF_SIZE macro is defined as 256. Of course, if we defined a different value for the buffer size then the modulus arithmetic will change accordingly.tail尾指示
This index is used to retrieve the oldest data in the queue. This index also follows the same modulus arithmetic as in the HEAD index case.count已记录字节个数
This field is used to keep track of the total number of elements currently in the queue. The maximum value of this field is set by the RBUF_SIZE macro.
The simple ring buffer methods实现函数
There are six(6) methods for the simple unsigned character ring buffer. A brief description of these methods is shown in Table 1.
ringBufS_init
#include
#include "ringBufS.h"
void ringBufS_init (ringBufS *_this)
{
/*****
The following clears:
-> buf
-> head
-> tail
-> count
and sets head = tail
***/
memset (_this, 0, sizeof (*_this));
}
ringBufS_empty
#include "ringBufS.h"
int ringBufS_empty (ringBufS *_this)
{
return (0==_this->count);
}
ringBufS_full
.
#include "ringBufS.h"
int ringBufS_full (ringBufS *_this)
{
return (_this->count>=RBUF_SIZE);
}
ringBufS_get
modulo_inc()
method here. This method encapsulates the modulus arithmetic required for updating the buffer indices.
#include "modulo.h"
#include "ringBufS.h"
int ringBufS_get (ringBufS *_this)
{
int c;
if (_this->count>0)
{
c = _this->buf[_this->tail];
_this->tail = modulo_inc (_this->tail, RBUF_SIZE);
--_this->count;
}
else
{
c = -1;
}
return (c);
}
ringBufS_put
#include "modulo.h"
#include "ringBufS.h"
void ringBufS_put (ringBufS *_this, const unsigned char c)
{
if (_this->count < RBUF_SIZE)
{
_this->buf[_this->head] = c;
_this->head = modulo_inc (_this->head, RBUF_SIZE);
++_this->count;
}
}
ringBufS_flush
#include
#include "ringBufS.h"
void ringBufS_flush (ringBufS *_this, const int clearBuffer)
{
_this->count = 0;
_this->head = 0;
_this->tail = 0;
if (clearBuffer)
{
memset (_this->buf, 0, sizeof (_this->buf));
}
}
#include "modulo.h"
/****************************************************************************/
/* CODE STARTS HERE */
/****************************************************************************/
unsigned int modulo_inc (const unsigned int value, const unsigned int modulus)
{
unsigned int my_value = value + 1;
if (my_value >= modulus)
{
my_value = 0;
}
return (my_value);
}
unsigned int modulo_dec (const unsigned int value, const unsigned int modulus)
{
unsigned int my_value = (0==value) ? (modulus - 1) : (value - 1);
return (my_value);
}