XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEWorkflow

【WinUI】XFE基于windows的工作流

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Globalization;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;

namespace XFEWorkflow.Abstractions;

public static partial class WorkflowJson
{
    // Display/file JSON only. Keep the default serializer for protocols and script injection.
    private static readonly Lazy<JsonSerializerOptions> displayCompact = new(() => CreateDisplayOptions(false));
    private static readonly Lazy<JsonSerializerOptions> displayIndented = new(() => CreateDisplayOptions(true));
    private static JsonSerializerOptions CreateDisplayOptions(bool indented) => new(Options)
    { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = indented };

    public static string Display(this JsonNode? value, bool indented = false) =>
        ReadableUnicode(value?.ToJsonString(indented ? displayIndented.Value : displayCompact.Value) ?? "null");

    public static string SerializeDisplay<T>(T value, bool indented = true) =>
        ReadableUnicode(JsonSerializer.Serialize(value, indented ? displayIndented.Value : displayCompact.Value));

    private static string ReadableUnicode(string json)
    {
        // System.Text.Json still escapes supplementary characters (including emoji).
        // Scan JSON escapes once: never decode a user-authored literal \\uXXXX or
        // turn escaped quotes, backslashes or controls into invalid JSON.
        var result = new StringBuilder(json.Length);
        for (var i = 0; i < json.Length;)
        {
            if (json[i] != '\\' || i + 1 >= json.Length) { result.Append(json[i++]); continue; }
            if (TryUnicode(json, i, out var character))
            {
                if (char.IsHighSurrogate(character) && TryUnicode(json, i + 6, out var low) && char.IsLowSurrogate(low))
                { result.Append(character).Append(low); i += 12; continue; }
                if (!char.IsSurrogate(character) && !char.IsControl(character) && character is not '"' and not '\\')
                { result.Append(character); i += 6; continue; }
                result.Append(json, i, 6); i += 6; continue;
            }
            result.Append(json, i, 2); i += 2;
        }
        return result.ToString();
    }

    private static bool TryUnicode(string json, int index, out char character)
    {
        character = default;
        if (index + 6 > json.Length || json[index] != '\\' || json[index + 1] != 'u' ||
            !ushort.TryParse(json.AsSpan(index + 2, 4), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var code)) return false;
        character = (char)code;
        return true;
    }
}