예제 #1
0
        /// <summary>
        /// Reads the string from input stream.
        /// </summary>
        private object ReadString()
        {
            int                    beginLine   = _input.Line;
            int                    beginOffset = _input.LineOffset + 1;
            int                    lastLine;
            int                    lastOffset;
            StringBuilder          buffer = new StringBuilder();
            StringBuilder          number = new StringBuilder();
            StringHelperStatusCode result = StringHelper.ReadStringChars(_input, buffer, number, true, out lastLine, out lastOffset);

            // throw exceptions for selected errors:
            switch (result)
            {
            case StringHelperStatusCode.UnexpectedEoF:
                throw new JSonReaderException("Unexpected end of text while reading a string", PopTopToken());

            case StringHelperStatusCode.UnexpectedNewLine:
                throw new JSonReaderException("Unexpected new line character in the middle of a string", buffer.ToString(), beginLine, beginOffset);

            case StringHelperStatusCode.UnknownEscapedChar:
                throw new JSonReaderException("Unknown escape combination", _input.CurrentChar.ToString(), lastLine, lastOffset);

            case StringHelperStatusCode.TooShortEscapedChar:
                throw new JSonReaderException("Invalid escape definition of Unicode character", _input.CurrentChar.ToString(), lastLine, lastOffset);

            case StringHelperStatusCode.TooLongEscapedChar:
                throw new JSonReaderException("Too long Unicode number definition", number.ToString(), lastLine, lastOffset);
            }

            // remove the beggining of the string token " from the top of the tokens stack
            PopTopToken();

            return(_factory.CreateString(buffer.ToString()));
        }
예제 #2
0
        /// <summary>
        /// Reads the string from given input stream.
        /// </summary>
        internal static StringHelperStatusCode ReadStringChars(IStringReader reader, StringBuilder output, StringBuilder escapedUnicodeNumberBuffer, bool errorOnNewLine, out int lastLine, out int lastOffset)
        {
            bool escape        = false;
            bool unicodeNumber = false;

            if (escapedUnicodeNumberBuffer == null)
            {
                escapedUnicodeNumberBuffer = new StringBuilder();
            }

            lastLine   = reader.Line;
            lastOffset = reader.LineOffset;

            do
            {
                if (!unicodeNumber)
                {
                    lastLine   = reader.Line;
                    lastOffset = reader.LineOffset;
                }

                var currentChar = reader.ReadNext();

                // verify if not an invalid character was found in text:
                if (reader.IsEof)
                {
                    return(StringHelperStatusCode.UnexpectedEoF);
                }
                if (errorOnNewLine && (currentChar == '\r' || currentChar == '\n'))
                {
                    return(StringHelperStatusCode.UnexpectedNewLine);
                }

                if (unicodeNumber)
                {
                    StringHelperStatusCode result = ReadStringUnicodeCharacter(currentChar, output, escapedUnicodeNumberBuffer, out unicodeNumber);

                    // if parsing Unicode character failed, immediatelly stop!
                    if (result != StringHelperStatusCode.Success)
                    {
                        return(result);
                    }

                    continue;
                }

                if (currentChar == '\\' && !escape)
                {
                    escape = true;
                }
                else
                {
                    if (escape)
                    {
                        switch (currentChar)
                        {
                        case 'n':
                            output.Append('\n');
                            break;

                        case 'r':
                            output.Append('\r');
                            break;

                        case 't':
                            output.Append('\t');
                            break;

                        case '/':
                            output.Append('/');
                            break;

                        case '\\':
                            output.Append('\\');
                            break;

                        case 'f':
                            output.Append('\f');
                            break;

                        case 'U':
                        case 'u':
                            unicodeNumber = true;
                            break;

                        case '"':
                            output.Append('"');
                            break;

                        case '\'':
                            output.Append('\'');
                            break;

                        default:
                            return(StringHelperStatusCode.UnknownEscapedChar);
                        }

                        escape = false;
                    }
                    else
                    {
                        if (currentChar == '"')
                        {
                            break;
                        }

                        output.Append(currentChar);
                    }
                }
            }while (true);

            // as the string might finish with a Unicode character...
            if (unicodeNumber)
            {
                return(AddUnicodeChar(output, escapedUnicodeNumberBuffer, false));
            }

            return(StringHelperStatusCode.Success);
        }
예제 #3
0
        private static StringList Read(IStringReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            // if there is nothing to read, return an empty instance:
            if (reader.IsEmpty)
            {
                return(new StringList());
            }

            StringBuilder               buffer         = new StringBuilder();
            StringBuilder               escapedUnicode = new StringBuilder();
            StringListToken             token;
            Dictionary <string, string> result = new Dictionary <string, string>();
            string key          = null;
            string value        = null;
            bool   identitySpot = false;

            do
            {
                token = ReadNextToken(reader);

                switch (token)
                {
                case StringListToken.CommentLine:
                    // skip till the end of line:
                    StringHelper.ReadCommentChars(reader, false);
                    break;

                case StringListToken.CommentMultiline:
                    StringHelper.ReadCommentChars(reader, true);
                    break;

                case StringListToken.Semicolon:
                    // verify if semicolon is at the end of the 'stable' state:
                    if (!string.IsNullOrEmpty(key))
                    {
                        if (identitySpot && value != null)
                        {
                            if (result.ContainsKey(key))
                            {
                                result[key] = value;
                            }
                            else
                            {
                                result.Add(key, value);
                            }

                            // reset state:
                            key          = null;
                            value        = null;
                            identitySpot = false;
                        }
                        else
                        {
                            if (identitySpot)
                            {
                                throw new FormatException("Incomplete definition at: (" + reader.Line + ":" + reader.LineOffset + ")");
                            }
                            throw new FormatException("Single text without valid assignment found: \"" + key + "\"");
                        }
                    }
                    break;

                case StringListToken.Identity:
                    if (identitySpot)
                    {
                        throw new FormatException("Double identity operator found");
                    }
                    identitySpot = true;
                    if (string.IsNullOrEmpty(key))
                    {
                        throw new FormatException("Empty assignment found");
                    }
                    break;

                case StringListToken.String:
                {
                    if (key != null && value != null)
                    {
                        throw new FormatException("Invalid definition found at: (" + reader.Line + ":" + reader.LineOffset + ")");
                    }

                    int lastLine;
                    int lastOffset;
                    StringHelperStatusCode status = StringHelper.ReadStringChars(reader, buffer, escapedUnicode, false, out lastLine, out lastOffset);

                    // throw exceptions for selected errors:
                    switch (status)
                    {
                    case StringHelperStatusCode.UnexpectedEoF:
                        throw new FormatException("Unexpected end of file while reading a string: \"" + buffer + "\"");

                    case StringHelperStatusCode.UnexpectedNewLine:
                        throw new FormatException("Unexpected new line character in the middle of a string: \"" + buffer + "\"");

                    case StringHelperStatusCode.UnknownEscapedChar:
                        throw new FormatException("Unknown escape combination: " + reader.CurrentChar);

                    case StringHelperStatusCode.TooShortEscapedChar:
                        throw new FormatException("Invalid escape definition of Unicode character: " + reader.CurrentChar);

                    case StringHelperStatusCode.TooLongEscapedChar:
                        throw new FormatException("Too long Unicode number definition: " + escapedUnicode);
                    }

                    if (identitySpot)
                    {
                        value = buffer.ToString();
                    }
                    else
                    {
                        if (key != null)
                        {
                            throw new FormatException("Missing identity operator");
                        }

                        key = buffer.ToString();
                    }
                    buffer.Remove(0, buffer.Length);
                }
                break;

                case StringListToken.Eof:

                    if (identitySpot)
                    {
                        throw new FormatException("Missing value for key at the end of the file");
                    }
                    if (!string.IsNullOrEmpty(key))
                    {
                        throw new FormatException("Missing definition for key at the of the file");
                    }

                    return(new StringList(result));

                case StringListToken.Invalid:
                    throw new FormatException("Invalid token found at (" + reader.Line + ":" + reader.LineOffset + ")");
                }
            }while (true);
        }