using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; using System.ComponentModel; using static LittleCms.CmsNative; using System.Runtime.CompilerServices; namespace LittleCms.Data { public class MLU : CmsObject { public const string NoLanguage = "\0\0"; public const string NoCountry = "\0\0"; #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member [Obsolete("Only allocator in context is used in MLU, which is not modeled in this binding")] public override CmsContext Context { get; } = CmsContext.Default; #pragma warning restore CS0809 internal unsafe static (uint, uint) EncodeLanguageCountryCode(string code1, string code2) { if (code1 == null || code1.Length != 2 || code1[0] >= 0x80 || code1[1] >= 0x80) throw new ArgumentException(); if (code2 == null || code2.Length != 2 || code2[0] >= 0x80 || code2[1] >= 0x80) throw new ArgumentException(); Span result32 = stackalloc uint[2]; var result8 = MemoryMarshal.Cast(result32); result8[0] = (byte)code1[0]; result8[1] = (byte)code1[1]; result8[4] = (byte)code2[0]; result8[5] = (byte)code2[1]; return (result32[0], result32[1]); } /// /// Attach a cmsMLU /// /// /// public MLU(IntPtr handle, bool moveOwnership = false) : base(handle, moveOwnership) { // FIXME: missing cmsGetMLUContextID } public MLU(int itemCount) : this(CmsContext.Default, itemCount) { } public MLU(CmsContext context, int itemCount) { Context = context; IntPtr handle = CheckError(cmsMLUalloc(context.Handle, (uint)itemCount)); AttachObject(handle, true); } /// /// Copy a cmsMLU by handle /// /// /// public static MLU CopyFromObject(nint handleToCopy) { nint handle = CheckError(cmsMLUdup(handleToCopy)); return new(handle, true); } /// /// Creates a MLU with en-US string /// /// public MLU(string s) : this(1) { Set("en", "US", s); } protected override void FreeObject() { cmsMLUfree(Handle); } public unsafe void Set(string language, string country, string s) { var (lang, cont) = EncodeLanguageCountryCode(language, country); var wchbuf = WcharEncoding.GetBytes(s + "\0"); CheckError(cmsMLUsetWide(Handle, in lang, in cont, in wchbuf[0])); } public unsafe string? Get(string languageCode, string countryCode) { var (lang, cont) = EncodeLanguageCountryCode(languageCode, countryCode); var len = cmsMLUgetWide(Handle, in lang, in cont, null, 0); if (len == 0) { return null; } var buf = new byte[(int)len]; fixed (byte* ptr = buf) len = CheckError(cmsMLUgetWide(Handle, in lang, in cont, ptr, len)); var s = WcharEncoding.GetString(buf); return s[..^1]; } public string? GetAny() => Get(NoLanguage, NoCountry); public override string ToString() => GetAny() ?? ""; } }