예제 #1
0
            } // end constructor

            private bool CommandTreeRootStateHandler(char commandChar)
            {
                switch (commandChar)
                {
                case 'm':
                    _SelectGraphicsRendition(m_state.FinishParsingParams());
                    return(true);

                case '#':
                    m_state.CurrentCommandHandler = HashCommandStateHandler;
                    return(false);

                default:
                    throw new NotSupportedException(String.Format("The command code '{0}' (0x{1:x}) is not supported.", commandChar, (int)commandChar));
                }
            }
            } // end Write()

            /// <summary>
            ///    Returns the index of the first character past the control sequence (which
            ///    could be past the end of the string, or could be the start of another
            ///    control sequence).
            /// </summary>
            private int _HandleControlSequence(string s, int escIndex)
            {
                m_state.Begin(); // we may actually be continuing...

                char c;
                int  curIndex = escIndex;

                while (++curIndex < s.Length)
                {
                    c = s[curIndex];
                    if ((c >= '0') && (c <= '9'))
                    {
                        m_state.AccumParamDigit(((int)c) - 0x30);
                        continue;
                    }
                    else if (';' == c)
                    {
                        m_state.EnterParam();
                        continue;
                    }
                    else if (((c >= '@') && (c <= '~')) || (c == '#'))
                    {
                        if (_FindCommand(c, out Action <List <int> > command))
                        {
                            command(m_state.FinishParsingParams());
                            return(curIndex + 1);
                        }
                    }
                    else
                    {
                        // You're supposed to be able to have anonther character, like a space
                        // (0x20) before the command code character, but I'm not going to do that.

                        // TODO: Unfortunately, we can get into this scenario. Say somebody wrote a string to the
                        // output stream, and that string had control sequences. And say then somebody tried to process
                        // that string in a pipeline, for instance tried to find some property on it, that didn't
                        // exist, causing an error to be written, where the "target object" is the string... and stuff
                        // maybe gets truncated or ellipsis-ized... and then we're hosed. What should I do about this?
                        // Try to sanitize higher-level output? Seems daunting... Just reset state and ignore it? Hm.
                        m_state.Reset();
                        throw new ArgumentException(String.Format("Invalid command sequence character at position {0} (0x{1:x}).", curIndex, (int)c));
                    }
                }
                // Finished parsing the whole string--the control sequence must be broken across
                // strings.
                return(curIndex);
            } // end _HandleControlSequence()