Ejemplo n.º 1
0
        private bool TryReadEscapeChar(ref TextPosition end)
        {
            if (_c == '\\')
            {
                end = _position;
                NextChar();
                // 0 \ ' " a b f n r t v u0000-uFFFF x00-xFF
                switch (_c)
                {
                case 'b':
                    _textBuilder.Append('\b');
                    end = _position;
                    NextChar();
                    return(true);

                case 't':
                    _textBuilder.Append('\t');
                    end = _position;
                    NextChar();
                    return(true);

                case 'n':
                    _textBuilder.Append('\n');
                    end = _position;
                    NextChar();
                    return(true);

                case 'f':
                    _textBuilder.Append('\f');
                    end = _position;
                    NextChar();
                    return(true);

                case 'r':
                    _textBuilder.Append('\r');
                    end = _position;
                    NextChar();
                    return(true);

                case '"':
                    _textBuilder.Append('"');
                    end = _position;
                    NextChar();
                    return(true);

                case '\\':
                    _textBuilder.Append('\\');
                    end = _position;
                    NextChar();
                    return(true);

                // toml-specs:  When the last non-whitespace character on a line is a \,
                // it will be trimmed along with all whitespace (including newlines)
                // up to the next non-whitespace character or closing delimiter.
                case '\r':
                case '\n':
                    while (CharHelper.IsWhiteSpaceOrNewLine(_c))
                    {
                        end = _position;
                        NextChar();
                    }
                    return(true);

                case 'u':
                case 'U':
                {
                    var start = _position;
                    end = _position;
                    var maxCount = _c == 'u' ? 4 : 8;
                    NextChar();

                    // Must be followed 0 to 8 hex numbers (0-FFFFFFFF)
                    int i     = 0;
                    int value = 0;
                    for (; CharHelper.IsHexFunc(_c) && i < maxCount; i++)
                    {
                        value = (value << 4) + CharHelper.HexToDecimal(_c);
                        end   = _position;
                        NextChar();
                    }

                    if (i == maxCount)
                    {
                        if (!CharHelper.IsValidUnicodeScalarValue(value))
                        {
                            AddError($"Invalid Unicode scalar value [{value:X}]", start, start);
                        }
                        _textBuilder.AppendUtf32((char32)value);
                        return(true);
                    }
                }
                break;
                }

                AddError($"Unexpected escape character [{_c}] in string. Only b t n f r \\ \" u0000-uFFFF U00000000-UFFFFFFFF are allowed", _position, _position);
                return(false);
            }
            return(false);
        }