using System; using System.Runtime.InteropServices; using System.Text; using System.Collections.Generic; namespace Steamworks { internal static class Helpers { public const int MaxStringSize = 1024 * 32; private static object mutex = new object(); private static IntPtr[] MemoryPool; private static int MemoryPoolIndex; public static unsafe IntPtr TakeMemory() { IntPtr take = IntPtr.Zero; lock (mutex) { if (MemoryPool == null) { // // The pool has 5 items. This should be safe because we shouldn't really // ever be using more than 2 memory pools // MemoryPool = new IntPtr[5]; for (int i = 0; i < MemoryPool.Length; i++) MemoryPool[i] = Marshal.AllocHGlobal(MaxStringSize); } MemoryPoolIndex++; if (MemoryPoolIndex >= MemoryPool.Length) MemoryPoolIndex = 0; take = MemoryPool[MemoryPoolIndex]; ((byte*)take)[0] = 0; } return take; } private static byte[][] BufferPool; private static int BufferPoolIndex; private static object BufferMutex = new object(); /// /// Returns a buffer. This will get returned and reused later on. /// public static byte[] TakeBuffer( int minSize ) { int bufferPoolIndex; lock (BufferMutex) { if (BufferPool == null) { // // The pool has 8 items. // BufferPool = new byte[8][]; for (int i = 0; i < BufferPool.Length; i++) BufferPool[i] = new byte[1024 * 128]; } BufferPoolIndex++; if (BufferPoolIndex < 0 || BufferPoolIndex >= BufferPool.Length) BufferPoolIndex = 0; bufferPoolIndex = BufferPoolIndex; } if ( BufferPool[bufferPoolIndex].Length < minSize ) { BufferPool[bufferPoolIndex] = new byte[minSize + 1024]; } return BufferPool[bufferPoolIndex]; } internal unsafe static string MemoryToString( IntPtr ptr ) { var len = 0; for( len = 0; len < MaxStringSize; len++ ) { if ( ((byte*)ptr)[len] == 0 ) break; } if ( len == 0 ) return string.Empty; return UTF8Encoding.UTF8.GetString( (byte*)ptr, len ); } } internal class MonoPInvokeCallbackAttribute : Attribute { public MonoPInvokeCallbackAttribute() { } } /// /// Prevent unity from stripping shit we depend on /// https://docs.unity3d.com/Manual/ManagedCodeStripping.html /// internal class PreserveAttribute : System.Attribute { } }