Example #1
0
        private static unsafe void AsMemory_Roundtrips_Core <T>(ReadOnlyMemory <T> readOnlyMemory)
        {
            Memory <T>         memory        = MemoryMarshal.AsMemory(readOnlyMemory);
            ReadOnlyMemory <T> readOnlyClone = memory;

            // Equals
            Assert.True(readOnlyMemory.Equals(readOnlyClone));
            Assert.True(readOnlyMemory.Equals((object)readOnlyClone));
            Assert.True(readOnlyMemory.Equals((object)memory));

            // Span
            Assert.True(readOnlyMemory.Span == readOnlyClone.Span);
            Assert.True(readOnlyMemory.Span == memory.Span);

            // TryGetArray
            Assert.True(MemoryMarshal.TryGetArray(readOnlyMemory, out ArraySegment <T> array1) == memory.TryGetArray(out ArraySegment <T> array2));
            Assert.Same(array1.Array, array2.Array);
            Assert.Equal(array1.Offset, array2.Offset);
            Assert.Equal(array1.Count, array2.Count);

            // Retain
            using (MemoryHandle readOnlyMemoryHandle = readOnlyMemory.Retain())
                using (MemoryHandle readOnlyCloneHandle = readOnlyMemory.Retain())
                    using (MemoryHandle memoryHandle = readOnlyMemory.Retain())
                    {
                        Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)readOnlyCloneHandle.Pointer);
                        Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)memoryHandle.Pointer);
                    }
        }
Example #2
0
        public static void MemoryRetainWithPinningAndSlice()
        {
            int[] array = { 1, 2, 3, 4, 5 };
            ReadOnlyMemory <int> memory = array;

            memory = memory.Slice(1);
            MemoryHandle       handle = memory.Retain(pin: true);
            ReadOnlySpan <int> span   = memory.Span;

            Assert.True(handle.HasPointer);
            unsafe
            {
                int *pointer = (int *)handle.Pointer;

                GC.Collect();

                for (int i = 0; i < memory.Length; i++)
                {
                    Assert.Equal(array[i + 1], pointer[i]);
                }

                for (int i = 0; i < memory.Length; i++)
                {
                    Assert.Equal(array[i + 1], span[i]);
                }
            }
            handle.Dispose();
        }
Example #3
0
        public static void OwnedMemoryRetainWithPinningAndSlice()
        {
            int[]                array  = { 1, 2, 3, 4, 5 };
            OwnedMemory <int>    owner  = new CustomMemoryForTest <int>(array);
            ReadOnlyMemory <int> memory = owner.Memory.Slice(1);
            MemoryHandle         handle = memory.Retain(pin: true);
            ReadOnlySpan <int>   span   = memory.Span;

            unsafe
            {
                int *pointer = (int *)handle.PinnedPointer;
                Assert.True(pointer != null);

                GC.Collect();

                for (int i = 0; i < memory.Length; i++)
                {
                    Assert.Equal(array[i + 1], pointer[i]);
                }

                for (int i = 0; i < memory.Length; i++)
                {
                    Assert.Equal(array[i + 1], span[i]);
                }
            }
            handle.Dispose();
        }
Example #4
0
        public static unsafe void AsReadOnlyMemory_Retain_ExpectedPointerValue()
        {
            string input            = "0123456789";
            ReadOnlyMemory <char> m = input.AsReadOnlyMemory();

            using (MemoryHandle h = m.Retain(pin: false))
            {
                Assert.Equal(IntPtr.Zero, (IntPtr)h.Pointer);
            }

            using (MemoryHandle h = m.Retain(pin: true))
            {
                GC.Collect();
                fixed(char *ptr = input)
                {
                    Assert.Equal((IntPtr)ptr, (IntPtr)h.Pointer);
                }
            }
        }
Example #5
0
        public static void DefaultMemoryRetain(bool pin)
        {
            ReadOnlyMemory <int> memory = default;
            MemoryHandle         handle = memory.Retain(pin: pin);

            Assert.False(handle.HasPointer);
            unsafe
            {
                Assert.True(handle.Pointer == null);
            }
            handle.Dispose();
        }
Example #6
0
        public static void MemoryRetainWithoutPinning()
        {
            int[] array = { 1, 2, 3, 4, 5 };
            ReadOnlyMemory <int> memory = array;
            MemoryHandle         handle = memory.Retain();

            Assert.False(handle.HasPointer);
            unsafe
            {
                Assert.True(handle.Pointer == null);
            }
            handle.Dispose();
        }
Example #7
0
        public static void MemoryRetainWithoutPinning()
        {
            int[] array = { 1, 2, 3, 4, 5 };
            ReadOnlyMemory <int> memory = array;
            MemoryHandle         handle = memory.Retain();

            unsafe
            {
                int *pointer = (int *)handle.PinnedPointer;
                Assert.True(pointer == null);
            }
            handle.Dispose();
        }
Example #8
0
        public static void OwnedMemoryRetainWithoutPinning()
        {
            int[]                array  = { 1, 2, 3, 4, 5 };
            OwnedMemory <int>    owner  = new CustomMemoryForTest <int>(array);
            ReadOnlyMemory <int> memory = owner.Memory;
            MemoryHandle         handle = memory.Retain();

            Assert.False(handle.HasPointer);
            unsafe
            {
                Assert.True(handle.Pointer == null);
            }
            handle.Dispose();
        }
Example #9
0
        internal static int Encrypt(SafeSslHandle context, ReadOnlyMemory <byte> input, ref byte[] output, out Ssl.SslErrorCode errorCode)
        {
            errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;

            int retVal;

            unsafe
            {
                using (MemoryHandle handle = input.Retain(pin: true))
                {
                    retVal = Ssl.SslWrite(context, (byte *)handle.Pointer, input.Length);
                }
            }

            if (retVal != input.Length)
            {
                errorCode = GetSslError(context, retVal, out Exception innerError);
                retVal    = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case Ssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                case Ssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    break;

                default:
                    throw new SslException(SR.Format(SR.net_ssl_encrypt_failed, errorCode), innerError);
                }
            }
            else
            {
                int capacityNeeded = Crypto.BioCtrlPending(context.OutputBio);

                if (output == null || output.Length < capacityNeeded)
                {
                    output = new byte[capacityNeeded];
                }

                retVal = BioRead(context.OutputBio, output, capacityNeeded);
                if (retVal <= 0)
                {
                    // Make sure we clear out the error that is stored in the queue
                    Crypto.ErrGetError();
                }
            }

            return(retVal);
        }
        static void BufferLifetime(ReadOnlyMemory <byte> buffer)
        {
            var array = buffer.ToArray();

            using (var pinned = buffer.Retain(pin: true))
            {
                unsafe
                {
                    var p = (byte *)pinned.Pointer;
                    Assert.True(null != p);
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        Assert.Equal(array[i], p[i]);
                    }
                }
            }
        }
Example #11
0
        // Using RunContinuationsAsynchronously for compat reasons (old API used ThreadPool.QueueUserWorkItem for continuations)
        protected PipeCompletionSource(ThreadPoolBoundHandle handle, ReadOnlyMemory <byte> bufferToPin)
            : base(TaskCreationOptions.RunContinuationsAsynchronously)
        {
            Debug.Assert(handle != null, "handle is null");

            _threadPoolBinding = handle;
            _state             = NoResult;

            _pinnedMemory = bufferToPin.Retain(pin: true);
            _overlapped   = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                var completionSource = (PipeCompletionSource <TResult>)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(completionSource.Overlapped == pOverlapped);

                completionSource.AsyncCallback(errorCode, numBytes);
            }, this, null);
        }
Example #12
0
        internal unsafe void SetInput(ReadOnlyMemory <byte> inputBuffer)
        {
            Debug.Assert(NeedsInput(), "We have something left in previous input!");
            Debug.Assert(_inputBufferHandle.PinnedPointer == null);

            if (0 == inputBuffer.Length)
            {
                return;
            }

            lock (SyncLock)
            {
                _inputBufferHandle = inputBuffer.Retain(pin: true);

                _zlibStream.NextIn  = (IntPtr)_inputBufferHandle.PinnedPointer;
                _zlibStream.AvailIn = (uint)inputBuffer.Length;
            }
        }
Example #13
0
        public unsafe RioBufferSegment GetSegmentFromMemory(ReadOnlyMemory <byte> memory)
        {
            // It's ok to unpin the handle here because the memory is from the pool
            // we created, which is already pinned.
            var pin     = memory.Retain(pin: true);
            var spanPtr = (IntPtr)pin.Pointer;

            pin.Dispose();

            long spanAddress = spanPtr.ToInt64();
            var  bufferId    = GetBufferId(spanPtr, out long startAddress);

            checked
            {
                var offset = (uint)(spanAddress - startAddress);
                return(new RioBufferSegment(bufferId, offset, (uint)memory.Length));
            }
        }
Example #14
0
        public static void MemoryRetainWithPinning()
        {
            int[] array = { 1, 2, 3, 4, 5 };
            ReadOnlyMemory <int> memory = array;
            MemoryHandle         handle = memory.Retain(pin: true);

            unsafe
            {
                int *pointer = (int *)handle.PinnedPointer;
                Assert.True(pointer != null);

                GC.Collect();

                for (int i = 0; i < memory.Length; i++)
                {
                    Assert.Equal(array[i], pointer[i]);
                }
            }
            handle.Dispose();
        }
Example #15
0
        public static void OwnedMemoryRetainWithPinning()
        {
            int[]                array  = { 1, 2, 3, 4, 5 };
            OwnedMemory <int>    owner  = new CustomMemoryForTest <int>(array);
            ReadOnlyMemory <int> memory = owner.Memory;
            MemoryHandle         handle = memory.Retain(pin: true);

            Assert.True(handle.HasPointer);
            unsafe
            {
                int *pointer = (int *)handle.Pointer;

                GC.Collect();

                for (int i = 0; i < memory.Length; i++)
                {
                    Assert.Equal(array[i], pointer[i]);
                }
            }
            handle.Dispose();
        }
Example #16
0
        internal unsafe void SetInput(ReadOnlyMemory <byte> inputBuffer)
        {
            if (!NeedsInput())
            {
                throw new InvalidOperationException("We have something left in previous input!");
            }
            if (_inputBufferHandle.HasPointer)
            {
                throw new InvalidOperationException("Unexpected input buffer handler found.");
            }

            if (0 == inputBuffer.Length)
            {
                return;
            }

            lock (SyncLock) {
                _inputBufferHandle = inputBuffer.Retain(pin: true);

                _compression_struct.Source     = (IntPtr)_inputBufferHandle.Pointer;
                _compression_struct.SourceSize = inputBuffer.Length;
            }
        }
Example #17
0
        public static SecurityStatusPal EncryptMessage(
            SafeDeleteContext securityContext,
            ReadOnlyMemory <byte> input,
            int headerSize,
            int trailerSize,
            ref byte[] output,
            out int resultSize)
        {
            resultSize = 0;

            Debug.Assert(input.Length > 0, $"{nameof(input.Length)} > 0 since {nameof(CanEncryptEmptyMessage)} is false");

            try
            {
                SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext;
                SafeSslHandle        sslHandle  = sslContext.SslContext;

                unsafe
                {
                    MemoryHandle memHandle = input.Retain(pin: true);
                    try
                    {
                        PAL_TlsIo status;

                        lock (sslHandle)
                        {
                            status = Interop.AppleCrypto.SslWrite(
                                sslHandle,
                                (byte *)memHandle.Pointer,
                                input.Length,
                                out int written);
                        }

                        if (status < 0)
                        {
                            return(new SecurityStatusPal(
                                       SecurityStatusPalErrorCode.InternalError,
                                       Interop.AppleCrypto.CreateExceptionForOSStatus((int)status)));
                        }

                        if (sslContext.BytesReadyForConnection <= output?.Length)
                        {
                            resultSize = sslContext.ReadPendingWrites(output, 0, output.Length);
                        }
                        else
                        {
                            output     = sslContext.ReadPendingWrites();
                            resultSize = output.Length;
                        }

                        switch (status)
                        {
                        case PAL_TlsIo.Success:
                            return(new SecurityStatusPal(SecurityStatusPalErrorCode.OK));

                        case PAL_TlsIo.WouldBlock:
                            return(new SecurityStatusPal(SecurityStatusPalErrorCode.ContinueNeeded));

                        default:
                            Debug.Fail($"Unknown status value: {status}");
                            return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError));
                        }
                    }
                    finally
                    {
                        memHandle.Dispose();
                    }
                }
            }
            catch (Exception e)
            {
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, e));
            }
        }
            private MemoryHandle _handle; // mutable struct; do not make this readonly

            internal MemoryFileStreamCompletionSource(FileStream stream, int numBufferedBytes, ReadOnlyMemory <byte> memory) :
                base(stream, numBufferedBytes, bytes: null) // this type handles the pinning, so null is passed for bytes
            {
                _handle = memory.Retain(pin: true);
            }
Example #19
0
            private MemoryHandle _handle; // mutable struct; do not make this readonly

            internal MemoryFileStreamCompletionSource(FileStream stream, int numBufferedBytes, ReadOnlyMemory <byte> memory) :
                base(stream, numBufferedBytes, bytes: null) // this type handles the pinning, so null is passed for bytes
            {
                Debug.Assert(!MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> array), "The base should be used directly if we can get the array.");
                _handle = memory.Retain(pin: true);
            }