Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        public void RegisterPluginsTest()
        {
            try
            {
                // Arrange
                IntPtr plugin   = IntPtr.Zero;
                IntPtr userData = IntPtr.Zero;

                // Act
                using (var context = Context.Create(plugin, userData))
                {
                    PluginTag tag = new PluginTag
                    {
                        Base = new PluginBase
                        {
                            Magic           = Cms.PluginMagicNumber,
                            ExpectedVersion = (uint)Cms.EncodedCMMVersion,    // >= 2.8
                            Type            = PluginType.Tag,
                            Next            = IntPtr.Zero
                        },
                        Signature  = (TagSignature)0x696e6b63,  // 'inkc'
                        Descriptor = new TagDescriptor
                        {
                            ElemCount       = 1,
                            nSupportedTypes = 1,
                            SupportedTypes  = new TagTypeSignature[TagDescriptor.MAX_TYPES_IN_LCMS_PLUGIN],
                            Decider         = IntPtr.Zero
                        }
                    };
                    tag.Descriptor.SupportedTypes[0] = TagTypeSignature.Lut16;

                    int    rawsize = Marshal.SizeOf(tag);
                    IntPtr buffer  = Marshal.AllocHGlobal(rawsize);
                    Marshal.StructureToPtr(tag, buffer, false);
                    try
                    {
                        var registered = context.RegisterPlugins(buffer);

                        // Assert
                        Assert.IsTrue(registered);
                    }
                    finally
                    {
                        context.UnregisterPlugins();
                        Marshal.DestroyStructure(buffer, typeof(PluginTag));
                        Marshal.FreeHGlobal(buffer);
                    }
                }
            }
            catch (EntryPointNotFoundException)
            {
                Assert.Inconclusive("Requires Little CMS 2.8 or later.");
            }
        }
Esempio n. 3
0
        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}'");
            }
        }
Esempio n. 4
0
        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);
            }
        }