| File: System\Text\Json\Serialization\Converters\Value\UInt128Converter.cs | Web Access |
| Project: src\runtime\src\libraries\System.Text.Json\src\System.Text.Json.csproj (System.Text.Json) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; using System.Diagnostics; using System.Globalization; using System.Text.Json.Nodes; using System.Text.Json.Schema; namespace System.Text.Json.Serialization.Converters { internal sealed class UInt128Converter : JsonPrimitiveConverter<UInt128> { private const int MaxFormatLength = 39; public UInt128Converter() { IsInternalConverterForNumberType = true; } public override UInt128 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (options?.NumberHandling is not null and not JsonNumberHandling.Strict) { return ReadNumberWithCustomHandling(ref reader, options.NumberHandling, options); } if (reader.TokenType != JsonTokenType.Number) { ThrowHelper.ThrowInvalidOperationException_ExpectedNumber(reader.TokenType); } return ReadCore(ref reader); } public override void Write(Utf8JsonWriter writer, UInt128 value, JsonSerializerOptions options) { if (options?.NumberHandling is not null and not JsonNumberHandling.Strict) { WriteNumberWithCustomHandling(writer, value, options.NumberHandling); return; } WriteCore(writer, value); } private static unsafe UInt128 ReadCore(ref Utf8JsonReader reader) { int bufferLength = reader.ValueLength; byte[]? rentedBuffer = null; Span<byte> buffer = bufferLength <= JsonConstants.StackallocByteThreshold ? stackalloc byte[JsonConstants.StackallocByteThreshold] : (rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferLength)); int written = reader.CopyValue(buffer); if (!UInt128.TryParse(buffer.Slice(0, written), CultureInfo.InvariantCulture, out UInt128 result)) { ThrowHelper.ThrowFormatException(NumericType.UInt128); } if (rentedBuffer is not null) { ArrayPool<byte>.Shared.Return(rentedBuffer); } return result; } private static unsafe void WriteCore(Utf8JsonWriter writer, UInt128 value) { Span<byte> buffer = stackalloc byte[MaxFormatLength]; Format(buffer, value, out int written); writer.WriteRawValue(buffer.Slice(0, written)); } internal override UInt128 ReadAsPropertyNameCore(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); return ReadCore(ref reader); } internal override unsafe void WriteAsPropertyNameCore(Utf8JsonWriter writer, UInt128 value, JsonSerializerOptions options, bool isWritingExtensionDataProperty) { Span<byte> buffer = stackalloc byte[MaxFormatLength]; Format(buffer, value, out int written); writer.WritePropertyName(buffer.Slice(0, written)); } internal override UInt128 ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String && (JsonNumberHandling.AllowReadingFromString & handling) != 0) { return ReadCore(ref reader); } if (reader.TokenType != JsonTokenType.Number) { ThrowHelper.ThrowInvalidOperationException_ExpectedNumber(reader.TokenType); } return ReadCore(ref reader); } internal override unsafe void WriteNumberWithCustomHandling(Utf8JsonWriter writer, UInt128 value, JsonNumberHandling handling) { if ((JsonNumberHandling.WriteAsString & handling) != 0) { const byte Quote = JsonConstants.Quote; Span<byte> buffer = stackalloc byte[MaxFormatLength + 2]; buffer[0] = Quote; Format(buffer.Slice(1), value, out int written); int length = written + 2; buffer[length - 1] = Quote; writer.WriteRawValue(buffer.Slice(0, length)); } else { WriteCore(writer, value); } } internal override JsonSchema? GetSchema(JsonNumberHandling numberHandling) => GetSchemaForNumericType(JsonSchemaType.Integer, numberHandling); internal override JsonValueType GetSupportedJsonValueTypes(JsonNumberHandling numberHandling) => GetSupportedJsonValueTypesForNumericType(numberHandling); private static void Format( Span<byte> destination, UInt128 value, out int written) { bool formattedSuccessfully = value.TryFormat(destination, out written, provider: CultureInfo.InvariantCulture); Debug.Assert(formattedSuccessfully); } } }