#if !defined(_MSGUTILITY1_H_)
#define _MSGUTILITY1_H_

#include <stdio.h>
#include <stdlib.h>

#include "PubHeader.h"

#include "Utility.h"
#include "otstr.h"
#include "DateTime.h"


///////////////////////////////////////////////////////////
#ifdef _DLL_PROJECT
class CLASS_EXPORT MSG_SEND
#else
class MSG_SEND
#endif
{
protected:
    bool		   m_bValid;
    long	       m_CurLocat;
    
    unsigned char* m_buf;
    long 		   m_buflen;

private:
    bool           m_bNeed_Free_buf;
    
    ////////////////////////////////////////
public:
    MSG_SEND(long len=0);
    virtual ~MSG_SEND();
    
    bool Attach(unsigned char* pbuf,long buf_len);
 
    bool isValid();	

    unsigned char* get_buf();
    long get_len();

    //////////////////////////////////////////////////////   
    bool Reset();

    //////////////////////////////////
    // BASE FUNCTION
    bool Add_UINT1(UINT1 value);
    bool Add_UINT2(UINT2 value,bool breverse=false);
    bool Add_UINT4(UINT4 value,bool breverse=false);

    bool Add_INT1(INT1 value);
    bool Add_INT2(INT2 value,bool breverse=false);
    bool Add_INT4(INT4 value,bool breverse=false);

    bool Add_BYTES(UINT1* buf, long len);

    bool Add_STRING_AS_BCD(char* lpstr, bool bBeginWithLen, bool IsPositive=true);
                    // ADD  STRING_LEN (bBeginWithLen)
                    // ADD  BCD_DATA... 
    
    //////////////////////////////////
    // EXTEND FUNCTION

    bool Add_STRING(const char* lpstr, bool bCutSupport, bool bEndWithZero); // bCutSupport, cut when strlen>0xF0
                    // ADD  LEN         (BYTE) Not include '\0'
                    // ADD  STRING...
                    // ADD  '\0'        set when bEndWithZero=true

    bool Add_DOUBLE(double value, int precision); // precision 1-9
                    // ADD  VALUE's STRING_LEN
                    // ADD  BCD_DATA...  ( '.' -> 0x0E )

    bool Add_DATETIME(uDateTime_& DateTime,bool breverse=false);
    
private:
    int DOUBLE_STR_TO_BCD(char* Sbuf,unsigned char* BCDbuf);
    unsigned char DOUBLE_TO_NUM(unsigned char ch);
};

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
#ifdef _DLL_PROJECT
class CLASS_EXPORT BinStream 
#else
class BinStream
#endif
{
protected:
    unsigned char*  m_buf;
    long   		    m_buflen;          

    long            m_Valid_Datalen;  // 用于定义有效消息的边界，便于解析，例如可用于对消息尾0xEF的排除 
                                      // 缺省状态下，m_Valid_Datalen=m_buflen
    
    long			m_curLocat;
    
public:
    BinStream();
   ~BinStream();
    
    void Attach(unsigned char* pbuf,long buflen);
    
    bool setValidDatalen(long len);

    bool isAtEnd();

    /////////////////////////////////////
    bool setLocat(long Locat);   
    long getLocat();
    long getTotalLength();
    
    bool Get_UINT1(UINT1& value, bool bJustPreview=false);
    bool Get_UINT2(UINT2& value, bool breverse, bool bJustPreview=false);
    bool Get_UINT4(UINT4& value, bool breverse, bool bJustPreview=false);
    
    bool Get_INT1 (INT1&  value, bool bJustPreview=false);
    bool Get_INT2 (INT2&  value, bool breverse, bool bJustPreview=false);
    bool Get_INT4 (INT4&  value, bool breverse, bool bJustPreview=false);

    bool Get_BYTES(unsigned char** pbuf,long len, bool bJustPreview=false);     // No mem copy, just give the pointer of bytes
    bool Get_BYTES(OTSTR& str,long len, bool bJustPreview=false);                     

    bool Get_BCD_AS_STRING(OTSTR& str,int BCDLen,bool IsPositive, bool bJustPreview=false); 
                    // Format:  BCDLen<=0   len + BCDstr ( beginWithLen )
                    //          BCDLen>=1   BCDstr
    
    //////////////////////////////////
    bool Get_STRING(OTSTR& str,bool bEndWithZero, bool bJustPreview=false);
                                                              // Format: strLen + string ['\0']  
                                                              //         strLen - the len of the string
                                                              //         bEndWithZero - Whether the String End with '\0'
    bool Get_DOUBLE(double& value, bool bJustPreview=false);  // Format: VALUE's STRING_LEN + VALUE's BCD_DATA...  ( '.' -> 0x0E )

    bool Get_DATETIME(uDateTime_& DateTime,bool breverse=false);

private:
    static int  DOUBLE_BCD_TO_STR(unsigned char* BCDbuf,int BCDLen,char* Dbuf);
};


#endif 
