예제 #1
0
        static object ReadInt(StringView input)
        {
            int offset = -1;

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

                if (c == '-' && offset == 0)
                {
                    continue;
                }
                //ASCII 0 - 9
                if (c >= 0x30 && c <= 0x39)
                {
                    continue;
                }

                break;
            }

            var intString = input.SubString(0, offset);

            input.Move(offset);


            try
            {
                long longValue = Convert.ToInt64(intString);

                //Previous versions always returned int32,
                //and asint32 is the most common data type
                //for numbers we return an int32 if possible
                if (longValue >= int.MinValue && longValue <= int.MaxValue)
                {
                    return((int)longValue);
                }


                return(longValue);
            }
            catch (OverflowException) { }

            try
            {
                return(Convert.ToUInt64(intString));
            }
            catch (OverflowException) { }

            return(Convert.ToDouble(intString));
        }
예제 #2
0
        static object ReadNull(StringView input)
        {
            if (input.Length < 4)
            {
                throw new Exception($"Unexpected value at offset {input.offset}");
            }

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

            input.Move(4);

            if (nullStr == "null")
            {
                return(null);
            }

            throw new Exception($"Unexpected value at offset {input.offset}");
        }
예제 #3
0
        static bool ReadBool(StringView input)
        {
            if (input.Length < 4)
            {
                throw new Exception($"Unexpected value at offset {input.offset}");
            }

            int offset = -1;

            while (++offset < input.Length)
            {
                char c = input[offset];
                //ASCII a - z
                if (c >= 0x61 && c <= 0x7a)
                {
                    continue;
                }

                break;
            }

            if (offset > 5)
            {
                throw new Exception($"Unexpected value at offset {input.offset}");
            }

            string boolStr = input.SubString(0, offset);

            input.Move(boolStr.Length);

            if (boolStr == "true")
            {
                return(true);
            }
            if (boolStr == "false")
            {
                return(false);
            }

            throw new Exception($"Unexpected value at offset {input.offset}");
        }
예제 #4
0
        static double ReadDouble(StringView input)
        {
            int nonNumberChars = 0;

            int doubleDotOffset = -1;
            int eOffset         = -1;
            int eSignOffset     = -1;

            int offset = -1;

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

                if (c == '-' && offset == 0)
                {
                    ++nonNumberChars;
                    continue;
                }
                if (c == '.' && doubleDotOffset == -1)
                {
                    if (offset == nonNumberChars)
                    {
                        throw new Exception($"Invalid float value at offset {input.offset}. Floats mustn't start with a dot");
                    }

                    doubleDotOffset = offset;
                    ++nonNumberChars;
                    continue;
                }
                if (c == 'e' && eOffset == -1)
                {
                    if (offset == nonNumberChars)
                    {
                        throw new Exception($"Invalid float value at offset {input.offset}. Floats mustn't start with an 'e'");
                    }

                    eOffset = offset;
                    ++nonNumberChars;
                    continue;
                }
                if ((c == '+' || c == '-') && eOffset != -1 && offset == eOffset + 1)
                {
                    eSignOffset = offset;
                    continue;
                }
                //ASCII 0 - 9
                if (c >= 0x30 && c <= 0x39)
                {
                    continue;
                }

                break;
            }

            if (doubleDotOffset == offset - 1)
            {
                throw new Exception($"Invalid float value at offset {input.offset}. Floats mustn't end with a dot");
            }
            if (eOffset == offset - 1)
            {
                throw new Exception($"Invalid float value at offset {input.offset}. Floats mustn't end with an 'e'");
            }
            if (eSignOffset == offset - 1)
            {
                throw new Exception($"Invalid float value at offset {input.offset}. Floats mustn't end with an 'e'-sign");
            }

            var doubleString = input.SubString(0, offset);

            input.Move(offset);

            return(Convert.ToDouble(doubleString, CultureInfo.InvariantCulture));
        }
예제 #5
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);
            }
        }