// // CT_Time: C // REBINT CT_Time(REBVAL *a, REBVAL *b, REBINT mode) { REBINT num = Cmp_Time(a, b); if (mode >= 0) return (num == 0); if (mode == -1) return (num >= 0); return (num > 0); }
*/ REBINT Cmp_Date(const REBVAL *d1, const REBVAL *d2) /* ***********************************************************************/ { REBINT diff; diff = Diff_Date(VAL_DATE(d1), VAL_DATE(d2)); if (diff == 0) diff = Cmp_Time(d1, d2); return diff; }
//获取pSrc时间点或该时间点之前的最近一个冻结时间点,包括pSrc本身所指向的时间点 //即<=pSrc指向时间的最近一个冻结时间点时间点 void Get_Last_Freeze_Time(S_HEX_Time *pSrc,S_HEX_Time *pDst) { S_HEX_Time TempTime; Get_NowMonth_Freeze_Time(pSrc,&TempTime);//获取当月冻结时间 if(Cmp_Time(pSrc,&TempTime)==TIME_BEF) { Time_Dec(&TempTime,1,UNIT_MON,pDst); } else mem_cpy(pDst,&TempTime,sizeof(TempTime),pDst,sizeof(S_HEX_Time)); }
*/ REBINT Cmp_Value(REBVAL *s, REBVAL *t, REBFLG is_case) /* ** Compare two values and return the difference. ** ** is_case TRUE for case sensitive compare ** ***********************************************************************/ { REBDEC d1, d2; if (VAL_TYPE(t) != VAL_TYPE(s) && !(IS_NUMBER(s) && IS_NUMBER(t))) return VAL_TYPE(s) - VAL_TYPE(t); switch(VAL_TYPE(s)) { case REB_INTEGER: if (IS_DECIMAL(t)) { d1 = (REBDEC)VAL_INT64(s); d2 = VAL_DECIMAL(t); goto chkDecimal; } return THE_SIGN(VAL_INT64(s) - VAL_INT64(t)); case REB_LOGIC: return VAL_LOGIC(s) - VAL_LOGIC(t); case REB_CHAR: if (is_case) return THE_SIGN(VAL_CHAR(s) - VAL_CHAR(t)); return THE_SIGN((REBINT)(UP_CASE(VAL_CHAR(s)) - UP_CASE(VAL_CHAR(t)))); case REB_DECIMAL: case REB_MONEY: d1 = VAL_DECIMAL(s); if (IS_INTEGER(t)) d2 = (REBDEC)VAL_INT64(t); else d2 = VAL_DECIMAL(t); chkDecimal: if (Eq_Decimal(d1, d2)) return 0; if (d1 < d2) return -1; return 1; case REB_PAIR: return Cmp_Pair(s, t); case REB_EVENT: return Cmp_Event(s, t); case REB_GOB: return Cmp_Gob(s, t); case REB_TUPLE: return Cmp_Tuple(s, t); case REB_TIME: return Cmp_Time(s, t); case REB_DATE: return Cmp_Date(s, t); case REB_BLOCK: case REB_PAREN: case REB_MAP: case REB_PATH: case REB_SET_PATH: case REB_GET_PATH: case REB_LIT_PATH: return Cmp_Block(s, t, is_case); case REB_STRING: case REB_FILE: case REB_EMAIL: case REB_URL: case REB_TAG: return Compare_String_Vals(s, t, (REBOOL)!is_case); case REB_BITSET: case REB_BINARY: case REB_IMAGE: return Compare_Binary_Vals(s, t); case REB_VECTOR: return Compare_Vector(s, t); case REB_DATATYPE: return VAL_DATATYPE(s) - VAL_DATATYPE(t); case REB_WORD: case REB_SET_WORD: case REB_GET_WORD: case REB_LIT_WORD: case REB_REFINEMENT: case REB_ISSUE: return Compare_Word(s,t,is_case); case REB_ERROR: return VAL_ERR_NUM(s) - VAL_ERR_NUM(s); case REB_OBJECT: case REB_MODULE: case REB_PORT: return VAL_OBJ_FRAME(s) - VAL_OBJ_FRAME(t); case REB_NATIVE: return &VAL_FUNC_CODE(s) - &VAL_FUNC_CODE(t); case REB_ACTION: case REB_COMMAND: case REB_OP: case REB_FUNCTION: return VAL_FUNC_BODY(s) - VAL_FUNC_BODY(t); case REB_NONE: case REB_UNSET: case REB_END: default: break; } return 0; }
//函数作用主要是从CUR_DEMAND存储区或者CUR_DEMAND_BAK存储区读出数据,然后进行月数据冻结 //在上电补冻或者跨越冻结时可以调用该函数,但是注意: //pTime表示冻结时的时间,一般为当前时间 //如果冻结完后,马上就停电了,那么重上电后,仍在冻结时刻,继续补冻的话,发现已经有冻结数据了,便不会再冻了 void Freeze_Demand_Data(S_HEX_Time *pTime)//S_HEX_Time *pTime) { INT8U i,Re,Err; S_One_Demand *p; S_HEX_Time TempTime;//,TempTime1; INT32U Off; DEBUG_PRINT(HUCK,DEBUG_0,"----------Freeze Demand Data %d-%d-%d %d:%d----------",\ pTime->Time[T_YEAR],pTime->Time[T_MONTH],pTime->Time[T_DATE],pTime->Time[T_HOUR],pTime->Time[T_MIN]); Re=CHECK_STRUCT_SUM(Cur_Demand); if(ASSERT(A_WARNING,1==Re)) Check_Data_Avail(); OS_Sem_Pend(PUB_BUF0_SEM_ID);//申请Pub_Buf信号量 //分别读取每个份费率的数据,并将其转存到相应的历史数据区 for(i=0;i<=Multi_Rate_Para.Rates && i<=MAX_RATES;i++) { //p指向该费率的需量数据 //当前费率与Cur_Demand中的数据相符 if(i==0 || i==Cur_Demand.Rate) { if(i==0) p=(S_One_Demand *)&Cur_Demand.Demand[0]; else if(i==Cur_Demand.Rate) p=(S_One_Demand *)&Cur_Demand.Demand[1]; Re=1; } else if(Read_Demand_Rate_Data(i,(INT8U *)Pub_Buf0,(INT8U *)Pub_Buf0,sizeof(Pub_Buf0))==ONE_DEMAND_SAVE_SIZE) { p=(S_One_Demand *)Pub_Buf0; Re=1; } else Re=0; if(1==Re)//得到了正确的原始数据才进行冻结 { DEBUG_PRINT(HUCK,DEBUG_0,"Demand Data Rate %u Freeze, Data Time: ",i); Debug_Print_HEX_Time((p->Time).Time); //先找到pTime之前的上次结算的时间点(包括pTime本身) if(((p->Time).Time[T_YEAR]==0 && (p->Time).Time[T_MONTH]==0) ||\ Check_HEX_Time(&(p->Time))!=1)//必须保证时间格式正确才进行补冻,因为里面也可能是全0的数据,设置默认参数或者清0了 { DEBUG_PRINT(HUCK,DEBUG_0,"Demand Rate %u Time EQ Zero or format error",i); continue; } //<=pTime的最近一个冻结时间点,pTime可能就是冻结时间点 Get_Last_Freeze_Time(pTime,&TempTime);//pTime以前的最近一个冻结时间点,包括pTime本身 //现在TempTime就是最近一次的冻结时间点,p->Time是需量数据的时间点 Re=Cmp_Time(&(p->Time),&TempTime);//比较需量数据时间点与最近一次冻结时间点 if(TIME_AFT==Re)//需量时间点在最近一次结算时间点之后,是一条当前数据,不需要补存到历史数据中,时间相等也有可能需要保存,因为需量生成时间可能正好是结算时间点 { DEBUG_PRINT(HUCK,DEBUG_0,"Demand Rate %u Time > FreezeTime",i); Debug_Print_HEX_Time((p->Time).Time); Debug_Print_HEX_Time(TempTime.Time); continue; } //>=p->Time的最近一个冻结时间点,可能就是p->Time,因为p->Time可能就是当前时间,同时当前时间就是冻结时间点 Get_Next_Freeze_Time(&(p->Time),&TempTime);//历史数据的冻结时间点,需量数据需要找到其时间之后的一个冻结时间点 //这个月的这个费率的数据是否冻结过?没有冻结过才冻结 if(Read_Demand_HIS_Data(i,&TempTime,(INT8U *)Pub_Buf0+sizeof(S_Demand),(INT8U *)Pub_Buf0,sizeof(Pub_Buf0),&Err) EQ ONE_DEMAND_SAVE_SIZE) { DEBUG_PRINT(HUCK,DEBUG_0,"Demand Rate %u Time Data Freezed!",i); Debug_Print_HEX_Time(TempTime.Time); //continue; } else { mem_cpy(p->Time.Time,&TempTime,sizeof(TempTime),p,sizeof(S_One_Demand)); Set_STRUCT_Sum(p,sizeof(S_One_Demand),p->CS,sizeof(p->CS)); Write_Demand_HIS_Data(i,&TempTime,p,ONE_DEMAND_SAVE_SIZE); } //因为是历史数据,所以需要重置变为当月数据 //需要重置本月的需量初值以及需量冻结时间 mem_set(p,0,sizeof(S_One_Demand),p,sizeof(S_One_Demand));//将数据全部清0存入当前存储区,下次读出全0数据,表示尚未生成新数据 Set_STRUCT_Sum(p,sizeof(S_One_Demand),p->CS,sizeof(p->CS)); //确保当前数据域时间点不会是冻结时间点 //确保分域不为0 //重新写入当前需量存储区包括备份区 Off=DEMAND_RATE_OFF(i); Write_Storage_Data_Fix_Len(CUR_DEMAND,Off,p,ONE_DEMAND_SAVE_SIZE); Write_Storage_Data_Fix_Len(CUR_DEMAND_BAK,Off,p,ONE_DEMAND_SAVE_SIZE); Demand_Accu_Clear(); //将修改后的Cur_Demand数据保存到掉电数据区 if(i==0 || i==Cur_Demand.Rate) { SET_STRUCT_SUM(Cur_Demand); Save_Cur_Demand_PD_Data(); } } } OS_Sem_Post(PUB_BUF0_SEM_ID);//释放Pub_Buf信号量 DEBUG_PRINT(HUCK,DEBUG_0,"----------Freeze Demand Data End----------"); }
// // Cmp_Value: C // // Compare two values and return the difference. // // is_case TRUE for case sensitive compare // REBINT Cmp_Value(const RELVAL *s, const RELVAL *t, REBOOL is_case) { REBDEC d1, d2; if (VAL_TYPE(t) != VAL_TYPE(s) && !(ANY_NUMBER(s) && ANY_NUMBER(t))) return VAL_TYPE(s) - VAL_TYPE(t); assert(NOT_END(s) && NOT_END(t)); switch(VAL_TYPE(s)) { case REB_INTEGER: if (IS_DECIMAL(t)) { d1 = (REBDEC)VAL_INT64(s); d2 = VAL_DECIMAL(t); goto chkDecimal; } return THE_SIGN(VAL_INT64(s) - VAL_INT64(t)); case REB_LOGIC: return VAL_LOGIC(s) - VAL_LOGIC(t); case REB_CHAR: if (is_case) return THE_SIGN(VAL_CHAR(s) - VAL_CHAR(t)); return THE_SIGN((REBINT)(UP_CASE(VAL_CHAR(s)) - UP_CASE(VAL_CHAR(t)))); case REB_PERCENT: case REB_DECIMAL: case REB_MONEY: if (IS_MONEY(s)) d1 = deci_to_decimal(VAL_MONEY_AMOUNT(s)); else d1 = VAL_DECIMAL(s); if (IS_INTEGER(t)) d2 = cast(REBDEC, VAL_INT64(t)); else if (IS_MONEY(t)) d2 = deci_to_decimal(VAL_MONEY_AMOUNT(t)); else d2 = VAL_DECIMAL(t); chkDecimal: if (Eq_Decimal(d1, d2)) return 0; if (d1 < d2) return -1; return 1; case REB_PAIR: return Cmp_Pair(s, t); case REB_EVENT: return Cmp_Event(s, t); case REB_GOB: return Cmp_Gob(s, t); case REB_TUPLE: return Cmp_Tuple(s, t); case REB_TIME: return Cmp_Time(s, t); case REB_DATE: return Cmp_Date(s, t); case REB_BLOCK: case REB_GROUP: case REB_MAP: case REB_PATH: case REB_SET_PATH: case REB_GET_PATH: case REB_LIT_PATH: return Cmp_Array(s, t, is_case); case REB_STRING: case REB_FILE: case REB_EMAIL: case REB_URL: case REB_TAG: return Compare_String_Vals(s, t, NOT(is_case)); case REB_BITSET: case REB_BINARY: case REB_IMAGE: return Compare_Binary_Vals(s, t); case REB_VECTOR: return Compare_Vector(s, t); case REB_DATATYPE: return VAL_TYPE_KIND(s) - VAL_TYPE_KIND(t); case REB_WORD: case REB_SET_WORD: case REB_GET_WORD: case REB_LIT_WORD: case REB_REFINEMENT: case REB_ISSUE: return Compare_Word(s,t,is_case); case REB_ERROR: return VAL_ERR_NUM(s) - VAL_ERR_NUM(t); case REB_OBJECT: case REB_MODULE: case REB_PORT: return VAL_CONTEXT(s) - VAL_CONTEXT(t); case REB_FUNCTION: return VAL_FUNC_PARAMLIST(s) - VAL_FUNC_PARAMLIST(t); case REB_LIBRARY: return VAL_LIBRARY(s) - VAL_LIBRARY(t); case REB_STRUCT: return Cmp_Struct(s, t); case REB_BLANK: case REB_MAX_VOID: default: break; } return 0; }