예제 #1
0
        static string ParseNumber(JsonContext ctx)
        {
            int start = ctx.Idx - 1;

            for (; ctx.Idx < ctx.Val.Length && IsNumber(ctx.Cur); ctx.Idx++)
            {
                ;
            }
            return(ctx.Val.Substring(start, ctx.Idx - start));
        }
예제 #2
0
        static int NextToken(JsonContext ctx)
        {
            for (; ctx.Idx < ctx.Val.Length && IsWhitespace(ctx.Cur); ctx.Idx++)
            {
                ;
            }
            if (ctx.Idx >= ctx.Val.Length)
            {
                return(T_NONE);
            }

            char c = ctx.Cur; ctx.Idx++;

            if (c == '{' || c == '}')
            {
                return(c);
            }
            if (c == '[' || c == ']')
            {
                return(c);
            }
            if (c == ',' || c == '"' || c == ':')
            {
                return(c);
            }

            if (IsNumber(c))
            {
                return(T_NUM);
            }
            ctx.Idx--;

            if (NextConstant(ctx, "true"))
            {
                return(T_TRUE);
            }
            if (NextConstant(ctx, "false"))
            {
                return(T_FALSE);
            }
            if (NextConstant(ctx, "null"))
            {
                return(T_NULL);
            }

            // invalid token
            ctx.Idx++; return(T_NONE);
        }
예제 #3
0
        static bool NextConstant(JsonContext ctx, string value)
        {
            if (ctx.Idx + value.Length > ctx.Val.Length)
            {
                return(false);
            }

            for (int i = 0; i < value.Length; i++)
            {
                if (ctx.Val[ctx.Idx + i] != value[i])
                {
                    return(false);
                }
            }

            ctx.Idx += value.Length; return(true);
        }
예제 #4
0
        static object ParseValue(int token, JsonContext ctx)
        {
            switch (token)
            {
            case '{': return(ParseObject(ctx));

            case '[': return(ParseArray(ctx));

            case '"': return(ParseString(ctx));

            case T_NUM:   return(ParseNumber(ctx));

            case T_TRUE:  return(true);

            case T_FALSE: return(false);

            case T_NULL:  return(null);

            default: return(null);
            }
        }
예제 #5
0
        static JsonArray ParseArray(JsonContext ctx)
        {
            JsonArray elements = new JsonArray();

            while (true)
            {
                int token = NextToken(ctx);
                if (token == ',')
                {
                    continue;
                }
                if (token == ']')
                {
                    return(elements);
                }

                if (token == T_NONE)
                {
                    ctx.Success = false; return(null);
                }
                elements.Add(ParseValue(token, ctx));
            }
        }
예제 #6
0
        static JsonObject ParseObject(JsonContext ctx)
        {
            JsonObject members = new JsonObject();

            while (true)
            {
                int token = NextToken(ctx);
                if (token == ',')
                {
                    continue;
                }
                if (token == '}')
                {
                    return(members);
                }

                if (token != '"')
                {
                    ctx.Success = false; return(null);
                }
                string key = ParseString(ctx);

                token = NextToken(ctx);
                if (token != ':')
                {
                    ctx.Success = false; return(null);
                }

                token = NextToken(ctx);
                if (token == T_NONE)
                {
                    ctx.Success = false; return(null);
                }

                members[key] = ParseValue(token, ctx);
            }
        }
예제 #7
0
 public static object ParseStream(JsonContext ctx)
 {
     return(ParseValue(NextToken(ctx), ctx));
 }
예제 #8
0
        static string ParseString(JsonContext ctx)
        {
            StringBuilder s = ctx.strBuffer; s.Length = 0;

            for (; ctx.Idx < ctx.Val.Length;)
            {
                char c = ctx.Cur; ctx.Idx++;
                if (c == '"')
                {
                    return(s.ToString());
                }
                if (c != '\\')
                {
                    s.Append(c); continue;
                }

                if (ctx.Idx >= ctx.Val.Length)
                {
                    break;
                }
                c = ctx.Cur; ctx.Idx++;
                if (c == '/' || c == '\\' || c == '"')
                {
                    s.Append(c); continue;
                }

                if (c != 'u')
                {
                    break;
                }
                if (ctx.Idx + 4 > ctx.Val.Length)
                {
                    break;
                }

                // form of \uYYYY
                int aH, aL, bH, bL;
                if (!PackedCol.UnHex(ctx.Val[ctx.Idx + 0], out aH))
                {
                    break;
                }
                if (!PackedCol.UnHex(ctx.Val[ctx.Idx + 1], out aL))
                {
                    break;
                }
                if (!PackedCol.UnHex(ctx.Val[ctx.Idx + 2], out bH))
                {
                    break;
                }
                if (!PackedCol.UnHex(ctx.Val[ctx.Idx + 3], out bL))
                {
                    break;
                }

                int codePoint = (aH << 12) | (aL << 8) | (bH << 4) | bL;
                // don't want control characters in names/software
                if (codePoint >= 32)
                {
                    s.Append((char)codePoint);
                }
                ctx.Idx += 4;
            }

            ctx.Success = false; return(null);
        }