00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "BaseClasses.h"
00023 #include "ParseNode.h"
00024 #include "Engine.h"
00025 #include "ASN1Codes.h"
00026 #include "Logging.h"
00027
00028 #ifdef _DEBUG
00029 #undef THIS_FILE
00030 static char THIS_FILE[] = __FILE__;
00031 #define new DEBUG_NEW
00032 #endif
00033
00034 MHOctetString::MHOctetString()
00035 {
00036 m_nLength = 0;
00037 m_pChars = NULL;
00038 }
00039
00040
00041 MHOctetString::MHOctetString(const char *str, int nLen)
00042 {
00043 if (nLen < 0)
00044 {
00045 nLen = strlen(str);
00046 }
00047
00048 m_nLength = nLen;
00049
00050 if (nLen == 0)
00051 {
00052 m_pChars = 0;
00053 }
00054 else
00055 {
00056 m_pChars = (unsigned char *)malloc(nLen);
00057
00058 if (! m_pChars)
00059 {
00060 throw "Out of memory";
00061 }
00062
00063 memcpy(m_pChars, str, nLen);
00064 }
00065 }
00066
00067 MHOctetString::MHOctetString(const unsigned char *str, int nLen)
00068 {
00069 m_nLength = nLen;
00070
00071 if (nLen == 0)
00072 {
00073 m_pChars = 0;
00074 }
00075 else
00076 {
00077 m_pChars = (unsigned char *)malloc(nLen);
00078
00079 if (! m_pChars)
00080 {
00081 throw "Out of memory";
00082 }
00083
00084 memcpy(m_pChars, str, nLen);
00085 }
00086 }
00087
00088
00089 MHOctetString::MHOctetString(const MHOctetString &str, int nOffset, int nLen)
00090 {
00091 if (nLen < 0)
00092 {
00093 nLen = str.Size() - nOffset;
00094 }
00095
00096 if (nLen < 0)
00097 {
00098 nLen = 0;
00099 }
00100
00101 if (nLen > str.Size())
00102 {
00103 nLen = str.Size();
00104 }
00105
00106 m_nLength = nLen;
00107
00108 if (nLen == 0)
00109 {
00110 m_pChars = 0;
00111 }
00112 else
00113 {
00114 m_pChars = (unsigned char *)malloc(nLen);
00115
00116 if (! m_pChars)
00117 {
00118 throw "Out of memory";
00119 }
00120
00121 memcpy(m_pChars, str.m_pChars + nOffset, nLen);
00122 }
00123 }
00124
00125 MHOctetString::~MHOctetString()
00126 {
00127 free(m_pChars);
00128 }
00129
00130
00131 void MHOctetString::Copy(const MHOctetString &str)
00132 {
00133 free(m_pChars);
00134 m_pChars = NULL;
00135 m_nLength = str.m_nLength;
00136
00137 if (str.m_pChars)
00138 {
00139
00140 m_pChars = (unsigned char *)malloc(m_nLength + 1);
00141
00142 if (m_pChars == NULL)
00143 {
00144 throw "Out of memory";
00145 }
00146
00147 memcpy(m_pChars, str.m_pChars, m_nLength);
00148 m_pChars[m_nLength] = 0;
00149 }
00150 }
00151
00152
00153
00154 void MHOctetString::PrintMe(FILE *fd, int ) const
00155 {
00156 putc('\'', fd);
00157
00158 for (int i = 0; i < m_nLength; i++)
00159 {
00160 unsigned char ch = m_pChars[i];
00161
00162
00163 if (ch == '=' || ch == '\'' || ch < ' ' || ch >= 127)
00164 {
00165 fprintf(fd, "=%02X", ch);
00166 }
00167 else
00168 {
00169 putc(ch, fd);
00170 }
00171 }
00172
00173 putc('\'', fd);
00174 }
00175
00176
00177 int MHOctetString::Compare(const MHOctetString &str) const
00178 {
00179 int nLength = m_nLength;
00180
00181 if (nLength > str.m_nLength)
00182 {
00183 nLength = str.m_nLength;
00184 }
00185
00186
00187 int nTest = 0;
00188
00189 if (nLength > 0)
00190 {
00191 nTest = memcmp(str.m_pChars, m_pChars, nLength);
00192 }
00193
00194
00195 if (nTest != 0)
00196 {
00197 return nTest;
00198 }
00199
00200
00201 if (m_nLength == str.m_nLength)
00202 {
00203 return 0;
00204 }
00205 else if (m_nLength < str.m_nLength)
00206 {
00207 return -1;
00208 }
00209 else
00210 {
00211 return 1;
00212 }
00213 }
00214
00215
00216 void MHOctetString::Append(const MHOctetString &str)
00217 {
00218 if (str.m_nLength == 0)
00219 {
00220 return;
00221 }
00222
00223 int newLen = m_nLength + str.m_nLength;
00224
00225 unsigned char *p = (unsigned char *)realloc(m_pChars, newLen);
00226
00227 if (p == NULL)
00228 {
00229 throw "Out of memory";
00230 }
00231
00232 m_pChars = p;
00233
00234 memcpy(m_pChars + m_nLength, str.m_pChars, str.m_nLength);
00235 m_nLength = newLen;
00236 }
00237
00238
00239 void MHColour::Initialise(MHParseNode *p, MHEngine * )
00240 {
00241 if (p->m_nNodeType == MHParseNode::PNInt)
00242 {
00243 m_nColIndex = p->GetIntValue();
00244 }
00245 else
00246 {
00247 p->GetStringValue(m_ColStr);
00248 }
00249 }
00250
00251 void MHColour::PrintMe(FILE *fd, int nTabs) const
00252 {
00253 if (m_nColIndex >= 0)
00254 {
00255 fprintf(fd, " %d ", m_nColIndex);
00256 }
00257 else
00258 {
00259 m_ColStr.PrintMe(fd, nTabs);
00260 }
00261 }
00262
00263 void MHColour::SetFromString(const char *str, int nLen)
00264 {
00265 m_nColIndex = -1;
00266 m_ColStr.Copy(MHOctetString(str, nLen));
00267 }
00268
00269 void MHColour::Copy(const MHColour &col)
00270 {
00271 m_nColIndex = col.m_nColIndex;
00272 m_ColStr.Copy(col.m_ColStr);
00273 }
00274
00275
00276
00277
00278 MHObjectRef MHObjectRef::Null;
00279
00280
00281 void MHObjectRef::Initialise(MHParseNode *p, MHEngine *engine)
00282 {
00283 if (p->m_nNodeType == MHParseNode::PNInt)
00284 {
00285 m_nObjectNo = p->GetIntValue();
00286
00287 m_GroupId.Copy(engine->GetGroupId());
00288 }
00289 else if (p->m_nNodeType == MHParseNode::PNSeq)
00290 {
00291 MHParseNode *pFirst = p->GetSeqN(0);
00292 MHOctetString groupId;
00293 pFirst->GetStringValue(m_GroupId);
00294 m_nObjectNo = p->GetSeqN(1)->GetIntValue();
00295 }
00296 else
00297 {
00298 p->Failure("ObjectRef: Argument is not int or sequence");
00299 }
00300 }
00301
00302 void MHObjectRef::PrintMe(FILE *fd, int nTabs) const
00303 {
00304 if (m_GroupId.Size() == 0)
00305 {
00306 fprintf(fd, " %d ", m_nObjectNo);
00307 }
00308 else
00309 {
00310 fprintf(fd, " ( ");
00311 m_GroupId.PrintMe(fd, nTabs);
00312 fprintf(fd, " %d ) ", m_nObjectNo);
00313 }
00314 }
00315
00316 QString MHObjectRef::Printable() const
00317 {
00318 if (m_GroupId.Size() == 0)
00319 {
00320 return QString(" %1 ").arg(m_nObjectNo);
00321 }
00322 else
00323 {
00324 return QString(" ( ") + m_GroupId.Printable() + QString(" %1 ").arg(m_nObjectNo);
00325 }
00326 }
00327
00328
00329 void MHObjectRef::Copy(const MHObjectRef &objr)
00330 {
00331 m_nObjectNo = objr.m_nObjectNo;
00332 m_GroupId.Copy(objr.m_GroupId);
00333 }
00334
00335
00336
00337 bool MHObjectRef::Equal(const MHObjectRef &objr, MHEngine *engine) const
00338 {
00339 return m_nObjectNo == objr.m_nObjectNo && engine->GetPathName(m_GroupId) == engine->GetPathName(objr.m_GroupId);
00340 }
00341
00342 bool MHContentRef::Equal(const MHContentRef &cr, MHEngine *engine) const
00343 {
00344 return engine->GetPathName(m_ContentRef) == engine->GetPathName(cr.m_ContentRef);
00345 }
00346
00347
00348
00349 void MHGenericBoolean::Initialise(MHParseNode *pArg, MHEngine *engine)
00350 {
00351 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE)
00352 {
00353
00354 m_fIsDirect = false;
00355 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00356 }
00357 else
00358 {
00359 m_fIsDirect = true;
00360 m_fDirect = pArg->GetBoolValue();
00361 }
00362 }
00363
00364 void MHGenericBoolean::PrintMe(FILE *fd, int nTabs) const
00365 {
00366 if (m_fIsDirect)
00367 {
00368 fprintf(fd, "%s ", m_fDirect ? "true" : "false");
00369 }
00370 else
00371 {
00372 fprintf(fd, ":IndirectRef ");
00373 m_Indirect.PrintMe(fd, nTabs + 1);
00374 }
00375 }
00376
00377
00378 bool MHGenericBoolean::GetValue(MHEngine *engine) const
00379 {
00380 if (m_fIsDirect)
00381 {
00382 return m_fDirect;
00383 }
00384 else
00385 {
00386 MHUnion result;
00387 MHRoot *pBase = engine->FindObject(m_Indirect);
00388 pBase->GetVariableValue(result, engine);
00389 result.CheckType(MHUnion::U_Bool);
00390 return result.m_fBoolVal;
00391 }
00392 }
00393
00394
00395 MHObjectRef *MHGenericBase::GetReference()
00396 {
00397 if (m_fIsDirect)
00398 {
00399 MHERROR("Expected indirect reference");
00400 }
00401
00402 return &m_Indirect;
00403 }
00404
00405 void MHGenericInteger::Initialise(MHParseNode *pArg, MHEngine *engine)
00406 {
00407 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE)
00408 {
00409
00410 m_fIsDirect = false;
00411 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00412 }
00413 else
00414 {
00415 m_fIsDirect = true;
00416 m_nDirect = pArg->GetIntValue();
00417 }
00418 }
00419
00420 void MHGenericInteger::PrintMe(FILE *fd, int nTabs) const
00421 {
00422 if (m_fIsDirect)
00423 {
00424 fprintf(fd, "%d ", m_nDirect);
00425 }
00426 else
00427 {
00428 fprintf(fd, ":IndirectRef ");
00429 m_Indirect.PrintMe(fd, nTabs + 1);
00430 }
00431 }
00432
00433
00434 int MHGenericInteger::GetValue(MHEngine *engine) const
00435 {
00436 if (m_fIsDirect)
00437 {
00438 return m_nDirect;
00439 }
00440 else
00441 {
00442 MHUnion result;
00443 MHRoot *pBase = engine->FindObject(m_Indirect);
00444 pBase->GetVariableValue(result, engine);
00445
00446
00447
00448
00449 if (result.m_Type == MHUnion::U_String)
00450 {
00451
00452 int v = 0;
00453 int p = 0;
00454 bool fNegative = false;
00455
00456 if (result.m_StrVal.Size() > 0 && result.m_StrVal.GetAt(0) == '-')
00457 {
00458 p++;
00459 fNegative = true;
00460 }
00461
00462 for (; p < result.m_StrVal.Size(); p++)
00463 {
00464 unsigned char ch = result.m_StrVal.GetAt(p);
00465
00466 if (ch < '0' || ch > '9')
00467 {
00468 break;
00469 }
00470
00471 v = v * 10 + ch - '0';
00472 }
00473
00474 if (fNegative)
00475 {
00476 return -v;
00477 }
00478 else
00479 {
00480 return v;
00481 }
00482 }
00483 else
00484 {
00485 result.CheckType(MHUnion::U_Int);
00486 return result.m_nIntVal;
00487 }
00488 }
00489 }
00490
00491 void MHGenericOctetString::Initialise(MHParseNode *pArg, MHEngine *engine)
00492 {
00493 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE)
00494 {
00495
00496 m_fIsDirect = false;
00497 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00498 }
00499 else
00500 {
00501 m_fIsDirect = true;
00502 pArg->GetStringValue(m_Direct);
00503 }
00504 }
00505
00506 void MHGenericOctetString::PrintMe(FILE *fd, int ) const
00507 {
00508 if (m_fIsDirect)
00509 {
00510 m_Direct.PrintMe(fd, 0);
00511 }
00512 else
00513 {
00514 fprintf(fd, ":IndirectRef ");
00515 m_Indirect.PrintMe(fd, 0);
00516 }
00517 }
00518
00519
00520 void MHGenericOctetString::GetValue(MHOctetString &str, MHEngine *engine) const
00521 {
00522 if (m_fIsDirect)
00523 {
00524 str.Copy(m_Direct);
00525 }
00526 else
00527 {
00528 MHUnion result;
00529 MHRoot *pBase = engine->FindObject(m_Indirect);
00530 pBase->GetVariableValue(result, engine);
00531
00532
00533
00534
00535 if (result.m_Type == MHUnion::U_Int)
00536 {
00537
00538 char buff[30];
00539 #ifdef _WIN32
00540 _snprintf(buff, sizeof(buff), "%0d", result.m_nIntVal);
00541 #else
00542 snprintf(buff, sizeof(buff), "%0d", result.m_nIntVal);
00543 #endif
00544 str.Copy(buff);
00545 }
00546 else
00547 {
00548 result.CheckType(MHUnion::U_String);
00549 str.Copy(result.m_StrVal);
00550 }
00551 }
00552 }
00553
00554 void MHGenericObjectRef::Initialise(MHParseNode *pArg, MHEngine *engine)
00555 {
00556 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE)
00557 {
00558
00559 m_fIsDirect = false;
00560 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00561 }
00562 else
00563 {
00564 m_fIsDirect = true;
00565 m_ObjRef.Initialise(pArg, engine);
00566 }
00567 }
00568
00569 void MHGenericObjectRef::PrintMe(FILE *fd, int nTabs) const
00570 {
00571 if (m_fIsDirect)
00572 {
00573 m_ObjRef.PrintMe(fd, nTabs + 1);
00574 }
00575 else
00576 {
00577 fprintf(fd, ":IndirectRef ");
00578 m_Indirect.PrintMe(fd, nTabs + 1);
00579 }
00580 }
00581
00582
00583 void MHGenericObjectRef::GetValue(MHObjectRef &ref, MHEngine *engine) const
00584 {
00585 if (m_fIsDirect)
00586 {
00587 ref.Copy(m_ObjRef);
00588 }
00589 else
00590 {
00591 MHUnion result;
00592 MHRoot *pBase = engine->FindObject(m_Indirect);
00593 pBase->GetVariableValue(result, engine);
00594 result.CheckType(MHUnion::U_ObjRef);
00595 ref.Copy(result.m_ObjRefVal);
00596 }
00597 }
00598
00599 void MHGenericContentRef::Initialise(MHParseNode *pArg, MHEngine *engine)
00600 {
00601 if (pArg->GetTagNo() == C_INDIRECTREFERENCE)
00602 {
00603
00604 m_fIsDirect = false;
00605 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00606 }
00607 else if (pArg->GetTagNo() == C_CONTENT_REFERENCE)
00608 {
00609 m_fIsDirect = true;
00610 m_Direct.Initialise(pArg->GetArgN(0), engine);
00611 }
00612 else
00613 {
00614 MHERROR("Expected direct or indirect content reference");
00615 }
00616 }
00617
00618 void MHGenericContentRef::PrintMe(FILE *fd, int ) const
00619 {
00620 if (m_fIsDirect)
00621 {
00622 m_Direct.PrintMe(fd, 0);
00623 }
00624 else
00625 {
00626 fprintf(fd, ":IndirectRef ");
00627 m_Indirect.PrintMe(fd, 0);
00628 }
00629 }
00630
00631
00632 void MHGenericContentRef::GetValue(MHContentRef &ref, MHEngine *engine) const
00633 {
00634 if (m_fIsDirect)
00635 {
00636 ref.Copy(m_Direct);
00637 }
00638 else
00639 {
00640 MHUnion result;
00641 MHRoot *pBase = engine->FindObject(m_Indirect);
00642 pBase->GetVariableValue(result, engine);
00643 result.CheckType(MHUnion::U_ContentRef);
00644 ref.Copy(result.m_ContentRefVal);
00645 }
00646 }
00647
00648
00649 void MHUnion::GetValueFrom(const MHParameter &value, MHEngine *engine)
00650 {
00651 switch (value.m_Type)
00652 {
00653 case MHParameter::P_Int:
00654 m_Type = U_Int;
00655 m_nIntVal = value.m_IntVal.GetValue(engine);
00656 break;
00657 case MHParameter::P_Bool:
00658 m_Type = U_Bool;
00659 m_fBoolVal = value.m_BoolVal.GetValue(engine);
00660 break;
00661 case MHParameter::P_String:
00662 m_Type = U_String;
00663 value.m_StrVal.GetValue(m_StrVal, engine);
00664 break;
00665 case MHParameter::P_ObjRef:
00666 m_Type = U_ObjRef;
00667 value.m_ObjRefVal.GetValue(m_ObjRefVal, engine);
00668 break;
00669 case MHParameter::P_ContentRef:
00670 m_Type = U_ContentRef;
00671 value.m_ContentRefVal.GetValue(m_ContentRefVal, engine);
00672 break;
00673 case MHParameter::P_Null:
00674 m_Type = U_None;
00675 break;
00676 }
00677 }
00678
00679 const char *MHUnion::GetAsString(enum UnionTypes t)
00680 {
00681 switch (t)
00682 {
00683 case U_Int:
00684 return "int";
00685 case U_Bool:
00686 return "bool";
00687 case U_String:
00688 return "string";
00689 case U_ObjRef:
00690 return "objref";
00691 case U_ContentRef:
00692 return "contentref";
00693 case U_None:
00694 return "none";
00695 }
00696
00697 return "";
00698 }
00699
00700 void MHUnion::CheckType(enum UnionTypes t) const
00701 {
00702 if (m_Type != t)
00703 {
00704 MHERROR(QString("Type mismatch - expected %1 found %2").arg(GetAsString(m_Type)).arg(GetAsString(t)));
00705 }
00706 }
00707
00708
00709
00710 void MHParameter::Initialise(MHParseNode *p, MHEngine *engine)
00711 {
00712 switch (p->GetTagNo())
00713 {
00714 case C_NEW_GENERIC_BOOLEAN:
00715 m_Type = P_Bool;
00716 m_BoolVal.Initialise(p->GetArgN(0), engine);
00717 break;
00718 case C_NEW_GENERIC_INTEGER:
00719 m_Type = P_Int;
00720 m_IntVal.Initialise(p->GetArgN(0), engine);
00721 break;
00722 case C_NEW_GENERIC_OCTETSTRING:
00723 m_Type = P_String;
00724 m_StrVal.Initialise(p->GetArgN(0), engine);
00725 break;
00726 case C_NEW_GENERIC_OBJECT_REF:
00727 m_Type = P_ObjRef;
00728 m_ObjRefVal.Initialise(p->GetArgN(0), engine);
00729 break;
00730 case C_NEW_GENERIC_CONTENT_REF:
00731 m_Type = P_ContentRef;
00732 m_ContentRefVal.Initialise(p->GetArgN(0), engine);
00733 break;
00734 default:
00735 p->Failure("Expected generic");
00736 }
00737 }
00738
00739 void MHParameter::PrintMe(FILE *fd, int nTabs) const
00740 {
00741 PrintTabs(fd, nTabs);
00742
00743 switch (m_Type)
00744 {
00745
00746 case P_Int:
00747 fprintf(fd, ":GInteger ");
00748 m_IntVal.PrintMe(fd, 0);
00749 break;
00750 case P_Bool:
00751 fprintf(fd, ":GBoolean ");
00752 m_BoolVal.PrintMe(fd, 0);
00753 break;
00754 case P_String:
00755 fprintf(fd, ":GOctetString ");
00756 m_StrVal.PrintMe(fd, 0);
00757 break;
00758 case P_ObjRef:
00759 fprintf(fd, ":GObjectRef ");
00760 m_ObjRefVal.PrintMe(fd, 0);
00761 break;
00762 case P_ContentRef:
00763 fprintf(fd, ":GObjectRef ");
00764 m_ContentRefVal.PrintMe(fd, 0);
00765 break;
00766 case P_Null:
00767 break;
00768 }
00769 }
00770
00771
00772
00773
00774 MHObjectRef *MHParameter::GetReference()
00775 {
00776 switch (m_Type)
00777 {
00778 case P_Int:
00779 return m_IntVal.GetReference();
00780 case P_Bool:
00781 return m_BoolVal.GetReference();
00782 case P_String:
00783 return m_StrVal.GetReference();
00784 case P_ObjRef:
00785 return m_ObjRefVal.GetReference();
00786 case P_ContentRef:
00787 return m_ContentRefVal.GetReference();
00788 case P_Null:
00789 return NULL;
00790 }
00791
00792 return NULL;
00793 }
00794
00795
00796 MHContentRef MHContentRef::Null;
00797
00798 void MHContentRef::Initialise(MHParseNode *p, MHEngine *)
00799 {
00800 p->GetStringValue(m_ContentRef);
00801 }
00802
00803 void MHFontBody::Initialise(MHParseNode *p, MHEngine *engine)
00804 {
00805 if (p->m_nNodeType == MHParseNode::PNString)
00806 {
00807 p->GetStringValue(m_DirFont);
00808 }
00809 else
00810 {
00811 m_IndirFont.Initialise(p, engine);
00812 }
00813 }
00814
00815 void MHFontBody::PrintMe(FILE *fd, int nTabs) const
00816 {
00817 if (m_DirFont.Size() > 0)
00818 {
00819 m_DirFont.PrintMe(fd, nTabs);
00820 }
00821 else
00822 {
00823 m_IndirFont.PrintMe(fd, nTabs);
00824 }
00825 }
00826
00827 void MHFontBody::Copy(const MHFontBody &fb)
00828 {
00829 m_DirFont.Copy(fb.m_DirFont);
00830 m_IndirFont.Copy(fb.m_IndirFont);
00831 }
00832
00833 void MHPointArg::Initialise(MHParseNode *p, MHEngine *engine)
00834 {
00835 x.Initialise(p->GetSeqN(0), engine);
00836 y.Initialise(p->GetSeqN(1), engine);
00837 }
00838
00839 void MHPointArg::PrintMe(FILE *fd, int nTabs) const
00840 {
00841 fprintf(fd, "( ");
00842 x.PrintMe(fd, nTabs);
00843 y.PrintMe(fd, nTabs);
00844 fprintf(fd, ") ");
00845 }
00846