protected static JObject _ParseJObject(CharReader reader) { JObject result = new JObject(); char c; try { _SkipWhitespace(reader); if (reader.Read() != '{') { throw new SystemException("Begining brace expected"); } string key; object value; _SkipWhitespace(reader); while (reader.Peek() != '}') { _SkipWhitespace(reader); if (reader.Peek() == ',') { // allow extraneous commas reader.Read(); // gobble char _SkipWhitespace(reader); continue; } if (reader.Peek() != '\"') { throw new SystemException("Quote char expected"); } key = _GetStringValue(reader); _SkipWhitespace(reader); if (reader.Read() != ':') { throw new SystemException("Colon char expected"); } _SkipWhitespace(reader); value = _GetValue(reader); result.Add(key, value); _SkipWhitespace(reader); c = reader.Peek(); if (c != ',' && c != '}') { throw new SystemException("Comma or end brace expected"); } if (c == ',') { reader.Read(); // gobble comma char _SkipWhitespace(reader); } } reader.Read(); // gobble } char } catch (Exception ex) { throw new ArgumentException($"Invalid JObject input\r\n{ex.Message}"); } return(result); }
protected static JArray _ParseJArray(CharReader reader) { JArray result = new JArray(); char c; try { _SkipWhitespace(reader); c = reader.Read(); if (c != '[') { throw new SystemException("Begining bracket expected"); } object value; _SkipWhitespace(reader); while (reader.Peek() != ']') { _SkipWhitespace(reader); if (reader.Peek() == ',') { // allow extraneous commas reader.Read(); // gobble char _SkipWhitespace(reader); continue; } value = _GetValue(reader); result.Add(value); _SkipWhitespace(reader); c = reader.Peek(); if (c != ',' && c != ']') { throw new SystemException("Comma or end bracket expected"); } if (c == ',') { reader.Read(); // gobble comma char _SkipWhitespace(reader); } } reader.Read(); // gobble end bracket char } catch (Exception ex) { throw new ArgumentException($"Invalid JArray input\r\n{ex.Message}"); } return(result); }
private static string _GetToken(CharReader reader) { StringBuilder result = new StringBuilder(); char c; while (true) { c = reader.Read(); if (char.IsLetterOrDigit(c) || c == '-' || c == '+' || c == '.') { result.Append(c); continue; } reader.Push(c); break; } return(result.ToString()); }
private static string _GetStringValue(CharReader reader) { // reader must be on starting quote char if (reader.Read() != '\"') { throw new ArgumentException("Invalid JSON string"); } StringBuilder result = new StringBuilder(); bool escaped = false; char c; while (true) { c = reader.Read(); if (escaped) { switch (c) { case '\"': case '\\': case '/': result.Append(c); break; case 'b': result.Append('\b'); break; case 'f': result.Append('\f'); break; case 'n': result.Append('\n'); break; case 'r': result.Append('\r'); break; case 't': result.Append('\t'); break; case 'u': string unicodeValue = $"{reader.Read()}{reader.Read()}{reader.Read()}{reader.Read()}"; result.Append(Convert.ToChar(Convert.ToUInt16(unicodeValue, 16))); break; default: throw new ArgumentException($"Invalid escaped char in string: {c}"); } escaped = false; continue; } // escape next char if (c == '\\') { escaped = true; continue; } // ending quote, done if (c == '\"') { break; } // normal char result.Append(c); } return(result.ToString()); }
protected static void _SkipWhitespace(CharReader reader) { char currChar; while (true) { if (reader.EOF()) { break; } currChar = reader.Peek(); // use c# definition of whitespace if (char.IsWhiteSpace(currChar)) { reader.Read(); // gobble char continue; } // check for comments if (currChar == '/') { reader.Read(); // gobble char char nextChar = reader.Read(); if (nextChar == '/') // to EOF { while (true) { // not error if EOF before CR-LF if (reader.EOF()) { break; } currChar = reader.Read(); if (currChar == '\r' || currChar == '\n') { break; } } continue; } else if (nextChar == '*') /* to */ { nextChar = ' '; // clear for comparison while (true) { // will throw an error if EOF before '*/' is found currChar = nextChar; nextChar = reader.Read(); if (currChar == '*' && nextChar == '/') { break; } } continue; } else // not a comment { // push back in reverse order reader.Push(nextChar); reader.Push(currChar); break; } } break; } }