#nullable enable using System; using System.Collections; using System.Linq; using System.Reflection.Metadata; using System.Text; using NBXplorer; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace BTCPayServer.Data { public static class IHasBlobExtensions { static readonly JsonSerializerSettings DefaultSerializer; static IHasBlobExtensions() { DefaultSerializer = new JsonSerializerSettings() { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(), Formatting = Formatting.None }; NBitcoin.JsonConverters.Serializer.RegisterFrontConverters(DefaultSerializer); } class HasBlobWrapper : IHasBlob { IHasBlobUntyped data; public HasBlobWrapper(IHasBlobUntyped data) { this.data = data; } [Obsolete("Use Blob2 instead")] public byte[] Blob { get { return data.Blob; } set { data.Blob = value; } } public string Blob2 { get { return data.Blob2; } set { data.Blob2 = value; } } } class HasBlobWrapper : IHasBlob { IHasBlobUntyped data; private Type type; public HasBlobWrapper(IHasBlobUntyped data, Type type) { this.data = data; this.type = type; } [Obsolete("Use Blob2 instead")] public byte[] Blob { get => data.Blob; set => data.Blob = value; } public string Blob2 { get => data.Blob2; set => data.Blob2 = value; } public Type Type { get => type; set => type = value; } } public static IHasBlob HasTypedBlob(this IHasBlobUntyped data) { return new HasBlobWrapper(data); } public static IHasBlob HasTypedBlob(this IHasBlobUntyped data, Type blobType) { return new HasBlobWrapper(data, blobType); } public static B? GetBlob(this IHasBlob data, JsonSerializerSettings? settings = null) { if (data.Blob2 is not null) return JObject.Parse(data.Blob2).ToObject(JsonSerializer.CreateDefault(settings ?? DefaultSerializer)); #pragma warning disable CS0618 // Type or member is obsolete if (data.Blob is not null && data.Blob.Length != 0) { string str; if (data.Blob[0] == 0x7b) str = Encoding.UTF8.GetString(data.Blob); else str = ZipUtils.Unzip(data.Blob); return JObject.Parse(str).ToObject(JsonSerializer.CreateDefault(settings ?? DefaultSerializer)); } #pragma warning restore CS0618 // Type or member is obsolete return default; } public static object? GetBlob(this IHasBlob data, JsonSerializerSettings? settings = null) { if (data.Blob2 is not null) return JObject.Parse(data.Blob2).ToObject(data.Type, JsonSerializer.CreateDefault(settings ?? DefaultSerializer)); #pragma warning disable CS0618 // Type or member is obsolete if (data.Blob is not null && data.Blob.Length != 0) return JObject.Parse(ZipUtils.Unzip(data.Blob)).ToObject(data.Type, JsonSerializer.CreateDefault(settings ?? DefaultSerializer)); #pragma warning restore CS0618 // Type or member is obsolete return default; } public static T SetBlob(this T data, B blob, JsonSerializerSettings? settings = null) where T : IHasBlob { if (blob is null) data.Blob2 = null; else data.Blob2 = JObject.FromObject(blob, JsonSerializer.CreateDefault(settings ?? DefaultSerializer)).ToString(Formatting.None); #pragma warning disable CS0618 // Type or member is obsolete data.Blob = new byte[0]; #pragma warning restore CS0618 // Type or member is obsolete return data; } } }