Beispiel #1
0
        /// <summary>
        /// Initializes the <see cref="Atom"/> instance from the specified <see cref="IntPtr"/>
        /// value.
        /// </summary>
        /// <param name="fileHandle">The <see cref="IntPtr"/> file handle of the file from which to read this <see cref="Atom"/>.</param>
        /// <returns><see langword="true"/> if this <see cref="Atom"/> was successfully initialized; otherwise, <see langword="false"/>.</returns>
        internal bool Initialize(IntPtr fileHandle)
        {
            bool   isInitialized  = false;
            IntPtr rawAtomPointer = NativeMethods.MP4ItmfGetItemsByMeaning(fileHandle, this.Meaning, this.Name);

            if (rawAtomPointer != IntPtr.Zero)
            {
                NativeMethods.MP4ItmfItemList atomItemList = rawAtomPointer.ReadStructure <NativeMethods.MP4ItmfItemList>();
                isInitialized = atomItemList.size > 0;
                for (int i = 0; i < atomItemList.size; i++)
                {
                    IntPtr itemPointer = atomItemList.elements[i];
                    NativeMethods.MP4ItmfItem     item     = itemPointer.ReadStructure <NativeMethods.MP4ItmfItem>();
                    NativeMethods.MP4ItmfDataList dataList = item.dataList;
                    for (int j = 0; j < dataList.size; j++)
                    {
                        IntPtr dataListItemPointer     = dataList.elements[i];
                        NativeMethods.MP4ItmfData data = dataListItemPointer.ReadStructure <NativeMethods.MP4ItmfData>();
                        if (data.typeCode == this.DataType)
                        {
                            byte[] dataBuffer = data.value.ReadBuffer(data.valueSize);
                            this.Populate(dataBuffer);
                        }
                    }
                }

                NativeMethods.MP4ItmfItemListFree(rawAtomPointer);
            }

            return(isInitialized);
        }
        private static void WriteRawAtom <T>(IntPtr fileHandle, T atom) where T : Atom, new()
        {
            // Because Generics don't allow inheritable static members, and we
            // really don't want to resort to reflection, we can create an instance
            // of the appropriate Atom type, only to get the Meaning and Name properties.
            // Passing in the parameters leads to potentially getting the strings wrong.
            // This solution is hacky in the worst possible way; let's think of a better
            // approach.
            T      templateAtom = new T();
            string atomMeaning  = templateAtom.Meaning;
            string atomName     = templateAtom.Name;

            IntPtr listPtr = NativeMethods.MP4ItmfGetItemsByMeaning(fileHandle, atomMeaning, atomName);

            if (listPtr != IntPtr.Zero)
            {
                NativeMethods.MP4ItmfItemList list = listPtr.ReadStructure <NativeMethods.MP4ItmfItemList>();
                for (int i = 0; i < list.size; i++)
                {
                    IntPtr item = list.elements[i];
                    NativeMethods.MP4ItmfRemoveItem(fileHandle, item);
                }

                NativeMethods.MP4ItmfItemListFree(listPtr);

                if (atom != null)
                {
                    IntPtr newItemPtr = NativeMethods.MP4ItmfItemAlloc("----", 1);
                    NativeMethods.MP4ItmfItem newItem = newItemPtr.ReadStructure <NativeMethods.MP4ItmfItem>();
                    newItem.mean = atom.Meaning;
                    newItem.name = atom.Name;

                    NativeMethods.MP4ItmfData data = new NativeMethods.MP4ItmfData();
                    data.typeCode = atom.DataType;
                    byte[] dataBuffer = atom.ToByteArray();
                    data.valueSize = dataBuffer.Length;

                    IntPtr dataValuePointer = Marshal.AllocHGlobal(dataBuffer.Length);
                    Marshal.Copy(dataBuffer, 0, dataValuePointer, dataBuffer.Length);
                    data.value = dataValuePointer;

                    IntPtr dataPointer = Marshal.AllocHGlobal(Marshal.SizeOf(data));
                    Marshal.StructureToPtr(data, dataPointer, false);
                    newItem.dataList.elements[0] = dataPointer;

                    Marshal.StructureToPtr(newItem, newItemPtr, false);
                    NativeMethods.MP4ItmfAddItem(fileHandle, newItemPtr);

                    Marshal.FreeHGlobal(dataPointer);
                    Marshal.FreeHGlobal(dataValuePointer);
                }
            }
        }