private object GetNumberFromString(MyStringReader jsonString, char ch) { StringBuilder sb = new StringBuilder(); sb.Append(ch); bool isFloatingPoint = false; while (true) { ch = jsonString.ReadChar(); if (!((ch >= '0' && ch <= '9') || ch == '.' || (isFloatingPoint && (ch == 'e' || ch == 'E' || ch == '-' || ch == '+')))) { jsonString.Position -= 1; break; } sb.Append(ch); if (ch == '.' && !isFloatingPoint) { isFloatingPoint = true; } else if (ch == '.' && isFloatingPoint) { throw new Exception("Invalid JSON document."); } } if (!isFloatingPoint) { int temp; if (int.TryParse(sb.ToString(), out temp)) { return(temp); } else { throw new Exception("Invalid JSON document."); } } else { double temp; if (double.TryParse(sb.ToString(), out temp)) { return(temp); } else { throw new Exception("Invalid JSON document."); } } }
private string GetStringFromString(MyStringReader jsonString) { char ch; StringBuilder sb = new StringBuilder(); bool backslashMode = false; while (true) { ch = jsonString.ReadChar(); if (backslashMode) { switch (ch) { case 'n': sb [sb.Length - 1] = '\n'; break; case 'r': sb [sb.Length - 1] = '\r'; break; case 't': sb [sb.Length - 1] = '\t'; break; case '\\': sb [sb.Length - 1] = '\\'; break; case '"': sb [sb.Length - 1] = '"'; break; case '/': sb [sb.Length - 1] = '/'; break; case 'b': sb [sb.Length - 1] = '\b'; break; case 'f': sb [sb.Length - 1] = '\f'; break; case 'u': sb.Remove(sb.Length - 1, 1); sb.Append(ToNumberFromHexa(jsonString.ReadChars(2))); sb.Append(ToNumberFromHexa(jsonString.ReadChars(2))); break; default: throw new Exception(); } backslashMode = false; } else if (ch == '"') { break; } else { sb.Append(ch); if (ch == '\\') { backslashMode = true; } } } return(sb.ToString()); }
private JsonContainer ParseString(MyStringReader jsonString) { try { ParseState parseMode = ParseState.None; ParseState parseState = ParseState.None; Queue <object> tokenStack = new Queue <object> (); while (true) { char rc = '\0'; do { rc = jsonString.ReadChar(); } while (rc == ' ' || rc == ' '|| rc == ' ' || rc == '\n' || rc == '\r'); if (rc == ':') { if (!(parseMode == ParseState.Object && parseState == ParseState.Key)) { throw new Exception("Invalid JSON document."); } parseState = ParseState.Value; } else if (rc == ',') { if (parseState != ParseState.Value) { throw new Exception("Invalid JSON document."); } parseState = (parseMode == ParseState.Object) ? ParseState.Key : ParseState.Value; } else if (rc == '"') { tokenStack.Enqueue(GetStringFromString(jsonString)); } else if (rc == 't' || rc == 'f' || rc == 'n') { tokenStack.Enqueue(GetKeywordFromString(jsonString, rc)); } else if ((rc >= '0' && rc <= '9') || rc == '-' || rc == '+') { tokenStack.Enqueue(GetNumberFromString(jsonString, rc)); } else if (rc == '{' || rc == '[') { if (parseState == ParseState.Value) { jsonString.Position -= 1; tokenStack.Enqueue(ParseString(jsonString)); } else { switch (rc) { case '{': parseMode = ParseState.Object; parseState = ParseState.Key; break; case '[': parseMode = ParseState.Array; parseState = ParseState.Value; break; } } } else if ((rc == '}' && parseMode == ParseState.Object) || (rc == ']' && parseMode == ParseState.Array)) { break; } else { throw new ArgumentException("Invalid JSON document."); } } return(Build(parseMode, tokenStack)); } catch { throw new ArgumentException("Invalid JSON document."); } }