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
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.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;
[System.Runtime.CompilerServices.Nullable(2)]
public string MediaType {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
}
public BinaryData(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
_bytes = data;
}
public BinaryData(byte[] data, [System.Runtime.CompilerServices.Nullable(2)] string mediaType)
: this(data)
{
MediaType = mediaType;
}
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
[System.Diagnostics.CodeAnalysis.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")
{
}
[System.Runtime.CompilerServices.NullableContext(2)]
public BinaryData(object jsonSerializable, [System.Runtime.CompilerServices.Nullable(1)] JsonSerializerContext context, Type type = null)
: this(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, type ?? jsonSerializable?.GetType() ?? typeof(object), context), "application/json")
{
}
[System.Runtime.CompilerServices.NullableContext(0)]
public BinaryData(ReadOnlyMemory<byte> data)
{
_bytes = data;
}
[System.Runtime.CompilerServices.NullableContext(0)]
public BinaryData(ReadOnlyMemory<byte> data, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.Nullable(2)] string mediaType)
: this(data)
{
MediaType = mediaType;
}
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static BinaryData FromBytes(ReadOnlyMemory<byte> data)
{
return new BinaryData(data);
}
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(1)]
public static BinaryData FromBytes(ReadOnlyMemory<byte> data, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.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();
}
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
public static BinaryData FromObjectAsJson<[System.Runtime.CompilerServices.Nullable(2)] T>(T jsonSerializable, [System.Runtime.CompilerServices.Nullable(2)] JsonSerializerOptions options = null)
{
return new BinaryData(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, options), "application/json");
}
public static BinaryData FromObjectAsJson<[System.Runtime.CompilerServices.Nullable(2)] T>(T jsonSerializable, JsonTypeInfo<T> jsonTypeInfo)
{
return new BinaryData(JsonSerializer.SerializeToUtf8Bytes(jsonSerializable, jsonTypeInfo), "application/json");
}
public BinaryData WithMediaType([System.Runtime.CompilerServices.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 System.IO.ReadOnlyMemoryStream(_bytes);
}
[System.Runtime.CompilerServices.NullableContext(0)]
public ReadOnlyMemory<byte> ToMemory()
{
return _bytes;
}
public byte[] ToArray()
{
return _bytes.ToArray();
}
[System.Runtime.CompilerServices.NullableContext(2)]
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation.")]
[System.Diagnostics.CodeAnalysis.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);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public T ToObjectFromJson<T>([System.Runtime.CompilerServices.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>([System.Runtime.CompilerServices.Nullable(2)] BinaryData data)
{
return data?._bytes ?? default(ReadOnlyMemory<byte>);
}
public static implicit operator ReadOnlySpan<byte>([System.Runtime.CompilerServices.Nullable(2)] BinaryData data)
{
if (data == null)
return default(ReadOnlySpan<byte>);
return data._bytes.Span;
}
[System.Runtime.CompilerServices.NullableContext(2)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] object obj)
{
return this == obj;
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}