Example #1
0
        private static unsafe void AsMemory_Roundtrips_Core <T>(ReadOnlyMemory <T> readOnlyMemory, bool canBePinned)
        {
            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)
                        == MemoryMarshal.TryGetArray(memory, out ArraySegment <T> array2));
            Assert.Same(array1.Array, array2.Array);
            Assert.Equal(array1.Offset, array2.Offset);
            Assert.Equal(array1.Count, array2.Count);

            if (canBePinned)
            {
                // Pin
                using (MemoryHandle readOnlyMemoryHandle = readOnlyMemory.Pin())
                    using (MemoryHandle readOnlyCloneHandle = readOnlyMemory.Pin())
                        using (MemoryHandle memoryHandle = readOnlyMemory.Pin())
                        {
                            Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)readOnlyCloneHandle.Pointer);
                            Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)memoryHandle.Pointer);
                        }
            }
        }
Example #2
0
 private static unsafe string DecodeString(ReadOnlyMemory <byte> buffer)
 {
     using (var pinnedBuffer = buffer.Pin())
     {
         return(ControlFrameEncoding.GetString((byte *)pinnedBuffer.Pointer, buffer.Length));
     }
 }
Example #3
0
        public unsafe IEnumerable <IPix> Create(ReadOnlyMemory <byte> data)
        {
            using var pointer = data.Pin();
            if (Leptonica5Pix.findFileFormatBuffer(pointer.Pointer, out var format) != 0)
            {
                throw new InvalidOperationException("File format not supported.");
            }

            var sizeInMemory = data.Length;

            switch (format)
            {
            case ImageFileFormat.Tiff:
            case ImageFileFormat.TiffPackbits:
            case ImageFileFormat.TiffRle:
            case ImageFileFormat.TiffG3:
            case ImageFileFormat.TiffG4:
            case ImageFileFormat.TiffLzw:
            case ImageFileFormat.TiffZip:
                return(ReadTiff(pointer.Pointer, sizeInMemory));

            default:
                return(new [] { ReadImage(pointer.Pointer, sizeInMemory) });
            }
        }
Example #4
0
        /// <summary>
        /// Easy Find
        /// <para>Finds the extent of the match of <paramref name="pattern" /> in
        /// the given <paramref name="haystack" />. To check if a given pattern
        /// matches without needing to find the rage use <see cref="IsMatch(ReadOnlySpan&lt;byte&gt;)" />.
        /// </para>
        /// </summary>
        /// <param name="pattern">The regular expression to search for</param>
        /// <param name="haystack">The text to find the pattern in</param>
        /// <returns>A match object summarising the match result</returns>
        public unsafe static Match Find(
            ReadOnlySpan <byte> pattern, ReadOnlyMemory <byte> haystack)
        {
            var captures = new[] {
                new Re2Ffi.cre2_string_t()
            };

            using (var pin = haystack.Pin())
            {
                var matchResult = Re2Ffi.cre2_easy_match(
                    in MemoryMarshal.GetReference(pattern), pattern.Length,
                    haystack.Span[0], haystack.Length,
                    captures, 1
                    );
                if (matchResult != 1)
                {
                    return(Match.Empty);
                }

                // Convert the captured strings to array indices while we still
                // have the haystack pinned. We can't have the haystack move
                // between the `_match` and the conversion to byte ranges
                // otherwise the pointer arithmetic we do will be invalidated.
                var ranges = StringsToRanges(captures, new IntPtr(pin.Pointer));
                return(new Match(haystack, ranges[0]));
            }
        }
Example #5
0
        /// <summary>
        /// Decompresses data with <paramref name="size"/> at <paramref name="offset"/> in <paramref name="memory"/>
        /// </summary>
        /// <param name="memory">The compressed data buffer</param>
        /// <param name="offset">The offset of the compressed data</param>
        /// <param name="size">The size of the compressed data</param>
        /// <param name="uncompressedSize">Uncompressed size of <paramref name="buffer"/></param>
        /// <returns>The uncompressed buffer</returns>
        /// <remarks>If you do not know the uncompressed size then it is recommended to use <see cref="ZstdStream"/></remarks>
        public static Memory <byte> Decompress(ReadOnlyMemory <byte> memory, int offset, int size, int uncompressedSize)
        {
            ValidateDecompressionArguments(memory.Length, offset, size, uncompressedSize);

            // Allocate uncompressed buffer
            byte[] uncompressedBuffer = new byte[uncompressedSize];

            // Get handles to buffers
            using MemoryHandle compressedBufferHandle   = memory.Pin();
            using MemoryHandle uncompressedBufferHandle = uncompressedBuffer.AsMemory().Pin();

            unsafe
            {
                // Get pointers from handles
                IntPtr compressedBufferPointer   = (IntPtr)compressedBufferHandle.Pointer;
                IntPtr uncompressedBufferPointer = (IntPtr)uncompressedBufferHandle.Pointer;

                Size uncompressedBufferSize = Native.ZSTD_decompress(
                    uncompressedBufferPointer, (Size)uncompressedSize,
                    compressedBufferPointer + offset, (Size)size);

                // Check for errors
                ThrowOnError(uncompressedBufferSize);

                return(uncompressedBuffer.AsMemory(0, (int)uncompressedBufferSize));
            }
        }
Example #6
0
 internal NativeOverlapped *PrepareForOperation(ReadOnlyMemory <byte> memory)
 {
     _result       = 0;
     _memoryHandle = memory.Pin();
     _overlapped   = _strategy._fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(_preallocatedOverlapped);
     return(_overlapped);
 }
Example #7
0
        public async Task WriteAsync(CommandQueue commandQueue, ReadOnlyMemory <T> data)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            if (commandQueue == null)
            {
                throw new ArgumentNullException(nameof(commandQueue));
            }

            var handle = data.Pin();

            OpenClErrorCode error;
            IntPtr          evt;

            unsafe
            {
                error = Api.BufferApi.clEnqueueWriteBuffer(commandQueue.Id, Id, false, 0, (uint)Size,
                                                           new IntPtr(handle.Pointer), 0, null, out evt);
            }

            try
            {
                error.ThrowOnError();

                var eventObj = new Event(Api, evt);
                await eventObj.WaitCompleteAsync().ConfigureAwait(false);
            }
            finally
            {
                handle.Dispose();
            }
        }
Example #8
0
        internal static unsafe long WriteGatherAtOffset(SafeFileHandle handle, IReadOnlyList <ReadOnlyMemory <byte> > buffers, long fileOffset)
        {
            MemoryHandle[] handles = new MemoryHandle[buffers.Count];
            Span <Interop.Sys.IOVector> vectors = buffers.Count <= IovStackThreshold ? stackalloc Interop.Sys.IOVector[IovStackThreshold] : new Interop.Sys.IOVector[buffers.Count];

            long result;

            try
            {
                int buffersCount = buffers.Count;
                for (int i = 0; i < buffersCount; i++)
                {
                    ReadOnlyMemory <byte> buffer       = buffers[i];
                    MemoryHandle          memoryHandle = buffer.Pin();
                    vectors[i] = new Interop.Sys.IOVector {
                        Base = (byte *)memoryHandle.Pointer, Count = (UIntPtr)buffer.Length
                    };
                    handles[i] = memoryHandle;
                }

                fixed(Interop.Sys.IOVector *pinnedVectors = &MemoryMarshal.GetReference(vectors))
                {
                    result = Interop.Sys.PWriteV(handle, pinnedVectors, buffers.Count, fileOffset);
                }
            }
            finally
            {
                foreach (MemoryHandle memoryHandle in handles)
                {
                    memoryHandle.Dispose();
                }
            }

            return(FileStreamHelpers.CheckFileCall(result, handle.Path));
        }
Example #9
0
        public static void MemoryPinAndSlice()
        {
            int[] array = { 1, 2, 3, 4, 5 };
            ReadOnlyMemory <int> memory = array;

            memory = memory.Slice(1);
            MemoryHandle       handle = memory.Pin();
            ReadOnlySpan <int> span   = memory.Span;

            unsafe
            {
                int *pointer = (int *)handle.Pointer;
                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 #10
0
        public static ReadOnlyMemory <byte> Encode(ReadOnlyMemory <byte> source, ReadOnlyMemory <byte> target)
        {
            var estimatedOutputLength = Math.Max(16, (source.Length + target.Length) * 2);
            int ret = 0;

            for (var i = 0; i < 3; i++)
            {
                uint outputSize = 0;
                var  output     = new byte[estimatedOutputLength];
                ret = NativeMethods.EncodeMemory(
                    input: (byte *)target.Pin().Pointer,
                    input_size: (uint)target.Length,
                    source: (byte *)source.Pin().Pointer,
                    source_size: (uint)source.Length,
                    output_buffer: (byte *)output.AsMemory().Pin().Pointer,
                    output_size: ref outputSize,
                    avail_output: (uint)output.Length,
                    flags: 0);

                if (ret == 28)
                {
                    estimatedOutputLength *= 2;
                    continue;
                }
                else if (ret != 0)
                {
                    throw new InvalidOperationException($"Return value: {ret}");
                }

                return(output.Take((int)outputSize).ToArray());
            }

            throw new InvalidOperationException($"Return value: {ret}");
        }
Example #11
0
        /// <summary>
        /// Compresses data in <paramref name="memory"/> starting at <paramref name="offset"/> with <paramref name="size"/>
        /// using the specified <paramref name="compressionLevel"/>
        /// </summary>
        /// <param name="memory">The buffer to compress</param>
        /// <param name="offset">The offset at which the data to compress starts</param>
        /// <param name="size">The size of the data to compress</param>
        /// <param name="compressionLevel">The compression level to use</param>
        /// <returns>The compressed buffer wrapped in <see cref="Memory{Byte}"/></returns>
        public static Memory <byte> Compress(ReadOnlyMemory <byte> memory, int offset, int size, int compressionLevel = Native.ZSTD_CLEVEL_DEFAULT)
        {
            ValidateCompressionArguments(memory.Length, offset, size, compressionLevel);

            // Allocate compressed buffer
            Size compressionBound = Native.ZSTD_compressBound(new Size((uint)size));

            byte[] compressedBuffer = new byte[compressionBound.ToUInt32()];

            // Get handles to buffers
            using MemoryHandle compressedBufferHandle   = compressedBuffer.AsMemory().Pin();
            using MemoryHandle uncompressedBufferHandle = memory.Pin();

            unsafe
            {
                // Get raw pointers from handles
                IntPtr compressedBufferPointer   = new IntPtr(compressedBufferHandle.Pointer);
                IntPtr uncompressedBufferPointer = new IntPtr(uncompressedBufferHandle.Pointer);

                Size compressedBufferSize = Native.ZSTD_compress(
                    compressedBufferPointer, compressionBound,
                    uncompressedBufferPointer + offset, (Size)size,
                    compressionLevel);

                // Check for errors
                ThrowOnError(compressedBufferSize);

                return(compressedBuffer.AsMemory(0, (int)compressedBufferSize.ToUInt32()));
            }
        }
Example #12
0
        internal static unsafe void SSLStreamSetApplicationProtocols(SafeSslHandle sslHandle, List <SslApplicationProtocol> protocols)
        {
            int count = protocols.Count;

            MemoryHandle[]            memHandles   = new MemoryHandle[count];
            ApplicationProtocolData[] protocolData = new ApplicationProtocolData[count];
            try
            {
                for (int i = 0; i < count; i++)
                {
                    ReadOnlyMemory <byte> protocol = protocols[i].Protocol;
                    memHandles[i]   = protocol.Pin();
                    protocolData[i] = new ApplicationProtocolData
                    {
                        Data   = (byte *)memHandles[i].Pointer,
                        Length = protocol.Length
                    };
                }
                int ret = SSLStreamSetApplicationProtocols(sslHandle, protocolData, count);
                if (ret != SUCCESS)
                {
                    throw new SslException();
                }
            }
            finally
            {
                foreach (MemoryHandle memHandle in memHandles)
                {
                    memHandle.Dispose();
                }
            }
        }
Example #13
0
        public static RWOps FromMemory(ReadOnlyMemory <byte> buffer)
        {
            var handle = buffer.Pin();
            var ret    = ErrorIfInvalid(SDL_RWFromConstMem((IntPtr)handle.Pointer, buffer.Length));

            ret.memoryHandle = handle;
            return(ret);
        }
Example #14
0
 public static R Pin <T, R>(this ReadOnlyMemory <T> memory, Func <IntPtr, R> func)
 {
     using var handle = memory.Pin();
     unsafe
     {
         return(func(new IntPtr(handle.Pointer)));
     }
 }
Example #15
0
 public static void Pin <T>(this ReadOnlyMemory <T> memory, Action <IntPtr> action)
 {
     using var handle = memory.Pin();
     unsafe
     {
         action(new IntPtr(handle.Pointer));
     }
 }
Example #16
0
    private void SetBuffer(int index, ReadOnlyMemory <byte> buffer)
    {
        MemoryHandle handle = buffer.Pin();

        _handles[index]        = handle;
        _buffers[index].Buffer = (byte *)handle.Pointer;
        _buffers[index].Length = (uint)buffer.Length;
    }
Example #17
0
 internal NativeOverlapped *PrepareForOperation(ReadOnlyMemory <byte> memory, long fileOffset)
 {
     _result                 = 0;
     _memoryHandle           = memory.Pin();
     _overlapped             = _fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(_preallocatedOverlapped);
     _overlapped->OffsetLow  = (int)fileOffset;
     _overlapped->OffsetHigh = (int)(fileOffset >> 32);
     return(_overlapped);
 }
Example #18
0
 internal static unsafe PAL_SSLStreamStatus SSLStreamWrite(
     SafeSslHandle sslHandle,
     ReadOnlyMemory <byte> buffer)
 {
     using (MemoryHandle memHandle = buffer.Pin())
     {
         return(SSLStreamWrite(sslHandle, (byte *)memHandle.Pointer, buffer.Length));
     }
 }
            internal NativeOverlapped *Configure(ReadOnlyMemory <byte> memory)
            {
                _result = TaskSourceCodes.NoResult;

                _handle     = memory.Pin();
                _overlapped = _strategy._fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(_preallocatedOverlapped);

                return(_overlapped);
            }
 public static unsafe int GetCharCount(this Encoding encoding, ReadOnlyMemory <byte> bytes)
 {
     if (bytes.IsEmpty)
     {
         return(0);
     }
     using (var handle = bytes.Pin())
         return(encoding.GetCharCount((byte *)handle.Pointer, bytes.Length));
 }
Example #21
0
        public ImageFileFormat GetFileFormat(ReadOnlyMemory <byte> memory)
        {
            using var pointer = memory.Pin();
            if (Leptonica5Pix.findFileFormatBuffer(pointer.Pointer, out var format) != 0)
            {
                return(ImageFileFormat.Unknown);
            }

            return(format);
        }
Example #22
0
        public static unsafe void SaveBitmap(string fileName, int width, int height, ReadOnlyMemory <byte> imageData)
        {
            var handle = imageData.Pin();

            using (var image = new Bitmap(width, height, width,
                                          PixelFormat.Format8bppIndexed, (IntPtr)handle.Pointer))
            {
                image.Save(Path.ChangeExtension(fileName, ".jpg"));
            }
            handle.Dispose();
        }
Example #23
0
        public static void DefaultMemoryPin()
        {
            ReadOnlyMemory <int> memory = default;
            MemoryHandle         handle = memory.Pin();

            unsafe
            {
                Assert.True(handle.Pointer == null);
            }
            handle.Dispose();
        }
        async Task _WriteValueAsync(ReadOnlyMemory <byte> data, GattWriteOption option)
        {
            if (option == GattWriteOption.WriteWithoutResponse)
            {
                var(fd, mtu) = await proxy.AcquireWriteAsync(new Dictionary <string, object>());

                // do low level file I/O in background task
                await Task.Run(() => {
                    try {
                        using (var dataHandle = data.Pin()) {
                            unsafe {
                                var written = 0;
                                while (written < data.Length)
                                {
                                    var ret = write((int)fd.DangerousGetHandle(), dataHandle.Pointer, (UIntPtr)data.Length);
                                    if ((int)ret == -1)
                                    {
                                        var err = Marshal.GetLastWin32Error();
                                        if (err == EINTR || err == EAGAIN)
                                        {
                                            continue;
                                        }
                                        // TODO: marshal other errors to more specific exceptions
                                        throw new Exception($"IO error: {Marshal.PtrToStringAnsi(strerror(err))}");
                                    }
                                    written += (int)ret;
                                }
                            }
                        }
                    }
                    finally {
                        fd.Close();
                    }
                });
            }
            else
            {
                if (data.Length <= 20)
                {
                    await proxy.WriteValueAsync(data.ToArray(), new Dictionary <string, object>());
                }
                else
                {
                    var options = new Dictionary <string, object> {
                        { "offset", (ushort)0 }
                    };
                    for (ushort i = 0; i < data.Length; i += 20)
                    {
                        options["offset"] = i;
                        await proxy.WriteValueAsync(data.Slice(i, Math.Min(data.Length - i, 20)).ToArray(), options);
                    }
                }
            }
        }
 internal NativeOverlapped *PrepareForOperation(ReadOnlyMemory <byte> memory, long fileOffset, AsyncWindowsFileStreamStrategy?strategy = null)
 {
     _result                 = 0;
     _strategy               = strategy;
     _bufferSize             = memory.Length;
     _memoryHandle           = memory.Pin();
     _overlapped             = _fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(_preallocatedOverlapped);
     _overlapped->OffsetLow  = (int)fileOffset;
     _overlapped->OffsetHigh = (int)(fileOffset >> 32);
     return(_overlapped);
 }
Example #26
0
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
        public unsafe InputLayout(ReadOnlyMemory <ShaderInput> inputs)
        {
            Unsafe.SkipInit(out this);

            var pInputs = inputs.Pin();

            Type.Inner = new D3D12_INPUT_LAYOUT_DESC
            {
                NumElements        = (uint)inputs.Length,
                pInputElementDescs = (D3D12_INPUT_ELEMENT_DESC *)pInputs.Pointer
            };
        }
Example #27
0
 /// <summary>Decodes Webp data buffer to <seealso cref="BitmapSource"/>.</summary>
 /// <param name="data">The data buffer which contains WebP image.</param>
 /// <param name="options">The decoder options for webp decoder.</param>
 /// <returns><seealso cref="BitmapSource"/> which contains the image data.</returns>
 /// <exception cref="WebpDecodeException">Thrown when the decoder has wrong options or the buffer contains invalid data for Webp Image.</exception>
 public BitmapSource Decode(ReadOnlyMemory <byte> data, WindowsDecoderOptions options)
 {
     using (var pinned = data.Pin())
     {
         IntPtr pointer;
         unsafe
         {
             pointer = new IntPtr(pinned.Pointer);
         }
         return(this.Decode(pointer, data.Length, options));
     }
 }
Example #28
0
        internal static int Encrypt(SafeSslHandle context, ReadOnlyMemory <byte> input, ref byte[] output, out Ssl.SslErrorCode errorCode)
        {
#if DEBUG
            ulong assertNoError = Crypto.ErrPeekError();
            Debug.Assert(assertNoError == 0, "OpenSsl error queue is not empty, run: 'openssl errstr " + assertNoError.ToString("X") + "' for original error.");
#endif
            errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;

            int retVal;
            unsafe
            {
                using (MemoryHandle handle = input.Pin())
                {
                    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.ErrClearError();
                }
            }

            return(retVal);
        }
            internal NativeOverlapped *PrepareForOperation(ReadOnlyMemory <byte> memory, long fileOffset, OSFileStreamStrategy?strategy = null)
            {
                Debug.Assert(strategy is null || strategy is AsyncWindowsFileStreamStrategy, $"Strategy was expected to be null or async, got {strategy}.");

                _result                 = 0;
                _strategy               = strategy;
                _bufferSize             = memory.Length;
                _memoryHandle           = memory.Pin();
                _overlapped             = _fileHandle.ThreadPoolBinding !.AllocateNativeOverlapped(_preallocatedOverlapped);
                _overlapped->OffsetLow  = (int)fileOffset;
                _overlapped->OffsetHigh = (int)(fileOffset >> 32);
                return(_overlapped);
            }
        public static unsafe int GetChars(this Encoding encoding,
                                          ReadOnlyMemory <byte> bytes, Memory <char> chars)
        {
            if (bytes.IsEmpty)
            {
                return(0);
            }

            using (var dataHandle = bytes.Pin())
                using (var strHandle = chars.Pin())
                    return(encoding.GetChars((byte *)dataHandle.Pointer, bytes.Length, (char *)strHandle.Pointer,
                                             chars.Length));
        }