#ifndef __VS_RING_BUF_H__
#define __VS_RING_BUF_H__

#include <string>

#include "ssi.h"                //include the SSI public head file
#include "modules.h"
#include "slog.h"               //include the slog head file

#ifdef LINUX
#include <sys/types.h>
#include "table_structs.h"
#endif

typedef S32 NT_ERROR;
#define NT_OK                           WS_OK
#define NT_ERROR_CODE                   0X0000A000
#define NT_DEV_ADD_FAIL                 NT_ERROR_CODE+1    
#define NT_DEV_RMV_FAIL                 NT_ERROR_CODE+2
#define NT_DEV_MOD_FAIL                 NT_ERROR_CODE+3
#define NT_DEV_ADD_OK                   NT_ERROR_CODE+4
#define NT_DEV_RMV_OK                   NT_ERROR_CODE+5
#define NT_DEV_MOD_OK                   NT_ERROR_CODE+6
#define NT_INV_DEV_DES                  NT_ERROR_CODE+7                
#define NT_INV_OPTION                   NT_ERROR_CODE+8
#define NT_RE_INIT                      NT_ERROR_CODE+9
#define NT_TSK_CRE_FAIL                 NT_ERROR_CODE+10
#define NT_EPOLL_CRE_FAIL               NT_ERROR_CODE+11
#define NT_EPOLL_UNSUPPORT              NT_ERROR_CODE+12
#define NT_MEM_ALLOC                    NT_ERROR_CODE+13
#define NT_TMR_CRE                      NT_ERROR_CODE+14
#define NT_TMR_START                    NT_ERROR_CODE+15
#define NT_INV_ARG                      NT_ERROR_CODE+16
#define NT_NO_FREE_DEV_SLOT             NT_ERROR_CODE+17
#define NT_CRE_SOCK_FAIL                NT_ERROR_CODE+18
#define NT_DEV_NOT_EXSIT                NT_ERROR_CODE+19
#define NT_TASK_CREATE                  NT_ERROR_CODE+20
#define NT_SEM_CREATE                   NT_ERROR_CODE+21
#define NT_SEM_TAKE                     NT_ERROR_CODE+22
#define NT_FATAL_RB_CELL                NT_ERROR_CODE+23
#define NT_RB_EMPTY                     NT_ERROR_CODE+24
#define NT_UN_INIT                      NT_ERROR_CODE+25
#define NT_CONDT_CREATE                 NT_ERROR_CODE+26
#define NT_RB_EPT_READ                  NT_ERROR_CODE+27
#define NT_RB_RMV_NOTICED               NT_ERROR_CODE+28
#define NT_COND_SEM_GIVE                NT_ERROR_CODE+29
#define NT_SOCKET_CRE                   NT_ERROR_CODE+30
#define NT_SOCKET_SENDTO                NT_ERROR_CODE+31
//event define

#define WS_VS_NT_EVT_BASE             0xabcd
#define WS_EVT_TASK_HB_TIMEOUT          WS_VS_NT_EVT_BASE
#define WS_EVT_TASK_HB                  WS_VS_NT_EVT_BASE+1
#define WS_EVT_DEV_ADD		            WS_VS_NT_EVT_BASE+2
#define WS_EVT_DEV_ADD_RES	            WS_VS_NT_EVT_BASE+3
#define WS_EVT_DEV_RMV			        WS_VS_NT_EVT_BASE+4
#define WS_EVT_DEV_RMV_RES		        WS_VS_NT_EVT_BASE+5
#define WS_EVT_DEV_DATA_AVA		        WS_VS_NT_EVT_BASE+6
#define WS_EVT_DEV_HB			        WS_VS_NT_EVT_BASE+7
#define WS_EVT_DEV_ALARM			    WS_VS_NT_EVT_BASE+8
#define WS_EVT_ALARM_DEV_HB_LOST	    WS_VS_NT_EVT_BASE+9

#define NT_RB_CELL_MAGIC        0xABADCAFE

typedef struct ntRingBufferCell
{
	U32 iMagic;    // the magic number, always equal to NT_RB_CELL_MAGIC
	                // the iMagic should be reset to 0 once the cell is 
	                // pop out from the ring buffer
	U32 iLength;    // the length of current cell

	void *pNext;    // points to the next cell head    
}stRingBufferCell;


class CRingBuffer  
{
    public:
        U32 m_InitState;  // initialization state
        U32 m_nModule;
   	protected:
		S8 *m_pBuf;     // ring buffer head
        S8 *m_pBufEnd;  // ring buffer end, m_pBufEnd=m_pBuf+m_nBufSize
		U32 m_nBufSize; // the size of the ring buffer 
        S8 *m_pRead;    // the read pointer
        S8 *m_pWrite;   // the write pointer
        stRingBufferCell *m_pPreCell;   // the previous newly wrote cell pointer
        U32 m_bRBFull;  // TRUE or FALSE, edited by data write function
        U32 m_bRBEagerEMSAlarmFlag; // TURE or FALSE,indicating whether i have 
                                    // already raised an RB Eager alarm
        U32 m_bRBEmpty; // TRUE or FALSE, edited by data read function
        WS_MUTEX_ID m_OprLock;      // the operation mutex lock
        
        //debug info members
        U32 uRBWrFailbyFull;        // the number of write bin fail caused by 
                                    // ring buffer full
        U32 uRmvNoticeTag;          // whether i am notiece to be removed myself
        WS_CONDSEM_ID    m_cellNum;      // The counting semaphore to synch the read/
                                    // write of ring buffer
        U32 m_uBadCell;             // the total number of bad cell has been red
        U32 m_uEmptyRead;
        U32 m_uInitOpErr;           // try to r/w when system still uninit
        static S32 rbFlushCBF(void *pUserInfo, S32 nUsrInfoLen);
        U32 GetMaxWriteSize();
        U32 GetMaxReadSize();
        S8* AdjustWritePtr( U32 iChunkSize );
        

    public:
		S8 szDevId[VS_DEV_ID_LEN];

		CRingBuffer();
		virtual ~CRingBuffer();
		
		NT_ERROR Create( U32 iOption, U32 iTTLSec, U32 iSize, U32 nModuleId );
		NT_ERROR rmvNotice( void );
		void Destroy();
		U32 GetRBFilledSize();
		U32 GetRBLeftSize();
		S8 * WriteBinary( S8 * pBuf, U32 uBufLen, U32 *uWrittenLen );
        NT_ERROR GetCellInfo( S8 ** pBuf,U32* nBufLen );
		BOOL PeekChar( U32 iPos, S8 *ch );
		BOOL FindChar( S8 chLookFor, S32 & riPos );

		BOOL ReadTextLine( S8 *strLine );
		void show(void);
        void TestRBDestroy( void );    
		void RemoveAll(void);
};

#endif
