public void SafeReadWriteRaw(Reloaded.Memory.Sources.IMemory memorySource)
        {
            // Prepare
            int arrayElements = 13432;

            IMemoryTools.SwapExternalMemorySource(ref memorySource, _helloWorldProcess);
            IntPtr pointer = memorySource.Allocate(arrayElements);

            /* Start Test */

            // Generate random int struct to read/write to.
            var randomByteArray = RandomByteArray.GenerateRandomByteArray(arrayElements);

            // Run the change permission function to deny read/write access.
            try { memorySource.ChangePermission(pointer, arrayElements, Kernel32.Kernel32.MEM_PROTECTION.PAGE_NOACCESS); }
            catch (NotImplementedException) { return; } // ChangePermission is optional to implement

            // Throws corrupted state exception if operations fail until restore.
            memorySource.SafeWriteRaw(pointer, randomByteArray.Array);
            memorySource.SafeReadRaw(pointer, out byte[] randomByteArrayCopy, randomByteArray.Array.Length);

            // Restore or NETCore execution engine will complain.
            try { memorySource.ChangePermission(pointer, arrayElements, Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); }
            catch (NotImplementedException) { return; } // ChangePermission is optional to implement

            // Compare before exiting test.
            Assert.Equal(randomByteArray.Array, randomByteArrayCopy);

            // Cleanup
            memorySource.Free(pointer);
        }
        public void SafeReadWrite(Reloaded.Memory.Sources.IMemory memorySource)
        {
            // Prepare
            int structSize = Struct.GetSize <RandomIntStruct>();

            IMemoryTools.SwapExternalMemorySource(ref memorySource, _helloWorldProcess);
            IntPtr pointer = memorySource.Allocate(structSize);

            /* Start Test */

            // Generate random int struct to read/write to.
            var randomIntStruct = RandomIntStruct.BuildRandomStruct();

            // Run the change permission function to deny read/write access.
            try { memorySource.ChangePermission(pointer, structSize, Kernel32.Kernel32.MEM_PROTECTION.PAGE_NOACCESS); }
            catch (NotImplementedException) { return; } // ChangePermission is optional to implement

            // Throws corrupted state exception if operations fail until restore.
            memorySource.SafeWrite(pointer, ref randomIntStruct, false);
            memorySource.SafeRead(pointer, out RandomIntStruct randomIntStructOldOverload, false);
            memorySource.SafeRead(pointer, out RandomIntStruct randomIntStructNewOverload);
            Assert.Equal(randomIntStructOldOverload, randomIntStructNewOverload);

            // New overloads in 1.4.0
            memorySource.SafeWrite(pointer, ref randomIntStruct);
            memorySource.SafeRead(pointer, out randomIntStructOldOverload, false);
            memorySource.SafeRead(pointer, out randomIntStructNewOverload);
            Assert.Equal(randomIntStructOldOverload, randomIntStructNewOverload);

            // We test both read functions against each write function.

            // Restore or NETCore execution engine will complain.
            try { memorySource.ChangePermission(pointer, structSize, Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); }
            catch (NotImplementedException) { return; } // ChangePermission is optional to implement

            // Compare before exiting test.
            Assert.Equal(randomIntStruct, randomIntStructNewOverload);

            // Cleanup
            memorySource.Free(pointer);
        }