diff --git a/src/libraries/System.Console/src/System/ConsolePal.Android.cs b/src/libraries/System.Console/src/System/ConsolePal.Android.cs index 87958be3c4858..7f5dd1395ac76 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.Android.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.Android.cs @@ -4,20 +4,37 @@ using System.IO; using System.Text; +using System.Diagnostics; using System.Runtime.InteropServices; namespace System { internal sealed unsafe class LogcatStream : ConsoleStream { + private readonly StringBuilder _buffer = new StringBuilder(); + public LogcatStream() : base(FileAccess.Write) {} public override int Read(byte[] buffer, int offset, int count) => throw Error.GetReadNotSupported(); public override unsafe void Write(byte[] buffer, int offset, int count) { - string log = ConsolePal.OutputEncoding.GetString(buffer, offset, count); - Interop.Logcat.AndroidLogPrint(Interop.Logcat.LogLevel.Info, "DOTNET", log); + ValidateWrite(buffer, offset, count); + + ReadOnlySpan bufferSpan = new ReadOnlySpan(buffer, offset, count); + + Debug.Assert(ConsolePal.OutputEncoding == Encoding.Unicode); + Debug.Assert(bufferSpan.Length % 2 == 0); + + ReadOnlySpan charSpan = MemoryMarshal.Cast(bufferSpan); + + lock (_buffer) + { + AccumulateNewLines(_buffer, charSpan, line => + { + Interop.Logcat.AndroidLogPrint(Interop.Logcat.LogLevel.Info, "DOTNET", line); + }); + } } } diff --git a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs index d8ff911ed75d0..f68c7a2f2c2aa 100644 --- a/src/libraries/System.Console/src/System/ConsolePal.iOS.cs +++ b/src/libraries/System.Console/src/System/ConsolePal.iOS.cs @@ -4,11 +4,15 @@ using System.IO; using System.Text; +using System.Diagnostics; +using System.Runtime.InteropServices; namespace System { internal sealed class NSLogStream : ConsoleStream { + private readonly StringBuilder _buffer = new StringBuilder(); + public NSLogStream() : base(FileAccess.Write) {} public override int Read(byte[] buffer, int offset, int count) => throw Error.GetReadNotSupported(); @@ -17,9 +21,22 @@ public override unsafe void Write(byte[] buffer, int offset, int count) { ValidateWrite(buffer, offset, count); - fixed (byte* ptr = buffer) + ReadOnlySpan bufferSpan = new ReadOnlySpan(buffer, offset, count); + + Debug.Assert(ConsolePal.OutputEncoding == Encoding.Unicode); + Debug.Assert(bufferSpan.Length % 2 == 0); + + ReadOnlySpan charSpan = MemoryMarshal.Cast(bufferSpan); + + lock (_buffer) { - Interop.Sys.Log(ptr + offset, count); + AccumulateNewLines(_buffer, charSpan, line => + { + fixed (char* ptr = line) + { + Interop.Sys.Log((byte*)ptr, line.Length * 2); + } + }); } } } @@ -170,4 +187,4 @@ internal sealed class ControlCHandlerRegistrar internal void Unregister() => throw new PlatformNotSupportedException(); } } -} \ No newline at end of file +} diff --git a/src/libraries/System.Console/src/System/IO/ConsoleStream.cs b/src/libraries/System.Console/src/System/IO/ConsoleStream.cs index d2eda09de1c90..f5432f23de665 100644 --- a/src/libraries/System.Console/src/System/IO/ConsoleStream.cs +++ b/src/libraries/System.Console/src/System/IO/ConsoleStream.cs @@ -93,5 +93,37 @@ protected void ValidateWrite(byte[] buffer, int offset, int count) if (!_canWrite) throw Error.GetWriteNotSupported(); } + + protected static void AccumulateNewLines(StringBuilder accumulator, ReadOnlySpan buffer, Action printer) + { + int lineStartIndex = 0; + for (int i = 0; i < buffer.Length; i++) + { + if (buffer[i] == '\n') + { + ReadOnlySpan sliceWithNl = buffer.Slice(lineStartIndex, i - lineStartIndex); + if (accumulator.Length > 0) + { + // we found a new line, append content from accumulator if it's not empty + accumulator.Append(sliceWithNl); + printer(accumulator.ToString()); + accumulator.Clear(); + } + else + { + // accumulator is empty - print the line as it is + printer(sliceWithNl.ToString()); + } + lineStartIndex = i + 1; + } + } + + if (buffer.Length > 0 && buffer[^1] != '\n') + { + // add a line without '\n' to accumulator + ReadOnlySpan appendix = buffer.Slice(lineStartIndex, buffer.Length - lineStartIndex); + accumulator.Append(appendix); + } + } } } diff --git a/src/mono/netcore/sample/iOS/Makefile b/src/mono/netcore/sample/iOS/Makefile index 36dec2bc18dab..e3d8b5271453c 100644 --- a/src/mono/netcore/sample/iOS/Makefile +++ b/src/mono/netcore/sample/iOS/Makefile @@ -7,15 +7,15 @@ all: runtimepack run TOOLS_DIR=../../../../../tools-local/tasks/mobile.tasks appbuilder: - $(DOTNET) build -c Release $(TOOLS_DIR)/AotCompilerTask/MonoAOTCompiler.csproj - $(DOTNET) build -c Release $(TOOLS_DIR)/AppleAppBuilder/AppleAppBuilder.csproj + $(DOTNET) build -c Debug $(TOOLS_DIR)/AotCompilerTask/MonoAOTCompiler.csproj + $(DOTNET) build -c Debug $(TOOLS_DIR)/AppleAppBuilder/AppleAppBuilder.csproj runtimepack: ../../../../.././build.sh Mono+Libs -os iOS -arch $(MONO_ARCH) -c $(MONO_CONFIG) run: clean appbuilder $(DOTNET) publish -c $(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH) \ - /p:UseLLVM=$(USE_LLVM) /p:UseAotForSimulator=true + /p:UseLLVM=$(USE_LLVM) /p:UseAotForSimulator=false /p:TargetOS=iOS clean: rm -rf bin diff --git a/src/mono/netcore/sample/iOS/Program.csproj b/src/mono/netcore/sample/iOS/Program.csproj index f08d1806b4f4c..7b7d84303ecd0 100644 --- a/src/mono/netcore/sample/iOS/Program.csproj +++ b/src/mono/netcore/sample/iOS/Program.csproj @@ -4,7 +4,6 @@ bin Portable $(NetCoreAppCurrent) - iOS $(ArtifactsBinDir)lib-runtime-packs\$(NetCoreAppCurrent)-iOS-$(Configuration)-$(TargetArchitecture)\runtimes\ios-$(TargetArchitecture) false ios-$(TargetArchitecture) @@ -23,12 +22,9 @@ - - - - + + +