| @@ -0,0 +1,94 @@ | |||
| using System; | |||
| using System.IO; | |||
| using System.Runtime.CompilerServices; | |||
| using System.Runtime.InteropServices; | |||
| using NumSharp.Backends.Unmanaged; | |||
| namespace Tensorflow.Util | |||
| { | |||
| public static class UnmanagedExtensions | |||
| { | |||
| //internally UnmanagedMemoryStream can't construct with null address. | |||
| private static readonly unsafe byte* _empty = (byte*) Marshal.AllocHGlobal(1); | |||
| /// <summary> | |||
| /// Creates a memory stream based on given <paramref name="block"/>. | |||
| /// </summary> | |||
| /// <param name="block">The block to stream. Can be default/null.</param> | |||
| /// <remarks>There is no need to dispose the returned <see cref="UnmanagedMemoryStream"/></remarks> | |||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
| public static UnmanagedMemoryStream Stream(this UnmanagedMemoryBlock<byte> block) | |||
| { | |||
| unsafe | |||
| { | |||
| if (block.Address == null) | |||
| return new UnmanagedMemoryStream(_empty, 0); | |||
| return new UnmanagedMemoryStream(block.Address, block.BytesCount); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Creates a memory stream based on given <paramref name="block"/>. | |||
| /// </summary> | |||
| /// <param name="block">The block to stream. Can be default/null.</param> | |||
| /// <param name="offset">Offset from the start of the block.</param> | |||
| /// <remarks>There is no need to dispose the returned <see cref="UnmanagedMemoryStream"/></remarks> | |||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
| public static UnmanagedMemoryStream Stream(this UnmanagedMemoryBlock<byte> block, long offset) | |||
| { | |||
| if (block.BytesCount - offset <= 0) | |||
| throw new ArgumentOutOfRangeException(nameof(offset)); | |||
| unsafe | |||
| { | |||
| if (block.Address == null) | |||
| return new UnmanagedMemoryStream(_empty, 0); | |||
| return new UnmanagedMemoryStream(block.Address + offset, block.BytesCount - offset); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Creates a memory stream based on given <paramref name="address"/>. | |||
| /// </summary> | |||
| /// <param name="address">The block to stream. Can be IntPtr.Zero.</param> | |||
| /// <param name="length">The length of the block in bytes.</param> | |||
| /// <remarks>There is no need to dispose the returned <see cref="UnmanagedMemoryStream"/></remarks> | |||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
| public static UnmanagedMemoryStream Stream(this IntPtr address, long length) | |||
| { | |||
| if (length <= 0) | |||
| throw new ArgumentOutOfRangeException(nameof(length)); | |||
| unsafe | |||
| { | |||
| if (address == IntPtr.Zero) | |||
| return new UnmanagedMemoryStream(_empty, 0); | |||
| // ReSharper disable once AssignNullToNotNullAttribute | |||
| return new UnmanagedMemoryStream((byte*) address, length); | |||
| } | |||
| } | |||
| /// <summary> | |||
| /// Creates a memory stream based on given <paramref name="address"/>. | |||
| /// </summary> | |||
| /// <param name="address">The block to stream. Can be IntPtr.Zero.</param> | |||
| /// <param name="offset">Offset from the start of the block.</param> | |||
| /// <param name="length">The length of the block in bytes.</param> | |||
| /// <remarks>There is no need to dispose the returned <see cref="UnmanagedMemoryStream"/></remarks> | |||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
| public static UnmanagedMemoryStream Stream(this IntPtr address, long offset, long length) | |||
| { | |||
| if (length <= 0) | |||
| throw new ArgumentOutOfRangeException(nameof(length)); | |||
| unsafe | |||
| { | |||
| if (address == IntPtr.Zero) | |||
| return new UnmanagedMemoryStream(_empty, 0); | |||
| return new UnmanagedMemoryStream((byte*) address + offset, length); | |||
| } | |||
| } | |||
| } | |||
| } | |||