progress
This commit is contained in:
parent
16e76d6b31
commit
484dbfc9d9
529 changed files with 113694 additions and 0 deletions
307
AspClassic.Scripting/Runtime/SharedIO.cs
Normal file
307
AspClassic.Scripting/Runtime/SharedIO.cs
Normal file
|
@ -0,0 +1,307 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using AspClassic.Scripting.Utils;
|
||||
|
||||
namespace AspClassic.Scripting.Runtime;
|
||||
|
||||
public sealed class SharedIO
|
||||
{
|
||||
private sealed class StreamProxy : Stream
|
||||
{
|
||||
private readonly ConsoleStreamType _type;
|
||||
|
||||
private readonly SharedIO _io;
|
||||
|
||||
public override bool CanRead => _type == ConsoleStreamType.Input;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => !CanRead;
|
||||
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public StreamProxy(SharedIO io, ConsoleStreamType type)
|
||||
{
|
||||
_io = io;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
_io.GetStream(_type).Flush();
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
return _io.GetStream(_type).Read(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
_io.GetStream(_type).Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly object _mutex = new object();
|
||||
|
||||
private Stream _inputStream;
|
||||
|
||||
private Stream _outputStream;
|
||||
|
||||
private Stream _errorStream;
|
||||
|
||||
private TextReader _inputReader;
|
||||
|
||||
private TextWriter _outputWriter;
|
||||
|
||||
private TextWriter _errorWriter;
|
||||
|
||||
private Encoding _inputEncoding;
|
||||
|
||||
public Stream InputStream
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeInput();
|
||||
return _inputStream;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream OutputStream
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeOutput();
|
||||
return _outputStream;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream ErrorStream
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeErrorOutput();
|
||||
return _errorStream;
|
||||
}
|
||||
}
|
||||
|
||||
public TextReader InputReader
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeInput();
|
||||
return _inputReader;
|
||||
}
|
||||
}
|
||||
|
||||
public TextWriter OutputWriter
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeOutput();
|
||||
return _outputWriter;
|
||||
}
|
||||
}
|
||||
|
||||
public TextWriter ErrorWriter
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeErrorOutput();
|
||||
return _errorWriter;
|
||||
}
|
||||
}
|
||||
|
||||
public Encoding InputEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeInput();
|
||||
return _inputEncoding;
|
||||
}
|
||||
}
|
||||
|
||||
public Encoding OutputEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeOutput();
|
||||
return _outputWriter.Encoding;
|
||||
}
|
||||
}
|
||||
|
||||
public Encoding ErrorEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeErrorOutput();
|
||||
return _errorWriter.Encoding;
|
||||
}
|
||||
}
|
||||
|
||||
internal SharedIO()
|
||||
{
|
||||
}
|
||||
|
||||
private void InitializeInput()
|
||||
{
|
||||
if (_inputStream != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (_mutex)
|
||||
{
|
||||
if (_inputStream == null)
|
||||
{
|
||||
_inputStream = ConsoleInputStream.Instance;
|
||||
_inputEncoding = Console.InputEncoding;
|
||||
_inputReader = Console.In;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeOutput()
|
||||
{
|
||||
if (_outputStream != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (_mutex)
|
||||
{
|
||||
if (_outputStream == null)
|
||||
{
|
||||
_outputStream = Console.OpenStandardOutput();
|
||||
_outputWriter = Console.Out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeErrorOutput()
|
||||
{
|
||||
if (_errorStream == null)
|
||||
{
|
||||
Stream value = Console.OpenStandardError();
|
||||
Interlocked.CompareExchange(ref _errorStream, value, null);
|
||||
Interlocked.CompareExchange(ref _errorWriter, Console.Error, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOutput(Stream stream, TextWriter writer)
|
||||
{
|
||||
lock (_mutex)
|
||||
{
|
||||
_outputStream = stream;
|
||||
_outputWriter = writer;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetErrorOutput(Stream stream, TextWriter writer)
|
||||
{
|
||||
lock (_mutex)
|
||||
{
|
||||
_errorStream = stream;
|
||||
_errorWriter = writer;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInput(Stream stream, TextReader reader, Encoding encoding)
|
||||
{
|
||||
lock (_mutex)
|
||||
{
|
||||
_inputStream = stream;
|
||||
_inputReader = reader;
|
||||
_inputEncoding = encoding;
|
||||
}
|
||||
}
|
||||
|
||||
public void RedirectToConsole()
|
||||
{
|
||||
lock (_mutex)
|
||||
{
|
||||
_inputEncoding = null;
|
||||
_inputStream = null;
|
||||
_outputStream = null;
|
||||
_errorStream = null;
|
||||
_inputReader = null;
|
||||
_outputWriter = null;
|
||||
_errorWriter = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetStream(ConsoleStreamType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ConsoleStreamType.Input => InputStream,
|
||||
ConsoleStreamType.Output => OutputStream,
|
||||
ConsoleStreamType.ErrorOutput => ErrorStream,
|
||||
_ => throw Error.InvalidStreamType(type),
|
||||
};
|
||||
}
|
||||
|
||||
public TextWriter GetWriter(ConsoleStreamType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ConsoleStreamType.Output => OutputWriter,
|
||||
ConsoleStreamType.ErrorOutput => ErrorWriter,
|
||||
_ => throw Error.InvalidStreamType(type),
|
||||
};
|
||||
}
|
||||
|
||||
public Encoding GetEncoding(ConsoleStreamType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ConsoleStreamType.Input => InputEncoding,
|
||||
ConsoleStreamType.Output => OutputEncoding,
|
||||
ConsoleStreamType.ErrorOutput => ErrorEncoding,
|
||||
_ => throw Error.InvalidStreamType(type),
|
||||
};
|
||||
}
|
||||
|
||||
public TextReader GetReader(out Encoding encoding)
|
||||
{
|
||||
lock (_mutex)
|
||||
{
|
||||
TextReader inputReader = InputReader;
|
||||
encoding = InputEncoding;
|
||||
return inputReader;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetStreamProxy(ConsoleStreamType type)
|
||||
{
|
||||
return new StreamProxy(this, type);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue