环形队列FIFO
程序员文章站
2024-03-18 11:09:10
...
#ifndef __PROTOCOLBUFF_H
#define __PROTOCOLBUFF_H
#include "stdint.h"
/* fifo buff for data receive */
class FifoClass
{
private:
/* buff */
unsigned char buffData[1024 * 2 ];
/* valid data start and end piont */
unsigned char *pStart, *pEnd;
/* start and end piont of buff */
unsigned char * pBuffMax, *pBuffMin;
/* overflow flag */
/* true: data buff has overflowed */
bool overflow;
/* get free size of buff */
int getFreeSize();
/* write data to buff */
int writeToBuff(unsigned char *, int);
/* read data from buff */
/* bool: true */
int readFromBuff(unsigned char *, int, bool);
public:
/* data to fifo */
int pushData(unsigned char * data, int len);
int pushData( int data );
/* get data from fifo */
int popData( unsigned char * data, int len);
int popData( int * data);
int pickData( unsigned char *, int );
int available();
/* set fifo clean */
void clean();
void displayData();
unsigned char back();
unsigned char front();
FifoClass(/* args */);
~FifoClass();
};
#endif
#include "fifo.h"
#include "stdio.h"
#include "string.h"
FifoClass::FifoClass(/* args */)
{
pStart = buffData;
pEnd = buffData;
pBuffMax = buffData + sizeof( buffData );
pBuffMin = buffData;
overflow = false;
memset(buffData,0,sizeof(buffData));
}
void FifoClass::clean()
{
pStart = buffData;
pEnd = buffData;
pBuffMax = buffData + sizeof( buffData );
pBuffMin = buffData;
overflow = false;
}
FifoClass::~FifoClass()
{
}
unsigned char FifoClass::back()
{
if( pEnd > buffData )
return *(pEnd - 1 );
else
return *buffData;
}
unsigned char FifoClass::front()
{
return *pStart;
}
int FifoClass::available()
{
if( pEnd >= pStart )
/* when pEnd >= pStart, it means all available data at pStart to pEnd */
{
if( overflow )
/* at overflow, pStart always equal pEnd */
{
return sizeof( buffData );
}
else
{
return pEnd - pStart;
}
}
else
/* when pEnd < pStart, it means all available data are outside pStart to pEnd*/
{
return sizeof( buffData ) - ( pStart - pEnd );
}
}
int FifoClass::getFreeSize()
{
if (overflow)
return 0;
else
{
if( pEnd >= pStart )
{
return sizeof(buffData) - (pEnd - pStart );
}
else
{
return pStart - pEnd;
}
}
}
int FifoClass::writeToBuff(unsigned char *data, int len)
{
if (len >= getFreeSize())
overflow = true;
if (buffData + sizeof(buffData) - pEnd > len)
{
memcpy(pEnd, data, len);
pEnd = pEnd + len;
if (overflow)
pStart = pEnd;
return len;
}
else
{
int remainingLen = buffData + sizeof(buffData) - pEnd;
memcpy(pEnd, data, remainingLen);
pEnd = buffData;
memcpy(pEnd, data + remainingLen, len - remainingLen);
pEnd = buffData + (len - remainingLen);
if (overflow)
pStart = pEnd;
return len;
}
}
int FifoClass::readFromBuff( unsigned char *data, int len, bool iSThrowData )
{
if (available() >= len)
{
if (pBuffMax - pStart >= len)
{
memcpy(data, pStart, len);
if (iSThrowData)
{
pStart += len;
overflow = false;
}
return len;
}
else
{
int remaining = pBuffMax - pStart;
memcpy(data, pStart, remaining);
memcpy(data + remaining, pBuffMin, len - remaining);
if (iSThrowData)
{
pStart = pBuffMin + (len - remaining);
overflow = false;
}
return len;
}
}
else
{
return 0;
}
}
int FifoClass::pushData(unsigned char *data, int len)
{
if (len > getFreeSize())
{
overflow = true;
writeToBuff( data, len);
pStart = pEnd;
}
else
{
writeToBuff(data,len);
}
return len;
}
int FifoClass::pushData( int data )
{
return pushData( (unsigned char *) &data, 4 );
}
int FifoClass::pickData( unsigned char *data, int len)
{
return readFromBuff(data, len, false);
}
int FifoClass::popData(unsigned char *data, int len)
{
return readFromBuff(data,len,true);
}
int FifoClass::popData( int *data )
{
return popData( (unsigned char *) data, 4 );
}
void FifoClass::displayData() {
unsigned char buff[sizeof(buffData)];
memset( buff,0, sizeof(buff));
pickData(buff, available());
printf("Overflow:%d\tAvailable:%d\tData:%s\r\n",overflow ? 1 : 0, available(), buff);
}