欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

环形队列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);
}