Lucene.Net.Support: Added a SystemConsole class as a stand-in for System.Console, but with the ability to swap Out and Error to a different destination than System.Out and System.Error.
Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/51a6c52b Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/51a6c52b Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/51a6c52b Branch: refs/heads/master Commit: 51a6c52b39ce4183c6f18ba3af158bc132b12390 Parents: eaf4779 Author: Shad Storhaug <[email protected]> Authored: Mon Jul 31 12:43:54 2017 +0700 Committer: Shad Storhaug <[email protected]> Committed: Wed Aug 2 09:53:48 2017 +0700 ---------------------------------------------------------------------- src/Lucene.Net/Lucene.Net.csproj | 1 + src/Lucene.Net/Support/SystemConsole.cs | 411 ++++++++++++++++++++++ src/Lucene.Net/Util/PrintStreamInfoStream.cs | 12 +- 3 files changed, 421 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucenenet/blob/51a6c52b/src/Lucene.Net/Lucene.Net.csproj ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Lucene.Net.csproj b/src/Lucene.Net/Lucene.Net.csproj index 8f8fc4b..211a013 100644 --- a/src/Lucene.Net/Lucene.Net.csproj +++ b/src/Lucene.Net/Lucene.Net.csproj @@ -656,6 +656,7 @@ <Compile Include="Support\RectangularArrays.cs" /> <Compile Include="Support\Search\ReferenceContext.cs" /> <Compile Include="Support\Search\ReferenceManagerExtensions.cs" /> + <Compile Include="Support\SystemConsole.cs" /> <Compile Include="Support\SystemProperties.cs" /> <Compile Include="Support\Threading\ICompletionService.cs" /> <Compile Include="Support\IO\IDataInput.cs" /> http://git-wip-us.apache.org/repos/asf/lucenenet/blob/51a6c52b/src/Lucene.Net/Support/SystemConsole.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Support/SystemConsole.cs b/src/Lucene.Net/Support/SystemConsole.cs new file mode 100644 index 0000000..4a08ad1 --- /dev/null +++ b/src/Lucene.Net/Support/SystemConsole.cs @@ -0,0 +1,411 @@ +using System; +using System.IO; +using System.Runtime.CompilerServices; +#if !NETSTANDARD +using System.Security.Permissions; +#endif + +namespace Lucene.Net.Support +{ + /* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + // LUCENENET TODO: Replace all interaction with System.Console with this class + // so we can swap all input/ouput during testing or production scenarios + + /// <summary> + /// Mimics <see cref="System.Console"/>, but allows for swapping + /// the <see cref="TextWriter"/> of + /// <see cref="Out"/> and <see cref="Error"/>, or the <see cref="TextReader"/> of <see cref="In"/> + /// with user-defined implementations. + /// </summary> + public static class SystemConsole + { + public static TextWriter Out { get; set; } = Console.Out; + public static TextWriter Error { get; set; } = Console.Error; + public static TextReader In { get; set; } = Console.In; + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(bool value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(char value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(char[] buffer) + { + Out.Write(buffer); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(decimal value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(double value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(int value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(long value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(object value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(float value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(string value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(uint value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(ulong value) + { + Out.Write(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(string format, object arg0) + { + Out.Write(format, arg0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(string format, params object[] arg) + { + if (arg == null) + { + Out.Write(format, null, null); + } + else + { + Out.Write(format, arg); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(char[] buffer, int index, int count) + { + Out.Write(buffer, index, count); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(string format, object arg0, object arg1) + { + Out.Write(format, arg0, arg1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void Write(string format, object arg0, object arg1, object arg2) + { + Out.Write(format, arg0, arg1, arg2); + } + +#if !NETSTANDARD + [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false)] + [HostProtection(SecurityAction.LinkDemand, UI = true)] + public static void Write(string format, object arg0, object arg1, object arg2, object arg3, __arglist) + { + ArgIterator iterator = new ArgIterator(__arglist); + int num = iterator.GetRemainingCount() + 4; + object[] arg = new object[num]; + arg[0] = arg0; + arg[1] = arg1; + arg[2] = arg2; + arg[3] = arg3; + for (int i = 4; i < num; i++) + { + arg[i] = TypedReference.ToObject(iterator.GetNextArg()); + } + Out.Write(format, arg); + } +#endif + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine() + { + Out.WriteLine(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(bool value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(char value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(char[] buffer) + { + Out.WriteLine(buffer); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(decimal value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(double value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(int value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(long value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(object value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(float value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(string value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(uint value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(ulong value) + { + Out.WriteLine(value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(string format, object arg0) + { + Out.WriteLine(format, arg0); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(string format, params object[] arg) + { + if (arg == null) + { + Out.WriteLine(format, null, null); + } + else + { + Out.WriteLine(format, arg); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(char[] buffer, int index, int count) + { + Out.WriteLine(buffer, index, count); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(string format, object arg0, object arg1) + { + Out.WriteLine(format, arg0, arg1); + } + + [MethodImpl(MethodImplOptions.NoInlining)] +#if !NETSTANDARD + [HostProtection(SecurityAction.LinkDemand, UI = true)] +#endif + public static void WriteLine(string format, object arg0, object arg1, object arg2) + { + Out.WriteLine(format, arg0, arg1, arg2); + } + +#if !NETSTANDARD + [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false)] + [HostProtection(SecurityAction.LinkDemand, UI = true)] + public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3, __arglist) + { + ArgIterator iterator = new ArgIterator(__arglist); + int num = iterator.GetRemainingCount() + 4; + object[] arg = new object[num]; + arg[0] = arg0; + arg[1] = arg1; + arg[2] = arg2; + arg[3] = arg3; + for (int i = 4; i < num; i++) + { + arg[i] = TypedReference.ToObject(iterator.GetNextArg()); + } + Out.WriteLine(format, arg); + } +#endif + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/51a6c52b/src/Lucene.Net/Util/PrintStreamInfoStream.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net/Util/PrintStreamInfoStream.cs b/src/Lucene.Net/Util/PrintStreamInfoStream.cs index ebbb8d3..e8d6d4c 100644 --- a/src/Lucene.Net/Util/PrintStreamInfoStream.cs +++ b/src/Lucene.Net/Util/PrintStreamInfoStream.cs @@ -1,6 +1,8 @@ using Lucene.Net.Support; +using Lucene.Net.Support.IO; using System; using System.IO; +using System.Reflection; using System.Threading; namespace Lucene.Net.Util @@ -51,8 +53,8 @@ namespace Lucene.Net.Util private static readonly AtomicInt32 MESSAGE_ID = new AtomicInt32(); protected readonly int m_messageID; - protected readonly TextWriter m_stream; + private readonly bool isSystemStream; public TextWriterInfoStream(TextWriter stream) : this(stream, MESSAGE_ID.GetAndIncrement()) @@ -61,7 +63,11 @@ namespace Lucene.Net.Util public TextWriterInfoStream(TextWriter stream, int messageID) { - this.m_stream = stream; + // LUCENENET: Since we are wrapping our TextWriter to make it safe to use + // after calling Dispose(), we need to determine whether it is a system stream + // here instead of on demand. + this.isSystemStream = stream == SystemConsole.Out || stream == SystemConsole.Error; + this.m_stream = typeof(SafeTextWriterWrapper).GetTypeInfo().IsAssignableFrom(stream.GetType()) ? stream : new SafeTextWriterWrapper(stream); this.m_messageID = messageID; } @@ -87,7 +93,7 @@ namespace Lucene.Net.Util { get { - return m_stream == Console.Out || m_stream == Console.Error; + return isSystemStream; } } }
