PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/IronPython_2_0/Src/Microsoft.Scripting/Runtime/SharedIO.cs

#
C# | 239 lines | 185 code | 35 blank | 19 comment | 14 complexity | 5a59ac6e6f2c1dd1831cc0a875d00c23 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System; using Microsoft;
  16. using System.IO;
  17. using Microsoft.Linq.Expressions;
  18. using System.Text;
  19. using System.Threading;
  20. using Microsoft.Scripting.Utils;
  21. namespace Microsoft.Scripting.Runtime {
  22. public sealed class SharedIO {
  23. // prevents this object from transitions to an inconsistent state, doesn't sync output or input:
  24. private readonly object _mutex = new object();
  25. #region Proxies
  26. private sealed class StreamProxy : Stream {
  27. private readonly ConsoleStreamType _type;
  28. private readonly SharedIO _io;
  29. public StreamProxy(SharedIO io, ConsoleStreamType type) {
  30. Assert.NotNull(io);
  31. _io = io;
  32. _type = type;
  33. }
  34. public override bool CanRead {
  35. get { return _type == ConsoleStreamType.Input; }
  36. }
  37. public override bool CanSeek {
  38. get { return false; }
  39. }
  40. public override bool CanWrite {
  41. get { return !CanRead; }
  42. }
  43. public override void Flush() {
  44. _io.GetStream(_type).Flush();
  45. }
  46. public override int Read(byte[] buffer, int offset, int count) {
  47. return _io.GetStream(_type).Read(buffer, offset, count);
  48. }
  49. public override void Write(byte[] buffer, int offset, int count) {
  50. _io.GetStream(_type).Write(buffer, offset, count);
  51. }
  52. public override long Length {
  53. get {
  54. throw new NotSupportedException();
  55. }
  56. }
  57. public override long Position {
  58. get {
  59. throw new NotSupportedException();
  60. }
  61. set {
  62. throw new NotSupportedException();
  63. }
  64. }
  65. public override long Seek(long offset, SeekOrigin origin) {
  66. throw new NotSupportedException();
  67. }
  68. public override void SetLength(long value) {
  69. throw new NotSupportedException();
  70. }
  71. }
  72. #endregion
  73. // lazily initialized to Console by default:
  74. private Stream _inputStream;
  75. private Stream _outputStream;
  76. private Stream _errorStream;
  77. private TextReader _inputReader;
  78. private TextWriter _outputWriter;
  79. private TextWriter _errorWriter;
  80. private Encoding _inputEncoding;
  81. public Stream InputStream { get { InitializeInput(); return _inputStream; } }
  82. public Stream OutputStream { get { InitializeOutput(); return _outputStream; } }
  83. public Stream ErrorStream { get { InitializeErrorOutput(); return _errorStream; } }
  84. public TextReader InputReader { get { InitializeInput(); return _inputReader; } }
  85. public TextWriter OutputWriter { get { InitializeOutput(); return _outputWriter; } }
  86. public TextWriter ErrorWriter { get { InitializeErrorOutput(); return _errorWriter; } }
  87. public Encoding InputEncoding { get { InitializeInput(); return _inputEncoding; } }
  88. public Encoding OutputEncoding { get { InitializeOutput(); return _outputWriter.Encoding; } }
  89. public Encoding ErrorEncoding { get { InitializeErrorOutput(); return _errorWriter.Encoding; } }
  90. internal SharedIO() {
  91. }
  92. private void InitializeInput() {
  93. if (_inputStream == null) {
  94. lock (_mutex) {
  95. if (_inputStream == null) {
  96. #if SILVERLIGHT
  97. _inputEncoding = StringUtils.DefaultEncoding;
  98. _inputStream = new TextStream(Console.In, _inputEncoding);
  99. #else
  100. _inputStream = Console.OpenStandardInput();
  101. _inputEncoding = Console.InputEncoding;
  102. #endif
  103. _inputReader = Console.In;
  104. }
  105. }
  106. }
  107. }
  108. private void InitializeOutput() {
  109. if (_outputStream == null) {
  110. lock (_mutex) {
  111. if (_outputStream == null) {
  112. #if SILVERLIGHT
  113. _outputStream = new TextStream(Console.Out);
  114. #else
  115. _outputStream = Console.OpenStandardOutput();
  116. #endif
  117. _outputWriter = Console.Out;
  118. }
  119. }
  120. }
  121. }
  122. private void InitializeErrorOutput() {
  123. if (_errorStream == null) {
  124. #if SILVERLIGHT
  125. Stream errorStream = new TextStream(Console.Error);
  126. #else
  127. Stream errorStream = Console.OpenStandardError();
  128. #endif
  129. Interlocked.CompareExchange(ref _errorStream, errorStream, null);
  130. Interlocked.CompareExchange(ref _errorWriter, Console.Error, null);
  131. }
  132. }
  133. /// <summary>
  134. /// Only host should redirect I/O.
  135. /// </summary>
  136. public void SetOutput(Stream stream, TextWriter writer) {
  137. Assert.NotNull(stream, writer);
  138. lock (_mutex) {
  139. _outputStream = stream;
  140. _outputWriter = writer;
  141. }
  142. }
  143. public void SetErrorOutput(Stream stream, TextWriter writer) {
  144. Assert.NotNull(stream, writer);
  145. lock (_mutex) {
  146. _errorStream = stream;
  147. _errorWriter = writer;
  148. }
  149. }
  150. public void SetInput(Stream stream, TextReader reader, Encoding encoding) {
  151. Assert.NotNull(stream, reader, encoding);
  152. lock (_mutex) {
  153. _inputStream = stream;
  154. _inputReader = reader;
  155. _inputEncoding = encoding;
  156. }
  157. }
  158. public void RedirectToConsole() {
  159. lock (_mutex) {
  160. _inputEncoding = null;
  161. _inputStream = null;
  162. _outputStream = null;
  163. _errorStream = null;
  164. _inputReader = null;
  165. _outputWriter = null;
  166. _errorWriter = null;
  167. }
  168. }
  169. public Stream GetStream(ConsoleStreamType type) {
  170. switch (type) {
  171. case ConsoleStreamType.Input: return InputStream;
  172. case ConsoleStreamType.Output: return OutputStream;
  173. case ConsoleStreamType.ErrorOutput: return ErrorStream;
  174. }
  175. throw Error.InvalidStreamType(type);
  176. }
  177. public TextWriter GetWriter(ConsoleStreamType type) {
  178. switch (type) {
  179. case ConsoleStreamType.Output: return OutputWriter;
  180. case ConsoleStreamType.ErrorOutput: return ErrorWriter;
  181. }
  182. throw Error.InvalidStreamType(type);
  183. }
  184. public Encoding GetEncoding(ConsoleStreamType type) {
  185. switch (type) {
  186. case ConsoleStreamType.Input: return InputEncoding;
  187. case ConsoleStreamType.Output: return OutputEncoding;
  188. case ConsoleStreamType.ErrorOutput: return ErrorEncoding;
  189. }
  190. throw Error.InvalidStreamType(type);
  191. }
  192. public TextReader GetReader(out Encoding encoding) {
  193. TextReader reader;
  194. lock (_mutex) {
  195. reader = InputReader;
  196. encoding = InputEncoding;
  197. }
  198. return reader;
  199. }
  200. public Stream GetStreamProxy(ConsoleStreamType type) {
  201. return new StreamProxy(this, type);
  202. }
  203. }
  204. }