Skip to content

Commit

Permalink
Merge branch 'master' into muxtestinfra
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-hawker committed Oct 6, 2020
2 parents ef749d6 + b20befb commit c9b98c2
Show file tree
Hide file tree
Showing 24 changed files with 2,142 additions and 449 deletions.
826 changes: 826 additions & 0 deletions Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Buffers;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.CompilerServices;
using Microsoft.Toolkit.HighPerformance.Streams;
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;

namespace Microsoft.Toolkit.HighPerformance.Extensions
{
Expand All @@ -18,17 +19,18 @@ public static class IMemoryOwnerExtensions
/// <summary>
/// Returns a <see cref="Stream"/> wrapping the contents of the given <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.
/// </summary>
/// <param name="memory">The input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.</param>
/// <returns>A <see cref="Stream"/> wrapping the data within <paramref name="memory"/>.</returns>
/// <param name="memoryOwner">The input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.</param>
/// <returns>A <see cref="Stream"/> wrapping the data within <paramref name="memoryOwner"/>.</returns>
/// <remarks>
/// The caller does not need to track the lifetime of the input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/>
/// instance, as the returned <see cref="Stream"/> will take care of disposing that buffer when it is closed.
/// </remarks>
/// <exception cref="ArgumentException">Thrown when <paramref name="memoryOwner"/> has an invalid data store.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Stream AsStream(this IMemoryOwner<byte> memory)
public static Stream AsStream(this IMemoryOwner<byte> memoryOwner)
{
return new IMemoryOwnerStream(memory);
return MemoryStream.Create(memoryOwner);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ public static class MemoryExtensions
/// In particular, the caller must ensure that the target buffer is not disposed as long
/// as the returned <see cref="Stream"/> is in use, to avoid unexpected issues.
/// </remarks>
/// <exception cref="ArgumentException">Thrown when <paramref name="memory"/> has an invalid data store.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Stream AsStream(this Memory<byte> memory)
{
return new MemoryStream(memory);
return MemoryStream.Create(memory, false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.CompilerServices;
using MemoryStream = Microsoft.Toolkit.HighPerformance.Streams.MemoryStream;

namespace Microsoft.Toolkit.HighPerformance.Extensions
Expand All @@ -26,11 +25,11 @@ public static class ReadOnlyMemoryExtensions
/// In particular, the caller must ensure that the target buffer is not disposed as long
/// as the returned <see cref="Stream"/> is in use, to avoid unexpected issues.
/// </remarks>
/// <exception cref="ArgumentException">Thrown when <paramref name="memory"/> has an invalid data store.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Stream AsStream(this ReadOnlyMemory<byte> memory)
{
return new MemoryStream(memory);
return MemoryStream.Create(memory, true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Buffers;
using System.IO;

Expand All @@ -10,29 +11,32 @@ namespace Microsoft.Toolkit.HighPerformance.Streams
/// <summary>
/// A <see cref="Stream"/> implementation wrapping an <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance.
/// </summary>
internal sealed class IMemoryOwnerStream : MemoryStream
/// <typeparam name="TSource">The type of source to use for the underlying data.</typeparam>
internal sealed class IMemoryOwnerStream<TSource> : MemoryStream<TSource>
where TSource : struct, ISpanOwner
{
/// <summary>
/// The <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance currently in use.
/// The <see cref="IDisposable"/> instance currently in use.
/// </summary>
private readonly IMemoryOwner<byte> memory;
private readonly IDisposable disposable;

/// <summary>
/// Initializes a new instance of the <see cref="IMemoryOwnerStream"/> class.
/// Initializes a new instance of the <see cref="IMemoryOwnerStream{TSource}"/> class.
/// </summary>
/// <param name="memory">The input <see cref="IMemoryOwner{T}"/> of <see cref="byte"/> instance to use.</param>
public IMemoryOwnerStream(IMemoryOwner<byte> memory)
: base(memory.Memory)
/// <param name="source">The input <typeparamref name="TSource"/> instance to use.</param>
/// <param name="disposable">The <see cref="IDisposable"/> instance currently in use.</param>
public IMemoryOwnerStream(TSource source, IDisposable disposable)
: base(source, false)
{
this.memory = memory;
this.disposable = disposable;
}

/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

this.memory.Dispose();
this.disposable.Dispose();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

Expand All @@ -8,16 +8,41 @@
namespace Microsoft.Toolkit.HighPerformance.Streams
{
/// <summary>
/// A <see cref="Stream"/> implementation wrapping a <see cref="Memory{T}"/> or <see cref="ReadOnlyMemory{T}"/> instance.
/// A factory class to produce <see cref="MemoryStream{TSource}"/> instances.
/// </summary>
internal partial class MemoryStream
internal static partial class MemoryStream
{
/// <summary>
/// Throws an <see cref="ArgumentException"/> when trying to write too many bytes to the target stream.
/// </summary>
public static void ThrowArgumentExceptionForEndOfStreamOnWrite()
{
throw new ArgumentException("The current stream can't contain the requested input data.");
}

/// <summary>
/// Throws a <see cref="NotSupportedException"/> when trying to set the length of the stream.
/// </summary>
public static void ThrowNotSupportedExceptionForSetLength()
{
throw new NotSupportedException("Setting the length is not supported for this stream.");
}

/// <summary>
/// Throws an <see cref="ArgumentException"/> when using an invalid seek mode.
/// </summary>
/// <returns>Nothing, as this method throws unconditionally.</returns>
public static long ThrowArgumentExceptionForSeekOrigin()
{
throw new ArgumentException("The input seek mode is not valid.", "origin");
}

/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when setting the <see cref="Stream.Position"/> property.
/// </summary>
private static void ThrowArgumentOutOfRangeExceptionForPosition()
{
throw new ArgumentOutOfRangeException(nameof(Position), "The value for the property was not in the valid range.");
throw new ArgumentOutOfRangeException(nameof(Stream.Position), "The value for the property was not in the valid range.");
}

/// <summary>
Expand Down Expand Up @@ -60,37 +85,12 @@ private static void ThrowNotSupportedExceptionForCanWrite()
throw new NotSupportedException("The current stream doesn't support writing.");
}

/// <summary>
/// Throws an <see cref="ArgumentException"/> when trying to write too many bytes to the target stream.
/// </summary>
private static void ThrowArgumentExceptionForEndOfStreamOnWrite()
{
throw new ArgumentException("The current stream can't contain the requested input data.");
}

/// <summary>
/// Throws a <see cref="NotSupportedException"/> when trying to set the length of the stream.
/// </summary>
private static void ThrowNotSupportedExceptionForSetLength()
{
throw new NotSupportedException("Setting the length is not supported for this stream.");
}

/// <summary>
/// Throws an <see cref="ArgumentException"/> when using an invalid seek mode.
/// </summary>
/// <returns>Nothing, as this method throws unconditionally.</returns>
private static long ThrowArgumentExceptionForSeekOrigin()
{
throw new ArgumentException("The input seek mode is not valid.", "origin");
}

/// <summary>
/// Throws an <see cref="ObjectDisposedException"/> when using a disposed <see cref="Stream"/> instance.
/// </summary>
private static void ThrowObjectDisposedException()
{
throw new ObjectDisposedException(nameof(memory), "The current stream has already been disposed");
throw new ObjectDisposedException("source", "The current stream has already been disposed");
}
}
}
22 changes: 11 additions & 11 deletions Microsoft.Toolkit.HighPerformance/Streams/MemoryStream.Validate.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

Expand All @@ -8,17 +8,17 @@
namespace Microsoft.Toolkit.HighPerformance.Streams
{
/// <summary>
/// A <see cref="Stream"/> implementation wrapping a <see cref="System.Memory{T}"/> or <see cref="System.ReadOnlyMemory{T}"/> instance.
/// A factory class to produce <see cref="MemoryStream{TSource}"/> instances.
/// </summary>
internal partial class MemoryStream
internal static partial class MemoryStream
{
/// <summary>
/// Validates the <see cref="Stream.Position"/> argument.
/// </summary>
/// <param name="position">The new <see cref="Stream.Position"/> value being set.</param>
/// <param name="length">The maximum length of the target <see cref="Stream"/>.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ValidatePosition(long position, int length)
public static void ValidatePosition(long position, int length)
{
if ((ulong)position >= (ulong)length)
{
Expand All @@ -33,7 +33,7 @@ private static void ValidatePosition(long position, int length)
/// <param name="offset">The offset within <paramref name="buffer"/>.</param>
/// <param name="count">The number of elements to process within <paramref name="buffer"/>.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ValidateBuffer(byte[]? buffer, int offset, int count)
public static void ValidateBuffer(byte[]? buffer, int offset, int count)
{
if (buffer is null)
{
Expand All @@ -57,24 +57,24 @@ private static void ValidateBuffer(byte[]? buffer, int offset, int count)
}

/// <summary>
/// Validates the <see cref="CanWrite"/> property.
/// Validates the <see cref="MemoryStream{TSource}.CanWrite"/> property.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ValidateCanWrite()
public static void ValidateCanWrite(bool canWrite)
{
if (!CanWrite)
if (!canWrite)
{
ThrowNotSupportedExceptionForCanWrite();
}
}

/// <summary>
/// Validates that the current instance hasn't been disposed.
/// Validates that a given <see cref="Stream"/> instance hasn't been disposed.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ValidateDisposed()
public static void ValidateDisposed(bool disposed)
{
if (this.disposed)
if (disposed)
{
ThrowObjectDisposedException();
}
Expand Down
Loading

0 comments on commit c9b98c2

Please sign in to comment.