// Get an argument with a specific tag. Returns NULL if it doesn't exist. // There is a defined order of tags for both the binary and textual representations. // Unfortunately they're not the same. public MHParseNode GetNamedArg(int nTag) { MHParseSequence pArgs = null; if (m_nNodeType == PNTagged) { pArgs = ((MHPTagged)this).Args; } else if (m_nNodeType == PNSeq) { pArgs = (MHParseSequence)this; } else { Failure("Expected tagged value or sequence"); } for (int i = 0; i < pArgs.Size; i++) { MHParseNode p = pArgs.GetAt(i); if (p != null && p.NodeType == PNTagged && ((MHPTagged)p).TagNo == nTag) { return(p); } } return(null); }
// Add an argument to the argument sequence. public void AddArg(MHParseNode node) { m_Args.Append(node); }
private MHParseNode DoParse() { MHParseNode pRes = null; switch (m_nType) { case PTStartSection: // Open curly bracket { NextSym(); // Should be followed by a tag. if (m_nType != PTTag) { Error("Expected ':' after '{'"); } MHPTagged pTag = new MHPTagged(m_nTag); pRes = pTag; NextSym(); while (m_nType != PTEndSection) { pTag.AddArg(DoParse()); } NextSym(); // Remove the close curly bracket. break; } case PTTag: // Tag on its own. { int nTag = m_nTag; MHPTagged pTag = new MHPTagged(nTag); pRes = pTag; NextSym(); switch (nTag) { case ASN1Codes.C_ITEMS: case ASN1Codes.C_LINK_EFFECT: case ASN1Codes.C_ACTIVATE: case ASN1Codes.C_ADD: case ASN1Codes.C_ADD_ITEM: case ASN1Codes.C_APPEND: case ASN1Codes.C_BRING_TO_FRONT: case ASN1Codes.C_CALL: case ASN1Codes.C_CALL_ACTION_SLOT: case ASN1Codes.C_CLEAR: case ASN1Codes.C_CLONE: case ASN1Codes.C_CLOSE_CONNECTION: case ASN1Codes.C_DEACTIVATE: case ASN1Codes.C_DEL_ITEM: case ASN1Codes.C_DESELECT: case ASN1Codes.C_DESELECT_ITEM: case ASN1Codes.C_DIVIDE: case ASN1Codes.C_DRAW_ARC: case ASN1Codes.C_DRAW_LINE: case ASN1Codes.C_DRAW_OVAL: case ASN1Codes.C_DRAW_POLYGON: case ASN1Codes.C_DRAW_POLYLINE: case ASN1Codes.C_DRAW_RECTANGLE: case ASN1Codes.C_DRAW_SECTOR: case ASN1Codes.C_FORK: case ASN1Codes.C_GET_AVAILABILITY_STATUS: case ASN1Codes.C_GET_BOX_SIZE: case ASN1Codes.C_GET_CELL_ITEM: case ASN1Codes.C_GET_CURSOR_POSITION: case ASN1Codes.C_GET_ENGINE_SUPPORT: case ASN1Codes.C_GET_ENTRY_POINT: case ASN1Codes.C_GET_FILL_COLOUR: case ASN1Codes.C_GET_FIRST_ITEM: case ASN1Codes.C_GET_HIGHLIGHT_STATUS: case ASN1Codes.C_GET_INTERACTION_STATUS: case ASN1Codes.C_GET_ITEM_STATUS: case ASN1Codes.C_GET_LABEL: case ASN1Codes.C_GET_LAST_ANCHOR_FIRED: case ASN1Codes.C_GET_LINE_COLOUR: case ASN1Codes.C_GET_LINE_STYLE: case ASN1Codes.C_GET_LINE_WIDTH: case ASN1Codes.C_GET_LIST_ITEM: case ASN1Codes.C_GET_LIST_SIZE: case ASN1Codes.C_GET_OVERWRITE_MODE: case ASN1Codes.C_GET_PORTION: case ASN1Codes.C_GET_POSITION: case ASN1Codes.C_GET_RUNNING_STATUS: case ASN1Codes.C_GET_SELECTION_STATUS: case ASN1Codes.C_GET_SLIDER_VALUE: case ASN1Codes.C_GET_TEXT_CONTENT: case ASN1Codes.C_GET_TEXT_DATA: case ASN1Codes.C_GET_TOKEN_POSITION: case ASN1Codes.C_GET_VOLUME: case ASN1Codes.C_LAUNCH: case ASN1Codes.C_LOCK_SCREEN: case ASN1Codes.C_MODULO: case ASN1Codes.C_MOVE: case ASN1Codes.C_MOVE_TO: case ASN1Codes.C_MULTIPLY: case ASN1Codes.C_OPEN_CONNECTION: case ASN1Codes.C_PRELOAD: case ASN1Codes.C_PUT_BEFORE: case ASN1Codes.C_PUT_BEHIND: case ASN1Codes.C_QUIT: case ASN1Codes.C_READ_PERSISTENT: case ASN1Codes.C_RUN: case ASN1Codes.C_SCALE_BITMAP: case ASN1Codes.C_SCALE_VIDEO: case ASN1Codes.C_SCROLL_ITEMS: case ASN1Codes.C_SELECT: case ASN1Codes.C_SELECT_ITEM: case ASN1Codes.C_SEND_EVENT: case ASN1Codes.C_SEND_TO_BACK: case ASN1Codes.C_SET_BOX_SIZE: case ASN1Codes.C_SET_CACHE_PRIORITY: case ASN1Codes.C_SET_COUNTER_END_POSITION: case ASN1Codes.C_SET_COUNTER_POSITION: case ASN1Codes.C_SET_COUNTER_TRIGGER: case ASN1Codes.C_SET_CURSOR_POSITION: case ASN1Codes.C_SET_CURSOR_SHAPE: case ASN1Codes.C_SET_DATA: case ASN1Codes.C_SET_ENTRY_POINT: case ASN1Codes.C_SET_FILL_COLOUR: case ASN1Codes.C_SET_FIRST_ITEM: case ASN1Codes.C_SET_FONT_REF: case ASN1Codes.C_SET_HIGHLIGHT_STATUS: case ASN1Codes.C_SET_INTERACTION_STATUS: case ASN1Codes.C_SET_LABEL: case ASN1Codes.C_SET_LINE_COLOUR: case ASN1Codes.C_SET_LINE_STYLE: case ASN1Codes.C_SET_LINE_WIDTH: case ASN1Codes.C_SET_OVERWRITE_MODE: case ASN1Codes.C_SET_PALETTE_REF: case ASN1Codes.C_SET_PORTION: case ASN1Codes.C_SET_POSITION: case ASN1Codes.C_SET_SLIDER_VALUE: case ASN1Codes.C_SET_SPEED: case ASN1Codes.C_SET_TIMER: case ASN1Codes.C_SET_TRANSPARENCY: case ASN1Codes.C_SET_VARIABLE: case ASN1Codes.C_SET_VOLUME: case ASN1Codes.C_SPAWN: case ASN1Codes.C_STEP: case ASN1Codes.C_STOP: case ASN1Codes.C_STORE_PERSISTENT: case ASN1Codes.C_SUBTRACT: case ASN1Codes.C_TEST_VARIABLE: case ASN1Codes.C_TOGGLE: case ASN1Codes.C_TOGGLE_ITEM: case ASN1Codes.C_TRANSITION_TO: case ASN1Codes.C_UNLOAD: case ASN1Codes.C_UNLOCK_SCREEN: case ASN1Codes.C_CONTENT_REFERENCE: case ASN1Codes.C_TOKEN_GROUP_ITEMS: case ASN1Codes.C_POSITIONS: case ASN1Codes.C_MULTIPLEX: { // These are parenthesised in the text form. We have to remove the // parentheses otherwise we will return a sequence which will not be // be compatible with the binary form. if (m_nType != PTStartSeq) { Error("Expected '('"); } NextSym(); while (m_nType != PTEndSeq) { pTag.AddArg(DoParse()); } NextSym(); // Remove the close parenthesis. break; } case ASN1Codes.C_ORIGINAL_CONTENT: case ASN1Codes.C_NEW_GENERIC_BOOLEAN: case ASN1Codes.C_NEW_GENERIC_INTEGER: case ASN1Codes.C_NEW_GENERIC_OCTETSTRING: case ASN1Codes.C_NEW_GENERIC_OBJECT_REF: case ASN1Codes.C_NEW_GENERIC_CONTENT_REF: case ASN1Codes.C_ORIGINAL_VALUE: case ASN1Codes.C_INDIRECTREFERENCE: // These always have an argument which may be a tagged item. { // Is it always the case that there is at least one argument so if we haven't // had any arguments yet we should always process a tag as an argument? pTag.AddArg(DoParse()); break; } default: // This can be followed by an int, etc but a new tag is dealt with by the caller. while (m_nType == PTBool || m_nType == PTInt || m_nType == PTString || m_nType == PTEnum || m_nType == PTStartSeq) { pTag.AddArg(DoParse()); } break; } break; } case PTInt: { pRes = new MHPInt(m_nInt); NextSym(); break; } case PTBool: { pRes = new MHPBool(m_fBool); NextSym(); break; } case PTString: { MHOctetString str = new MHOctetString(); // str.Copy(MHOctetString((const char *)m_String, m_nStringLength)); str.Copy(m_String); pRes = new MHPString(str); NextSym(); break; } case PTEnum: { pRes = new MHPEnum(m_nInt); // ASSERT(m_nInt > 0); NextSym(); break; } case PTNull: { pRes = new MHPNull(); NextSym(); break; } case PTStartSeq: // Open parenthesis. { MHParseSequence pSeq = new MHParseSequence(); pRes = pSeq; NextSym(); while (m_nType != PTEndSeq) { pSeq.Append(DoParse()); } NextSym(); // Remove the close parenthesis. break; } default: Error("Unexpected symbol"); break; } return(pRes); }