diff options
Diffstat (limited to 'win/CS/HandBrake.Interop/Interop/Helpers/InteropUtilities.cs')
-rw-r--r-- | win/CS/HandBrake.Interop/Interop/Helpers/InteropUtilities.cs | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/win/CS/HandBrake.Interop/Interop/Helpers/InteropUtilities.cs b/win/CS/HandBrake.Interop/Interop/Helpers/InteropUtilities.cs new file mode 100644 index 000000000..c63fde326 --- /dev/null +++ b/win/CS/HandBrake.Interop/Interop/Helpers/InteropUtilities.cs @@ -0,0 +1,283 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="InteropUtilities.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// Helper utilities for native interop. +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Interop.Interop.Helpers +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Runtime.InteropServices; + using System.Text; + + using HandBrake.Interop.Interop.HbLib; + + /// <summary> + /// Helper utilities for native interop. + /// </summary> + internal static class InteropUtilities + { + /// <summary> + /// Reads the given native structure pointer. + /// </summary> + /// <typeparam name="T">The type to convert the structure to.</typeparam> + /// <param name="structPtr">The pointer to the native structure.</param> + /// <returns>The converted structure.</returns> + public static T ToStructureFromPtr<T>(IntPtr structPtr) + { + return (T)Marshal.PtrToStructure(structPtr, typeof(T)); + } + + /// <summary> + /// Reads the given native UTF-8 string. + /// </summary> + /// <param name="stringPtr">The pointer to the string.</param> + /// <returns>The resulting string.</returns> + public static string ToStringFromUtf8Ptr(IntPtr stringPtr) + { + var data = new List<byte>(); + var ptr = stringPtr; + var offset = 0; + while (true) + { + byte ch = Marshal.ReadByte(ptr, offset++); + if (ch == 0) + { + break; + } + + data.Add(ch); + } + + return Encoding.UTF8.GetString(data.ToArray()); + } + + /// <summary> + /// Creates a pointer to a UTF-8 null-terminated string. + /// </summary> + /// <param name="str"> + /// The string to encode. + /// </param> + /// <returns> + /// The <see cref="IntPtr"/>. + /// </returns> + public static IntPtr ToUtf8PtrFromString(string str) + { + byte[] bytes = Encoding.UTF8.GetBytes(str); + IntPtr stringPtr = Marshal.AllocHGlobal(bytes.Length + 1); + var offset = 0; + foreach (byte b in bytes) + { + Marshal.WriteByte(stringPtr, offset, b); + offset++; + } + + Marshal.WriteByte(stringPtr, offset, 0); + return stringPtr; + } + + /// <summary> + /// Converts the given native HandBrake list to a managed list. + /// </summary> + /// <typeparam name="T">The type of structure in the list.</typeparam> + /// <param name="listPtr">The pointer to the native list.</param> + /// <returns>The converted managed list.</returns> + public static List<T> ToListFromHandBrakeList<T>(this IntPtr listPtr) + { + List<T> returnList = new List<T>(); + NativeList nativeList = new NativeList(listPtr); + + for (int i = 0; i < nativeList.Count; i++) + { + IntPtr itemPtr = nativeList[i]; + returnList.Add(ToStructureFromPtr<T>(itemPtr)); + } + + return returnList; + } + + /// <summary> + /// Converts the HB list to a managed list of pointers. + /// </summary> + /// <param name="listPtr">The list to convert.</param> + /// <returns>The managed list of pointers.</returns> + public static List<IntPtr> ToIntPtrList(this IntPtr listPtr) + { + var returnList = new List<IntPtr>(); + NativeList nativeList = new NativeList(listPtr); + + for (int i = 0; i < nativeList.Count; i++) + { + IntPtr itemPtr = nativeList[i]; + returnList.Add(itemPtr); + } + + return returnList; + } + + /// <summary> + /// Converts the given native array to a managed collection. + /// </summary> + /// <typeparam name="T">The type of item in the list.</typeparam> + /// <param name="arrayPtr">The pointer to the array.</param> + /// <param name="count">The number of items in the array.</param> + /// <returns>The converted collection.</returns> + public static List<T> ToListFromNativeArray<T>(IntPtr arrayPtr, int count) + { + IntPtr currentItem = arrayPtr; + + var result = new List<T>(); + for (int i = 0; i < count; i++) + { + T nativeEncoder = ToStructureFromPtr<T>(currentItem); + result.Add(nativeEncoder); + + currentItem = IntPtr.Add(currentItem, Marshal.SizeOf(typeof(T))); + } + + return result; + } + + /// <summary> + /// Takes an array pointer and converts it into a list of strings. + /// </summary> + /// <param name="arrayPtr">A pointer to a raw list of strings.</param> + /// <returns>The list of strings.</returns> + public static List<string> ToStringListFromArrayPtr(IntPtr arrayPtr) + { + if (arrayPtr == IntPtr.Zero) + { + return null; + } + + return ToPtrListFromPtr(arrayPtr).Select(ptr => Marshal.PtrToStringAnsi(ptr)).ToList(); + } + + /// <summary> + /// Finds all the pointers starting at the given location and puts them in a list. Stops when it finds zero for a pointer. + /// </summary> + /// <param name="arrayPtr">The address of the list of pointers.</param> + /// <returns>The list of pointers.</returns> + public static List<IntPtr> ToPtrListFromPtr(IntPtr arrayPtr) + { + var result = new List<IntPtr>(); + int ptrSize = Marshal.SizeOf(typeof(IntPtr)); + IntPtr currentPtr = Marshal.ReadIntPtr(arrayPtr); + for (int i = 0; currentPtr != IntPtr.Zero; i++) + { + result.Add(currentPtr); + currentPtr = Marshal.ReadIntPtr(arrayPtr, (i + 1) * ptrSize); + } + + return result; + } + + /// <summary> + /// Creates a native HandBrake list from the given managed list of pointers. + /// </summary> + /// <param name="list">The managed list to convert.</param> + /// <returns>The converted native list.</returns> + public static NativeList ToHandBrakeListFromPtrList(List<IntPtr> list) + { + NativeList returnList = NativeList.CreateList(); + + foreach (IntPtr ptr in list) + { + returnList.Add(ptr); + } + + return returnList; + } + + /// <summary> + /// Creates a native HandBrake list from the given managed list of structures. + /// </summary> + /// <typeparam name="T">The type of structures in the list.</typeparam> + /// <param name="list">The managed list to convert.</param> + /// <returns>The converted native list.</returns> + public static NativeList ToHandBrakeListFromList<T>(List<T> list) + { + NativeList returnList = NativeList.CreateList(); + foreach (T item in list) + { + IntPtr itemPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T))); + returnList.AllocatedMemory.Add(itemPtr); + Marshal.StructureToPtr(item, itemPtr, false); + + returnList.Add(itemPtr); + } + + return returnList; + } + + /// <summary> + /// Reads in a list of objects given an iterator and a conversion function. + /// </summary> + /// <typeparam name="T1">The type of the struct given by the iterator.</typeparam> + /// <typeparam name="T2">The object type to convert to.</typeparam> + /// <param name="iterator">The iterator to use to build the list.</param> + /// <param name="converter">The converter to convert from the struct to the object.</param> + /// <returns>The list of objects.</returns> + public static List<T2> ToListFromIterator<T1, T2>(Func<IntPtr, IntPtr> iterator, Func<T1, T2> converter) + { + return ToListFromIterator<T1>(iterator).Select(converter).ToList(); + } + + /// <summary> + /// Reads in a list of structs given an iterator. + /// </summary> + /// <typeparam name="T">The type of the struct.</typeparam> + /// <param name="iterator">The iterator to use to build the list.</param> + /// <returns>The list of structs.</returns> + public static List<T> ToListFromIterator<T>(Func<IntPtr, IntPtr> iterator) + { + var structureList = new List<T>(); + IntPtr current = IntPtr.Zero; + + current = iterator(current); + while (current != IntPtr.Zero) + { + T encoder = ToStructureFromPtr<T>(current); + structureList.Add(encoder); + + current = iterator(current); + } + + return structureList; + } + + /// <summary> + /// Closes the given job. + /// </summary> + /// <param name="nativeJobPtr">The pointer to the job.</param> + public static void CloseJob(IntPtr nativeJobPtr) + { + // Create a point to the job pointer first. + IntPtr nativeJobPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); + + // Assign the new pointer to the job pointer and tell HB to clean the job up. + Marshal.WriteIntPtr(nativeJobPtrPtr, nativeJobPtr); + HBFunctions.hb_job_close(nativeJobPtrPtr); + + // Free the pointer we used. + Marshal.FreeHGlobal(nativeJobPtrPtr); + } + + /// <summary> + /// Frees all the memory locations in the given list. + /// </summary> + /// <param name="memoryList">The list of memory locations to free.</param> + public static void FreeMemory(List<IntPtr> memoryList) + { + foreach (IntPtr memoryLocation in memoryList) + { + Marshal.FreeHGlobal(memoryLocation); + } + } + } +} |