00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "Variables.h"
00023 #include "Ingredients.h"
00024 #include "Root.h"
00025 #include "BaseClasses.h"
00026 #include "ParseNode.h"
00027 #include "ASN1Codes.h"
00028 #include "Engine.h"
00029 #include "Logging.h"
00030
00031 enum TestCodes { TC_Equal = 1, TC_NotEqual, TC_Less, TC_LessOrEqual, TC_Greater, TC_GreaterOrEqual };
00032
00033 static const char *TestToText(int tc)
00034 {
00035 switch (tc) {
00036 case TC_Equal: return "Equal";
00037 case TC_NotEqual: return "NotEqual";
00038 case TC_Less: return "Less";
00039 case TC_LessOrEqual: return "LessOrEqual";
00040 case TC_Greater: return "Greater";
00041 case TC_GreaterOrEqual: return "GreaterOrEqual";
00042 }
00043 return NULL;
00044 }
00045
00046
00047 void MHVariable::Activation(MHEngine *engine)
00048 {
00049 if (m_fRunning) return;
00050 MHIngredient::Activation(engine);
00051 m_fRunning = true;
00052 engine->EventTriggered(this, EventIsRunning);
00053 }
00054
00055 void MHBooleanVar::Initialise(MHParseNode *p, MHEngine *engine)
00056 {
00057 MHVariable::Initialise(p, engine);
00058
00059 MHParseNode *pInitial = p->GetNamedArg(C_ORIGINAL_VALUE);
00060 m_fOriginalValue = pInitial->GetArgN(0)->GetBoolValue();
00061 }
00062
00063 void MHBooleanVar::PrintMe(FILE *fd, int nTabs) const
00064 {
00065 PrintTabs(fd, nTabs); fprintf(fd, "{:BooleanVar");
00066 MHVariable::PrintMe(fd, nTabs+1);
00067 PrintTabs(fd, nTabs+1); fprintf(fd, ":OrigValue %s\n", m_fOriginalValue ? "true" : "false");
00068 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00069 }
00070
00071 void MHBooleanVar::Preparation(MHEngine *engine)
00072 {
00073 if (m_fAvailable) return;
00074 m_fValue = m_fOriginalValue;
00075 MHVariable::Preparation(engine);
00076 }
00077
00078
00079 void MHBooleanVar::TestVariable(int nOp, const MHUnion &parm, MHEngine *engine)
00080 {
00081 parm.CheckType(MHUnion::U_Bool);
00082 bool fRes = false;
00083 switch (nOp) {
00084 case TC_Equal: fRes = m_fValue == parm.m_fBoolVal; break;
00085 case TC_NotEqual: fRes = m_fValue != parm.m_fBoolVal; break;
00086 default: MHERROR("Invalid comparison for bool");
00087 }
00088 MHLOG(MHLogDetail, QString("Comparison %1 between %2 and %3 => %4").arg(TestToText(nOp))
00089 .arg(m_fValue ? "true" : "false").arg(parm.m_fBoolVal ? "true" : "false").arg(fRes ? "true" : "false"));
00090 engine->EventTriggered(this, EventTestEvent, fRes);
00091 }
00092
00093
00094 void MHBooleanVar::GetVariableValue(MHUnion &value, MHEngine *)
00095 {
00096 value.m_Type = MHUnion::U_Bool;
00097 value.m_fBoolVal = m_fValue;
00098 }
00099
00100
00101 void MHBooleanVar::SetVariableValue(const MHUnion &value)
00102 {
00103 value.CheckType(MHUnion::U_Bool);
00104 m_fValue = value.m_fBoolVal;
00105 MHLOG(MHLogDetail, QString("Update %1 := %2").arg(m_ObjectReference.Printable()).arg( m_fValue ? "true": "false"));
00106 }
00107
00108
00109 void MHIntegerVar::Initialise(MHParseNode *p, MHEngine *engine)
00110 {
00111 MHVariable::Initialise(p, engine);
00112
00113 MHParseNode *pInitial = p->GetNamedArg(C_ORIGINAL_VALUE);
00114 m_nOriginalValue = pInitial->GetArgN(0)->GetIntValue();
00115 }
00116
00117 void MHIntegerVar::PrintMe(FILE *fd, int nTabs) const
00118 {
00119 PrintTabs(fd, nTabs); fprintf(fd, "{:IntegerVar");
00120 MHVariable::PrintMe(fd, nTabs+1);
00121 PrintTabs(fd, nTabs+1); fprintf(fd, ":OrigValue %d\n", m_nOriginalValue);
00122 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00123 }
00124
00125 void MHIntegerVar::Preparation(MHEngine *engine)
00126 {
00127 if (m_fAvailable) return;
00128 m_nValue = m_nOriginalValue;
00129 MHVariable::Preparation(engine);
00130 }
00131
00132
00133 void MHIntegerVar::TestVariable(int nOp, const MHUnion &parm, MHEngine *engine)
00134 {
00135 parm.CheckType(MHUnion::U_Int);
00136 bool fRes = false;
00137 switch (nOp) {
00138 case TC_Equal: fRes = m_nValue == parm.m_nIntVal; break;
00139 case TC_NotEqual: fRes = m_nValue != parm.m_nIntVal; break;
00140 case TC_Less: fRes = m_nValue < parm.m_nIntVal; break;
00141 case TC_LessOrEqual: fRes = m_nValue <= parm.m_nIntVal; break;
00142 case TC_Greater: fRes = m_nValue > parm.m_nIntVal; break;
00143 case TC_GreaterOrEqual: fRes = m_nValue >= parm.m_nIntVal; break;
00144 default: MHERROR("Invalid comparison for int");
00145 }
00146 MHLOG(MHLogDetail, QString("Comparison %1 between %2 and %3 => %4").arg(TestToText(nOp))
00147 .arg(m_nValue).arg(parm.m_nIntVal).arg(fRes ? "true" : "false"));
00148 engine->EventTriggered(this, EventTestEvent, fRes);
00149 }
00150
00151
00152 void MHIntegerVar::GetVariableValue(MHUnion &value, MHEngine *)
00153 {
00154 value.m_Type = MHUnion::U_Int;
00155 value.m_nIntVal = m_nValue;
00156 }
00157
00158
00159 void MHIntegerVar::SetVariableValue(const MHUnion &value)
00160 {
00161 if (value.m_Type == MHUnion::U_String) {
00162
00163 int v = 0;
00164 int p = 0;
00165 bool fNegative = false;
00166 if (value.m_StrVal.Size() > 0 && value.m_StrVal.GetAt(0) == '-') { p++; fNegative = true; }
00167 for ( ; p < value.m_StrVal.Size(); p++) {
00168 unsigned char ch = value.m_StrVal.GetAt(p);
00169 if (ch < '0' || ch > '9') break;
00170 v = v * 10 + ch - '0';
00171 }
00172 if (fNegative) m_nValue = -v; else m_nValue = v;
00173 }
00174 else {
00175 value.CheckType(MHUnion::U_Int);
00176 m_nValue = value.m_nIntVal;
00177 }
00178 MHLOG(MHLogDetail, QString("Update %1 := %2").arg(m_ObjectReference.Printable()).arg(m_nValue));
00179 }
00180
00181
00182
00183 void MHOctetStrVar::Initialise(MHParseNode *p, MHEngine *engine)
00184 {
00185 MHVariable::Initialise(p, engine);
00186
00187 MHParseNode *pInitial = p->GetNamedArg(C_ORIGINAL_VALUE);
00188 pInitial->GetArgN(0)->GetStringValue(m_OriginalValue);
00189 }
00190
00191 void MHOctetStrVar::PrintMe(FILE *fd, int nTabs) const
00192 {
00193 PrintTabs(fd, nTabs); fprintf(fd, "{:OStringVar");
00194 MHVariable::PrintMe(fd, nTabs+1);
00195 PrintTabs(fd, nTabs+1); fprintf(fd, ":OrigValue "); m_OriginalValue.PrintMe(fd, nTabs+1); fprintf(fd, "\n");
00196 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00197 }
00198
00199 void MHOctetStrVar::Preparation(MHEngine *engine)
00200 {
00201 if (m_fAvailable) return;
00202 m_Value.Copy(m_OriginalValue);
00203 MHVariable::Preparation(engine);
00204 }
00205
00206
00207 void MHOctetStrVar::TestVariable(int nOp, const MHUnion &parm, MHEngine *engine)
00208 {
00209 parm.CheckType(MHUnion::U_String);
00210 int nRes = m_Value.Compare(parm.m_StrVal);
00211 bool fRes = false;
00212 switch (nOp) {
00213 case TC_Equal: fRes = nRes == 0; break;
00214 case TC_NotEqual: fRes = nRes != 0; break;
00215
00216
00217
00218
00219 default: MHERROR("Invalid comparison for string");
00220 }
00221 MHOctetString sample1(m_Value, 0, 10);
00222 MHOctetString sample2(parm.m_StrVal, 0, 10);
00223 MHLOG(MHLogDetail, QString("Comparison %1 %2 and %3 => %4").arg(TestToText(nOp))
00224 .arg(sample1.Printable()).arg(sample2.Printable()).arg(fRes ? "true" : "false"));
00225 engine->EventTriggered(this, EventTestEvent, fRes);
00226 }
00227
00228
00229 void MHOctetStrVar::GetVariableValue(MHUnion &value, MHEngine *)
00230 {
00231 value.m_Type = MHUnion::U_String;
00232 value.m_StrVal.Copy(m_Value);
00233 }
00234
00235
00236 void MHOctetStrVar::SetVariableValue(const MHUnion &value)
00237 {
00238 if (value.m_Type == MHUnion::U_Int) {
00239
00240 char buff[30];
00241 snprintf(buff, sizeof(buff), "%0d", value.m_nIntVal);
00242 m_Value.Copy(buff);
00243 }
00244 else {
00245 value.CheckType(MHUnion::U_String);
00246 m_Value.Copy(value.m_StrVal);
00247 }
00248
00249 MHOctetString sample(m_Value, 0, 10);
00250 MHLOG(MHLogDetail, QString("Update %1 := %2").arg(m_ObjectReference.Printable())
00251 .arg(sample.Printable()));
00252 }
00253
00254
00255 void MHObjectRefVar::Initialise(MHParseNode *p, MHEngine *engine)
00256 {
00257 MHVariable::Initialise(p, engine);
00258
00259 MHParseNode *pInitial = p->GetNamedArg(C_ORIGINAL_VALUE);
00260
00261 MHParseNode *pArg = pInitial->GetNamedArg(C_OBJECT_REFERENCE);
00262 m_OriginalValue.Initialise(pArg->GetArgN(0), engine);
00263 }
00264
00265 void MHObjectRefVar::PrintMe(FILE *fd, int nTabs) const
00266 {
00267 PrintTabs(fd, nTabs); fprintf(fd, "{:ObjectRefVar");
00268 MHVariable::PrintMe(fd, nTabs+1);
00269 PrintTabs(fd, nTabs+1); fprintf(fd, ":OrigValue "); m_OriginalValue.PrintMe(fd, nTabs+1); fprintf(fd, "\n");
00270 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00271 }
00272
00273 void MHObjectRefVar::Preparation(MHEngine *engine)
00274 {
00275 if (m_fAvailable) return;
00276 m_Value.Copy(m_OriginalValue);
00277 MHVariable::Preparation(engine);
00278 }
00279
00280
00281 void MHObjectRefVar::TestVariable(int nOp, const MHUnion &parm, MHEngine *engine)
00282 {
00283 parm.CheckType(MHUnion::U_ObjRef);
00284 bool fRes = false;
00285 switch (nOp) {
00286 case TC_Equal: fRes = m_Value.Equal(parm.m_ObjRefVal, engine); break;
00287 case TC_NotEqual: fRes = ! m_Value.Equal(parm.m_ObjRefVal, engine); break;
00288 default: MHERROR("Invalid comparison for object ref");
00289 }
00290 engine->EventTriggered(this, EventTestEvent, fRes);
00291 }
00292
00293
00294 void MHObjectRefVar::GetVariableValue(MHUnion &value, MHEngine *)
00295 {
00296 value.m_Type = MHUnion::U_ObjRef;
00297 value.m_ObjRefVal.Copy(m_Value);
00298 }
00299
00300
00301 void MHObjectRefVar::SetVariableValue(const MHUnion &value)
00302 {
00303 value.CheckType(MHUnion::U_ObjRef);
00304 m_Value.Copy(value.m_ObjRefVal);
00305 MHLOG(MHLogDetail, QString("Update %1 := %2").arg(m_ObjectReference.Printable()).arg(m_Value.Printable()));
00306 }
00307
00308
00309 void MHContentRefVar::Initialise(MHParseNode *p, MHEngine *engine)
00310 {
00311 MHVariable::Initialise(p, engine);
00312
00313 MHParseNode *pInitial = p->GetNamedArg(C_ORIGINAL_VALUE);
00314
00315 MHParseNode *pArg = pInitial->GetNamedArg(C_CONTENT_REFERENCE);
00316 m_OriginalValue.Initialise(pArg->GetArgN(0), engine);
00317 }
00318
00319 void MHContentRefVar::PrintMe(FILE *fd, int nTabs) const
00320 {
00321 PrintTabs(fd, nTabs); fprintf(fd, "{:ContentRefVar");
00322 MHVariable::PrintMe(fd, nTabs+1);
00323 PrintTabs(fd, nTabs+1); fprintf(fd, ":OrigValue "); m_OriginalValue.PrintMe(fd, nTabs+1); fprintf(fd, "\n");
00324 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00325 }
00326
00327 void MHContentRefVar::Preparation(MHEngine *engine)
00328 {
00329 if (m_fAvailable) return;
00330 m_Value.Copy(m_OriginalValue);
00331 MHVariable::Preparation(engine);
00332 }
00333
00334
00335 void MHContentRefVar::TestVariable(int nOp, const MHUnion &parm, MHEngine *engine)
00336 {
00337 parm.CheckType(MHUnion::U_ContentRef);
00338 bool fRes = false;
00339 switch (nOp) {
00340 case TC_Equal: fRes = m_Value.Equal(parm.m_ContentRefVal, engine); break;
00341 case TC_NotEqual: fRes = !m_Value.Equal(parm.m_ContentRefVal, engine); break;
00342 default: MHERROR("Invalid comparison for content ref");
00343 }
00344 engine->EventTriggered(this, EventTestEvent, fRes);
00345 }
00346
00347
00348 void MHContentRefVar::GetVariableValue(MHUnion &value, MHEngine *)
00349 {
00350 value.m_Type = MHUnion::U_ContentRef;
00351 value.m_ContentRefVal.Copy(m_Value);
00352 }
00353
00354
00355 void MHContentRefVar::SetVariableValue(const MHUnion &value)
00356 {
00357 value.CheckType(MHUnion::U_ContentRef);
00358 m_Value.Copy(value.m_ContentRefVal);
00359 MHLOG(MHLogDetail, QString("Update %1 := %2").arg(m_ObjectReference.Printable()).arg(m_Value.Printable()));
00360 }
00361
00362
00363 void MHSetVariable::Initialise(MHParseNode *p, MHEngine *engine)
00364 {
00365 MHElemAction::Initialise(p, engine);
00366 m_NewValue.Initialise(p->GetArgN(1), engine);
00367 }
00368
00369 void MHSetVariable::Perform(MHEngine *engine)
00370 {
00371 MHObjectRef target;
00372 m_Target.GetValue(target, engine);
00373 MHUnion newValue;
00374 newValue.GetValueFrom(m_NewValue, engine);
00375 engine->FindObject(target)->SetVariableValue(newValue);
00376 }
00377
00378
00379 void MHTestVariable::Initialise(MHParseNode *p, MHEngine *engine)
00380 {
00381 MHElemAction::Initialise(p, engine);
00382 m_nOperator = p->GetArgN(1)->GetIntValue();
00383 m_Comparison.Initialise(p->GetArgN(2), engine);
00384 }
00385
00386 void MHTestVariable::PrintArgs(FILE *fd, int ) const
00387 {
00388 fprintf(fd, " %d ", m_nOperator);
00389 m_Comparison.PrintMe(fd, 0);
00390 }
00391
00392 void MHTestVariable::Perform(MHEngine *engine)
00393 {
00394 MHObjectRef target;
00395 m_Target.GetValue(target, engine);
00396 MHUnion testValue;
00397 testValue.GetValueFrom(m_Comparison, engine);
00398 engine->FindObject(target)->TestVariable(m_nOperator, testValue, engine);
00399 }
00400
00401 void MHIntegerAction::Initialise(MHParseNode *p, MHEngine *engine)
00402 {
00403 MHElemAction::Initialise(p, engine);
00404 MHParseNode *pOp = p->GetArgN(1);
00405 m_Operand.Initialise(pOp, engine);
00406 }
00407
00408 void MHIntegerAction::Perform(MHEngine *engine)
00409 {
00410 MHUnion targetVal;
00411
00412 MHObjectRef parm;
00413 m_Target.GetValue(parm, engine);
00414 MHRoot *pTarget = engine->FindObject(parm);
00415 pTarget->GetVariableValue(targetVal, engine);
00416 targetVal.CheckType(MHUnion::U_Int);
00417
00418 int nOperand = m_Operand.GetValue(engine);
00419
00420 targetVal.m_nIntVal = DoOp(targetVal.m_nIntVal, nOperand);
00421 pTarget->SetVariableValue(targetVal);
00422 }
00423
00424 void MHAppend::Initialise(MHParseNode *p, MHEngine *engine)
00425 {
00426 MHElemAction::Initialise(p, engine);
00427 m_Operand.Initialise(p->GetArgN(1), engine);
00428 }
00429
00430 void MHAppend::Perform(MHEngine *engine)
00431 {
00432 MHUnion targetVal;
00433
00434 MHObjectRef parm;
00435 m_Target.GetValue(parm, engine);
00436 MHRoot *pTarget = engine->FindObject(parm);
00437 pTarget->GetVariableValue(targetVal, engine);
00438 targetVal.CheckType(MHUnion::U_String);
00439
00440 MHOctetString toAppend;
00441 m_Operand.GetValue(toAppend, engine);
00442 targetVal.m_StrVal.Append(toAppend);
00443 pTarget->SetVariableValue(targetVal);
00444 }