Skip to content

Commit

Permalink
Enable CA1835-CA1841, CA1845, CA1846
Browse files Browse the repository at this point in the history
  • Loading branch information
pranavkm committed Jun 4, 2021
1 parent f02b25a commit 867c85c
Show file tree
Hide file tree
Showing 35 changed files with 162 additions and 68 deletions.
35 changes: 35 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,33 @@ dotnet_diagnostic.CA1833.severity = warning
# CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1834.severity = warning

# CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
dotnet_diagnostic.CA1835.severity = warning

# CA1836: Prefer IsEmpty over Count
dotnet_diagnostic.CA1836.severity = warning

# CA1837: Use 'Environment.ProcessId'
dotnet_diagnostic.CA1837.severity = warning

# CA1838: Avoid 'StringBuilder' parameters for P/Invokes
dotnet_diagnostic.CA1838.severity = warning

# CA1839: Use 'Environment.ProcessPath'
dotnet_diagnostic.CA1839.severity = warning

# CA1840: Use 'Environment.CurrentManagedThreadId'
dotnet_diagnostic.CA1840.severity = warning

# CA1841: Prefer Dictionary.Contains methods
dotnet_diagnostic.CA1841.severity = warning

# CA1845: Use span-based 'string.Concat'
dotnet_diagnostic.CA1845.severity = warning

# CA1846: Prefer AsSpan over Substring
dotnet_diagnostic.CA1846.severity = warning

# CA2012: Use ValueTask correctly
dotnet_diagnostic.CA2012.severity = warning

Expand All @@ -151,5 +178,13 @@ dotnet_diagnostic.CA1827.severity = suggestion
dotnet_diagnostic.CA1829.severity = suggestion
# CA1834: Consider using 'StringBuilder.Append(char)' when applicable
dotnet_diagnostic.CA1834.severity = suggestion
# CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'
dotnet_diagnostic.CA1835.severity = suggestion
# CA1837: Use 'Environment.ProcessId'
dotnet_diagnostic.CA1837.severity = suggestion
# CA1838: Avoid 'StringBuilder' parameters for P/Invokes
dotnet_diagnostic.CA1838.severity = suggestion
# CA1841: Prefer Dictionary.Contains methods
dotnet_diagnostic.CA1841.severity = suggestion
# CA2012: Use ValueTask correctly
dotnet_diagnostic.CA2012.severity = suggestion
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private static async Task<string> LaunchAndGetUrl(IServiceProvider serviceProvid
var environment = serviceProvider.GetRequiredService<IWebHostEnvironment>();
var executablePath = LocateDebugProxyExecutable(environment);
var muxerPath = DotNetMuxer.MuxerPathOrDefault();
var ownerPid = Process.GetCurrentProcess().Id;
var ownerPid = Environment.ProcessId;

var processStartInfo = new ProcessStartInfo
{
Expand Down
9 changes: 6 additions & 3 deletions src/Http/Http/src/Internal/ReferenceReadStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,15 @@ public override int Read(byte[] buffer, int offset, int count)
return read;
}

public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();

public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken)
{
ThrowIfDisposed();
VerifyPosition();
var toRead = Math.Min(count, _length - _position);
var read = await _inner.ReadAsync(buffer, offset, (int)toRead, cancellationToken);
var toRead = (int)Math.Min(buffer.Length, _length - _position);
var read = await _inner.ReadAsync(buffer.Slice(0, toRead), cancellationToken);
_position += read;
return read;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Shared/StreamCopyOperationInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static async Task CopyToAsync(Stream source, Stream destination, long? co
{
readLength = (int)Math.Min(bytesRemaining.GetValueOrDefault(), (long)readLength);
}
int read = await source.ReadAsync(buffer, 0, readLength, cancel);
int read = await source.ReadAsync(buffer.AsMemory(0, readLength), cancel);

if (bytesRemaining.HasValue)
{
Expand All @@ -75,7 +75,7 @@ public static async Task CopyToAsync(Stream source, Stream destination, long? co

cancel.ThrowIfCancellationRequested();

await destination.WriteAsync(buffer, 0, read, cancel);
await destination.WriteAsync(buffer.AsMemory(0, read), cancel);
}
}
finally
Expand Down
17 changes: 11 additions & 6 deletions src/Http/WebUtilities/src/BufferedReadStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,21 +218,26 @@ public override int Read(byte[] buffer, int offset, int count)
}

/// <inheritdoc/>
public async override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
ValidateBuffer(buffer, offset, count);
return ReadAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();
}

/// <inheritdoc/>
public async override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken)
{
// Drain buffer
if (_bufferCount > 0)
{
int toCopy = Math.Min(_bufferCount, count);
Buffer.BlockCopy(_buffer, _bufferOffset, buffer, offset, toCopy);
int toCopy = Math.Min(_bufferCount, buffer.Length);
_buffer.AsMemory(_bufferOffset, toCopy).CopyTo(buffer);
_bufferOffset += toCopy;
_bufferCount -= toCopy;
return toCopy;
}

return await _inner.ReadAsync(buffer, offset, count, cancellationToken);
return await _inner.ReadAsync(buffer, cancellationToken);
}

/// <summary>
Expand Down Expand Up @@ -264,7 +269,7 @@ public async Task<bool> EnsureBufferedAsync(CancellationToken cancellationToken)
}
// Downshift to make room
_bufferOffset = 0;
_bufferCount = await _inner.ReadAsync(_buffer, 0, _buffer.Length, cancellationToken);
_bufferCount = await _inner.ReadAsync(_buffer.AsMemory(), cancellationToken);
return _bufferCount > 0;
}

Expand Down Expand Up @@ -323,7 +328,7 @@ public async Task<bool> EnsureBufferedAsync(int minCount, CancellationToken canc
}
_bufferOffset = 0;
}
int read = await _inner.ReadAsync(_buffer, _bufferOffset + _bufferCount, _buffer.Length - _bufferCount - _bufferOffset, cancellationToken);
int read = await _inner.ReadAsync(_buffer.AsMemory(_bufferOffset + _bufferCount, _buffer.Length - _bufferCount - _bufferOffset), cancellationToken);
_bufferCount += read;
if (read == 0)
{
Expand Down
16 changes: 11 additions & 5 deletions src/Http/WebUtilities/src/FileBufferingWriteStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,20 +142,27 @@ public override void Write(byte[] buffer, int offset, int count)
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
ThrowArgumentException(buffer, offset, count);
await WriteAsync(buffer.AsMemory(offset, count), cancellationToken);
}

/// <inheritdoc />
[SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads", Justification = "This is a method overload.")]
public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
ThrowIfDisposed();

if (_bufferLimit.HasValue && _bufferLimit - Length < count)
if (_bufferLimit.HasValue && _bufferLimit - Length < buffer.Length)
{
Dispose();
throw new IOException("Buffer limit exceeded.");
}

// Allow buffering in memory if we're below the memory threshold once the current buffer is written.
var allowMemoryBuffer = (_memoryThreshold - count) >= PagedByteBuffer.Length;
var allowMemoryBuffer = (_memoryThreshold - buffer.Length) >= PagedByteBuffer.Length;
if (allowMemoryBuffer)
{
// Buffer content in the MemoryStream if it has capacity.
PagedByteBuffer.Add(buffer, offset, count);
PagedByteBuffer.Add(buffer);
Debug.Assert(PagedByteBuffer.Length <= _memoryThreshold);
}
else
Expand All @@ -166,7 +173,7 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc

// Spool memory content to disk.
await PagedByteBuffer.MoveToAsync(FileStream, cancellationToken);
await FileStream.WriteAsync(buffer, offset, count, cancellationToken);
await FileStream.WriteAsync(buffer, cancellationToken);
}
}

Expand All @@ -188,7 +195,6 @@ public override void Flush()
/// <param name="destination">The <see cref="Stream" /> to drain buffered contents to.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken" />.</param>
/// <returns>A <see cref="Task" /> that represents the asynchronous drain operation.</returns>
[SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")]
public async Task DrainBufferAsync(Stream destination, CancellationToken cancellationToken = default)
{
// When not null, FileStream always has "older" spooled content. The PagedByteBuffer always has "newer"
Expand Down
10 changes: 2 additions & 8 deletions src/Http/WebUtilities/src/HttpRequestStreamReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,7 @@ public override async ValueTask<int> ReadAsync(Memory<char> buffer, Cancellation
do
{
Debug.Assert(charsRemaining == 0);
_bytesRead = await _stream.ReadAsync(
_byteBuffer,
0,
_byteBufferSize);
_bytesRead = await _stream.ReadAsync(_byteBuffer.AsMemory(0, _byteBufferSize));
if (_bytesRead == 0) // EOF
{
_isBlocked = true;
Expand Down Expand Up @@ -534,10 +531,7 @@ private async Task<int> ReadIntoBufferAsync()

do
{
_bytesRead = await _stream.ReadAsync(
_byteBuffer,
0,
_byteBufferSize).ConfigureAwait(false);
_bytesRead = await _stream.ReadAsync(_byteBuffer.AsMemory(0, _byteBufferSize)).ConfigureAwait(false);
if (_bytesRead == 0)
{
// We're at EOF
Expand Down
2 changes: 1 addition & 1 deletion src/Http/WebUtilities/src/HttpResponseStreamWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ private async Task FlushInternalAsync(bool flushEncoder)

if (count > 0)
{
await _stream.WriteAsync(_byteBuffer, 0, count);
await _stream.WriteAsync(_byteBuffer.AsMemory(0, count));
}
}

Expand Down
20 changes: 19 additions & 1 deletion src/Http/WebUtilities/src/PagedByteBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ public void Add(byte[] buffer, int offset, int count)
}
}

public void Add(ReadOnlyMemory<byte> memory)
{
ThrowIfDisposed();

while (!memory.IsEmpty)
{
var currentPage = CurrentPage;
var copyLength = Math.Min(memory.Length, currentPage.Length - _currentPageIndex);

memory.Slice(0, copyLength).CopyTo(currentPage.AsMemory(_currentPageIndex, copyLength));

Length += copyLength;
_currentPageIndex += copyLength;

memory = memory.Slice(copyLength);
}
}

public void MoveTo(Stream stream)
{
ThrowIfDisposed();
Expand Down Expand Up @@ -113,7 +131,7 @@ public async Task MoveToAsync(Stream stream, CancellationToken cancellationToken
_currentPageIndex :
page.Length;

await stream.WriteAsync(page, 0, length, cancellationToken);
await stream.WriteAsync(page.AsMemory(0, length), cancellationToken);
}

ClearBuffers();
Expand Down
2 changes: 2 additions & 0 deletions src/Http/WebUtilities/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
*REMOVED*static Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseNullableQuery(string! queryString) -> System.Collections.Generic.Dictionary<string!, Microsoft.Extensions.Primitives.StringValues>?
Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.MemoryThreshold.get -> int
Microsoft.AspNetCore.WebUtilities.FileBufferingWriteStream.MemoryThreshold.get -> int
override Microsoft.AspNetCore.WebUtilities.BufferedReadStream.ReadAsync(System.Memory<byte> buffer, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<int>
override Microsoft.AspNetCore.WebUtilities.FileBufferingWriteStream.WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
static Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseNullableQuery(string? queryString) -> System.Collections.Generic.Dictionary<string!, Microsoft.Extensions.Primitives.StringValues>?
*REMOVED*static Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(string! queryString) -> System.Collections.Generic.Dictionary<string!, Microsoft.Extensions.Primitives.StringValues>!
static Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(string? queryString) -> System.Collections.Generic.Dictionary<string!, Microsoft.Extensions.Primitives.StringValues>!
5 changes: 3 additions & 2 deletions src/Http/WebUtilities/src/StreamHelperExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Buffers;
using System.IO;
using System.Threading;
Expand Down Expand Up @@ -62,7 +63,7 @@ public static async Task DrainAsync(this Stream stream, ArrayPool<byte> bytePool
long total = 0;
try
{
var read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
var read = await stream.ReadAsync(buffer.AsMemory(), cancellationToken);
while (read > 0)
{
// Not all streams support cancellation directly.
Expand All @@ -72,7 +73,7 @@ public static async Task DrainAsync(this Stream stream, ArrayPool<byte> bytePool
throw new InvalidDataException($"The stream exceeded the data limit {limit.GetValueOrDefault()}.");
}
total += read;
read = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
read = await stream.ReadAsync(buffer.AsMemory(), cancellationToken);
}
}
finally
Expand Down
5 changes: 4 additions & 1 deletion src/Http/WebUtilities/test/HttpResponseStreamWriterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -663,13 +663,16 @@ public override void Write(byte[] buffer, int offset, int count)
}

public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> WriteAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask();

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
WriteAsyncCallCount++;
if (ThrowOnWrite)
{
throw new IOException("Test IOException");
}
return base.WriteAsync(buffer, offset, count, cancellationToken);
return base.WriteAsync(buffer, cancellationToken);
}

protected override void Dispose(bool disposing)
Expand Down
2 changes: 1 addition & 1 deletion src/Middleware/HttpLogging/src/RequestBufferingStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public override async ValueTask<int> ReadAsync(Memory<byte> destination, Cancell

public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var res = await _innerStream.ReadAsync(buffer, offset, count, cancellationToken);
var res = await _innerStream.ReadAsync(buffer.AsMemory(offset, count), cancellationToken);

WriteToBuffer(buffer.AsSpan(offset, res));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ public override void Write(byte[] buffer, int offset, int count)
}
}

public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
await WriteAsync(buffer.AsMemory(offset, count));

public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
{
try
{
_startResponseCallback();
await _innerStream.WriteAsync(buffer, offset, count, cancellationToken);
await _innerStream.WriteAsync(buffer, cancellationToken);
}
catch
{
Expand All @@ -145,13 +148,13 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc

if (BufferingEnabled)
{
if (_segmentWriteStream.Length + count > _maxBufferSize)
if (_segmentWriteStream.Length + buffer.Length > _maxBufferSize)
{
DisableBuffering();
}
else
{
await _segmentWriteStream.WriteAsync(buffer, offset, count, cancellationToken);
await _segmentWriteStream.WriteAsync(buffer, cancellationToken);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,23 @@ public override void EndWrite(IAsyncResult asyncResult)
=> TaskToApm.End(asyncResult);

public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
=> await WriteAsync(buffer.AsMemory(offset, count), cancellationToken);

public override async ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken)
{
OnWrite();

if (_compressionStream != null)
{
await _compressionStream.WriteAsync(buffer, offset, count, cancellationToken);
await _compressionStream.WriteAsync(buffer, cancellationToken);
if (_autoFlush)
{
await _compressionStream.FlushAsync(cancellationToken);
}
}
else
{
await _innerStream.WriteAsync(buffer, offset, count, cancellationToken);
await _innerStream.WriteAsync(buffer, cancellationToken);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Middleware/WebSockets/test/UnitTests/BufferStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public override int Read(byte[] buffer, int offset, int count)
offset += actualCount;
count -= actualCount;
}
while (count > 0 && (_topBuffer.Count > 0 || _bufferedData.Count > 0));
while (count > 0 && (_topBuffer.Count > 0 || !_bufferedData.IsEmpty));
// Keep reading while there is more data available and we have more space to put it in.
return totalRead;
}
Expand Down Expand Up @@ -206,7 +206,7 @@ public async override Task<int> ReadAsync(byte[] buffer, int offset, int count,
offset += actualCount;
count -= actualCount;
}
while (count > 0 && (_topBuffer.Count > 0 || _bufferedData.Count > 0));
while (count > 0 && (_topBuffer.Count > 0 || !_bufferedData.IsEmpty));
// Keep reading while there is more data available and we have more space to put it in.
return totalRead;
}
Expand Down
Loading

0 comments on commit 867c85c

Please sign in to comment.