Itenso.Rtf.Parser.RtfParser.HandleTag C# (CSharp) Method

HandleTag() private method

private HandleTag ( TextReader reader, IRtfTag tag ) : bool
reader TextReader
tag IRtfTag
return bool
        private bool HandleTag( TextReader reader, IRtfTag tag )
        {
            if ( level == 0 )
            {
                throw new RtfStructureException( Strings.TagOnRootLevel( tag.ToString() ) );
            }

            if ( tagCount < 4 )
            {
                // this only handles the initial encoding tag in the header section
                UpdateEncoding( tag );
            }

            string tagName = tag.Name;
            // enable the font name detection in case the last tag was introducing
            // a theme font
            bool detectFontName = expectingThemeFont;
            if ( tagCountAtLastGroupStart == tagCount )
            {
                // first tag in a group
                switch ( tagName )
                {
                    case RtfSpec.TagThemeFontLoMajor:
                    case RtfSpec.TagThemeFontHiMajor:
                    case RtfSpec.TagThemeFontDbMajor:
                    case RtfSpec.TagThemeFontBiMajor:
                    case RtfSpec.TagThemeFontLoMinor:
                    case RtfSpec.TagThemeFontHiMinor:
                    case RtfSpec.TagThemeFontDbMinor:
                    case RtfSpec.TagThemeFontBiMinor:
                        // these introduce a new font, but the actual font tag will be
                        // the second tag in the group, so we must remember this condition ...
                        expectingThemeFont = true;
                        break;
                }
                // always enable the font name detection also for the first tag in a group
                detectFontName = true;
            }
            if ( detectFontName )
            {
                // first tag in a group:
                switch ( tagName )
                {
                    case RtfSpec.TagFont:
                        if ( fontTableStartLevel > 0 )
                        {
                            // in the font-table definition:
                            // -> remember the target font for charset mapping
                            targetFont = tag.FullName;
                            expectingThemeFont = false; // reset that state now
                        }
                        break;
                    case RtfSpec.TagFontTable:
                        // -> remember we're in the font-table definition
                        fontTableStartLevel = level;
                        break;
                }
            }
            if ( targetFont != null )
            {
                // within a font-tables font definition: perform charset mapping
                if ( RtfSpec.TagFontCharset.Equals( tagName ) )
                {
                    int charSet = tag.ValueAsNumber;
                    int codePage = RtfSpec.GetCodePage( charSet );
                    fontToCodePageMapping[ targetFont ] = codePage;
                    UpdateEncoding( codePage );
                }
            }
            if ( fontToCodePageMapping.Count > 0 && RtfSpec.TagFont.Equals( tagName ) )
            {
                int? codePage = (int?)fontToCodePageMapping[ tag.FullName ];
                if ( codePage != null )
                {
                    UpdateEncoding( codePage.Value );
                }
            }

            bool skippedContent = false;
            switch ( tagName )
            {
                case RtfSpec.TagUnicodeCode:
                    int unicodeValue = tag.ValueAsNumber;
                    char unicodeChar = (char)unicodeValue;
                    curText.Append( unicodeChar );
                    // skip over the indicated number of 'alternative representation' text
                    for ( int i = 0; i < unicodeSkipCount; i++ )
                    {
                        int nextChar = PeekNextChar( reader, true );
                        switch ( nextChar )
                        {
                            case ' ':
                            case '\r':
                            case '\n':
                                reader.Read(); // consume peeked char
                                skippedContent = true;
                                if ( i == 0 )
                                {
                                    // the first whitespace after the tag
                                    // -> only a delimiter, doesn't count for skipping ...
                                    i--;
                                }
                                break;
                            case '\\':
                                reader.Read(); // consume peeked char
                                skippedContent = true;
                                int secondChar = ReadOneByte( reader ); // mandatory
                                switch ( secondChar )
                                {
                                    case '\'':
                                        // ok, this is a hex-encoded 'byte' -> need to consume both
                                        // hex digits too
                                        ReadOneByte( reader ); // high nibble
                                        ReadOneByte( reader ); // low nibble
                                        break;
                                }
                                break;
                            case '{':
                            case '}':
                                // don't consume peeked char and abort skipping
                                i = unicodeSkipCount;
                                break;
                            default:
                                reader.Read(); // consume peeked char
                                skippedContent = true;
                                break;
                        }
                    }
                    break;

                case RtfSpec.TagUnicodeSkipCount:
                    int newSkipCount = tag.ValueAsNumber;
                    if ( newSkipCount < 0 || newSkipCount > 10 )
                    {
                        throw new RtfUnicodeEncodingException( Strings.InvalidUnicodeSkipCount( tag.ToString() ) );
                    }
                    unicodeSkipCount = newSkipCount;
                    break;

                default:
                    FlushText();
                    NotifyTagFound( tag );
                    break;
            }

            tagCount++;

            return skippedContent;
        }