BinaryData
A lightweight abstraction for a payload of bytes that supports converting between string, stream, JSON, and bytes.
                using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;
namespace System
{
    [NullableContext(1)]
    [Nullable(0)]
    [JsonConverter(typeof(BinaryDataJsonConverter))]
    public class BinaryData
    {
        private const string JsonSerializerRequiresDynamicCode = "JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.";
        private const string JsonSerializerRequiresUnreferencedCode = "JSON serialization and deserialization might require types that cannot be statically analyzed.";
        private const string MediaTypeApplicationJson = "application/json";
        private readonly ReadOnlyMemory<byte> _bytes;
        public static BinaryData Empty { get; } = new BinaryData(ReadOnlyMemory<byte>.Empty);
        public int Length => _bytes.Length;
        public bool IsEmpty => _bytes.IsEmpty;
        [Nullable(2)]
        public string MediaType {
            [NullableContext(2)]
            get;
        }
        public BinaryData(byte[] data)
        {
            if (data == null)
                throw new ArgumentNullException("data");
            _bytes = data;
        }
        public BinaryData(byte[] data, [Nullable(2)] string mediaType)
            : this(data)
        {
            MediaType = mediaType;
        }
        [NullableContext(2)]
        [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
        [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        public BinaryData(object jsonSerializable, JsonSerializerOptions options = null, Type type = null)
            : this(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, type ?? jsonSerializable?.GetType() ?? typeof(object), options), "application/json")
        {
        }
        [NullableContext(2)]
        public BinaryData(object jsonSerializable, [Nullable(1)] JsonSerializerContext context, Type type = null)
            : this(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, type ?? jsonSerializable?.GetType() ?? typeof(object), context), "application/json")
        {
        }
        [NullableContext(0)]
        public BinaryData(ReadOnlyMemory<byte> data)
        {
            _bytes = data;
        }
        [NullableContext(0)]
        public BinaryData(ReadOnlyMemory<byte> data, [Nullable(2)] string mediaType)
            : this(data)
        {
            MediaType = mediaType;
        }
        public BinaryData(string data)
        {
            if (data == null)
                throw new ArgumentNullException("data");
            _bytes = Encoding.UTF8.GetBytes(data);
        }
        public BinaryData(string data, [Nullable(2)] string mediaType)
            : this(data)
        {
            MediaType = mediaType;
        }
        [NullableContext(0)]
        [return: Nullable(1)]
        public static BinaryData FromBytes(ReadOnlyMemory<byte> data)
        {
            return new BinaryData(data);
        }
        [NullableContext(0)]
        [return: Nullable(1)]
        public static BinaryData FromBytes(ReadOnlyMemory<byte> data, [Nullable(2)] string mediaType)
        {
            return new BinaryData(data, mediaType);
        }
        public static BinaryData FromBytes(byte[] data)
        {
            return new BinaryData(data);
        }
        public static BinaryData FromBytes(byte[] data, [Nullable(2)] string mediaType)
        {
            return new BinaryData(data, mediaType);
        }
        public static BinaryData FromString(string data)
        {
            return new BinaryData(data);
        }
        public static BinaryData FromString(string data, [Nullable(2)] string mediaType)
        {
            return new BinaryData(data, mediaType);
        }
        public static BinaryData FromStream(Stream stream)
        {
            return FromStream(stream, null);
        }
        public static BinaryData FromStream(Stream stream, [Nullable(2)] string mediaType)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");
            return FromStreamAsync(stream, false, mediaType, default(CancellationToken)).GetAwaiter().GetResult();
        }
        public static Task<BinaryData> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
        {
            return FromStreamAsync(stream, null, cancellationToken);
        }
        public static Task<BinaryData> FromStreamAsync(Stream stream, [Nullable(2)] string mediaType, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (stream == null)
                throw new ArgumentNullException("stream");
            return FromStreamAsync(stream, true, mediaType, cancellationToken);
        }
        [AsyncStateMachine(typeof(<FromStreamAsync>d__32))]
        private static Task<BinaryData> FromStreamAsync(Stream stream, bool useAsync, string mediaType = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            <FromStreamAsync>d__32 stateMachine = default(<FromStreamAsync>d__32);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder<BinaryData>.Create();
            stateMachine.stream = stream;
            stateMachine.useAsync = useAsync;
            stateMachine.mediaType = mediaType;
            stateMachine.cancellationToken = cancellationToken;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        public static BinaryData FromFile(string path)
        {
            return FromFile(path, null);
        }
        public static BinaryData FromFile(string path, [Nullable(2)] string mediaType)
        {
            if (path == null)
                throw new ArgumentNullException("path");
            return new BinaryData(File.ReadAllBytes(path), mediaType);
        }
        public static Task<BinaryData> FromFileAsync(string path, CancellationToken cancellationToken = default(CancellationToken))
        {
            return FromFileAsync(path, null, cancellationToken);
        }
        public static Task<BinaryData> FromFileAsync(string path, [Nullable(2)] string mediaType, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (path == null)
                throw new ArgumentNullException("path");
            object obj;
            return ((<>c__DisplayClass36_0)obj).<FromFileAsync>g__Core|0();
        }
        [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
        [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        public static BinaryData FromObjectAsJson<[Nullable(2)] T>(T jsonSerializable, [Nullable(2)] JsonSerializerOptions options = null)
        {
            return new BinaryData(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, options), "application/json");
        }
        public static BinaryData FromObjectAsJson<[Nullable(2)] T>(T jsonSerializable, JsonTypeInfo<T> jsonTypeInfo)
        {
            return new BinaryData(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, jsonTypeInfo), "application/json");
        }
        public BinaryData WithMediaType([Nullable(2)] string mediaType)
        {
            return new BinaryData(_bytes, mediaType);
        }
        public unsafe override string ToString()
        {
            ReadOnlySpan<byte> span = _bytes.Span;
            if (!span.IsEmpty) {
                fixed (byte* bytes = &span.GetPinnableReference()) {
                    return Encoding.UTF8.GetString(bytes, span.Length);
                }
            }
            return string.Empty;
        }
        public Stream ToStream()
        {
            return new ReadOnlyMemoryStream(_bytes);
        }
        [NullableContext(0)]
        public ReadOnlyMemory<byte> ToMemory()
        {
            return _bytes;
        }
        public byte[] ToArray()
        {
            return _bytes.ToArray();
        }
        [NullableContext(2)]
        [RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
        [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
        public T ToObjectFromJson<T>(JsonSerializerOptions options = null)
        {
            return JsonSerializer.Deserialize<T>(GetBytesWithTrimmedBom(), options);
        }
        [NullableContext(2)]
        public T ToObjectFromJson<T>([Nullable(1)] JsonTypeInfo<T> jsonTypeInfo)
        {
            return JsonSerializer.Deserialize(GetBytesWithTrimmedBom(), jsonTypeInfo);
        }
        private ReadOnlySpan<byte> GetBytesWithTrimmedBom()
        {
            ReadOnlySpan<byte> result = _bytes.Span;
            if (result.Length > 2 && result[0] == 239 && result[1] == 187 && result[2] == 191)
                result = result.Slice(3);
            return result;
        }
        public static implicit operator ReadOnlyMemory<byte>([Nullable(2)] BinaryData data)
        {
            return data?._bytes ?? default(ReadOnlyMemory<byte>);
        }
        public static implicit operator ReadOnlySpan<byte>([Nullable(2)] BinaryData data)
        {
            if (data == null)
                return default(ReadOnlySpan<byte>);
            return data._bytes.Span;
        }
        [NullableContext(2)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override bool Equals([NotNullWhen(true)] object obj)
        {
            return this == obj;
        }
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}