public void PluginTagTest() { // Arrange const TagSignature SignaturelNET = (TagSignature)0x6C4E4554; // 'lNET' PluginTag tag = new PluginTag { Base = new PluginBase { Magic = Cms.PluginMagicNumber, ExpectedVersion = (uint)Cms.EncodedCMMVersion, // >= 2.8 Type = PluginType.Tag, Next = IntPtr.Zero }, Signature = SignaturelNET, Descriptor = new TagDescriptor { ElemCount = 1, nSupportedTypes = 1, SupportedTypes = new TagTypeSignature[TagDescriptor.MAX_TYPES_IN_LCMS_PLUGIN], Decider = IntPtr.Zero } }; tag.Descriptor.SupportedTypes[0] = TagTypeSignature.Text; string expected = "PluginTagTest"; // Act int rawsize = Marshal.SizeOf(tag); IntPtr plugin = Marshal.AllocHGlobal(rawsize); Marshal.StructureToPtr(tag, plugin, false); try { using (var context = Context.Create(plugin, IntPtr.Zero)) using (var profile = Profile.CreatePlaceholder(context)) { using (var mlu = MultiLocalizedUnicode.Create(context)) { mlu.SetASCII(MultiLocalizedUnicode.NoLanguage, MultiLocalizedUnicode.NoCountry, expected); bool written = profile.WriteTag(SignaturelNET, mlu); Assert.IsTrue(written); } using (var mlu = profile.ReadTag <MultiLocalizedUnicode>(SignaturelNET)) { var actual = mlu.GetASCII(MultiLocalizedUnicode.NoLanguage, MultiLocalizedUnicode.NoCountry); // Assert Assert.AreEqual(expected, actual); } } } finally { Marshal.DestroyStructure(plugin, typeof(PluginTag)); Marshal.FreeHGlobal(plugin); } }
private double[] Device_Multiprocess_PCS() { if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.DToB1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.DToB2Tag; } else if (PreferredRenderingIntent == RenderingIntent.AbsoluteColorimetric) { sig = TagSignature.DToB3Tag; } else { sig = TagSignature.DToB0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.DToB0Tag); } AdjustColor(); return(((multiProcessElementsTagDataEntry)TagEntry1).GetValue(ic)); }
internal TagTableEntry(TagSignature Signature, uint Offset, uint DataSize, int Index) { this.Signature = Signature; this.Offset = Offset; this.DataSize = DataSize; this.Index = Index; }
/// <summary> /// Get the first entry with the specific signature. Returns null if none is found /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The data of the named entry</returns> public TagDataEntry GetFirstEntry(TagSignature TagName) { TagTableEntry[] Entries = TagTable.Data.Where(t => t.Signature == TagName).ToArray(); if (Entries.Length != 0) { return(TagData[Entries[0].Index]); } else { return(null); } }
private TagDataEntry[] GetTagDataEntry(TagSignature sig1) { TagDataEntry entry = GetTag(sig1); if (entry != null) { return new TagDataEntry[] { entry } } ; else { return(null); } }
private double[] PCS_LUT_Device() { AdjustColor(); if (ic.Length != 3) { throw new ArgumentException("Input color has wrong number of channels"); } if (InModel != ColorModel.CIEXYZ && InModel != ColorModel.CIELab) { throw new ArgumentException("Profile connection space has to be either XYZ or Lab"); } if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.BToA1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.BToA2Tag; } else { sig = TagSignature.BToA0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.BToA0Tag); } if (TagEntry1.Signature == TypeSignature.lut8) { output = ((lut8TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lut16) { output = ((lut16TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lutBToA) { output = ((lutBToATagDataEntry)TagEntry1).GetValue(ic); } else { throw new CorruptProfileException("BToATag has wrong type"); } return(output); }
private static bool VerifyStream(Stream dataStream, TagSignature signature, RSAParameters parameters) { try { if (signature.Required().Algorithm != Algorithm.RSA) { throw new InvalidDataException($"Signature uses different algorithm {signature.Algorithm} from this RSA key!"); } if (parameters.Exponent == null || parameters.Modulus == null) { throw new InvalidDataException($"This RSA key is not properly configured to be able to verify a signature!"); } using var RSAalg = OpenProvider(parameters); return(RSAalg.VerifyData(dataStream, signature.Data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); } catch (CryptographicException e) { throw new InterlockLedgerCryptographicException("Failed to verify data with current parameters and signature", e); } }
/// <summary> /// Get the all entries with the specific signature /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The array of data of the named entry</returns> public TagDataEntry[] GetAllEntries(TagSignature TagName) { TagTableEntry[] Entries = TagTable.Data.Where(t => t.Signature == TagName).ToArray(); if (Entries.Length != 0) { TagDataEntry[] output = new TagDataEntry[Entries.Length]; for (int i = 0; i < Entries.Length; i++) { output[i] = TagData[Entries[i].Index]; } return(output); } else { return(null); } }
private void SetTagTableUI() { TagTableListBox.Items.Clear(); foreach (var tag in Profile.Data) { TagSignature sig = tag.TagSignature; bool defined = Enum.IsDefined(typeof(TagSignature), sig); string label = sig.ToString(); if (!defined) { byte[] data = BitConverter.GetBytes((uint)sig); string ascii = Encoding.ASCII.GetString(data); label += $" ({ascii})"; } TagTableListBox.Items.Add(label); } }
private static bool VerifyStream(Stream dataStream, TagSignature signature, ECParameters parameters) { try { if (signature.Required().Algorithm != Algorithm.EcDSA) { throw new InvalidDataException($"Signature uses different algorithm {signature.Algorithm} from this ECDsa key!"); } if (parameters.D == null) { throw new InvalidDataException($"This ECDsa key is not properly configured to be able to verify a signature!"); } using var algo = OpenWith(parameters); return(algo.VerifyData(dataStream, signature.Data, ECDsaParameters.ChooseHashAlgo(parameters.Curve).ToName())); } catch (CryptographicException e) { throw new InterlockLedgerCryptographicException("Failed to verify data with current parameters and signature", e); } }
public void CreateECKeySerializeDeserializeSignAndVerify(KeyStrength keyStrength) { var parameters = ECDsaHelper.CreateNewECDsaParameters(keyStrength); var key = new TagPubECKey(parameters); var bytes = key.EncodedBytes; TestContext.WriteLine(bytes.AsLiteral()); using var ms = new MemoryStream(bytes); var tag = ms.Decode <TagPubKey>(); Assert.NotNull(tag); Assert.AreEqual(key, tag); CollectionAssert.AreEqual(bytes, tag.EncodedBytes); var signatureBytes = ECDsaHelper.HashAndSign(bytes, parameters.Parameters, parameters.HashAlgorithm.ToName()); var signature = new TagSignature(Algorithm.EcDSA, signatureBytes); Assert.IsTrue(key.Verify(bytes, signature), "Signature failed!"); }
/// <summary> /// Creates a new instance of the <see cref="ProfileDescription"/> struct /// </summary> /// <param name="DeviceManufacturer">Device Manufacturer</param> /// <param name="DeviceModel">Device Model</param> /// <param name="DeviceAttributes">Device Attributes</param> /// <param name="TechnologyInformation">Technology Information</param> /// <param name="DeviceManufacturerInfo">Device Manufacturer Info</param> /// <param name="DeviceModelInfo">Device Model Info</param> public ProfileDescription(uint DeviceManufacturer, uint DeviceModel, DeviceAttribute DeviceAttributes, TagSignature TechnologyInformation, LocalizedString[] DeviceManufacturerInfo, LocalizedString[] DeviceModelInfo) { if (DeviceManufacturerInfo == null) { throw new ArgumentNullException(nameof(DeviceManufacturerInfo)); } if (DeviceModelInfo == null) { throw new ArgumentNullException(nameof(DeviceModelInfo)); } this.DeviceManufacturer = DeviceManufacturer; this.DeviceModel = DeviceModel; this.DeviceAttributes = DeviceAttributes; this.TechnologyInformation = TechnologyInformation; this.DeviceManufacturerInfo = DeviceManufacturerInfo; this.DeviceModelInfo = DeviceModelInfo; }
private double[] Device_LUT_PCS() { AdjustColor(); if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.AToB1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.AToB2Tag; } else { sig = TagSignature.AToB0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.AToB0Tag); } if (TagEntry1.Signature == TypeSignature.lut8) { output = ((lut8TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lut16) { output = ((lut16TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lutAToB) { output = ((lutAToBTagDataEntry)TagEntry1).GetValue(ic); } else { throw new CorruptProfileException("AToBTag has wrong type"); } return(output); }
private double[] PCS_Multiprocess_Device() { AdjustColor(); if (ic.Length != 3) { throw new ArgumentException("Input color has wrong number of channels"); } if (InModel != ColorModel.CIEXYZ && InModel != ColorModel.CIELab) { throw new ArgumentException("Profile connection space has to be either XYZ or Lab"); } if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.BToD1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.BToD2Tag; } else if (PreferredRenderingIntent == RenderingIntent.AbsoluteColorimetric) { sig = TagSignature.BToD3Tag; } else { sig = TagSignature.BToD0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.BToD0Tag); } return(((multiProcessElementsTagDataEntry)TagEntry1).GetValue(ic)); }
/// <summary> /// Get the all entries with the specific signature /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The array of data of the named entry</returns> internal TagDataEntry[] GetAllEntries(TagSignature TagName) { return profile.GetAllEntries(TagName); }
/// <summary> /// Gets the <see cref="TagDataEntry"/> of given tag signature /// </summary> /// <param name="sig">the tag signature of the wanted <see cref="TagDataEntry"/></param> /// <returns>The <see cref="TagDataEntry"/> or null if not found</returns> public TagDataEntry GetTag(TagSignature sig) { return(Data.FirstOrDefault(t => t.TagSignature == sig)); }
/// <summary> /// Get the first entry with the specific signature. Returns null if none is found /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The data of the named entry</returns> internal TagDataEntry GetEntry(TagSignature TagName) { return(profile.GetFirstEntry(TagName)); }
public IdentifiedSignature(TagSignature signature, BaseKeyId id, TagPubKey publicKey) : this() { Signature = signature.Required(); SignerId = id.Required(); PublicKey = publicKey.Required(); }
/// <summary> /// Checks if this profile contains a specific tag /// </summary> /// <param name="sig">The tag signature to look for</param> /// <returns>True if the tag is contained, false otherwise</returns> public bool HasTag(TagSignature sig) { return(Data.Any(t => t.TagSignature == sig)); }
private double[] PCS_LUT_Device() { AdjustColor(); if (ic.Length != 3) { throw new ArgumentException("Input color has wrong number of channels"); } if (InModel != ColorModel.CIEXYZ && InModel != ColorModel.CIELab) { throw new ArgumentException("Profile connection space has to be either XYZ or Lab"); } if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.BToA1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.BToA2Tag; } else { sig = TagSignature.BToA0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.BToA0Tag); } if (TagEntry1.Signature == TypeSignature.lut8) { output = ((lut8TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lut16) { output = ((lut16TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lutBToA) { output = ((lutBToATagDataEntry)TagEntry1).GetValue(ic); } else { throw new CorruptProfileException("BToATag has wrong type"); } return output; }
/// <summary> /// Get the all entries with the specific signature /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The array of data of the named entry</returns> internal TagDataEntry[] GetAllEntries(TagSignature TagName) { return(profile.GetAllEntries(TagName)); }
/// <summary> /// Get the first entry with the specific signature. Returns null if none is found /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The data of the named entry</returns> internal TagDataEntry GetEntry(TagSignature TagName) { return profile.GetFirstEntry(TagName); }
public virtual bool Verify(byte[] data, TagSignature signature) => false;
public virtual bool Verify <T>(T data, TagSignature signature) where T : Signable <T>, new() => false;
public void PluginTagTypeTest() { // Arrange const TagSignature SigInt = (TagSignature)0x74747448; // 'tttH' const TagTypeSignature SigIntType = (TagTypeSignature)0x74747448; // 'tttH' PluginTag tag = new PluginTag { Base = new PluginBase { Magic = Cms.PluginMagicNumber, ExpectedVersion = (uint)Cms.EncodedCMMVersion, // >= 2.8 Type = PluginType.Tag, Next = IntPtr.Zero }, Signature = SigInt, Descriptor = new TagDescriptor { ElemCount = 1, nSupportedTypes = 1, SupportedTypes = new TagTypeSignature[TagDescriptor.MAX_TYPES_IN_LCMS_PLUGIN], Decider = IntPtr.Zero } }; tag.Descriptor.SupportedTypes[0] = SigIntType; int rawsize = Marshal.SizeOf(tag); IntPtr tagPlugin = Marshal.AllocHGlobal(rawsize); Marshal.StructureToPtr(tag, tagPlugin, false); // ensure delegates are not garbage collected from managed code var read = new TagTypeRead(Read); var write = new TagTypeWrite(Write); var duplicate = new TagTypeDuplicate(Duplicate); var free = new TagTypeFree(Free); PluginTagType tagType = new PluginTagType { Base = new PluginBase { Magic = Cms.PluginMagicNumber, ExpectedVersion = (uint)Cms.EncodedCMMVersion, // >= 2.8 Type = PluginType.TagType, Next = tagPlugin }, Handler = new TagTypeHandler { Signature = SigIntType, Read = Marshal.GetFunctionPointerForDelegate(read), Write = Marshal.GetFunctionPointerForDelegate(write), Duplicate = Marshal.GetFunctionPointerForDelegate(duplicate), Free = Marshal.GetFunctionPointerForDelegate(free) } }; rawsize = Marshal.SizeOf(tagType); IntPtr tagTypePlugin = Marshal.AllocHGlobal(rawsize); Marshal.StructureToPtr(tagType, tagTypePlugin, false); // Act try { using (var context = Context.Create(tagTypePlugin, IntPtr.Zero)) using (var profile = Profile.CreatePlaceholder(context)) { var errorHandler = new ErrorHandler(HandleError); context.SetErrorHandler(errorHandler); uint expected = 1234; bool written = profile.WriteTag(SigInt, expected); Assert.IsTrue(written); profile.Save(null, out uint bytesNeeded); Assert.AreNotEqual(0, bytesNeeded); byte[] profileMemory = new byte[bytesNeeded]; bool saved = profile.Save(profileMemory, out uint bytesWritten); Assert.IsTrue(saved); // close original profile to flush caches profile.Close(); // re-open profile from memory using (var profile2 = Profile.Open(context, profileMemory)) { IntPtr data = profile2.ReadTag(SigInt); uint[] u = new uint[1]; Marshal.Copy(data, (int[])(object)u, 0, 1); uint actual = u[0]; // Assert Assert.AreEqual(expected, actual); } } } finally { Marshal.DestroyStructure(tagPlugin, typeof(PluginTag)); Marshal.FreeHGlobal(tagPlugin); Marshal.DestroyStructure(tagTypePlugin, typeof(PluginTagType)); Marshal.FreeHGlobal(tagTypePlugin); } // allocates unmanaged memory for a single 'uint' and reads from i/o handler into it IntPtr Read(in TagTypeHandler self, IntPtr io, out uint nItems, uint tagSize) { TestContext.WriteLine($"Read(self: {self}, io: 0x{io:X}, out nItems, tagSize: {tagSize})"); using (var context = Context.FromHandle(self.ContextID)) using (var iohandler = IOHandler.FromHandle(io)) { nItems = 1; IntPtr ptr = Memory.Malloc(context, sizeof(uint)); if (ptr == IntPtr.Zero) { return(IntPtr.Zero); } // unsafe, but faster... unsafe { if (!iohandler.Read(ref *(uint *)ptr)) { return(IntPtr.Zero); } } // - or - // verifiable, but slower... //uint[] arr = new uint[1]; //if (!iohandler.Read(ref arr[0])) return IntPtr.Zero; //Marshal.Copy((int[])(object)arr, 0, ptr, 1); return(ptr); } } // uses the i/o handler to write a single 'uint' read from unmanaged memory 'ptr' int Write(in TagTypeHandler self, IntPtr io, IntPtr ptr, uint nItems) { TestContext.WriteLine($"Write(self: {self}, io: 0x{io:X}, ptr: 0x{ptr:X}, nItems: {nItems})"); using (var iohandler = IOHandler.FromHandle(io)) { // unsafe, but faster... unsafe { return(iohandler.Write(*(uint *)ptr) ? 1 : 0); } // - or - // verifiable, but slower... //uint[] arr = new uint[1]; //Marshal.Copy(ptr, (int[])(object)arr, 0, 1); //return iohandler.Write(arr[0]) ? 1 : 0; } } // duplicates the unmanaged memory 'ptr' into a new block of size 'n x sizeof(uint)' IntPtr Duplicate(in TagTypeHandler self, IntPtr ptr, uint n) { TestContext.WriteLine($"Duplicate(self: {self}, ptr: 0x{ptr:X}, n: {n})"); using (var context = Context.FromHandle(self.ContextID)) { return(Memory.Duplicate(context, ptr, n * sizeof(uint))); } } // frees the unmanaged memory 'ptr' void Free(in TagTypeHandler self, IntPtr ptr) { TestContext.WriteLine($"Free(self: {self}, ptr: 0x{ptr:X})"); using (var context = Context.FromHandle(self.ContextID)) { Memory.Free(context, ptr); } } void HandleError(IntPtr contextID, int errorCode, string errorText) { TestContext.WriteLine($"Error!!! contextID: {contextID}, errorCode: {errorCode}, errorText: '{errorText}'"); } }
/// <summary> /// Get the first entry with the specific signature. Returns null if none is found /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The data of the named entry</returns> public TagDataEntry GetFirstEntry(TagSignature TagName) { TagTableEntry[] Entries = TagTable.Data.Where(t => t.Signature == TagName).ToArray(); if (Entries.Length != 0) { return TagData[Entries[0].Index]; } else { return null; } }
/// <summary> /// Creates a new instance of the <see cref="TagTableEntry"/> struct /// </summary> /// <param name="Signature">Signature of the tag</param> /// <param name="Offset">Offset of entry in bytes</param> /// <param name="DataSize">Size of entry in bytes</param> public TagTableEntry(TagSignature Signature, uint Offset, uint DataSize) { this.Signature = Signature; this.Offset = Offset; this.DataSize = DataSize; }
private double[] Device_LUT_PCS() { AdjustColor(); if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.AToB1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.AToB2Tag; } else { sig = TagSignature.AToB0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.AToB0Tag); } if (TagEntry1.Signature == TypeSignature.lut8) { output = ((lut8TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lut16) { output = ((lut16TagDataEntry)TagEntry1).GetValue(ic); } else if (TagEntry1.Signature == TypeSignature.lutAToB) { output = ((lutAToBTagDataEntry)TagEntry1).GetValue(ic); } else { throw new CorruptProfileException("AToBTag has wrong type"); } return output; }
private double[] PCS_Multiprocess_Device() { AdjustColor(); if (ic.Length != 3) { throw new ArgumentException("Input color has wrong number of channels"); } if (InModel != ColorModel.CIEXYZ && InModel != ColorModel.CIELab) { throw new ArgumentException("Profile connection space has to be either XYZ or Lab"); } if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.BToD1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.BToD2Tag; } else if (PreferredRenderingIntent == RenderingIntent.AbsoluteColorimetric) { sig = TagSignature.BToD3Tag; } else { sig = TagSignature.BToD0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.BToD0Tag); } return ((multiProcessElementsTagDataEntry)TagEntry1).GetValue(ic); }
public override bool Verify(byte[] data, TagSignature signature) => RSAHelper.Verify(data, signature, Parameters);
public static bool Verify <T>(T dataToVerify, TagSignature signature, RSAParameters parameters) where T : Signable <T>, new() { using var dataStream = dataToVerify.Required().OpenReadingStreamAsync().Result; return(VerifyStream(dataStream, signature, parameters)); }
public static bool Verify(byte[] dataToVerify, TagSignature signature, RSAParameters parameters) { using var dataStream = new MemoryStream(dataToVerify, writable: false); return(VerifyStream(dataStream, signature, parameters)); }
private double[] Device_Multiprocess_PCS() { if (PreferredRenderingIntent == RenderingIntent.RelativeColorimetric) { sig = TagSignature.DToB1Tag; } else if (PreferredRenderingIntent == RenderingIntent.Saturation) { sig = TagSignature.DToB2Tag; } else if (PreferredRenderingIntent == RenderingIntent.AbsoluteColorimetric) { sig = TagSignature.DToB3Tag; } else { sig = TagSignature.DToB0Tag; } TagEntry1 = Profile.GetEntry(sig); if (TagEntry1 == null) { TagEntry1 = Profile.GetEntry(TagSignature.DToB0Tag); } AdjustColor(); return ((multiProcessElementsTagDataEntry)TagEntry1).GetValue(ic); }
/// <summary> /// Get the all entries with the specific signature /// </summary> /// <param name="TagName">The signature of the entry</param> /// <returns>The array of data of the named entry</returns> public TagDataEntry[] GetAllEntries(TagSignature TagName) { TagTableEntry[] Entries = TagTable.Data.Where(t => t.Signature == TagName).ToArray(); if (Entries.Length != 0) { TagDataEntry[] output = new TagDataEntry[Entries.Length]; for (int i = 0; i < Entries.Length; i++ ) { output[i] = TagData[Entries[i].Index]; } return output; } else { return null; } }
public void PluginTagWithDeciderTest() { // Arrange const TagSignature SignaturelNET = (TagSignature)0x6C4E4554; // 'lNET' // ensure delegates are not garbage collected from managed code var decide = new DecideType(Decide); PluginTag tag = new PluginTag { Base = new PluginBase { Magic = Cms.PluginMagicNumber, ExpectedVersion = (uint)Cms.EncodedCMMVersion, // >= 2.8 Type = PluginType.Tag, Next = IntPtr.Zero }, Signature = SignaturelNET, Descriptor = new TagDescriptor { ElemCount = 1, nSupportedTypes = 1, SupportedTypes = new TagTypeSignature[TagDescriptor.MAX_TYPES_IN_LCMS_PLUGIN], Decider = Marshal.GetFunctionPointerForDelegate(decide) } }; tag.Descriptor.SupportedTypes[0] = TagTypeSignature.Text; string expected = "PluginTagWithDeciderTest"; // Act int rawsize = Marshal.SizeOf(tag); IntPtr plugin = Marshal.AllocHGlobal(rawsize); Marshal.StructureToPtr(tag, plugin, false); try { using (var context = Context.Create(plugin, IntPtr.Zero)) using (var profile = Profile.CreatePlaceholder(context)) { using (var mlu = MultiLocalizedUnicode.Create(context)) { mlu.SetASCII(MultiLocalizedUnicode.NoLanguage, MultiLocalizedUnicode.NoCountry, expected); bool written = profile.WriteTag(SignaturelNET, mlu); Assert.IsTrue(written); } using (var mlu = profile.ReadTag <MultiLocalizedUnicode>(SignaturelNET)) { var actual = mlu.GetASCII(MultiLocalizedUnicode.NoLanguage, MultiLocalizedUnicode.NoCountry); // Assert Assert.AreEqual(expected, actual); } } } finally { Marshal.DestroyStructure(plugin, typeof(PluginTag)); Marshal.FreeHGlobal(plugin); } TagTypeSignature Decide(double iccVersion, IntPtr data) { TestContext.WriteLine($"iccVersion: {iccVersion}, data: 0x{data:X}"); using (var mlu = MultiLocalizedUnicode.FromHandle(data)) { var text = mlu.GetASCII(MultiLocalizedUnicode.NoLanguage, MultiLocalizedUnicode.NoCountry); TestContext.WriteLine($"text: {text}"); } return(TagTypeSignature.Text); } }