PageRenderTime 26ms CodeModel.GetById 10ms app.highlight 12ms RepoModel.GetById 1ms 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
  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
 16using System; using Microsoft;
 17using System.IO;
 18using Microsoft.Linq.Expressions;
 19using System.Text;
 20using System.Threading;
 21using Microsoft.Scripting.Utils;
 22
 23namespace Microsoft.Scripting.Runtime {
 24    public sealed class SharedIO {
 25        // prevents this object from transitions to an inconsistent state, doesn't sync output or input:
 26        private readonly object _mutex = new object();
 27
 28        #region Proxies
 29
 30        private sealed class StreamProxy : Stream {
 31            private readonly ConsoleStreamType _type;
 32            private readonly SharedIO _io;
 33
 34            public StreamProxy(SharedIO io, ConsoleStreamType type) {
 35                Assert.NotNull(io);
 36                _io = io;
 37                _type = type;
 38            }
 39
 40            public override bool CanRead {
 41                get { return _type == ConsoleStreamType.Input; }
 42            }
 43
 44            public override bool CanSeek {
 45                get { return false; }
 46            }
 47
 48            public override bool CanWrite {
 49                get { return !CanRead; }
 50            }
 51
 52            public override void Flush() {
 53                _io.GetStream(_type).Flush();
 54            }
 55
 56            public override int Read(byte[] buffer, int offset, int count) {
 57                return _io.GetStream(_type).Read(buffer, offset, count);
 58            }
 59
 60            public override void Write(byte[] buffer, int offset, int count) {
 61                _io.GetStream(_type).Write(buffer, offset, count);
 62            }
 63
 64            public override long Length {
 65                get {
 66                    throw new NotSupportedException();
 67                }
 68            }
 69
 70            public override long Position {
 71                get {
 72                    throw new NotSupportedException();
 73                }
 74                set {
 75                    throw new NotSupportedException();
 76                }
 77            }
 78
 79            public override long Seek(long offset, SeekOrigin origin) {
 80                throw new NotSupportedException();
 81            }
 82
 83            public override void SetLength(long value) {
 84                throw new NotSupportedException();
 85            }
 86        }
 87
 88        #endregion
 89
 90        // lazily initialized to Console by default:
 91        private Stream _inputStream;
 92        private Stream _outputStream;
 93        private Stream _errorStream;
 94
 95        private TextReader _inputReader;
 96        private TextWriter _outputWriter;
 97        private TextWriter _errorWriter;
 98
 99        private Encoding _inputEncoding;
100
101        public Stream InputStream { get { InitializeInput(); return _inputStream; } }
102        public Stream OutputStream { get { InitializeOutput(); return _outputStream; } }
103        public Stream ErrorStream { get { InitializeErrorOutput(); return _errorStream; } }
104
105        public TextReader InputReader { get { InitializeInput(); return _inputReader; } }
106        public TextWriter OutputWriter { get { InitializeOutput(); return _outputWriter; } }
107        public TextWriter ErrorWriter { get { InitializeErrorOutput(); return _errorWriter; } }
108
109        public Encoding InputEncoding { get { InitializeInput(); return _inputEncoding; } }
110        public Encoding OutputEncoding { get { InitializeOutput(); return _outputWriter.Encoding; } }
111        public Encoding ErrorEncoding { get { InitializeErrorOutput(); return _errorWriter.Encoding; } }
112
113        internal SharedIO() {
114        }
115
116        private void InitializeInput() {
117            if (_inputStream == null) {
118                lock (_mutex) {
119                    if (_inputStream == null) {
120#if SILVERLIGHT
121                        _inputEncoding = StringUtils.DefaultEncoding;
122                        _inputStream = new TextStream(Console.In, _inputEncoding);
123#else
124                        _inputStream = Console.OpenStandardInput();
125                        _inputEncoding = Console.InputEncoding;
126#endif
127                        _inputReader = Console.In;
128                    }
129                }
130            }
131        }
132
133        private void InitializeOutput() {
134            if (_outputStream == null) {
135                lock (_mutex) {
136                    if (_outputStream == null) {
137#if SILVERLIGHT
138                        _outputStream = new TextStream(Console.Out);
139#else
140                        _outputStream = Console.OpenStandardOutput();
141#endif
142                        _outputWriter = Console.Out;
143                    }
144                }
145            }
146        }
147
148        private void InitializeErrorOutput() {
149            if (_errorStream == null) {
150#if SILVERLIGHT
151                Stream errorStream = new TextStream(Console.Error);
152#else
153                Stream errorStream = Console.OpenStandardError();
154#endif
155                Interlocked.CompareExchange(ref _errorStream, errorStream, null);
156                Interlocked.CompareExchange(ref _errorWriter, Console.Error, null);
157            }
158        }
159
160        /// <summary>
161        /// Only host should redirect I/O.
162        /// </summary>
163        public void SetOutput(Stream stream, TextWriter writer) {
164            Assert.NotNull(stream, writer);
165            lock (_mutex) {
166                _outputStream = stream;
167                _outputWriter = writer;
168            }
169        }
170
171        public void SetErrorOutput(Stream stream, TextWriter writer) {
172            Assert.NotNull(stream, writer);
173            lock (_mutex) {
174                _errorStream = stream;
175                _errorWriter = writer;
176            }
177        }
178
179        public void SetInput(Stream stream, TextReader reader, Encoding encoding) {
180            Assert.NotNull(stream, reader, encoding);
181            lock (_mutex) {
182                _inputStream = stream;
183                _inputReader = reader;
184                _inputEncoding = encoding;
185            }
186        }
187
188        public void RedirectToConsole() {
189            lock (_mutex) {
190                _inputEncoding = null;
191                _inputStream = null;
192                _outputStream = null;
193                _errorStream = null;
194                _inputReader = null;
195                _outputWriter = null;
196                _errorWriter = null;
197            }
198        }
199
200        public Stream GetStream(ConsoleStreamType type) {
201            switch (type) {
202                case ConsoleStreamType.Input: return InputStream;
203                case ConsoleStreamType.Output: return OutputStream;
204                case ConsoleStreamType.ErrorOutput: return ErrorStream;
205            }
206            throw Error.InvalidStreamType(type);
207        }
208
209        public TextWriter GetWriter(ConsoleStreamType type) {
210            switch (type) {
211                case ConsoleStreamType.Output: return OutputWriter;
212                case ConsoleStreamType.ErrorOutput: return ErrorWriter;
213            }
214            throw Error.InvalidStreamType(type);
215        }
216
217        public Encoding GetEncoding(ConsoleStreamType type) {
218            switch (type) {
219                case ConsoleStreamType.Input: return InputEncoding;
220                case ConsoleStreamType.Output: return OutputEncoding;
221                case ConsoleStreamType.ErrorOutput: return ErrorEncoding;
222            }
223            throw Error.InvalidStreamType(type);
224        }
225
226        public TextReader GetReader(out Encoding encoding) {
227            TextReader reader;
228            lock (_mutex) {
229                reader = InputReader;
230                encoding = InputEncoding;
231            }
232            return reader;
233        }
234
235        public Stream GetStreamProxy(ConsoleStreamType type) {
236            return new StreamProxy(this, type);
237        }
238    }
239}