#if !defined(_UTILITY_H)
#define _UTILITY_H

#include "PubHeader.h"
#include "StringObject.h"
#include "MemPool.h"

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

#define max(a,b)    (((a) > (b)) ? (a) : (b))
#define min(a,b)    (((a) < (b)) ? (a) : (b))

#ifndef ARRAY_DIM
#define ARRAY_DIM(a) (sizeof(a)/sizeof(*(a)))
#endif

#define MAKEDWORD(h,l)      ((LONG)(((WORD)(l)) | ((DWORD)((WORD)(h))) << 16))
#define LO_WORD(l)           ((WORD)(l))
#define HI_WORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))

#define NO_WDATA    0xFFFF
#define NO_DWDATA   0xFFFFFFFF


/////////////////////////////////////////////////////////
// lookup tables for translating names into values
struct LookupTableEnt
{
    DWORD   value;
    char*   name;
};

#ifdef _DLL_PROJECT
class CLASS_EXPORT Utility
#else
class Utility
#endif
{
public:
	static char* getname_(struct LookupTableEnt *table, DWORD val, char* lpdefaultname=NULL);
	// SAMPLE: table end with NULL
	// struct LookupTableEnt Tbl_LinkStates[] = 
	// {	// link state names 
	//		{ 0, "INACTIVE"		},
	//		{ 0,  NULL }	 /* NULL end of table */
	// };
	static char* getname_(struct LookupTableEnt *table, int tabsize, DWORD val, char* lpdefaultname=NULL);

	// string parser
	static void  parser_(char* lpstr,char separater,StringArray& szArray, bool bRemoveAllFirst=true);
    static void  parser_(char* lpstr,int len, char separater,StringArray& szArray, bool bRemoveAllFirst=true);
        
	////////////////////////////////////////////////////////////////////
	static int   tokenize( char *buf, char *tokens[], int max_tokens, bool toUpper=true);

	// Takes input line and creates an array of pointers to individual tokens in the input line.  
	// First separator after each token in input line is replaced with a null so that each token becomes
	// a null terminated string.
	// USAGE: 
	//			char *tokens[MAX_PARMS +1];
	//			int   cnt;
	//
	//			//input line received, break it into individual tokens; note that tokenize() shifts all alphas to uppercase
    //		    cnt = tokenize( buffer, tokens ,MAX_PARMS, TRUE );
	//			if( cnt > 0 )
	//	        {
	//				if( (strcmp( tokens[0], "QUIT" ) == 0) || (strcmp( tokens[0], "Q" ) == 0) )
	//                   exit(0);
	//			}	

    static void argFormat(char* buf,const char* pszFormat, va_list arglist);

    static long difftime_(time_t& end_t,time_t& begin_t);

    static int  HexToAscii(unsigned char* buf, int buflen,char *Dbuf,int Dbuflen,long AddSpacePerChars=10);  //  Convert Hex to AsciiText; for example: 0xab->"AB" 
    static int  AsciiToHex(char* buf, int buflen,unsigned char *Dbuf,int Dbuflen);  //  Convert AsciiText to Hex; for example: "AB"->0xab 
    
    static int  BCD_TO_STR(unsigned char* BCDbuf,int BCDLen,char* Dbuf,bool IsPositive=true);
    static int  STR_TO_BCD(char* Sbuf,unsigned char* BCDbuf,bool IsPositive=true);
    static void ReverseBCD(unsigned char* SBCDbuf,int BCDLen,unsigned char* DBCDbuf);
    static bool BCD_Equal (unsigned char BCDStrALen,unsigned char* BCDStrA,
                           unsigned char BCDStrBLen,unsigned char* BCDStrB,
                           bool IsPositive=true);

    ///////////////////////////////////////////////////////////////////
    static bool DumpInfo(char* filename,bool bOverWrite,const char* pszFormat, ...);
    static bool SaveToFile  (char* szFilename,char*  pData, long nDataLen); 
    static bool LoadFromFile(char* szFilename,OTSTR& strContent);
        
    static bool str_equal(char* str1, char* str2, int length, bool bcase=true);
        
    ///////////////////////////////////////////////////////////////////
    static DWORD bitsmask[33];

    // 从数据中取指定位置的Bits   
    // High ->  Low         Low  ->  High
    // bitN ... bit0        bit0 ... bitN
    static bool getBits(BYTE  data, bool bHighToLow, int FirstBitLocat, unsigned int BitLen, DWORD& val); 
    static bool getBits(WORD  data, bool bHighToLow, int FirstBitLocat, unsigned int BitLen, DWORD& val); 
    static bool getBits(DWORD data, bool bHighToLow, int FirstBitLocat, unsigned int BitLen, DWORD& val); 

    static void BitsValueToSTR(DWORD val, unsigned int BitLen, OTSTR& strRet); 
    
    ///////////////////////////////////////////////////////////////////
    friend bool IsVisibleCharactor (char ch);    // 32<ch<127 
    friend bool IsVisibleCharactor_(char ch);    // all charactor except 0<=ch<=32
    friend bool IsDigit(char ch);

    ///////////////////////////////////////////////////////////////////
    static void GetCurDate(unsigned long& nYear, unsigned long& nMonth, unsigned long& nDay);

    ///////////////////////////////////////////////////////////////////
    static OTSTR GetAbsoluteFilename(char* szFullFilename); // 去除../
};


///////////////////////////////////////////////////
//#define DIGIT_XING				0x0E
//#define DIGIT_JING              0x0F

unsigned char ToChar(unsigned char Hch,unsigned char Lch,int *Err);
unsigned char To_Num(unsigned char ch);

///////////////////////////////////////////////////
///////////////////////////////////////////////////
#ifdef _DLL_PROJECT
class CLASS_EXPORT BufferFile
#else
class BufferFile
#endif
{
protected:
    OTSTR m_strAbsoluteFilename;
    OTSTR m_strFullFilename;
    OTSTR m_strFilename;
    OTSTR m_strFilepath;

    char* m_pbuf;
    long  m_bufLen;
    
    OTSTR m_strLastError;
    
public:
    BufferFile();
   ~BufferFile();
    
    bool   Open(char* szfilename,bool bAsTextFile=true);
    char*  getAbsoluteFilename() { return m_strAbsoluteFilename.GetBuffer(); }
    char*  getFilename() { return m_strFilename.GetBuffer(); }
    char*  getFilepath() { return m_strFilepath.GetBuffer(); }
    char*  getBuffer() { return m_pbuf;   }
    long   getBufLen() { return m_bufLen; }

    OTSTR& GetLastError() { return m_strLastError; }
};


///////////////////////////////////////////////////
///////////////////////////////////////////////////

#endif 
