public ReadResults ReadString(out JsonString result) { result = default; string actualString = ""; if (!StringReader.CanRead() || StringReader.Peek() != STRING_CHARACTER) { return(ReadResults.Failure(JsonCommandError.MalformedJson().WithContext(StringReader))); } StringReader.Skip(); bool escaped = false; while (StringReader.CanRead()) { char c = StringReader.Read(); if (escaped) { if (c == UNICODE_CHARACTER) { if (!StringReader.CanRead(4)) { return(ReadResults.Failure(JsonCommandError.UnterminatedEscapeSequence().WithContext(StringReader))); } string unicode = StringReader.Read(4); if (!short.TryParse(unicode, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out _)) { return(ReadResults.Failure(JsonCommandError.InvalidUnicodeCharacter(unicode).WithContext(StringReader))); } escaped = false; actualString += c + unicode; } else if (ESCAPABLE_CHARACTERS.Contains(c)) { escaped = false; actualString += c; } else { return(ReadResults.Failure(JsonCommandError.InvalidEscapeSequence().WithContext(StringReader))); } } else if (c == ESCAPE_CHARACTER) { escaped = true; actualString += c; } else if (c == STRING_CHARACTER) { result = new JsonString(actualString); return(ReadResults.Success()); } else { actualString += c; } } return(ReadResults.Failure(JsonCommandError.UnterminatedString().WithContext(StringReader))); }
public ReadResults ReadObject(out JsonObject result) { result = new JsonObject(); if (!StringReader.CanRead() || StringReader.Peek() != OBJECT_OPEN_CHARACTER) { return(ReadResults.Failure(JsonCommandError.MalformedJson())); } StringReader.Skip(); SkipWhitespace(); ReadResults readResults; while (StringReader.CanRead() && StringReader.Peek() != OBJECT_CLOSE_CHARACTER) { SkipWhitespace(); readResults = ReadString(out JsonString name); if (!readResults.Successful) { return(readResults); } SkipWhitespace(); if (!StringReader.CanRead() || StringReader.Peek() != NAME_VALUE_SEPARATOR) { return(ReadResults.Failure(JsonCommandError.ExpectedNameValueSeparator().WithContext(StringReader))); } StringReader.Skip(); SkipWhitespace(); readResults = ReadAny(out IJsonArgument argument); if (!readResults.Successful) { return(readResults); } result.Add(name, argument); SkipWhitespace(); if (!StringReader.CanRead() || StringReader.Peek() != ARGUMENT_SEPARATOR) { break; } StringReader.Skip(); } if (!StringReader.CanRead() || StringReader.Peek() != OBJECT_CLOSE_CHARACTER) { return(ReadResults.Failure(JsonCommandError.EndOfInput().WithContext(StringReader))); } StringReader.Skip(); return(ReadResults.Success()); }
public ReadResults ReadArray(out JsonArray result) { result = new JsonArray(); if (!StringReader.CanRead() || StringReader.Peek() != ARRAY_OPEN_CHARACTER) { return(ReadResults.Failure(JsonCommandError.MalformedJson())); } StringReader.Skip(); SkipWhitespace(); ReadResults readResults; while (StringReader.CanRead() && StringReader.Peek() != ARRAY_CLOSE_CHARACTER) { SkipWhitespace(); readResults = ReadAny(out IJsonArgument argument); if (!readResults.Successful) { return(readResults); } result.Add(argument); SkipWhitespace(); if (!StringReader.CanRead() || StringReader.Peek() != ARGUMENT_SEPARATOR) { break; } StringReader.Skip(); } if (!StringReader.CanRead() || StringReader.Peek() != ARRAY_CLOSE_CHARACTER) { return(ReadResults.Failure(JsonCommandError.EndOfInput().WithContext(StringReader))); } StringReader.Skip(); return(ReadResults.Success()); }