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) nLen = strlen(str);
00044 m_nLength = nLen;
00045 if (nLen == 0) m_pChars = 0;
00046 else {
00047 m_pChars = (unsigned char*)malloc(nLen);
00048 if (! m_pChars) throw "Out of memory";
00049 memcpy(m_pChars, str, nLen);
00050 }
00051 }
00052
00053 MHOctetString::MHOctetString(const unsigned char *str, int nLen)
00054 {
00055 m_nLength = nLen;
00056 if (nLen == 0) m_pChars = 0;
00057 else {
00058 m_pChars = (unsigned char*)malloc(nLen);
00059 if (! m_pChars) throw "Out of memory";
00060 memcpy(m_pChars, str, nLen);
00061 }
00062 }
00063
00064
00065 MHOctetString::MHOctetString(const MHOctetString &str, int nOffset, int nLen)
00066 {
00067 if (nLen < 0) nLen = str.Size()-nOffset;
00068 if (nLen < 0) nLen = 0;
00069 if (nLen > str.Size()) nLen = str.Size();
00070 m_nLength = nLen;
00071 if (nLen == 0) m_pChars = 0;
00072 else {
00073 m_pChars = (unsigned char*)malloc(nLen);
00074 if (! m_pChars) throw "Out of memory";
00075 memcpy(m_pChars, str.m_pChars + nOffset, nLen);
00076 }
00077 }
00078
00079 MHOctetString::~MHOctetString()
00080 {
00081 free(m_pChars);
00082 }
00083
00084
00085 void MHOctetString::Copy(const MHOctetString &str)
00086 {
00087 free(m_pChars); m_pChars = NULL;
00088 m_nLength = str.m_nLength;
00089 if (str.m_pChars) {
00090
00091 m_pChars = (unsigned char*)malloc(m_nLength+1);
00092 if (m_pChars == NULL) throw "Out of memory";
00093 memcpy(m_pChars, str.m_pChars, m_nLength);
00094 m_pChars[m_nLength] = 0;
00095 }
00096 }
00097
00098
00099
00100 void MHOctetString::PrintMe(FILE *fd, int ) const
00101 {
00102 putc('\'', fd);
00103 for (int i = 0; i < m_nLength; i++) {
00104 unsigned char ch = m_pChars[i];
00105
00106 if (ch == '=' || ch == '\'' || ch < ' ' || ch >= 127) fprintf(fd, "=%02X", ch);
00107 else putc(ch, fd);
00108 }
00109 putc('\'', fd);
00110 }
00111
00112
00113 int MHOctetString::Compare(const MHOctetString &str) const
00114 {
00115 int nLength = m_nLength;
00116 if (nLength > str.m_nLength) nLength = str.m_nLength;
00117
00118 int nTest = 0;
00119 if (nLength > 0) nTest = memcmp(str.m_pChars, m_pChars, nLength);
00120
00121 if (nTest != 0) return nTest;
00122
00123 if (m_nLength == str.m_nLength) return 0;
00124 else if (m_nLength < str.m_nLength) return -1;
00125 else return 1;
00126 }
00127
00128
00129 void MHOctetString::Append(const MHOctetString &str)
00130 {
00131 if (str.m_nLength == 0) return;
00132 int newLen = m_nLength + str.m_nLength;
00133
00134 unsigned char *p = (unsigned char *)realloc(m_pChars, newLen);
00135 if (p == NULL) throw "Out of memory";
00136 m_pChars = p;
00137
00138 memcpy(m_pChars+m_nLength, str.m_pChars, str.m_nLength);
00139 m_nLength = newLen;
00140 }
00141
00142
00143 void MHColour::Initialise(MHParseNode *p, MHEngine *)
00144 {
00145 if (p->m_nNodeType == MHParseNode::PNInt) m_nColIndex = p->GetIntValue();
00146 else p->GetStringValue(m_ColStr);
00147 }
00148
00149 void MHColour::PrintMe(FILE *fd, int nTabs) const
00150 {
00151 if (m_nColIndex >= 0) fprintf(fd, " %d ", m_nColIndex);
00152 else m_ColStr.PrintMe(fd, nTabs);
00153 }
00154
00155 void MHColour::SetFromString(const char *str, int nLen)
00156 {
00157 m_nColIndex = -1;
00158 m_ColStr.Copy(MHOctetString(str, nLen));
00159 }
00160
00161 void MHColour::Copy(const MHColour &col)
00162 {
00163 m_nColIndex = col.m_nColIndex;
00164 m_ColStr.Copy(col.m_ColStr);
00165 }
00166
00167
00168
00169
00170 MHObjectRef MHObjectRef::Null;
00171
00172
00173 void MHObjectRef::Initialise(MHParseNode *p, MHEngine *engine)
00174 {
00175 if (p->m_nNodeType == MHParseNode::PNInt) {
00176 m_nObjectNo = p->GetIntValue();
00177
00178 m_GroupId.Copy(engine->GetGroupId());
00179 }
00180 else if (p->m_nNodeType == MHParseNode::PNSeq) {
00181 MHParseNode *pFirst = p->GetSeqN(0);
00182 MHOctetString groupId;
00183 pFirst->GetStringValue(m_GroupId);
00184 m_nObjectNo = p->GetSeqN(1)->GetIntValue();
00185 }
00186 else p->Failure("ObjectRef: Argument is not int or sequence");
00187 }
00188
00189 void MHObjectRef::PrintMe(FILE *fd, int nTabs) const
00190 {
00191 if (m_GroupId.Size() == 0) fprintf(fd, " %d ", m_nObjectNo);
00192 else {
00193 fprintf(fd, " ( ");
00194 m_GroupId.PrintMe(fd, nTabs);
00195 fprintf(fd, " %d ) ", m_nObjectNo);
00196 }
00197 }
00198
00199 QString MHObjectRef::Printable() const
00200 {
00201 if (m_GroupId.Size() == 0) return QString(" %1 ").arg(m_nObjectNo);
00202 else return QString(" ( ") + m_GroupId.Printable() + QString(" %1 ").arg(m_nObjectNo);
00203 }
00204
00205
00206 void MHObjectRef::Copy(const MHObjectRef &objr)
00207 {
00208 m_nObjectNo = objr.m_nObjectNo;
00209 m_GroupId.Copy(objr.m_GroupId);
00210 }
00211
00212
00213
00214 bool MHObjectRef::Equal(const MHObjectRef &objr, MHEngine *engine) const
00215 {
00216 return m_nObjectNo == objr.m_nObjectNo && engine->GetPathName(m_GroupId) == engine->GetPathName(objr.m_GroupId);
00217 }
00218
00219 bool MHContentRef::Equal(const MHContentRef &cr, MHEngine *engine) const
00220 {
00221 return engine->GetPathName(m_ContentRef) == engine->GetPathName(cr.m_ContentRef);
00222 }
00223
00224
00225
00226 void MHGenericBoolean::Initialise(MHParseNode *pArg, MHEngine *engine)
00227 {
00228 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE) {
00229
00230 m_fIsDirect = false;
00231 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00232 }
00233 else {
00234 m_fIsDirect = true;
00235 m_fDirect = pArg->GetBoolValue();
00236 }
00237 }
00238
00239 void MHGenericBoolean::PrintMe(FILE *fd, int nTabs) const
00240 {
00241 if (m_fIsDirect) fprintf(fd, "%s ", m_fDirect ? "true" : "false");
00242 else { fprintf(fd, ":IndirectRef "); m_Indirect.PrintMe(fd, nTabs+1); }
00243 }
00244
00245
00246 bool MHGenericBoolean::GetValue(MHEngine *engine) const
00247 {
00248 if (m_fIsDirect) return m_fDirect;
00249 else {
00250 MHUnion result;
00251 MHRoot *pBase = engine->FindObject(m_Indirect);
00252 pBase->GetVariableValue(result, engine);
00253 result.CheckType(MHUnion::U_Bool);
00254 return result.m_fBoolVal;
00255 }
00256 }
00257
00258
00259 MHObjectRef *MHGenericBase::GetReference()
00260 {
00261 if (m_fIsDirect) MHERROR("Expected indirect reference");
00262 return &m_Indirect;
00263 }
00264
00265 void MHGenericInteger::Initialise(MHParseNode *pArg, MHEngine *engine)
00266 {
00267 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE) {
00268
00269 m_fIsDirect = false;
00270 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00271 }
00272 else {
00273 m_fIsDirect = true;
00274 m_nDirect = pArg->GetIntValue();
00275 }
00276 }
00277
00278 void MHGenericInteger::PrintMe(FILE *fd, int nTabs) const
00279 {
00280 if (m_fIsDirect) fprintf(fd, "%d ", m_nDirect);
00281 else { fprintf(fd, ":IndirectRef "); m_Indirect.PrintMe(fd, nTabs+1); }
00282 }
00283
00284
00285 int MHGenericInteger::GetValue(MHEngine *engine) const
00286 {
00287 if (m_fIsDirect) return m_nDirect;
00288 else {
00289 MHUnion result;
00290 MHRoot *pBase = engine->FindObject(m_Indirect);
00291 pBase->GetVariableValue(result, engine);
00292
00293
00294
00295 if (result.m_Type == MHUnion::U_String) {
00296
00297 int v = 0;
00298 int p = 0;
00299 bool fNegative = false;
00300 if (result.m_StrVal.Size() > 0 && result.m_StrVal.GetAt(0) == '-') { p++; fNegative = true; }
00301 for ( ; p < result.m_StrVal.Size(); p++) {
00302 unsigned char ch = result.m_StrVal.GetAt(p);
00303 if (ch < '0' || ch > '9') break;
00304 v = v * 10 + ch - '0';
00305 }
00306 if (fNegative) return -v; else return v;
00307 }
00308 else {
00309 result.CheckType(MHUnion::U_Int);
00310 return result.m_nIntVal;
00311 }
00312 }
00313 }
00314
00315 void MHGenericOctetString::Initialise(MHParseNode *pArg, MHEngine *engine)
00316 {
00317 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE) {
00318
00319 m_fIsDirect = false;
00320 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00321 }
00322 else {
00323 m_fIsDirect = true;
00324 pArg->GetStringValue(m_Direct);
00325 }
00326 }
00327
00328 void MHGenericOctetString::PrintMe(FILE *fd, int ) const
00329 {
00330 if (m_fIsDirect) m_Direct.PrintMe(fd, 0);
00331 else { fprintf(fd, ":IndirectRef "); m_Indirect.PrintMe(fd, 0); }
00332 }
00333
00334
00335 void MHGenericOctetString::GetValue(MHOctetString &str, MHEngine *engine) const
00336 {
00337 if (m_fIsDirect) str.Copy(m_Direct);
00338 else {
00339 MHUnion result;
00340 MHRoot *pBase = engine->FindObject(m_Indirect);
00341 pBase->GetVariableValue(result, engine);
00342
00343
00344
00345 if (result.m_Type == MHUnion::U_Int) {
00346
00347 char buff[30];
00348 #ifdef WIN32
00349 _snprintf(buff, sizeof(buff), "%0d", result.m_nIntVal);
00350 #else
00351 snprintf(buff, sizeof(buff), "%0d", result.m_nIntVal);
00352 #endif
00353 str.Copy(buff);
00354 }
00355 else {
00356 result.CheckType(MHUnion::U_String);
00357 str.Copy(result.m_StrVal);
00358 }
00359 }
00360 }
00361
00362 void MHGenericObjectRef::Initialise(MHParseNode *pArg, MHEngine *engine)
00363 {
00364 if (pArg->m_nNodeType == MHParseNode::PNTagged && pArg->GetTagNo() == C_INDIRECTREFERENCE) {
00365
00366 m_fIsDirect = false;
00367 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00368 }
00369 else {
00370 m_fIsDirect = true;
00371 m_ObjRef.Initialise(pArg, engine);
00372 }
00373 }
00374
00375 void MHGenericObjectRef::PrintMe(FILE *fd, int nTabs) const
00376 {
00377 if (m_fIsDirect) m_ObjRef.PrintMe(fd, nTabs+1);
00378 else { fprintf(fd, ":IndirectRef "); m_Indirect.PrintMe(fd, nTabs+1); }
00379 }
00380
00381
00382 void MHGenericObjectRef::GetValue(MHObjectRef &ref, MHEngine *engine) const
00383 {
00384 if (m_fIsDirect) ref.Copy(m_ObjRef);
00385 else {
00386 MHUnion result;
00387 MHRoot *pBase = engine->FindObject(m_Indirect);
00388 pBase->GetVariableValue(result, engine);
00389 result.CheckType(MHUnion::U_ObjRef);
00390 ref.Copy(result.m_ObjRefVal);
00391 }
00392 }
00393
00394 void MHGenericContentRef::Initialise(MHParseNode *pArg, MHEngine *engine)
00395 {
00396 if (pArg->GetTagNo() == C_INDIRECTREFERENCE) {
00397
00398 m_fIsDirect = false;
00399 m_Indirect.Initialise(pArg->GetArgN(0), engine);
00400 }
00401 else if (pArg->GetTagNo() == C_CONTENT_REFERENCE){
00402 m_fIsDirect = true;
00403 m_Direct.Initialise(pArg->GetArgN(0), engine);
00404 }
00405 else MHERROR("Expected direct or indirect content reference");
00406 }
00407
00408 void MHGenericContentRef::PrintMe(FILE *fd, int ) const
00409 {
00410 if (m_fIsDirect) m_Direct.PrintMe(fd, 0);
00411 else { fprintf(fd, ":IndirectRef "); m_Indirect.PrintMe(fd, 0); }
00412 }
00413
00414
00415 void MHGenericContentRef::GetValue(MHContentRef &ref, MHEngine *engine) const
00416 {
00417 if (m_fIsDirect) ref.Copy(m_Direct);
00418 else {
00419 MHUnion result;
00420 MHRoot *pBase = engine->FindObject(m_Indirect);
00421 pBase->GetVariableValue(result, engine);
00422 result.CheckType(MHUnion::U_ContentRef);
00423 ref.Copy(result.m_ContentRefVal);
00424 }
00425 }
00426
00427
00428 void MHUnion::GetValueFrom(const MHParameter &value, MHEngine *engine)
00429 {
00430 switch (value.m_Type) {
00431 case MHParameter::P_Int: m_Type = U_Int; m_nIntVal = value.m_IntVal.GetValue(engine); break;
00432 case MHParameter::P_Bool: m_Type = U_Bool; m_fBoolVal = value.m_BoolVal.GetValue(engine); break;
00433 case MHParameter::P_String: m_Type = U_String; value.m_StrVal.GetValue(m_StrVal, engine); break;
00434 case MHParameter::P_ObjRef: m_Type = U_ObjRef; value.m_ObjRefVal.GetValue(m_ObjRefVal, engine); break;
00435 case MHParameter::P_ContentRef: m_Type = U_ContentRef; value.m_ContentRefVal.GetValue(m_ContentRefVal, engine); break;
00436 case MHParameter::P_Null: m_Type = U_None; break;
00437 }
00438 }
00439
00440 const char *MHUnion::GetAsString(enum UnionTypes t)
00441 {
00442 switch (t) {
00443 case U_Int: return "int";
00444 case U_Bool: return "bool";
00445 case U_String: return "string";
00446 case U_ObjRef: return "objref";
00447 case U_ContentRef: return "contentref";
00448 case U_None: return "none";
00449 }
00450 return "";
00451 }
00452
00453 void MHUnion::CheckType(enum UnionTypes t) const
00454 {
00455 if (m_Type != t)
00456 MHERROR(QString("Type mismatch - expected %1 found %2").arg(GetAsString(m_Type)).arg(GetAsString(t)));
00457 }
00458
00459
00460
00461 void MHParameter::Initialise(MHParseNode *p, MHEngine *engine)
00462 {
00463 switch (p->GetTagNo()) {
00464 case C_NEW_GENERIC_BOOLEAN: m_Type = P_Bool; m_BoolVal.Initialise(p->GetArgN(0), engine); break;
00465 case C_NEW_GENERIC_INTEGER: m_Type = P_Int; m_IntVal.Initialise(p->GetArgN(0), engine); break;
00466 case C_NEW_GENERIC_OCTETSTRING: m_Type = P_String; m_StrVal.Initialise(p->GetArgN(0), engine); break;
00467 case C_NEW_GENERIC_OBJECT_REF: m_Type = P_ObjRef; m_ObjRefVal.Initialise(p->GetArgN(0), engine); break;
00468 case C_NEW_GENERIC_CONTENT_REF: m_Type = P_ContentRef; m_ContentRefVal.Initialise(p->GetArgN(0), engine); break;
00469 default: p->Failure("Expected generic");
00470 }
00471 }
00472
00473 void MHParameter::PrintMe(FILE *fd, int nTabs) const
00474 {
00475 PrintTabs(fd, nTabs);
00476 switch (m_Type) {
00477
00478 case P_Int: fprintf(fd, ":GInteger "); m_IntVal.PrintMe(fd, 0); break;
00479 case P_Bool: fprintf(fd, ":GBoolean "); m_BoolVal.PrintMe(fd, 0); break;
00480 case P_String: fprintf(fd, ":GOctetString "); m_StrVal.PrintMe(fd, 0); break;
00481 case P_ObjRef: fprintf(fd, ":GObjectRef "); m_ObjRefVal.PrintMe(fd, 0); break;
00482 case P_ContentRef: fprintf(fd, ":GObjectRef "); m_ContentRefVal.PrintMe(fd, 0); break;
00483 case P_Null: break;
00484 }
00485 }
00486
00487
00488
00489
00490 MHObjectRef *MHParameter::GetReference()
00491 {
00492 switch (m_Type) {
00493 case P_Int: return m_IntVal.GetReference();
00494 case P_Bool: return m_BoolVal.GetReference();
00495 case P_String: return m_StrVal.GetReference();
00496 case P_ObjRef: return m_ObjRefVal.GetReference();
00497 case P_ContentRef: return m_ContentRefVal.GetReference();
00498 case P_Null: return NULL;
00499 }
00500 return NULL;
00501 }
00502
00503
00504 MHContentRef MHContentRef::Null;
00505
00506 void MHContentRef::Initialise(MHParseNode *p, MHEngine *)
00507 {
00508 p->GetStringValue(m_ContentRef);
00509 }
00510
00511 void MHFontBody::Initialise(MHParseNode *p, MHEngine *engine)
00512 {
00513 if (p->m_nNodeType == MHParseNode::PNString) p->GetStringValue(m_DirFont);
00514 else m_IndirFont.Initialise(p, engine);
00515 }
00516
00517 void MHFontBody::PrintMe(FILE *fd, int nTabs) const
00518 {
00519 if (m_DirFont.Size() > 0) m_DirFont.PrintMe(fd, nTabs);
00520 else m_IndirFont.PrintMe(fd, nTabs);
00521 }
00522
00523 void MHFontBody::Copy(const MHFontBody &fb)
00524 {
00525 m_DirFont.Copy(fb.m_DirFont);
00526 m_IndirFont.Copy(fb.m_IndirFont);
00527 }
00528
00529 void MHPointArg::Initialise(MHParseNode *p, MHEngine *engine)
00530 {
00531 x.Initialise(p->GetSeqN(0), engine);
00532 y.Initialise(p->GetSeqN(1), engine);
00533 }
00534
00535 void MHPointArg::PrintMe(FILE *fd, int nTabs) const
00536 {
00537 fprintf(fd, "( "); x.PrintMe(fd, nTabs); y.PrintMe(fd, nTabs); fprintf(fd, ") ");
00538 }
00539