/// <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); } } }