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)); }
public static object Parse(string s, out bool success) { JsonContext ctx = new JsonContext(); ctx.Val = s; ctx.Success = true; object obj = ParseStream(ctx); success = ctx.Success; return(obj); }
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 = Colors.UnHex(ctx.Val[ctx.Idx + 0]); int aL = Colors.UnHex(ctx.Val[ctx.Idx + 1]); int bH = Colors.UnHex(ctx.Val[ctx.Idx + 2]); int bL = Colors.UnHex(ctx.Val[ctx.Idx + 3]); if (aH == -1 || aL == -1 || bH == -1 || bL == -1) { break; } int codePoint = (aH << 12) | (aL << 8) | (bH << 4) | bL; s.Append((char)codePoint); ctx.Idx += 4; } ctx.Success = false; return(null); }
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); }
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); }
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); } }
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); } object value = ParseValue(token, ctx); members.Keys.Add(key); members.Values.Add(value); } }
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)); } }
static object ParseStream(JsonContext ctx) { return(ParseValue(NextToken(ctx), ctx)); }