diff options
Diffstat (limited to 'win/CS/HandBrake.Interop/Interop/Helpers')
3 files changed, 459 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); + } + } + } +} diff --git a/win/CS/HandBrake.Interop/Interop/Helpers/NativeList.cs b/win/CS/HandBrake.Interop/Interop/Helpers/NativeList.cs new file mode 100644 index 000000000..dc0f9c3db --- /dev/null +++ b/win/CS/HandBrake.Interop/Interop/Helpers/NativeList.cs @@ -0,0 +1,127 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="NativeList.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> +// Represents a HandBrake style native list. +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Interop.Interop.Helpers +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Runtime.InteropServices; + + using HandBrake.Interop.Interop.HbLib; + + /// <summary> + /// Represents a HandBrake style native list. + /// </summary> + internal class NativeList : IDisposable + { + /// <summary> + /// Initializes a new instance of the NativeList class. + /// </summary> + /// <param name="listPtr">The pointer to use for the list.</param> + public NativeList(IntPtr listPtr) + { + this.Ptr = listPtr; + } + + /// <summary> + /// The list of native memory locations allocated for this list. + /// </summary> + private readonly List<IntPtr> allocatedMemory = new List<IntPtr>(); + + /// <summary> + /// Gets the pointer to the native list. + /// </summary> + public IntPtr Ptr { get; private set; } + + /// <summary> + /// Gets the number of items in the list. + /// </summary> + public int Count + { + get + { + Debug.WriteLine("Got a Zero Pointer in the NativeList"); + return this.Ptr == IntPtr.Zero ? 0 : HBFunctions.hb_list_count(this.Ptr); + } + } + + /// <summary> + /// Gets the list of native memory locations allocated for this list. + /// </summary> + public List<IntPtr> AllocatedMemory + { + get + { + return this.allocatedMemory; + } + } + + /// <summary> + /// Adds an item to the end of the list. + /// </summary> + /// <param name="item">The item to add.</param> + public void Add(IntPtr item) + { + HBFunctions.hb_list_add(this.Ptr, item); + } + + /// <summary> + /// Inserts an item into the list. + /// </summary> + /// <param name="position">The index to insert the item at.</param> + /// <param name="item">The item to insert.</param> + public void Insert(int position, IntPtr item) + { + HBFunctions.hb_list_insert(this.Ptr, position, item); + } + + /// <summary> + /// Removes an item from the list. + /// </summary> + /// <param name="item">The item to remove.</param> + public void Remove(IntPtr item) + { + HBFunctions.hb_list_rem(this.Ptr, item); + } + + /// <summary> + /// Gets an item out of the list. + /// </summary> + /// <param name="i">Index in the list.</param> + /// <returns>The item at that index in the list.</returns> + public IntPtr this[int i] + { + get + { + return HBFunctions.hb_list_item(this.Ptr, i); + } + } + + /// <summary> + /// Disposes resources associated with this object. + /// </summary> + public void Dispose() + { + IntPtr listPtrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr))); + Marshal.WriteIntPtr(listPtrPtr, this.Ptr); + HBFunctions.hb_list_close(listPtrPtr); + Marshal.FreeHGlobal(listPtrPtr); + } + + /// <summary> + /// Creates a new list in unmanaged memory. + /// </summary> + /// <returns>The created list.</returns> + public static NativeList CreateList() + { + return new NativeList(HBFunctions.hb_list_init()); + } + } +} diff --git a/win/CS/HandBrake.Interop/Interop/Helpers/Utilities.cs b/win/CS/HandBrake.Interop/Interop/Helpers/Utilities.cs new file mode 100644 index 000000000..369216023 --- /dev/null +++ b/win/CS/HandBrake.Interop/Interop/Helpers/Utilities.cs @@ -0,0 +1,49 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="Utilities.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> +// Defines the Utilities type. +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Interop.Interop.Helpers +{ + /// <summary> + /// The utilities. + /// </summary> + internal static class Utilities + { + /// <summary> + /// Get the Greatest Common Factor + /// </summary> + /// <param name="a"> + /// The a. + /// </param> + /// <param name="b"> + /// The b. + /// </param> + /// <returns> + /// The greatest common factor + /// </returns> + public static int GreatestCommonFactor(int a, int b) + { + if (a == 0) + { + return b; + } + + if (b == 0) + { + return a; + } + + if (a > b) + { + return GreatestCommonFactor(a % b, b); + } + + return GreatestCommonFactor(a, b % a); + } + } +} |