private DateOnly ReadCore(ref Utf8JsonReader reader) { if (!JsonHelpers.IsInRangeInclusive(reader.ValueLength, FormatLength, MaxEscapedFormatLength)) { ThrowHelper.ThrowFormatException(DataType.DateOnly); } scoped ReadOnlySpan <byte> source; if (!reader.HasValueSequence && !reader.ValueIsEscaped) { source = reader.ValueSpan; } else { Span <byte> stackSpan = stackalloc byte[MaxEscapedFormatLength]; int bytesWritten = reader.CopyString(stackSpan); source = stackSpan.Slice(0, bytesWritten); } if (!JsonHelpers.TryParseAsIso(source, out DateOnly value)) { ThrowHelper.ThrowFormatException(DataType.DateOnly); } return(value); }
public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) { ThrowHelper.ThrowInvalidOperationException_ExpectedString(reader.TokenType); } if (!JsonHelpers.IsInRangeInclusive(reader.ValueLength, MinimumTimeOnlyFormatLength, MaximumEscapedTimeOnlyFormatLength)) { ThrowHelper.ThrowFormatException(DataType.TimeOnly); } ReadOnlySpan <byte> source = stackalloc byte[0]; if (!reader.HasValueSequence && !reader.ValueIsEscaped) { source = reader.ValueSpan; } else { Span <byte> stackSpan = stackalloc byte[MaximumEscapedTimeOnlyFormatLength]; int bytesWritten = reader.CopyString(stackSpan); source = stackSpan.Slice(0, bytesWritten); } byte firstChar = source[0]; int firstSeparator = source.IndexOfAny((byte)'.', (byte)':'); if (!JsonHelpers.IsDigit(firstChar) || firstSeparator < 0 || source[firstSeparator] == (byte)'.') { // Note: Utf8Parser.TryParse permits leading whitespace, negative values // and numbers of days so we need to exclude these cases here. ThrowHelper.ThrowFormatException(DataType.TimeOnly); } bool result = Utf8Parser.TryParse(source, out TimeSpan timespan, out int bytesConsumed, 'c'); // Note: Utf8Parser.TryParse will return true for invalid input so // long as it starts with an integer. Example: "2021-06-18" or // "1$$$$$$$$$$". We need to check bytesConsumed to know if the // entire source was actually valid. if (!result || source.Length != bytesConsumed) { ThrowHelper.ThrowFormatException(DataType.TimeOnly); } Debug.Assert(TimeOnly.MinValue.ToTimeSpan() <= timespan && timespan <= TimeOnly.MaxValue.ToTimeSpan()); return(TimeOnly.FromTimeSpan(timespan)); }
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) { ThrowHelper.ThrowInvalidOperationException_ExpectedString(reader.TokenType); } if (!JsonHelpers.IsInRangeInclusive(reader.ValueLength, MinimumTimeSpanFormatLength, MaximumEscapedTimeSpanFormatLength)) { ThrowHelper.ThrowFormatException(DataType.TimeSpan); } scoped ReadOnlySpan <byte> source; if (!reader.HasValueSequence && !reader.ValueIsEscaped) { source = reader.ValueSpan; } else { Span <byte> stackSpan = stackalloc byte[MaximumEscapedTimeSpanFormatLength]; int bytesWritten = reader.CopyString(stackSpan); source = stackSpan.Slice(0, bytesWritten); } byte firstChar = source[0]; if (!JsonHelpers.IsDigit(firstChar) && firstChar != '-') { // Note: Utf8Parser.TryParse allows for leading whitespace so we // need to exclude that case here. ThrowHelper.ThrowFormatException(DataType.TimeSpan); } bool result = Utf8Parser.TryParse(source, out TimeSpan tmpValue, out int bytesConsumed, 'c'); // Note: Utf8Parser.TryParse will return true for invalid input so // long as it starts with an integer. Example: "2021-06-18" or // "1$$$$$$$$$$". We need to check bytesConsumed to know if the // entire source was actually valid. if (!result || source.Length != bytesConsumed) { ThrowHelper.ThrowFormatException(DataType.TimeSpan); } return(tmpValue); }
public override char Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (!JsonHelpers.IsInRangeInclusive(reader.ValueLength, 1, MaxEscapedCharacterLength)) { ThrowHelper.ThrowInvalidOperationException_ExpectedChar(reader.TokenType); } Span <char> buffer = stackalloc char[MaxEscapedCharacterLength]; int charsWritten = reader.CopyString(buffer); if (charsWritten != 1) { ThrowHelper.ThrowInvalidOperationException_ExpectedChar(reader.TokenType); } return(buffer[0]); }
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) { ThrowHelper.ThrowInvalidOperationException_ExpectedString(reader.TokenType); } #if NETCOREAPP if (!JsonHelpers.IsInRangeInclusive(reader.ValueLength, MinimumVersionLength, MaximumEscapedVersionLength)) { ThrowHelper.ThrowFormatException(DataType.TimeSpan); } Span <char> charBuffer = stackalloc char[MaximumEscapedVersionLength]; int bytesWritten = reader.CopyString(charBuffer); ReadOnlySpan <char> source = charBuffer.Slice(0, bytesWritten); if (!char.IsDigit(source[0]) || !char.IsDigit(source[^ 1]))