| @@ -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); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||