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()) MHERROR("Unexpected end of file");
00049 return m_data[m_p++];
00050 }
00051
00052
00053
00054 void MHParseBinary::ParseString(int endStr, MHOctetString &str)
00055 {
00056
00057 if (endStr == INDEFINITE_LENGTH)
00058 MHERROR("Indefinite length strings are not implemented");
00059 int nLength = endStr - m_p;
00060 unsigned char *stringValue = (unsigned char*)malloc(endStr - m_p);
00061 unsigned char *p = stringValue;
00062 while (m_p < endStr) *p++ = GetNextChar();
00063 str.Copy(MHOctetString((const char *)stringValue, nLength));
00064 free(stringValue);
00065 }
00066
00067
00068 int MHParseBinary::ParseInt(int endInt)
00069 {
00070 int intVal = 0;
00071 bool firstByte = true;
00072 if (endInt == INDEFINITE_LENGTH)
00073 MHERROR("Indefinite length integers are not implemented");
00074 while (m_p < endInt) {
00075 unsigned char ch = GetNextChar();
00076
00077
00078 if (firstByte && ch >= 128) intVal = -1;
00079 firstByte = false;
00080 intVal = (intVal << 8) | ch;
00081 }
00082 return intVal;
00083 }
00084
00085
00086
00087 MHParseNode *MHParseBinary::DoParse()
00088 {
00089 unsigned char ch;
00090
00091 enum { Universal, Context } tagClass = Universal;
00092
00093 int endOfItem;
00094 unsigned int tagNumber = 0;
00095
00096
00097 ch = GetNextChar();
00098
00099
00100
00101
00102 switch (ch & 0xC0) {
00103 case 0x00:
00104 tagClass = Universal;
00105 break;
00106 case 0x80:
00107 tagClass = Context;
00108 break;
00109 default:
00110 MHERROR(QString("Invalid tag class = %1").arg(ch, 0, 16));
00111 }
00112
00113
00114 tagNumber = ch & 0x1f;
00115 if (tagNumber == 0x1f) {
00116 tagNumber = 0;
00117 do {
00118 ch = GetNextChar();
00119 tagNumber = (tagNumber << 7) | (ch & 0x7f);
00120 } while (ch & 0x80);
00121 }
00122
00123
00124
00125
00126 ch = GetNextChar();
00127 if (ch & 0x80) {
00128 int lengthOfLength = ch & 0x7f;
00129 if (lengthOfLength == 0) endOfItem = INDEFINITE_LENGTH;
00130 else {
00131 endOfItem = 0;
00132 while (lengthOfLength--) {
00133 ch = GetNextChar();
00134 endOfItem = (endOfItem << 8) | ch;
00135 }
00136 endOfItem += m_p;
00137 }
00138 }
00139 else endOfItem = ch + m_p;
00140
00141 if (tagClass == Context) {
00142 MHPTagged *pNode = new MHPTagged(tagNumber);
00143 try {
00144
00145 switch (tagNumber) {
00146 case C_MULTIPLE_SELECTION:
00147 case C_OBSCURED_INPUT:
00148 case C_INITIALLY_AVAILABLE:
00149 case C_WRAP_AROUND:
00150 case C_TEXT_WRAPPING:
00151 case C_INITIALLY_ACTIVE:
00152 case C_MOVING_CURSOR:
00153 case C_SHARED:
00154 case C_ENGINE_RESP:
00155 case C_TILING:
00156 case C_BORDERED_BOUNDING_BOX:
00157 {
00158
00159
00160 if (m_p != endOfItem){
00161 int intVal = ParseInt(endOfItem);
00162 pNode->AddArg(new MHPBool(intVal != 0));
00163 }
00164 break;
00165 }
00166
00167 case C_INPUT_TYPE:
00168 case C_SLIDER_STYLE:
00169 case C_TERMINATION:
00170 case C_ORIENTATION:
00171 case C_HORIZONTAL_JUSTIFICATION:
00172 case C_BUTTON_STYLE:
00173 case C_START_CORNER:
00174 case C_LINE_ORIENTATION:
00175 case C_VERTICAL_JUSTIFICATION:
00176 case C_STORAGE:
00177 {
00178 if (m_p != endOfItem){
00179 int intVal = ParseInt(endOfItem);
00180 pNode->AddArg(new MHPEnum(intVal));
00181 }
00182 }
00183
00184 case C_INITIAL_PORTION:
00185 case C_STEP_SIZE:
00186 case C_INPUT_EVENT_REGISTER:
00187 case C_INITIAL_VALUE:
00188 case C_IP_CONTENT_HOOK:
00189 case C_MAX_VALUE:
00190 case C_MIN_VALUE:
00191 case C_LINE_ART_CONTENT_HOOK:
00192 case C_BITMAP_CONTENT_HOOK:
00193 case C_TEXT_CONTENT_HOOK:
00194 case C_STREAM_CONTENT_HOOK:
00195 case C_MAX_LENGTH:
00196 case C_CHARACTER_SET:
00197 case C_ORIGINAL_TRANSPARENCY:
00198 case C_ORIGINAL_GC_PRIORITY:
00199 case C_LOOPING:
00200 case C_ORIGINAL_LINE_STYLE:
00201 case C_STANDARD_VERSION:
00202 case C_ORIGINAL_LINE_WIDTH:
00203 case C_CONTENT_HOOK:
00204 case C_CONTENT_CACHE_PRIORITY:
00205 case C_COMPONENT_TAG:
00206 case C_ORIGINAL_VOLUME:
00207 case C_PROGRAM_CONNECTION_TAG:
00208 case C_CONTENT_SIZE:
00209 {
00210 if (m_p != endOfItem){
00211 int intVal = ParseInt(endOfItem);
00212 pNode->AddArg(new MHPInt(intVal));
00213 }
00214 }
00215
00216 case C_OBJECT_INFORMATION:
00217 case C_CONTENT_REFERENCE:
00218 case C_FONT_ATTRIBUTES:
00219 case C_CHAR_LIST:
00220 case C_NAME:
00221 case C_ORIGINAL_LABEL:
00222 {
00223
00224
00225 MHOctetString str;
00226 ParseString(endOfItem, str);
00227 pNode->AddArg(new MHPString(str));
00228 }
00229
00230 default:
00231 {
00232
00233
00234 if (endOfItem == INDEFINITE_LENGTH)
00235 MHERROR("Indefinite length arguments are not implemented");
00236 while (m_p < endOfItem) {
00237 pNode->AddArg(DoParse());
00238 }
00239 }
00240 }
00241 }
00242 catch (...) {
00243
00244 delete pNode;
00245 throw;
00246 }
00247 return pNode;
00248 }
00249 else {
00250
00251
00252 switch (tagNumber) {
00253 case U_BOOL:
00254 {
00255 int intVal = ParseInt(endOfItem);
00256 return new MHPBool(intVal != 0);
00257 }
00258 case U_INT:
00259 {
00260 int intVal = ParseInt(endOfItem);
00261 return new MHPInt(intVal);
00262 }
00263 case U_ENUM:
00264 {
00265 int intVal = ParseInt(endOfItem);
00266 return new MHPEnum(intVal);
00267 }
00268 case U_STRING:
00269 {
00270 MHOctetString str;
00271 ParseString(endOfItem, str);
00272 return new MHPString(str);
00273 }
00274 case U_NULL:
00275 {
00276 return new MHPNull;
00277 }
00278 case U_SEQUENCE:
00279 {
00280 MHParseSequence *pNode = new MHParseSequence();
00281 if (endOfItem == INDEFINITE_LENGTH)
00282 MHERROR("Indefinite length sequences are not implemented");
00283 try {
00284 while (m_p < endOfItem) {
00285 pNode->Append(DoParse());
00286 }
00287 }
00288 catch (...) {
00289
00290 delete pNode;
00291 throw;
00292 }
00293 return pNode;
00294 }
00295 default:
00296 MHERROR(QString("Unknown universal %1").arg(tagNumber));
00297 }
00298 }
00299 }