Ejemplo n.º 1
0
 internal DeserializationException(string msg, ref ThunkReader reader, Exception inner, bool endedEarly)
     : base(msg, inner)
 {
     SetMessage(msg);
     InspectReader(ref reader);
     EndedUnexpectedly = endedEarly;
 }
Ejemplo n.º 2
0
 static void _ConsumeThunkReader(ref ThunkReader tr, int ch)
 {
     while (ch != '\"' && ch != -1)
     {
         ch = tr.Read();
     }
 }
Ejemplo n.º 3
0
 internal DeserializationException(Exception inner, ref ThunkReader reader, bool endedEarly)
     : base(inner.Message, inner)
 {
     SetMessage(inner.Message);
     InspectReader(ref reader);
     EndedUnexpectedly = endedEarly;
 }
        static void _DeserializeMemberThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            Methods.ConsumeWhiteSpaceThunkReader(ref reader);

            var c = reader.Read();

            switch (c)
            {
                case '"': DeserializeStringThunkReader(ref reader, builder); return;
                case '[': DeserializeArrayThunkReader(ref reader, builder); return;
                case '{': DeserializeObjectThunkReader(ref reader, builder); return;
                case 'n': DeserializeNullThunkReader(ref reader, builder); return;
                case 't': DeserializeTrueThunkReader(ref reader, builder); return;
                case 'f': DeserializeFalseThunkReader(ref reader, builder); return;
                case '-': DeserializeNumberThunkReader('-', ref reader, builder); return;
            }

            if (c >= '0' && c <= '9')
            {
                DeserializeNumberThunkReader((char)c, ref reader, builder);
                return;
            }

            if (c == -1) throw new DeserializationException("Unexpected end of stream", ref reader, true);

            throw new DeserializationException("Expected \", [, {, n, t, f, -, 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9; found " + (char)c, ref reader, false);
        }
Ejemplo n.º 5
0
        public static void ConsumeWhiteSpaceThunkReader(ref ThunkReader reader)
        {
            int c;
            while ((c = reader.Peek()) != -1)
            {
                if (!IsWhiteSpace(c)) return;

                reader.Read();
            }
        }
Ejemplo n.º 6
0
            static int _ExpectUnicodeHexQuadThunkReader(ref ThunkReader reader)
            {
                var c = reader.Read();

                if (c != 'u')
                {
                    throw new DeserializationException("Escape sequence expected unicode hex quad", ref reader, c == -1);
                }

                return(Methods.ReadHexQuadThunkReader(ref reader));
            }
        static void DeserializeNullThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            var c = reader.Read();
            if (c != 'u') throw new DeserializationException("Expected u", ref reader, c == -1);
            c = reader.Read();
            if (c != 'l') throw new DeserializationException("Expected l", ref reader, c == -1);
            c = reader.Read();
            if (c != 'l') throw new DeserializationException("Expected l", ref reader, c == -1);

            builder.PutNull();
        }
        static void DeserializeTrueThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            var c = reader.Read();
            if (c != 'r') throw new DeserializationException("Expected r", ref reader, c == -1);
            c = reader.Read();
            if (c != 'u') throw new DeserializationException("Expected u", ref reader, c == -1);
            c = reader.Read();
            if (c != 'e') throw new DeserializationException("Expected e", ref reader, c == -1);

            builder.PutTrue();
        }
        static void DeserializeFalseThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            var c = reader.Read();
            if (c != 'a') throw new DeserializationException("Expected a", ref reader, c == -1);
            c = reader.Read();
            if (c != 'l') throw new DeserializationException("Expected l", ref reader, c == -1);
            c = reader.Read();
            if (c != 's') throw new DeserializationException("Expected s", ref reader, c == -1);
            c = reader.Read();
            if (c != 'e') throw new DeserializationException("Expected e", ref reader, c == -1);

            builder.PutFalse();
        }
        static void DeserializeArrayThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            int c;
            builder.StartArray();

            while (true)
            {
                Methods.ConsumeWhiteSpaceThunkReader(ref reader);

                c = reader.Peek();
                if (c == -1) throw new DeserializationException("Unexpected end of stream", ref reader, true);
                if (c == ']')
                {
                    reader.Read();  // skip the ]
                    break;
                }

                _DeserializeMemberThunkReader(ref reader, builder);
                Methods.ConsumeWhiteSpaceThunkReader(ref reader);
                c = reader.Read();

                if (c == ',') continue;
                if (c == ']') break;

                throw new DeserializationException("Expected , or ], found " + (char)c, ref reader, c == -1);
            }

            builder.EndArray();
        }
        static void DeserializeStringThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            var str = Methods.ReadEncodedStringWithBufferThunkReader(ref reader, builder.CommonCharBuffer, ref builder.CommonStringBuffer);

            builder.PutString(str);
        }
Ejemplo n.º 12
0
        public static string ReadEncodedStringWithBufferThunkReader(ref ThunkReader reader, char[] buffer, ref StringBuilder commonSb)
        {
            commonSb = commonSb ?? new StringBuilder();

            {
                var ix = 0;

                while (ix <= CharBufferSize)
                {
                    if (ix == CharBufferSize)
                    {
                        commonSb.Append(buffer, 0, ix);
                        break;
                    }

                    var first = reader.Read();
                    if (first == -1) throw new DeserializationException("Expected any character", ref reader, true);

                    // we didn't have to use anything but the buffer, make a string and return it!
                    if (first == '"')
                    {
                        // avoid an allocation here
                        if (ix == 0) return "";

                        return new string(buffer, 0, ix);
                    }

                    if (first != '\\')
                    {
                        buffer[ix] = (char)first;
                        ix++;
                        continue;
                    }

                    var second = reader.Read();
                    if (second == -1) throw new DeserializationException("Expected any character", ref reader, true);

                    switch (second)
                    {
                        case '"': buffer[ix] = '"'; ix++; continue;
                        case '\\': buffer[ix] = '\\'; ix++; continue;
                        case '/': buffer[ix] = '/'; ix++; continue;
                        case 'b': buffer[ix] = '\b'; ix++; continue;
                        case 'f': buffer[ix] = '\f'; ix++; continue;
                        case 'n': buffer[ix] = '\n'; ix++; continue;
                        case 'r': buffer[ix] = '\r'; ix++; continue;
                        case 't': buffer[ix] = '\t'; ix++; continue;
                    }

                    if (second != 'u') throw new DeserializationException("Unrecognized escape sequence", ref reader, false);

                    commonSb.Append(buffer, 0, ix);

                    // now we're in an escape sequence, we expect 4 hex #s; always
                    ReadHexQuadToBuilderThunkReader(ref reader, commonSb);
                    break;
                }
            }

            // fall through to using a StringBuilder

            while (true)
            {
                var first = reader.Read();
                if (first == -1) throw new DeserializationException("Expected any character", ref reader, true);

                if (first == '"')
                {
                    break;
                }

                if (first != '\\')
                {
                    commonSb.Append((char)first);
                    continue;
                }

                var second = reader.Read();
                if (second == -1) throw new DeserializationException("Expected any character", ref reader, true);

                switch (second)
                {
                    case '"': commonSb.Append('"'); continue;
                    case '\\': commonSb.Append('\\'); continue;
                    case '/': commonSb.Append('/'); continue;
                    case 'b': commonSb.Append('\b'); continue;
                    case 'f': commonSb.Append('\f'); continue;
                    case 'n': commonSb.Append('\n'); continue;
                    case 'r': commonSb.Append('\r'); continue;
                    case 't': commonSb.Append('\t'); continue;
                }

                if (second != 'u') throw new DeserializationException("Unrecognized escape sequence", ref reader, false);

                // now we're in an escape sequence, we expect 4 hex #s; always
                ReadHexQuadToBuilderThunkReader(ref reader, commonSb);
            }

            var ret = commonSb.ToString();

            // leave this clean for the next use
            commonSb.Clear();

            return ret;
        }
        static void DeserializeNumberThunkReader(char leadingChar, ref ThunkReader reader, ObjectBuilder builder)
        {
            if (!UseFastNumberParsing)
            {
                var number = Methods.ReadDoubleThunkReader(leadingChar, ref reader, ref builder.CommonStringBuffer);

                builder.PutNumber(number);

                return;
            }

            bool negative;
            ulong beforeDot;
            long afterE;
            uint afterDot;
            byte afterDotLen;
            byte extraOrdersOfMagnitude;

            if (leadingChar == '-')
            {
                var next = reader.Read();
                if (next != '-' && !(next >= '0' && next <= '9')) throw new DeserializationException("Expected -, or digit", ref reader, next == -1);

                leadingChar = (char)next;
                negative = true;
            }
            else
            {
                negative = false;
            }

            beforeDot = Methods.ReadULongThunkReader(leadingChar, ref reader, out extraOrdersOfMagnitude);
            var c = reader.Peek();
            if (c == '.')
            {
                reader.Read();
                c = reader.Read();
                if (c < '0' || c > '9') throw new DeserializationException("Expected digit", ref reader, c == -1);

                afterDot = Methods.ReadUIntThunkReader((char)c, ref reader, out afterDotLen);

                c = reader.Peek();
            }
            else
            {
                afterDot = afterDotLen = 0;
            }

            if (c == 'e' || c == 'E')
            {
                reader.Read();
                c = reader.Read();
                if (c == '+')
                {
                    c = reader.Read();
                }
                if (c != '-' && !(c >= '0' || c <= '9')) throw new DeserializationException("Expected -, +, or digit", ref reader, c == -1);
                afterE = Methods.ReadLongThunkReader((char)c, ref reader);
            }
            else
            {
                afterE = 0;
            }

            if (extraOrdersOfMagnitude != 0)
            {
                try
                {
                    checked
                    {
                        afterE += extraOrdersOfMagnitude;
                    }
                }
                catch (OverflowException)
                {
                    throw new DeserializationException("Number too large to be parsed encountered", ref reader, false);
                }
            }

            builder.PutFastNumber(negative, beforeDot, afterDot, afterDotLen, afterE);
        }
Ejemplo n.º 14
0
        static void ReadHexQuadToBuilderThunkReader(ref ThunkReader reader, StringBuilder commonSb)
        {
            var encodedChar = 0;

            //char1:
            {
                var c = reader.Read();
                if (c == -1) throw new DeserializationException("Unexpected end of reader", ref reader, true);

                c -= '0';
                if (c >= 0 && c <= 9)
                {
                    encodedChar += c;
                    goto char2;
                }

                c -= ('A' - '0');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto char2;
                }

                c -= ('f' - 'F');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto char2;
                }

                throw new DeserializationException("Expected hex digit, found: " + c, ref reader, false);
            }

            char2:
            encodedChar *= 16;
            {
                var c = reader.Read();
                if (c == -1) throw new DeserializationException("Unexpected end of reader", ref reader, true);

                c -= '0';
                if (c >= 0 && c <= 9)
                {
                    encodedChar += c;
                    goto char3;
                }

                c -= ('A' - '0');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto char3;
                }

                c -= ('f' - 'F');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto char3;
                }

                throw new DeserializationException("Expected hex digit, found: " + c, ref reader, false);
            }

            char3:
            encodedChar *= 16;
            {
                var c = reader.Read();
                if (c == -1) throw new DeserializationException("Unexpected end of reader", ref reader, true);

                c -= '0';
                if (c >= 0 && c <= 9)
                {
                    encodedChar += c;
                    goto char4;
                }

                c -= ('A' - '0');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto char4;
                }

                c -= ('f' - 'F');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto char4;
                }

                throw new DeserializationException("Expected hex digit, found: " + c, ref reader, false);
            }

            char4:
            encodedChar *= 16;
            {
                var c = reader.Read();
                if (c == -1) throw new DeserializationException("Unexpected end of reader", ref reader, true);

                c -= '0';
                if (c >= 0 && c <= 9)
                {
                    encodedChar += c;
                    goto finished;
                }

                c -= ('A' - '0');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto finished;
                }

                c -= ('f' - 'F');
                if (c >= 0 && c <= 5)
                {
                    encodedChar += 10 + c;
                    goto finished;
                }

                throw new DeserializationException("Expected hex digit, found: " + c, ref reader, false);
            }

            finished:
            commonSb.Append(Utils.SafeConvertFromUtf32(encodedChar));
        }
Ejemplo n.º 15
0
 public DeserializationException(string msg, ref ThunkReader reader, Exception inner, bool endedEarly)
     : base(msg, inner)
 {
     InspectReader(ref reader);
     EndedUnexpectedly = endedEarly;
 }
Ejemplo n.º 16
0
        void InspectReader(ref ThunkReader reader)
        {
            try
            {
                Position = reader.Position;

                var sb = new StringBuilder();

                int c;
                while ((c = reader.Read()) != -1 && sb.Length < 50)
                {
                    sb.Append((char)c);
                }

                SnippetAfterError = sb.ToString();
            }
            catch (Exception) { /* best effort here, things are already jacked */ }
        }
Ejemplo n.º 17
0
        public static double ReadDoubleThunkReader(char firstChar, ref ThunkReader reader, ref StringBuilder commonSb)
        {
            commonSb = commonSb ?? new StringBuilder();

            int c;

            int prev = firstChar;
            var afterFirstDigit = (firstChar >= '0' && firstChar <= '9');
            var afterE = false;
            var afterDot = false;

            commonSb.Append(firstChar);

            while ((c = reader.Peek()) != -1)
            {
                var isDigit = c >= '0' && c <= '9';
                if (!isDigit)
                {
                    var isPlus = c == '+';
                    if (isPlus)
                    {
                        if (!(prev == 'e' || prev == 'E'))
                        {
                            throw new DeserializationException("Unexpected +", ref reader, false);
                        }

                        goto storeChar;
                    }

                    var isMinus = c == '-';
                    if (isMinus)
                    {
                        if (!(prev == 'e' || prev == 'E'))
                        {
                            throw new DeserializationException("Unexpected -", ref reader, false);
                        }

                        goto storeChar;
                    }

                    var isE = c == 'e' || c == 'E';
                    if (isE)
                    {
                        if (afterE || !afterFirstDigit)
                        {
                            throw new DeserializationException("Unexpected " + c, ref reader, false);
                        }

                        afterE = true;
                        goto storeChar;
                    }

                    var isDot = c == '.';
                    if (isDot)
                    {
                        if (!afterFirstDigit || afterE || afterDot)
                        {
                            throw new DeserializationException("Unexpected .", ref reader, false);
                        }

                        afterDot = true;
                        goto storeChar;
                    }

                    break;
                }
                else
                {
                    afterFirstDigit = true;
                }

                storeChar:
                commonSb.Append((char)c);
                reader.Read();
                prev = c;
            }

            var result = double.Parse(commonSb.ToString(), CultureInfo.InvariantCulture);
            commonSb.Clear();
            return result;
        }
Ejemplo n.º 18
0
        public static long ReadLongThunkReader(char firstChar, ref ThunkReader reader)
        {
            var negate = false;
            long ret = 0;
            if (firstChar == '-')
            {
                negate = true;
            }
            else
            {
                ret = (firstChar - '0');
            }

            int c;
            while ((c = reader.Peek()) != -1)
            {
                c -= '0';
                if (c < 0 || c > 9) break;

                reader.Read();  // skip digit

                ret *= 10;
                ret += c;
            }

            if (negate) ret = -ret;

            return ret;
        }
Ejemplo n.º 19
0
        public static uint ReadUIntThunkReader(char firstChar, ref ThunkReader reader, out byte length)
        {
            length = 1;
            uint ret = (uint)(firstChar - '0');

            int c;
            while ((c = reader.Peek()) != -1)
            {
                c -= '0';
                if (c < 0 || c > 9) break;

                reader.Read();  // skip digit
                length++;

                ret *= 10;
                ret += (uint)c;
            }

            return ret;
        }
Ejemplo n.º 20
0
        public static ulong ReadULongThunkReader(char firstChar, ref ThunkReader reader, out byte overflowByPowersOfTen)
        {
            // ulong.MaxValue
            // ==============
            // 18446744073709551615
            // 123456789ABCDEFGHIJK
            //
            // Length: 20 

            overflowByPowersOfTen = 0;
            ulong ret;
            int c;

            var firstDigitZero = firstChar == '0';

            // char1
            ret = (ulong)(firstChar - '0');

            for (var i = 2; i < 20; i++)
            {
                c = reader.Peek();
                if (c < '0' || c > '9') return ret;
                reader.Read();

                if (firstDigitZero) throw new DeserializationException("Number cannot have leading zeros", ref reader, false);

                ret *= 10;
                ret += (uint)(c - '0');
            }

            // still more number to go?
            c = reader.Peek();
            if (c < '0' || c > '9') return ret;

            // now we need to see if we can pack this very last digit into the ulong
            //  this check is only necessary *now* because, due to base 10, you can't 
            //  overflow a ulong until the 20th digit
            var retCanBeMultiplied = (ulong.MaxValue / ret) >= 10;
            if (retCanBeMultiplied)
            {
                // remaining space will only be < 9 when we're really close
                //   to ulong.MaxValue (ie. we've read 1844674407370955161 
                //   and are now on the last digit, which could be [0, 5])
                var remainingSpace = (ulong.MaxValue - (ret * 10UL));
                var asAdd = (uint)(c - '0');
                if (asAdd <= remainingSpace)
                {
                    // we fit the criteria, advance!
                    reader.Read();
                    ret *= 10;
                    ret += asAdd;
                }
            }

            // now every character is just an extra order of magnitude for the exponent
            for (var i = 0; i < byte.MaxValue; i++)
            {
                c = reader.Peek();
                if (c < '0' || c > '9') return ret;
                reader.Read();
                overflowByPowersOfTen++;
            }

            throw new DeserializationException("Number too large to be parsed encountered", ref reader, false);
        }
Ejemplo n.º 21
0
 public static int FindSetterIndexThunkReader(ref ThunkReader reader)
 {
     return(_findMemberThunkReader(ref reader));
 }
        static void DeserializeObjectThunkReader(ref ThunkReader reader, ObjectBuilder builder)
        {
            int c;
            builder.StartObject();

            while (true)
            {
                Methods.ConsumeWhiteSpaceThunkReader(ref reader);

                c = reader.Peek();
                if (c == -1) throw new DeserializationException("Unexpected end of stream", ref reader, true);
                if (c == '}')
                {
                    reader.Read();  // skip }
                    break;
                }

                c = reader.Read();
                if (c == -1) throw new DeserializationException("Unexpected end of stream", ref reader, true);
                if (c != '"') throw new DeserializationException("Expected \", found " + (char)c, ref reader, false);

                builder.StartObjectMember();
                DeserializeStringThunkReader(ref reader, builder);

                Methods.ConsumeWhiteSpaceThunkReader(ref reader);
                c = reader.Read();
                if (c == -1) throw new DeserializationException("Unexpected end of stream", ref reader, true);
                if (c != ':') throw new DeserializationException("Expected :, found " + (char)c, ref reader, false);

                _DeserializeMemberThunkReader(ref reader, builder);

                builder.EndObjectMember();

                Methods.ConsumeWhiteSpaceThunkReader(ref reader);
                c = reader.Read();

                if (c == ',') continue;
                if (c == '}') break;

                if (c == -1) throw new DeserializationException("Unexpected end of stream", ref reader, true);

                throw new DeserializationException("Expected , or }, found " + (char)c, ref reader, false);
            }

            builder.EndObject();
        }
Ejemplo n.º 23
0
 public static EnumType GetEnumValueThunkReader(ref ThunkReader reader)
 {
     return(_getEnumValueThunkReader(ref reader));
 }
Ejemplo n.º 24
0
 public static int FindConstructorParameterIndexThunkReader(ref ThunkReader reader)
 {
     return(_findConstructorParameterIndexThunkReader(ref reader));
 }