一个数组队列的实现

来源:互联网 发布:淘宝售假被扣24分 编辑:程序博客网 时间:2024/06/06 00:52
#ifndef SPMMSGQUEUE_H
#define SPMMSGQUEUE_H
#include<stdlib.h>
#include<stdio.h>
#include<exception>
#include<iostream>
#include<new>
//template<typename T>
class spmQueue
{
private:
#define BUFLEN 4096     //Initialize Buffer Length
#define MAXLEN 9999999
    char *qBuffer; //[BUFLEN];
    char *pPopBuf; // Popup Temp Buffer
    long m_nCurr;           // Current Vaild Queue Length
    long m_nTotalLen;           // Current Length
public:
    spmQueue()
        :qBuffer( NULL ),
          pPopBuf( NULL )
    {
        m_nCurr = 0;
        try
        {
            qBuffer = new char[BUFLEN];
        }
        catch(const std::bad_alloc& e)
        {
            std::cout<<e.what()<<endl;
            std::cout<<"new exception\n";
        }
        catch(const std::exception& e)
        {
            std::cout<<e.what();
            std::cout<<"other exception\n";
        }
        memset( qBuffer, 0, BUFLEN );
        m_nTotalLen = BUFLEN;
    };
    virtual ~ spmQueue()
    {
        std::cout<<"@SpmQueue Deconstruct!!!"<<std::endl;
        clearPopBuf();
        clearQueueBuf();
        pPopBuf = NULL;
        qBuffer = NULL;
    };
    void clearPopBuf()
    {
        if( pPopBuf != NULL )
            delete pPopBuf;
        pPopBuf = NULL;
    };
    void clearQueueBuf()
    {
        if( qBuffer != NULL )
            delete qBuffer;
        qBuffer = NULL;
        m_nTotalLen = 0;
    };
    void empty()
    {
        if( size() > 0)
            pop_front( size() );
        statusDump();
    };
    bool isEmpty()
    {
        if(this->size() == 0)
            return TRUE;
        return FALSE;
    };
    char operator [](int idx)
    {
        if( idx <= 0 )
            return qBuffer[0];
        return qBuffer[idx - 1];
    };
    char *getElems(int len)
    {
        if( len <= BUFLEN )
        {
            char *pOut = new char[len+1];
            memset( pOut, 0, len+1 );
            memcpy( pOut, qBuffer, len );
            return pOut;
        }
        else
        {
            return NULL;
        }
    };
    ////////////////////////////////////////////////
    //////////// Enter Queue
    void push_back( char *p, int len=0 )
    {
        // pPopBuf = new char[BUFLEN];
        if(len == 0)
        {
            if(p != NULL)
            {
                len = strlen((char *)p);
            }
            else
            {
                return ;
            }
        }
        if( ( len + 1 ) < BUFLEN )
        {
            //memset( pPopBuf, 0, ( len + 1 ) )
            memcpy( &qBuffer[m_nCurr], p, len );
            m_nCurr += len;
        }
        else
        {
            char *pNew = new char[ m_nCurr + len + 1 ];  //// Realloc The Buffer
            memcpy( pNew, qBuffer, m_nCurr );
            m_nTotalLen = m_nCurr + len + 1;
            clearQueueBuf();
            qBuffer = pNew;
            memcpy( &qBuffer[m_nCurr], p, len );
            //memcpy( &qBuffer[m_nCurr], p, ( BUFLEN - len - 1 ) );
            m_nCurr = BUFLEN - 1;
        }
        statusDump();
    };
    void statusDump()
    {
        std::cout<<"@@ StatusDump Buffer Elems:"<<qBuffer<<"  @Len="<<m_nCurr<<std::endl;
    };
    char * pop_front( int nSize = 1 ) //move and reset n units
    {
        //pPopBuf = NULL;
        clearPopBuf();
        if( nSize >= BUFLEN )
        {
            pPopBuf = new char[BUFLEN];
            memcpy( pPopBuf, qBuffer, BUFLEN );
            memset( qBuffer, 0, BUFLEN );
            m_nCurr = 0;
        }
        else
        {
            try
            {
                pPopBuf = new char[ nSize  + 1 ];
            }
            catch(const std::bad_alloc& e)
            {
                std::cout<<e.what()<<endl;
                std::cout<<"new exception\n";
            }
            catch(const std::exception& e)
            {
                std::cout<<e.what();
                std::cout<<"other exception\n";
            }
            memset( pPopBuf, 1, nSize );
            memcpy( pPopBuf, &qBuffer[0], nSize );
            memcpy( &qBuffer[0], &qBuffer[nSize], ( m_nCurr - nSize ) );
            memset( &qBuffer[m_nCurr - nSize], 0, ( BUFLEN - ( m_nCurr - nSize ) ) );
            m_nCurr = m_nCurr - nSize;
        }
        return pPopBuf;
    };
    char * popFront_Until( char cx ) // pop the buffer until meet 'cx'
    {
        int ii;
        for( ii=0; ii < m_nCurr; ++ ii )
        {
            if( qBuffer[ii] == cx )
                break;
        }
        if( qBuffer[ii] == cx )
        {
            //while( m_incomingQue.first() != cAck )
            //   m_incomingQue.pop_front();
            return pop_front( ii );
        }
        else
            return NULL;
    };
    char * getBuffer() //visit the buffer
    {
        return qBuffer;
    };
    int containc(char cx)
    {
        for( int ii = 0; ii < m_nCurr; ++ ii )
        {
            if(qBuffer[ii] == cx )
                return (ii + 1);
        }
        return 0;
    };
    bool contains(char* str)
    {
        if( str != NULL)
            for( int ii = 0; ii < m_nCurr; ++ ii )
            {
                //if(qBuffer[ii] == *str )
                if( strstr( qBuffer, str ) )
                    return TRUE;
            }
        return FALSE;
    };
    long size()
    {
        return m_nCurr; // Current Length
    };
    void testSpmQ()
    {
        spmQueue *q = new spmQueue();
        char *pStr = "ASfiijag9ert0q35t9q3ut9w4yjwo";
        q->push_back( pStr );
        std::cout<<"@ Que Contains iij:"<< q->contains( "iij" ) <<std::endl;
        std::cout<<"@ Que Popout 15 Elems:"<< q->pop_front(15) <<" @RemainStr:" <<std::endl;;
        q->statusDump();
        delete q;
        q = NULL;
    }
};
#endif // SPMMSGQUEUE_H