From b9cd5a0363903891ddc149b5ff57d3028cd061f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Sep 2021 08:29:51 +0200 Subject: [PATCH] [release/6.0] Use caching ConsoleStream for both iOS and Android (#59088) Co-authored-by: Steve Pfister --- .../System.Console/src/System.Console.csproj | 1 + .../src/System/ConsolePal.Android.cs | 14 ++-- .../System.Console/src/System/ConsolePal.iOS.cs | 70 ++------------------ .../src/System/IO/CachedConsoleStream.cs | 77 ++++++++++++++++++++++ 4 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 src/libraries/System.Console/src/System/IO/CachedConsoleStream.cs diff --git a/src/libraries/System.Console/src/System.Console.csproj b/src/libraries/System.Console/src/System.Console.csproj index c464007..6cbdc48 100644 --- a/src/libraries/System.Console/src/System.Console.csproj +++ b/src/libraries/System.Console/src/System.Console.csproj @@ -13,6 +13,7 @@ + buffer) => throw Error.GetReadNotSupported(); - - public override unsafe void Write(ReadOnlySpan buffer) + protected override void Print(ReadOnlySpan line) { - string log = ConsolePal.OutputEncoding.GetString(buffer); + string log = line.ToString(); Interop.Logcat.AndroidLogPrint(Interop.Logcat.LogLevel.Info, "DOTNET", log); } } @@ -26,9 +24,9 @@ namespace System public static Stream OpenStandardInput() => throw new PlatformNotSupportedException(); - public static Stream OpenStandardOutput() => new LogcatStream(); + public static Stream OpenStandardOutput() => new LogcatStream(OutputEncoding); - public static Stream OpenStandardError() => new LogcatStream(); + public static Stream OpenStandardError() => new LogcatStream(OutputEncoding); public static Encoding InputEncoding => throw new PlatformNotSupportedException(); diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index a58d4ba..8794d55 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -8,75 +8,15 @@ using System.Text; namespace System { - internal sealed class NSLogStream : ConsoleStream + internal sealed class NSLogStream : CachedConsoleStream { - private readonly StringBuilder _buffer = new StringBuilder(); - private readonly Encoding _encoding; - private readonly Decoder _decoder; + public NSLogStream(Encoding encoding) : base(encoding) {} - public NSLogStream(Encoding encoding) : base(FileAccess.Write) + protected override unsafe void Print(ReadOnlySpan line) { - _encoding = encoding; - _decoder = _encoding.GetDecoder(); - } - - public override int Read(Span buffer) => throw Error.GetReadNotSupported(); - - public override void Write(ReadOnlySpan buffer) - { - int maxCharCount = _encoding.GetMaxCharCount(buffer.Length); - char[]? pooledBuffer = null; - Span charSpan = maxCharCount <= 512 ? stackalloc char[512] : (pooledBuffer = ArrayPool.Shared.Rent(maxCharCount)); - try - { - int count = _decoder.GetChars(buffer, charSpan, false); - if (count > 0) - { - WriteOrCache(_buffer, charSpan.Slice(0, count)); - } - } - finally - { - if (pooledBuffer != null) - { - ArrayPool.Shared.Return(pooledBuffer); - } - } - } - - private static void WriteOrCache(StringBuilder cache, Span charBuffer) - { - int lastNewLine = charBuffer.LastIndexOf('\n'); - if (lastNewLine != -1) - { - Span lineSpan = charBuffer.Slice(0, lastNewLine); - if (cache.Length > 0) - { - Print(cache.Append(lineSpan).ToString()); - cache.Clear(); - } - else - { - Print(lineSpan); - } - - if (lastNewLine + 1 < charBuffer.Length) - { - cache.Append(charBuffer.Slice(lastNewLine + 1)); - } - - return; - } - - // no newlines found, add the entire buffer to the cache - cache.Append(charBuffer); - - static unsafe void Print(ReadOnlySpan line) + fixed (char* ptr = line) { - fixed (char* ptr = line) - { - Interop.Sys.Log((byte*)ptr, line.Length * 2); - } + Interop.Sys.Log((byte*)ptr, line.Length * 2); } } } diff --git a/src/libraries/System.Console/src/System/IO/CachedConsoleStream.cs b/src/libraries/System.Console/src/System/IO/CachedConsoleStream.cs new file mode 100644 index 0000000..6aacda6 --- /dev/null +++ b/src/libraries/System.Console/src/System/IO/CachedConsoleStream.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace System.IO +{ + internal abstract class CachedConsoleStream : ConsoleStream + { + private readonly StringBuilder _buffer = new StringBuilder(); + private readonly Encoding _encoding; + private readonly Decoder _decoder; + + public CachedConsoleStream(Encoding encoding) : base(FileAccess.Write) + { + _encoding = encoding; + _decoder = _encoding.GetDecoder(); + } + + public override int Read(Span buffer) => throw Error.GetReadNotSupported(); + + public override void Write(ReadOnlySpan buffer) + { + int maxCharCount = _encoding.GetMaxCharCount(buffer.Length); + char[]? pooledBuffer = null; + Span charSpan = maxCharCount <= 512 ? stackalloc char[512] : (pooledBuffer = ArrayPool.Shared.Rent(maxCharCount)); + try + { + int count = _decoder.GetChars(buffer, charSpan, false); + if (count > 0) + { + WriteOrCache(this, _buffer, charSpan.Slice(0, count)); + } + } + finally + { + if (pooledBuffer != null) + { + ArrayPool.Shared.Return(pooledBuffer); + } + } + } + + protected abstract void Print(ReadOnlySpan line); + + private static void WriteOrCache(CachedConsoleStream stream, StringBuilder cache, Span charBuffer) + { + int lastNewLine = charBuffer.LastIndexOf('\n'); + if (lastNewLine != -1) + { + Span lineSpan = charBuffer.Slice(0, lastNewLine); + if (cache.Length > 0) + { + stream.Print(cache.Append(lineSpan).ToString()); + cache.Clear(); + } + else + { + stream.Print(lineSpan); + } + + if (lastNewLine + 1 < charBuffer.Length) + { + cache.Append(charBuffer.Slice(lastNewLine + 1)); + } + + return; + } + + // no newlines found, add the entire buffer to the cache + cache.Append(charBuffer); + } + } +} -- 2.7.4