using System.Runtime.InteropServices; using System.Text; using System.Text.Json; using System.Text.Json.Serialization.Metadata; namespace Shared.Models.Templates { public static class UtilsTpl { #region HtmlEncode public static void HtmlEncode(ReadOnlySpan value, StringBuilder sb) { foreach (var c in value) { switch (c) { case '<': sb.Append("<"); break; case '>': sb.Append(">"); break; case '&': sb.Append("&"); break; case '"': sb.Append("""); break; case '\'': sb.Append("'"); break; default: sb.Append(c); break; } } } #endregion #region WriteJson public static void WriteJson(StringBuilder sb, in T value, JsonTypeInfo options) { using (var msm = PoolInvk.msm.GetStream()) { using (var writer = new Utf8JsonWriter((Stream)msm, new JsonWriterOptions { Indented = false, SkipValidation = true })) { JsonSerializer.Serialize(writer, value, options); } if (msm.TryGetBuffer(out ArraySegment buffer)) { ReadOnlySpan utf8 = buffer.AsSpan(0, (int)msm.Length); int neededChars = Encoding.UTF8.GetCharCount(utf8); if (neededChars < 512) { Span stackChars = stackalloc char[neededChars]; int charsWritten = Encoding.UTF8.GetChars(utf8, stackChars); if (charsWritten > 0) sb.Append(stackChars.Slice(0, charsWritten)); } else { unsafe { nint rentedJsonPtr = (nint)NativeMemory.Alloc((nuint)neededChars, (nuint)sizeof(char)); try { Span rentedChars = new Span((void*)rentedJsonPtr, neededChars); int charsWritten = Encoding.UTF8.GetChars(utf8, rentedChars); if (charsWritten > 0) sb.Append(rentedChars.Slice(0, charsWritten)); } finally { NativeMemory.Free((void*)rentedJsonPtr); } } } } } } #endregion } }