00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "Engine.h"
00028 #include "ParseBinary.h"
00029 #include "ASN1Codes.h"
00030 #include "ParseNode.h"
00031 #include "BaseClasses.h"
00032 #include "Root.h"
00033 #include "Groups.h"
00034 #include "Logging.h"
00035
00036 MHParseBinary::MHParseBinary(QByteArray &program)
00037 {
00038 m_data = program;
00039 m_p = 0;
00040 }
00041
00042 #define INDEFINITE_LENGTH (-1)
00043
00044
00045
00046 unsigned char MHParseBinary::GetNextChar()
00047 {
00048 if (m_p >= (int)m_data.size())
00049 {
00050 MHERROR("Unexpected end of file");
00051 }
00052
00053 return m_data[m_p++];
00054 }
00055
00056
00057
00058 void MHParseBinary::ParseString(int endStr, MHOctetString &str)
00059 {
00060
00061 if (endStr == INDEFINITE_LENGTH)
00062 {
00063 MHERROR("Indefinite length strings are not implemented");
00064 }
00065
00066 int nLength = endStr - m_p;
00067 unsigned char *stringValue = (unsigned char *)malloc(endStr - m_p);
00068 unsigned char *p = stringValue;
00069
00070 while (m_p < endStr)
00071 {
00072 *p++ = GetNextChar();
00073 }
00074
00075 str.Copy(MHOctetString((const char *)stringValue, nLength));
00076 free(stringValue);
00077 }
00078
00079
00080 int MHParseBinary::ParseInt(int endInt)
00081 {
00082 int intVal = 0;
00083 bool firstByte = true;
00084
00085 if (endInt == INDEFINITE_LENGTH)
00086 {
00087 MHERROR("Indefinite length integers are not implemented");
00088 }
00089
00090 while (m_p < endInt)
00091 {
00092 unsigned char ch = GetNextChar();
00093
00094
00095
00096 if (firstByte && ch >= 128)
00097 {
00098 intVal = -1;
00099 }
00100
00101 firstByte = false;
00102 intVal = (intVal << 8) | ch;
00103 }
00104
00105 return intVal;
00106 }
00107
00108
00109
00110 MHParseNode *MHParseBinary::DoParse()
00111 {
00112 unsigned char ch;
00113
00114 enum { Universal, Context } tagClass = Universal;
00115
00116 int endOfItem;
00117 unsigned int tagNumber = 0;
00118
00119
00120 ch = GetNextChar();
00121
00122
00123
00124
00125 switch (ch & 0xC0)
00126 {
00127 case 0x00:
00128 tagClass = Universal;
00129 break;
00130 case 0x80:
00131 tagClass = Context;
00132 break;
00133 default:
00134 MHERROR(QString("Invalid tag class = %1").arg(ch, 0, 16));
00135 }
00136
00137
00138
00139 tagNumber = ch & 0x1f;
00140
00141 if (tagNumber == 0x1f)
00142 {
00143 tagNumber = 0;
00144
00145 do
00146 {
00147 ch = GetNextChar();
00148 tagNumber = (tagNumber << 7) | (ch & 0x7f);
00149 }
00150 while (ch & 0x80);
00151 }
00152
00153
00154
00155
00156 ch = GetNextChar();
00157
00158 if (ch & 0x80)
00159 {
00160 int lengthOfLength = ch & 0x7f;
00161
00162 if (lengthOfLength == 0)
00163 {
00164 endOfItem = INDEFINITE_LENGTH;
00165 }
00166 else
00167 {
00168 endOfItem = 0;
00169
00170 while (lengthOfLength--)
00171 {
00172 ch = GetNextChar();
00173 endOfItem = (endOfItem << 8) | ch;
00174 }
00175
00176 endOfItem += m_p;
00177 }
00178 }
00179 else
00180 {
00181 endOfItem = ch + m_p;
00182 }
00183
00184 if (tagClass == Context)
00185 {
00186 MHPTagged *pNode = new MHPTagged(tagNumber);
00187
00188 try
00189 {
00190
00191 switch (tagNumber)
00192 {
00193 case C_MULTIPLE_SELECTION:
00194 case C_OBSCURED_INPUT:
00195 case C_INITIALLY_AVAILABLE:
00196 case C_WRAP_AROUND:
00197 case C_TEXT_WRAPPING:
00198 case C_INITIALLY_ACTIVE:
00199 case C_MOVING_CURSOR:
00200 case C_SHARED:
00201 case C_ENGINE_RESP:
00202 case C_TILING:
00203 case C_BORDERED_BOUNDING_BOX:
00204 {
00205
00206
00207
00208 if (m_p != endOfItem)
00209 {
00210 int intVal = ParseInt(endOfItem);
00211 pNode->AddArg(new MHPBool(intVal != 0));
00212 }
00213
00214 break;
00215 }
00216
00217 case C_INPUT_TYPE:
00218 case C_SLIDER_STYLE:
00219 case C_TERMINATION:
00220 case C_ORIENTATION:
00221 case C_HORIZONTAL_JUSTIFICATION:
00222 case C_BUTTON_STYLE:
00223 case C_START_CORNER:
00224 case C_LINE_ORIENTATION:
00225 case C_VERTICAL_JUSTIFICATION:
00226 case C_STORAGE:
00227 {
00228
00229 if (m_p != endOfItem)
00230 {
00231 int intVal = ParseInt(endOfItem);
00232 pNode->AddArg(new MHPEnum(intVal));
00233 }
00234 }
00235
00236 case C_INITIAL_PORTION:
00237 case C_STEP_SIZE:
00238 case C_INPUT_EVENT_REGISTER:
00239 case C_INITIAL_VALUE:
00240 case C_IP_CONTENT_HOOK:
00241 case C_MAX_VALUE:
00242 case C_MIN_VALUE:
00243 case C_LINE_ART_CONTENT_HOOK:
00244 case C_BITMAP_CONTENT_HOOK:
00245 case C_TEXT_CONTENT_HOOK:
00246 case C_STREAM_CONTENT_HOOK:
00247 case C_MAX_LENGTH:
00248 case C_CHARACTER_SET:
00249 case C_ORIGINAL_TRANSPARENCY:
00250 case C_ORIGINAL_GC_PRIORITY:
00251 case C_LOOPING:
00252 case C_ORIGINAL_LINE_STYLE:
00253 case C_STANDARD_VERSION:
00254 case C_ORIGINAL_LINE_WIDTH:
00255 case C_CONTENT_HOOK:
00256 case C_CONTENT_CACHE_PRIORITY:
00257 case C_COMPONENT_TAG:
00258 case C_ORIGINAL_VOLUME:
00259 case C_PROGRAM_CONNECTION_TAG:
00260 case C_CONTENT_SIZE:
00261 {
00262
00263 if (m_p != endOfItem)
00264 {
00265 int intVal = ParseInt(endOfItem);
00266 pNode->AddArg(new MHPInt(intVal));
00267 }
00268 }
00269
00270 case C_OBJECT_INFORMATION:
00271 case C_CONTENT_REFERENCE:
00272 case C_FONT_ATTRIBUTES:
00273 case C_CHAR_LIST:
00274 case C_NAME:
00275 case C_ORIGINAL_LABEL:
00276 {
00277
00278
00279
00280 MHOctetString str;
00281 ParseString(endOfItem, str);
00282 pNode->AddArg(new MHPString(str));
00283 }
00284
00285 default:
00286 {
00287
00288
00289 if (endOfItem == INDEFINITE_LENGTH)
00290 {
00291 MHERROR("Indefinite length arguments are not implemented");
00292 }
00293
00294 while (m_p < endOfItem)
00295 {
00296 pNode->AddArg(DoParse());
00297 }
00298 }
00299 }
00300 }
00301 catch (...)
00302 {
00303
00304 delete pNode;
00305 throw;
00306 }
00307
00308 return pNode;
00309 }
00310 else
00311 {
00312
00313
00314 switch (tagNumber)
00315 {
00316 case U_BOOL:
00317 {
00318 int intVal = ParseInt(endOfItem);
00319 return new MHPBool(intVal != 0);
00320 }
00321 case U_INT:
00322 {
00323 int intVal = ParseInt(endOfItem);
00324 return new MHPInt(intVal);
00325 }
00326 case U_ENUM:
00327 {
00328 int intVal = ParseInt(endOfItem);
00329 return new MHPEnum(intVal);
00330 }
00331 case U_STRING:
00332 {
00333 MHOctetString str;
00334 ParseString(endOfItem, str);
00335 return new MHPString(str);
00336 }
00337 case U_NULL:
00338 {
00339 return new MHPNull;
00340 }
00341 case U_SEQUENCE:
00342 {
00343 MHParseSequence *pNode = new MHParseSequence();
00344
00345 if (endOfItem == INDEFINITE_LENGTH)
00346 {
00347 MHERROR("Indefinite length sequences are not implemented");
00348 }
00349
00350 try
00351 {
00352 while (m_p < endOfItem)
00353 {
00354 pNode->Append(DoParse());
00355 }
00356 }
00357 catch (...)
00358 {
00359
00360 delete pNode;
00361 throw;
00362 }
00363
00364 return pNode;
00365 }
00366 default:
00367 MHERROR(QString("Unknown universal %1").arg(tagNumber));
00368 }
00369 }
00370 }