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