Ejemplo n.º 1
0
        // Set this up from the parse tree.
        public override void Initialise(MHParseNode p, MHEngine engine)
        {
            // Set to empty before we start (just in case).
            engine.GetGroupId().Copy("");

            base.Initialise(p, engine);

            // Must be an external reference with an object number of zero.
            Logging.Assert(m_ObjectIdentifier.ObjectNo == 0 && m_ObjectIdentifier.GroupId.Size != 0);

            // Set the group id for the rest of the group to this.
            engine.GetGroupId().Copy(m_ObjectIdentifier.GroupId);

            // Some of the information is irrelevant.
            //  MHParseNode pStdId = p.GetNamedArg(C_STANDARD_IDENTIFIER);
            //  MHParseNode pStdVersion = p.GetNamedArg(C_STANDARD_VERSION);
            //  MHParseNode pObjectInfo = p.GetNamedArg(C_OBJECT_INFORMATION);

            MHParseNode pOnStartUp = p.GetNamedArg(ASN1Codes.C_ON_START_UP);

            if (pOnStartUp != null)
            {
                m_StartUp.Initialise(pOnStartUp, engine);
            }
            MHParseNode pOnCloseDown = p.GetNamedArg(ASN1Codes.C_ON_CLOSE_DOWN);

            if (pOnCloseDown != null)
            {
                m_CloseDown.Initialise(pOnCloseDown, engine);
            }
            MHParseNode pOriginalGCPrio = p.GetNamedArg(ASN1Codes.C_ORIGINAL_GC_PRIORITY);

            if (pOriginalGCPrio != null)
            {
                m_nOrigGroupCachePriority = pOriginalGCPrio.GetArgN(0).GetIntValue();
            }

            // Ignore the other stuff at the moment.
            MHParseNode pItems = p.GetNamedArg(ASN1Codes.C_ITEMS);

            if (pItems == null)
            {
                p.Failure("Missing :Items block");
            }
            for (int i = 0; i < pItems.GetArgCount(); i++)
            {
                MHParseNode  pItem       = pItems.GetArgN(i);
                MHIngredient pIngredient = null;

                // Generate the particular kind of ingredient.
                switch (pItem.GetTagNo())
                {
                case ASN1Codes.C_RESIDENT_PROGRAM: pIngredient = new MHResidentProgram(); break;

//  NOT UK                  case ASN1Codes.C_REMOTE_PROGRAM: pIngredient = new MHRemoteProgram(); break;
//  NOT UK                  case ASN1Codes.C_INTERCHANGED_PROGRAM: pIngredient = new MHInterChgProgram(); break;
//  NOT UK                  case ASN1Codes.C_PALETTE: pIngredient = new MHPalette(); break;
//  NOT UK                  case ASN1Codes.C_FONT: pIngredient = new MHFont(); break;
//  NOT UK                  case ASN1Codes.C_CURSOR_SHAPE: pIngredient = new MHCursorShape(); break;
                case ASN1Codes.C_BOOLEAN_VARIABLE: pIngredient = new MHBooleanVar(); break;

                case ASN1Codes.C_INTEGER_VARIABLE: pIngredient = new MHIntegerVar(); break;

                case ASN1Codes.C_OCTET_STRING_VARIABLE: pIngredient = new MHOctetStrVar(); break;

                case ASN1Codes.C_OBJECT_REF_VARIABLE: pIngredient = new MHObjectRefVar(); break;

                case ASN1Codes.C_CONTENT_REF_VARIABLE: pIngredient = new MHContentRefVar(); break;

                case ASN1Codes.C_LINK: pIngredient = new MHLink(); break;

                case ASN1Codes.C_STREAM: pIngredient = new MHStream(); break;

                case ASN1Codes.C_BITMAP: pIngredient = new MHBitmap(); break;

                case ASN1Codes.C_LINE_ART: pIngredient = new MHLineArt(); break;

                case ASN1Codes.C_DYNAMIC_LINE_ART: pIngredient = new MHDynamicLineArt(); break;

                case ASN1Codes.C_RECTANGLE: pIngredient = new MHRectangle(); break;

// NOT UK                   case ASN1Codes.C_HOTSPOT: pIngredient = new MHHotSpot(); break;
// NOT UK                   case ASN1Codes.C_SWITCH_BUTTON: pIngredient = new MHSwitchButton(); break;
// NOT UK                   case ASN1Codes.C_PUSH_BUTTON: pIngredient = new MHPushButton(); break;
                case ASN1Codes.C_TEXT: pIngredient = new MHText(); break;

                case ASN1Codes.C_ENTRY_FIELD: pIngredient = new MHEntryField(); break;

                case ASN1Codes.C_HYPER_TEXT: pIngredient = new MHHyperText(); break;

                case ASN1Codes.C_SLIDER: pIngredient = new MHSlider(); break;

                case ASN1Codes.C_TOKEN_GROUP: pIngredient = new MHTokenGroup(); break;

                case ASN1Codes.C_LIST_GROUP: pIngredient = new MHListGroup(); break;

                default:
                    // So we find out about these when debugging.
                    Logging.Log(Logging.MHLogError, "'" + pItem.GetTagNo() + "' tag not in switch");
                    Logging.Assert(false);

                    // Future proofing: ignore any ingredients that we don't know about.
                    // Obviously these can only arise in the binary coding.
                    break;
                }
                if (pIngredient != null)
                {
                    // Initialise it from its argments.
                    pIngredient.Initialise(pItem, engine);
                    // Remember the highest numbered ingredient
                    if (pIngredient.ObjectIdentifier.ObjectNo > m_nLastId)
                    {
                        m_nLastId = pIngredient.ObjectIdentifier.ObjectNo;
                    }
                    // Add it to the ingedients of this group.
                    m_Items.Append(pIngredient);
                }
            }
        }
Ejemplo n.º 2
0
        private void NextSym()
        {
            while (true)
            {
                switch (m_ch)
                {
                case '\n':
                    m_lineCount++; // And drop to next
                    goto case ' ';

                case ' ':
                case '\r':
                case '\t':
                case '\f':
                    // Skip white space.
                    GetNextChar();
                    continue;

                case '/':
                {     // Comment.
                    GetNextChar();
                    if (m_ch != '/')
                    {
                        Error("Malformed comment");
                    }
                    do
                    {
                        GetNextChar();
                    } while (m_ch != '\n' && m_ch != '\f' && m_ch != '\r');
                    continue;     // Next symbol
                }

                case ':': // Start of a tag
                {
                    m_nType = PTTag;
                    char[] buff = new char[MAX_TAG_LENGTH + 1];
                    int    p    = 0;
                    do
                    {
                        buff[p++] = (char)m_ch;
                        GetNextChar();
                        if (p == MAX_TAG_LENGTH)
                        {
                            break;
                        }
                    } while ((m_ch >= 'a' && m_ch <= 'z') || (m_ch >= 'A' && m_ch <= 'Z'));

                    // Look it up and return it if it's found.
                    m_nTag = FindTag(new string(buff, 0, p));
                    if (m_nTag >= 0)
                    {
                        return;
                    }
                    // Unrecognised tag.
                    Error("Unrecognised tag");
                    break;
                }

                case '"': // Start of a string
                {
                    m_nType = PTString;
                    // MHEG strings can include NULLs.  For the moment we pass back the length and also
                    // null-terminate the strings.
                    StringBuilder sb = new StringBuilder();
                    while (true)
                    {
                        GetNextChar();
                        if (m_ch == '"')
                        {
                            break;                  // Finished the string.
                        }
                        if (m_ch == '\\')
                        {
                            GetNextChar();                   // Escape character. Include the next char in the string.
                        }
                        if (m_ch == '\n' || m_ch == '\r')
                        {
                            Error("Unterminated string");
                        }

                        sb.Append((char)m_ch);
                    }
                    GetNextChar();     // Skip the closing quote
                    m_String        = sb.ToString();
                    m_nStringLength = sb.Length;
                    return;
                }

                case '\'': // Start of a string using quoted printable
                {
                    m_nType = PTString;
                    StringBuilder sb = new StringBuilder();
                    // Quotable printable strings contain escape sequences beginning with the
                    // escape character '='.  The strings can span lines but each line must
                    // end with an equal sign.
                    while (true)
                    {
                        GetNextChar();
                        if (m_ch == '\'')
                        {
                            break;
                        }
                        if (m_ch == '\n')
                        {
                            Error("Unterminated string");
                        }
                        if (m_ch == '=')       // Special code in quoted-printable.
                        // Should be followed by two hex digits or by white space and a newline.
                        {
                            GetNextChar();
                            if (m_ch == ' ' || m_ch == '\t' || m_ch == '\r' || m_ch == '\n')
                            {
                                // White space.  Remove everything up to the newline.
                                while (m_ch != '\n')
                                {
                                    if (!(m_ch == ' ' || m_ch == '\t' || m_ch == '\r'))
                                    {
                                        Error("Malformed quoted printable string");
                                    }
                                    GetNextChar();
                                }
                                continue;     // continue with the first character on the next line
                            }
                            else
                            {
                                int nByte = 0;
                                if (m_ch >= '0' && m_ch <= '9')
                                {
                                    nByte = m_ch - '0';
                                }
                                else if (m_ch >= 'A' && m_ch <= 'F')
                                {
                                    nByte = m_ch - 'A' + 10;
                                }
                                else if (m_ch >= 'a' && m_ch <= 'f')
                                {
                                    nByte = m_ch - 'a' + 10;
                                }
                                else
                                {
                                    Error("Malformed quoted printable string");
                                }
                                nByte *= 16;
                                GetNextChar();
                                if (m_ch >= '0' && m_ch <= '9')
                                {
                                    nByte += m_ch - '0';
                                }
                                else if (m_ch >= 'A' && m_ch <= 'F')
                                {
                                    nByte += m_ch - 'A' + 10;
                                }
                                else if (m_ch >= 'a' && m_ch <= 'f')
                                {
                                    nByte += m_ch - 'a' + 10;
                                }
                                else
                                {
                                    Error("Malformed quoted printable string");
                                }
                                m_ch = nByte;     // Put this into the string.
                            }
                        }
                        // We grow the buffer to the largest string in the input.

                        sb.Append((char)m_ch);
                    }
                    GetNextChar();     // Skip the closing quote
                    m_String        = sb.ToString();
                    m_nStringLength = sb.Length;
                    return;
                }

                case '`':                  // Start of a string using base 64
                    // These can, presumably span lines.
                    Logging.Assert(false); // TODO
                    break;

                case '#':                  // Start of 3-byte hex constant.
                    Logging.Assert(false); // TODO
                    break;

                case '-':
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                {
                    m_nType = PTInt;
                    bool negative = m_ch == '-';
                    if (negative)
                    {
                        GetNextChar();
                        if (m_ch < '0' || m_ch > '9')
                        {
                            Error("Expected digit after '-'");
                        }
                    }
                    // Start of a number.  Hex can be represented as 0xn.
                    // Strictly speaking hex values cannot be preceded by a minus sign.
                    m_nInt = m_ch - '0';
                    GetNextChar();
                    if (m_nInt == 0 && (m_ch == 'x' || m_ch == 'X'))
                    {
                        throw new MHEGException("TODO");
//                            ASSERT(FALSE); // TODO
                    }
                    while (m_ch >= '0' && m_ch <= '9')
                    {
                        m_nInt = m_nInt * 10 + m_ch - '0';
                        // TODO: What about overflow?
                        GetNextChar();
                    }
                    if (negative)
                    {
                        m_nInt = -m_nInt;
                    }
                    return;
                }

                case 'a':
                case 'b':
                case 'c':
                case 'd':
                case 'e':
                case 'f':
                case 'g':
                case 'h':
                case 'i':
                case 'j':
                case 'k':
                case 'l':
                case 'm':
                case 'n':
                case 'o':
                case 'p':
                case 'q':
                case 'r':
                case 's':
                case 't':
                case 'u':
                case 'v':
                case 'w':
                case 'x':
                case 'y':
                case 'z':
                case 'A':
                case 'B':
                case 'C':
                case 'D':
                case 'E':
                case 'F':
                case 'G':
                case 'H':
                case 'I':
                case 'J':
                case 'K':
                case 'L':
                case 'M':
                case 'N':
                case 'O':
                case 'P':
                case 'Q':
                case 'R':
                case 'S':
                case 'T':
                case 'U':
                case 'V':
                case 'W':
                case 'X':
                case 'Y':
                case 'Z':
                {     // Start of an enumerated type.
                    m_nType = PTEnum;
                    char[] buff = new char[MAX_ENUM + 1];
                    int    p    = 0;
                    do
                    {
                        buff[p++] = (char)m_ch;
                        GetNextChar();
                        if (p == MAX_ENUM)
                        {
                            break;
                        }
                    }while ((m_ch >= 'a' && m_ch <= 'z') || (m_ch >= 'A' && m_ch <= 'Z') || m_ch == '-');
                    string b = new string(buff, 0, p);
                    if (b.Equals("NULL"))
                    {
                        m_nType = PTNull; return;
                    }
                    if (b.Equals("true"))
                    {
                        m_nType = PTBool; m_fBool = true; return;
                    }
                    if (b.Equals("false"))
                    {
                        m_nType = PTBool; m_fBool = false; return;
                    }
                    // Look up the tag in all the tables.  Fortunately all the enumerations
                    // are distinct so we don't need to know the context.

                    m_nInt = MHLink.GetEventType(b);
                    if (m_nInt > 0)
                    {
                        return;
                    }

                    m_nInt = MHText.GetJustification(b);
                    if (m_nInt > 0)
                    {
                        return;
                    }
                    m_nInt = MHText.GetLineOrientation(b);
                    if (m_nInt > 0)
                    {
                        return;
                    }
                    m_nInt = MHText.GetStartCorner(b);
                    if (m_nInt > 0)
                    {
                        return;
                    }


                    // Check the colour table.  If it's there generate a string containing the colour info.
                    for (int i = 0; i < colourTable.Length; i++)
                    {
                        if (b.ToLower().Equals(colourTable[i].name))
                        {
                            m_nType = PTString;
                            string str = new string((char)colourTable[i].red, 1);
                            str            += (char)colourTable[i].green;
                            str            += (char)colourTable[i].blue;
                            str            += (char)colourTable[i].alpha;
                            m_String        = str;
                            m_nStringLength = 4;
                            return;
                        }
                    }

                    Error("Unrecognised enumeration");
                    break;
                }

                case '{': // Start of a "section".
                    // The standard indicates that open brace followed by a tag should be written
                    // as a single word.  We'll be more lenient and allow spaces or comments between them.
                    m_nType = PTStartSection;
                    GetNextChar();
                    return;

                case '}': // End of a "section".
                    m_nType = PTEndSection;
                    GetNextChar();
                    return;

                case '(': // Start of a sequence.
                    m_nType = PTStartSeq;
                    GetNextChar();
                    return;

                case ')': // End of a sequence.
                    m_nType = PTEndSeq;
                    GetNextChar();
                    return;

                case -1:
                    m_nType = PTEOF;
                    return;

                default:
                    Error("Unknown character");
                    GetNextChar();
                    break;
                }
            }
        }