// rdb4cls.h 辅助工具类 For vc6,vc7,vc8,vc9,vc10 X86/X64
#ifndef I_RDB4CLS_H_
#define I_RDB4CLS_H_

#include "rdb4api.h"
//////////////////////////////////////////////////////////////////////////
#include <time.h>
class CRdbTime //包装的实时数据库时间类
{
	//construct
public: 
	CRdbTime() //默认构造为当前时间
	{
		SYSTEMTIME syst;
		::GetLocalTime(&syst);
		tordbtime(syst.wYear,syst.wMonth,syst.wDay,syst.wHour, syst.wMinute,syst.wSecond,syst.wMilliseconds);
	};
	CRdbTime(int nyear,int nmon,int nday,int nhour,int nmin,int nsec,int nmsec = 0)//本地时间的年，月，时，分，秒，毫秒构造
	{
		tordbtime(nyear, nmon, nday, nhour, nmin, nsec, nmsec);
	};
	CRdbTime(T_TIME gmt) // T_TIME 构造
	{
		*this = gmt;
	};
	~CRdbTime(){};

	// operations
public:
	CRdbTime& operator=( T_TIME gmt) //重载=符号
	{
		ToLocalTime(gmt);
		return *this;
	};
	CRdbTime& operator=( CRdbTime &ct) //重载=符号
	{
		*this = ct.GetTime();
		return *this;
	};
	CRdbTime& operator +=( T_TIME dgmt) //重载 += 符号
	{
		*this = m_t + dgmt;
		return *this;
	};
	CRdbTime& operator -=( T_TIME dgmt) //重载 -= 符号
	{
		*this = m_t - dgmt;
		return *this;
	};
	bool operator<( CRdbTime& t ) const {return m_t < t.GetTime();};
	bool operator>( CRdbTime& t ) const {return m_t > t.GetTime();};
	bool operator<=( CRdbTime& t ) const {return m_t <= t.GetTime();};
	bool operator>=( CRdbTime& t ) const {return m_t >= t.GetTime();};

	inline T_TIME GetTime()		const{ return m_t;		};
	inline int GetYear()		const{ return m_year;	};
	inline int GetMonth()		const{ return m_mon;	};
	inline int GetDay()			const{ return m_day;	};
	inline int GetHour()		const{ return m_hour;	};
	inline int GetMinute()		const{ return m_min;	};
	inline int GetSecond()		const{ return m_sec;	};
	inline int GetMilSecond()	const{ return m_msec;	};

	bool	IsValidated() //是否有效
	{
		return (m_t > 0);
	};
	char *GetTimeStr(char* sbuf,size_t nbufsize)
	{
		if(!sbuf || !nbufsize)
			return NULL;
		sbuf[0] = '\0';
		if(m_t <= 0)	
			return (char*)sbuf;
		sbuf[nbufsize-1] = '\0';
		if(m_t < TOM_MIN_TIME || m_t > TOM_MAX_TIME){
			strncpy(sbuf,"BADTIME",nbufsize-1);
			return sbuf;
		}
		_snprintf(sbuf,nbufsize-1,"%04d-%02d-%02d %02d:%02d:%02d.%03d",m_year,m_mon,m_day,m_hour,m_min,m_sec,m_msec);
		return (char*)sbuf;
	}
	// static operations
public:
	static T_TIME GetCurrentTime(){
		SYSTEMTIME syst;
		::GetLocalTime(&syst);
		CRdbTime rdbt(syst.wYear,syst.wMonth,syst.wDay,syst.wHour, syst.wMinute,syst.wSecond,syst.wMilliseconds);
		return rdbt.GetTime();
	}; //静态函数，取当前时间不改变本类的成员.

protected:
	void errtime(){
		m_t		= -1;		m_year	= 0;		m_mon = 0;
		m_day	= 0;		m_hour	= 0;		m_min = 0;
		m_sec	= 0;		m_msec	= 0;
	};
	T_TIME tordbtime(int nyear,int nmon,int nday,int nhour,int nmin,int nsec,int nmsec)
	{
		struct tm t;
		time_t tmp;
		time( &tmp );
		t = *_localtime64(&tmp);//强制64位版
		t.tm_year = nyear - 1900;	t.tm_mon = nmon -1;
		t.tm_mday = nday;			t.tm_hour = nhour;
		t.tm_min = nmin;			t.tm_sec = nsec;
		m_t = _mktime64(&t);	//强制64位版
		if(m_t > 0)	{
			m_t = m_t * 10 + nmsec/100;
			m_year = nyear;		m_mon = nmon;		m_day = nday;
			m_hour = nhour;		m_min = nmin;		m_sec = nsec;
			m_msec = nmsec;
		}
		else
			errtime();
		return m_t;
	};
	void	ToLocalTime(T_TIME gmt)
	{
		if(gmt <= 0){
			errtime();
			return;
		}
		m_t = gmt/10;
		struct tm *ptm = _localtime64(&m_t); //强制64位版
		if(ptm == NULL)	{
			errtime();
			return;
		}
		m_year = ptm->tm_year + 1900;
		m_mon = ptm->tm_mon + 1;
		m_day = ptm->tm_mday;
		m_hour = ptm->tm_hour;
		m_min = ptm->tm_min;
		m_sec = ptm->tm_sec;
		m_msec = (gmt%10) * 100;
		m_t = m_t * 10 + (gmt%10);
	};
protected:
	T_TIME	m_t; //总是GMT时间，从1970-1-1开始的100毫秒数,注意T_TIME不是 time_t
	int		m_year,m_mon,m_day,m_hour,m_min,m_sec,m_msec; //本地时间的年，月，时，分，秒，毫秒
};

//////////////////////////////////////////////////////////////////////////
class CBaseVal : public T_BASEVAL // 基本数据类型
{
public:
	CBaseVal(){
		time	= 0;
		u64		= 0;
		cvt		= DT_VOID;	//类型
		cqa		= QA_OK;	//质量
		cerr	= SE_OK;	//错误码
		cres	= 0;		//保留
		unres	= 0;		//保留
	};
	CBaseVal(T_I32 ctype)
	{
		time	= 0;
		u64		= 0;
		cvt		= ctype;	//类型
		cqa		= QA_OK;	//质量
		cerr	= SE_OK;	//错误码
		cres	= 0;		//保留
		unres	= 0;		//保留
	};
public:
	//下面重载的=带类型自动转换
	CBaseVal& operator=( CBaseVal& vv) //重载=符号
	{
		time	= vv.time;
		switch(cvt)
		{
		case DT_DIGITAL: 
		case DT_INT32: 		i32 = vv.GetI32();	break;
		case DT_FLOAT32:	f32 = vv.GetF32();	break;
		case DT_INT64:		i64 = vv.GetI64();	break;
		case DT_FLOAT64:	f64 = vv.GetF64();	break;
		default: // DT_VOID 完全复制
			cvt = vv.cvt;
			u64 = vv.u64;
			break;
		}
		cqa		= vv.cqa;		//质量
		cerr	= vv.cerr;		//错误码
		cres	= vv.cres;		//保留
		unres	= vv.unres;		//保留
		return *this;
	};

	CBaseVal& operator=( CBaseVal* pv) //重载=符号
	{
		time	= pv->time;
		switch(cvt)
		{
		case DT_DIGITAL: 
		case DT_INT32: 		i32 = pv->GetI32();	break;
		case DT_FLOAT32:	f32 = pv->GetF32();	break;
		case DT_INT64:		i64 = pv->GetI64();	break;
		case DT_FLOAT64:	f64 = pv->GetF64();	break;
		default: // DT_VOID 完全复制
			cvt = pv->cvt;
			u64 = pv->u64;
			break;
		}
		cqa		= pv->cqa;		//质量
		cerr	= pv->cerr;		//错误码
		cres	= pv->cres;		//保留
		unres	= pv->unres;		//保留
		return *this;
	};

	CBaseVal& clone(const CBaseVal* pv) //完全复制
	{
		time	= pv->time;
		u64		= pv->u64;
		cvt		= pv->cvt;		//类型
		cqa		= pv->cqa;		//质量
		cerr	= pv->cerr;		//错误码
		cres	= pv->cres;		//保留
		unres	= pv->unres;		//保留
		return *this;
	};

	inline void	SetType(T_I8 ctype) {	cvt = ctype;	};

	template<typename  T>   
	CBaseVal& InitVal(T_TIME Time,T val,T_I8 cType,T_I8 cQa = QA_OK,T_I8 cErr = SE_OK) //初始化值
	{
		time = Time;
		switch(cType)
		{
		case DT_DIGITAL: 
		case DT_INT32: 		i32 = (T_I32)val;	break;
		case DT_FLOAT32:	f32 = (T_F32)val;	break;
		case DT_INT64:		i64 = (T_I64)val;	break;
		case DT_FLOAT64:	f64 = (T_F64)val;	break;
		default:
			break;
		}
		cvt		= cType;
		cqa		= cQa;	//质量
		cerr	= cErr;	//错误码
		cres	= 0;		//保留
		unres	= 0;		//保留
		return *this;
	};

	T_I32	GetI32(){		T_I32 v;		GetVal(v);		return v;	};
	T_I64	GetI64(){		T_I64 v;		GetVal(v);		return v;	};
	T_F32   GetF32(){		T_F32 v;		GetVal(v);		return v;	};
	T_F64   GetF64(){		T_F64 v;		GetVal(v);		return v;	};

	char*	GetValStr(char* sbuf,size_t nbufsize)
	{
		if(!sbuf || !nbufsize)
			return NULL;
		sbuf[0] = '\0';
		sbuf[nbufsize-1] = '\0';
		if((cvt == DT_DIGITAL) || (cvt == DT_INT32))
			_snprintf(sbuf,nbufsize-1,"%d",i32);
		else if(cvt == DT_INT64)
			_snprintf(sbuf,nbufsize-1,"%I64d",i64);
		else if(cvt == DT_FLOAT32)
			_snprintf(sbuf,nbufsize-1,"%.3f",f32);
		else if(cvt == DT_FLOAT64)
			_snprintf(sbuf,nbufsize-1,"%G",f64);
		return sbuf;
	};

	char* GetTimeStr(char* sbuf,size_t nbufsize,long lsecadjust = 0)
	{	
		CRdbTime rdbt(time + lsecadjust * 10);		
		return rdbt.GetTimeStr(sbuf,nbufsize);
	};
	char* GetQaStr(char* sbuf,size_t nbufsize)
	{
		if(!sbuf || !nbufsize)
			return NULL;
		sbuf[0] = '\0';
		
		if((cvt == DT_VOID)||(time<=0))
			return sbuf;
		sbuf[nbufsize-1] = '\0';
		_snprintf(sbuf,nbufsize-1,"%d",cqa);
		return sbuf;
	};
	
	//{{下面是MFC版本
	CString GetValStr() //取值，转换为字符串形式
	{
		CString sval = "";
		if(cvt == DT_VOID)
			return sval;
		else if((cvt == DT_DIGITAL) || (cvt == DT_INT32))
			sval.Format("%d",i32);
		else if(cvt == DT_INT64)
			sval.Format("%I64d",i64);
		else if(cvt == DT_FLOAT32)
			sval.Format("%.3f",f32);
		else if(cvt == DT_FLOAT64)
			sval.Format("%G",f64);

		return sval;
	}
	CString GetTimeStr(long lsecadjust = 0)
	{
		CString sval = "";
		CRdbTime rdbt(time + lsecadjust * 10);
		char sbuf[512];
		size_t  nbufsize = 512;
		sval = rdbt.GetTimeStr(sbuf,nbufsize);
		return sval;	
	}

	CString GetQaStr()
	{
		CString sval = "";
		if((cvt == DT_VOID)||(time<=0))
			return sval;
		sval.Format("%d",cqa);
		return sval;
	}
	//}}

protected:
	template<typename  T>   
	void GetVal(T& val)
	{
		switch(cvt)
		{
		case DT_DIGITAL: 
		case DT_INT32: 		val = (T)i32;	break;
		case DT_FLOAT32:	val = (T)f32;	break;
		case DT_INT64:		val = (T)i64;	break;
		case DT_FLOAT64:	val = (T)f64;	break;
		default:
			val = 0;
			break;
		}
	};
	
}; // CBaseVal

//////////////////////////////////////////////////////////////////////////
#define VARVALINFO_SIZE			24 //
class CVarVal : public T_VARVAL // 可变长度类型
{
public:
	CVarVal(){
		time		= 0;	

		uobjtype	= 0;
		ures		= 0;

		cvt			= DT_BLOB;
		cqa			= QA_OK;
		cerr		= SE_OK;
		cres		= 0;
		usres		= 0;
		uslen		= 0;
		memset(sdata,0,MAX_VAR_LEN);
	};
	CVarVal(T_I8 ctype){
		time		= 0;	

		uobjtype	= 0;
		ures		= 0;

		cvt			= ctype;
		cqa			= QA_OK;
		cerr		= SE_OK;
		cres		= 0;
		usres		= 0;
		uslen		= 0;
		memset(sdata,0,MAX_VAR_LEN);
	};
	
	CVarVal& operator=( CVarVal& v) //重载=符号
	{
		memcpy((T_VARVAL*)this,&v,sizeof(T_VARVAL));
		return *this;
	};
	
	bool operator==( CVarVal& v)
	{
		if(time != v.time || uobjtype != v.uobjtype|| cqa != v.cqa || uslen != v.uslen  )
			return FALSE;
		int i;
		for(i=0;i<uslen && i < MAX_VAR_LEN;i++){
			if(sdata[i] != v.sdata[i])
				return FALSE;
		}
		return TRUE;
	}
	inline CVarVal& clone(const CVarVal* pv) //完全复制
	{
		memcpy(this,pv,sizeof(T_VARVAL));
		return *this;
	};
	void	SetStr(const char* pstr,T_TIME tTime,T_I8 cQa,T_U32 objtype = 0,T_I8 cErr = SE_OK)
	{
		time		= tTime;	

		uobjtype	= objtype;
		ures		= 0;

		cvt			= DT_STRING;
		cqa			= cQa;
		cerr		= cErr;
		cres		= 0;
		usres		= 0;
		
		if(!pstr)
		{
			uslen		= 0;
			memset(sdata,0,MAX_VAR_LEN);
		}
		else
		{
			uslen = (T_U16)strlen(pstr);
			if(uslen >= MAX_VAR_LEN-1)
				uslen = MAX_VAR_LEN-1;
			memcpy(sdata,pstr,uslen);
		}
		FmtData();
	};
	void	SetBlob(void* pdata,T_U16 usLen,T_TIME tTime,T_I8 cType,T_I8 cQa,T_U32 objtype = 0,T_I8 cErr = SE_OK)
	{
		time		= tTime;	

		uobjtype	= 0;
		ures		= 0;

		cvt			= DT_BLOB;
		cqa			= cQa;
		cerr		= cErr;
		cres		= 0;
		usres		= 0;

		if(!pdata)
		{
			uslen		= 0;
			memset(sdata,0,MAX_VAR_LEN);
		}
		else
		{
			uslen = usLen;
			if(uslen >= MAX_VAR_LEN)
				uslen = MAX_VAR_LEN;
			memcpy(sdata,pdata,uslen);
		}
		FmtData();
	};
	
	void FmtData() //格式化，无效的字节填0,利于压缩
	{
		if(uslen >= MAX_VAR_LEN)
			return;
		T_I8 *p = (T_I8*)sdata + uslen;
		memset(p,0,sizeof(MAX_VAR_LEN - uslen));
	};
};


#endif // I_RDB4CLS_H_