Example #1
0
        /// <summary>
        /// Reads a <see cref="TagTypeSignature"/> from the I/O handler.
        /// </summary>
        /// <param name="sig">Returns the <see cref="TagTypeSignature"/>.</param>
        /// <returns>true if successful, otherwise false.</returns>
        public bool Read(out TagTypeSignature sig)
        {
            uint s = Interop.ReadTypeBase(handle);

            sig = (TagTypeSignature)s;
            return(s != 0);
        }
Example #2
0
        public void WriteTagTypeSignatureTest()
        {
            // Arrange
            using (var iohandler = IOHandler.Open(null))
            {
                TagTypeSignature sig      = TagTypeSignature.MultiLocalizedUnicode;
                bool             expected = true;

                // Act
                bool actual = iohandler.Write(sig);

                // Assert
                Assert.AreEqual(expected, actual);
            }
        }
Example #3
0
 /// <summary>
 /// Writes a <see cref="TagTypeSignature"/> to the I/O handler.
 /// </summary>
 /// <param name="sig">The <see cref="TagTypeSignature"/> to be written.</param>
 /// <returns>true if successful, otherwise false.</returns>
 public bool Write(TagTypeSignature sig)
 {
     return(Interop.WriteTypeBase(handle, (uint)sig));
 }
Example #4
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}'");
            }
        }