Ejemplo n.º 1
0
        static (string, object) ReadObjectEntry(StringView input)
        {
#if SHARE_INTERNAL_METHODS
            input.TrimStart();
#endif

            if (input.Length < 1 || input[0] != '"')
            {
                throw new Exception($"Unexpected value at offset {input.offset}. Expected object-key string at {input.offset}");
            }


            string key = ReadString(input);
            input.TrimStart();

            if (input.Length == 0 || input[0] != ':')
            {
                throw new Exception($"Unexpected value at offset {input.offset}. Expected object key-value separator ':'");
            }

            input.Move(1);
            object value = ReadElement(input);

            return(key, value);
        }
Ejemplo n.º 2
0
        static IEnumerable <object> ReadArray(StringView input)
        {
#if SHARE_INTERNAL_METHODS
            input.TrimStart();
            if (input.Length < 1 || input[0] != '[')
            {
                throw new Exception($"No Array at offset {input.offset}");
            }
#endif
            input.Move(1);
            input.TrimStart();

            List <object> objects     = new List <object>();
            int           startOffset = input.offset;


            if (input.Length != 0 && input[0] == ']')
            {
                input.Move(1);
                return(objects);
            }

            while (true)
            {
                input.TrimStart();

#if ALLOW_TRAILING_ARRAY_COMMAS
                if (input.Length == 0 || input[0] == ']')
                {
                    break;
                }
#endif

                object child = ReadElement(input);
                objects.Add(child);


                input.TrimStart();
                if (input.Length == 0 || input[0] == ']')
                {
                    break;
                }

                if (input[0] != ',')
                {
                    throw new Exception($"Unexpected char at offset {input.offset}. Expected array separator ','");
                }
                input.Move(1);
            }

            if (input.Length == 0)
            {
                throw new Exception($"Array at offset {startOffset} isn't closed");
            }

            input.Move(1);
            return(objects);
        }
Ejemplo n.º 3
0
        static object ReadNumber(StringView input)
        {
#if SHARE_INTERNAL_METHODS
            input.TrimStart();
#endif

            int offset = -1;
            while (++offset < input.Length)
            {
                char c = input[offset];

                if (c == '.' || c == 'e')
                {
                    return(ReadDouble(input));
                }
                if (c == '-' && offset == 0)
                {
                    continue;
                }
                //ASCII 0 - 9
                if (c >= 0x30 && c <= 0x39)
                {
                    continue;
                }

                break;
            }

            return(ReadInt(input));
        }
Ejemplo n.º 4
0
        static object ReadJSON(StringView input)
        {
            object result = ReadElement(input);

            input.TrimStart();
            if (input.Length != 0)
            {
                throw new Exception($"Forbidden second root element at offset {input.offset}");
            }

            return(result);
        }
Ejemplo n.º 5
0
        static object ReadElement(StringView input)
        {
            input.TrimStart();
            if (input.Length == 0)
            {
                throw new Exception("Unexpected EOF");
            }

            char indicator = input[0];

            //ASCII 0 - 9
            if (indicator >= 0x30 && indicator <= 0x39)
            {
                return(ReadNumber(input));
            }

            switch (input[0])
            {
            case '{':
                return(ReadObject(input));

            case '[':
                return(ReadArray(input));

            case '"':
                return(ReadString(input));

            case '-':
                return(ReadNumber(input));

            case 't':
            case 'f':
                return(ReadBool(input));

            case 'n':
                return(ReadNull(input));
            }

            throw new Exception("Unknown value at pos " + input.offset);
        }
Ejemplo n.º 6
0
        static string ReadString(StringView input)
        {
#if SHARE_INTERNAL_METHODS
            input.TrimStart();
            if (input.Length < 1 || input[0] != '"')
            {
                throw new Exception($"No string at offset {input.offset}");
            }
#endif

            if (input.Length < 2)
            {
                throw new Exception($"Invalid string at offset {input.offset}");
            }

            input.Move(1);

            var  builder      = new StringBuilder();
            bool escape       = false;
            bool stringClosed = false;

            while (input.Length != 0)
            {
                char c = input[0];
                input.Move(1);

                if (escape)
                {
                    switch (c)
                    {
                    case '\\':
                        builder.Append('\\');
                        break;

                    case 'b':
                        builder.Append('\b');
                        break;

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

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

                    case 'n':
                        builder.Append('\n');
                        break;

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

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

                    case 'u':
                        builder.Append(ReadEscapedUnicodeChar());
                        break;

                    default:
                        throw new Exception($"Invalid string escape sequence at offset {input.offset - 2}");
                    }

                    escape = false;
                    continue;
                }

                if (c == '\\')
                {
                    escape = true;
                    continue;
                }
                if (c == '"')
                {
                    stringClosed = true;
                    break;
                }

                builder.Append(c);
            }

            if (!stringClosed)
            {
                throw new Exception($"String not closed at offset {input.offset}");
            }

            return(builder.ToString());


            char ReadEscapedUnicodeChar()
            {
                if (input.Length < 4)
                {
                    throw new Exception($"Invalid Unicode escape sequence at offset {input.offset}");
                }

                string hexChars = input.SubString(0, 4);

                foreach (var c in hexChars)
                {
                    if ((c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66))
                    {
                        continue;
                    }

                    throw new Exception($"Invalid Unicode escape sequence at offset {input.offset}");
                }

                input.Move(4);

                int unicodePos = int.Parse(hexChars, NumberStyles.HexNumber);

                return((char)unicodePos);
            }
        }
Ejemplo n.º 7
0
        static Dictionary <string, object> ReadObject(StringView input)
        {
#if SHARE_INTERNAL_METHODS
            input.TrimStart();
            if (input.Length < 1 || input[0] != '{')
            {
                throw new Exception($"No Object at offset {input.offset}");
            }
#endif
            input.Move(1);
            input.TrimStart();

            Dictionary <string, object> childs = new Dictionary <string, object>();
            int startOffset = input.offset;


            if (input.Length != 0 && input[0] == '}')
            {
                input.Move(1);
                return(childs);
            }

            while (true)
            {
                input.TrimStart();

#if ALLOW_TRAILING_OBJECT_COMMAS
                if (input.Length == 0 || input[0] == '}')
                {
                    break;
                }
#endif

                var(key, value) = ReadObjectEntry(input);
                if (childs.ContainsKey(key))
                {
                    throw new Exception($"Key '{key}' already exists in object at offset {startOffset}");
                }

                childs[key] = value;


                input.TrimStart();
                if (input.Length == 0 || input[0] == '}')
                {
                    break;
                }

                if (input[0] != ',')
                {
                    throw new Exception($"Unexpected char at offset {input.offset}. Expected object separator ','");
                }
                input.Move(1);
            }

            input.TrimStart();
            if (input.Length == 0)
            {
                throw new Exception($"Object at offset {startOffset} isn't closed");
            }

            input.Move(1);
            return(childs);
        }