#if !defined(__DQFIXED__)
#define __DQFIXED__

#ifndef NULL_CLASS_DEFINED
#define NULL_CLASS_DEFINED
class CNullClass {};
#endif

template <class TYPE, int nMAX, class BaseClass>
class TDeQueueFixed : public BaseClass
{
protected:
    int m_nStart, m_nEnd;
    TYPE m_a[nMAX];
public:
    TDeQueueFixed()
    {
        m_nStart = m_nEnd = 0;
    }
    ~TDeQueueFixed()
    {
    }
    static int GetMax() { return nMAX; }
    int GetDataSize() const
    {
        return m_nEnd - m_nStart;
    }
    int GetFreeSize() const
    {
        return nMAX - (m_nEnd - m_nStart);
    }
    int GetFreeSizeEnd() const
    {
        return nMAX - m_nEnd;
    }
    TYPE* Prepare(int nSize)
    {
        if (GetFreeSize() >= nSize) {
            if (nMAX - m_nEnd < nSize) {
                memcpy(&m_a[0], &m_a[m_nStart], (m_nEnd - m_nStart) * sizeof(TYPE));
                m_nEnd -= m_nStart;
                m_nStart = 0;
            }
            int nEnd = m_nEnd;
            m_nEnd += nSize;

            return &m_a[nEnd];
        } else {
            return NULL;
		}
    }
    int GetBegin(TYPE*& pbBegin) const
    {
        pbBegin = (TYPE*)&m_a[m_nStart];

        return m_nEnd - m_nStart;
    }
    void CheckEmpty()
    {
        if (m_nStart >= m_nEnd) {
            m_nStart = m_nEnd = 0;
        }
    }
    void RemoveBegin(int nSize)
    {
        m_nStart += nSize;
        CheckEmpty();
    }
    void RemoveEnd(int nSize)
    {
        m_nEnd -= nSize;
        CheckEmpty();
    }
    BOOL AddData(const TYPE* pData, int nSize)
    {
        TYPE* pDest = Prepare(nSize);
        if (pDest) {
            memcpy(pDest, pData, nSize * sizeof(TYPE));
        }

        return pDest;
    }
    void FreeAll()
    {
        m_nStart = m_nEnd = 0;
    }
};

#endif // !defined(__DQFIXED__)
