//---------------------------------------------------------------------
//
// Copyright (C) 2004 Yingle Jia
//
// Permission to copy, use, modify, sell and distribute this software is
// granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
//
#include "stdafx.h"
namespace Acf {
namespace Internal {
class __ConsoleStream : public Stream
{
// Fields
private:
intptr_t _handle;
bool _canRead;
bool _canWrite;
// Constructors
public:
__ConsoleStream(intptr_t handle, FileAccess access)
{
this->_handle = handle;
this->_canRead = (access == FileAccess::Read);
this->_canWrite = (access == FileAccess::Write);
}
// Destructor
private:
virtual ~__ConsoleStream()
{
Close();
}
// Properties
public:
override bool get_CanRead()
{
return this->_canRead;
}
override bool get_CanWrite()
{
return this->_canWrite;
}
override bool get_CanSeek()
{
return false;
}
override int64 get_Length()
{
throw InvalidOperationException();
return 0;
}
override int64 get_Position()
{
throw InvalidOperationException();
return 0;
}
override void set_Position(int64 value)
{
throw InvalidOperationException();
}
// Methods
public:
override void SetLength(int64 value)
{
throw InvalidOperationException();
}
override int64 Seek(int64 offset, SeekOrigin origin)
{
throw InvalidOperationException();
return 0;
}
override int Read(Array<byte>* buffer, int offset, int count)
{
if (buffer == null)
throw ArgumentNullException();
if (offset < 0 || count < 0)
throw ArgumentOutOfRangeException();
if (offset + count > buffer->Length)
throw ArgumentException();
if (!this->_canRead)
throw InvalidOperationException();
int numBytesRead = 0;
bool ret = Pal::ReadFile(this->_handle, buffer->GetItemAddress(offset),
count, &numBytesRead);
if (!ret)
throw InvalidOperationException();
return numBytesRead;
}
override void Write(Array<byte>* buffer, int offset, int count)
{
Acf::VerifyArrayRange(buffer, offset, count);
if (!this->_canWrite)
throw InvalidOperationException();
if (count != 0)
{
int written = 0;
bool ret = Pal::WriteFile(this->_handle, buffer->GetItemAddress(offset),
count, &written);
if (!ret)
throw InvalidOperationException();
}
}
override void Flush()
{
if (this->_handle == Pal::InvalidHandle)
throw InvalidOperationException();
if (!this->CanWrite)
throw InvalidOperationException();
}
override void Close()
{
this->_handle = Pal::InvalidHandle;
this->_canRead = false;
this->_canWrite = false;
}
};
} // namespace Internal
using namespace Acf::Text;
/*static*/ TextReaderPtr Console::_in = null;
/*static*/ TextWriterPtr Console::_out = null;
/*static*/ TextWriterPtr Console::_err = null;
// The buffer size is not important since we'll not buffer console I/O,
// just make sure we use a minimum buffer size.
const int ConsoleBufferSize = 128;
ObjectPtr _consoleLock = new Object();
/*static*/ TextReaderPtr Console::get_In()
{
if (Console::_in == null)
{
LOCK (_consoleLock)
{
if (Console::_in == null)
{
StreamPtr stream = OpenStandardInput();
EncodingPtr enc = new CodePageEncoding(Pal::GetConsoleInputCodePage());
StreamReaderPtr reader = new StreamReader(stream, enc, false, ConsoleBufferSize);
Console::_in = reader;
}
}
}
return Console::_in;
}
/*static*/ TextWriterPtr Console::get_Out()
{
if (Console::_out == null)
{
LOCK (_consoleLock)
{
if (Console::_out == null)
{
StreamPtr stream = OpenStandardOutput();
EncodingPtr enc = new CodePageEncoding(Pal::GetConsoleOutputCodePage());
StreamWriterPtr writer = new StreamWriter(stream, enc, ConsoleBufferSize);
writer->AutoFlush = true;
Console::_out = writer;
}
}
}
return Console::_out;
}
/*static*/ TextWriterPtr Console::get_Err()
{
if (Console::_err == null)
{
LOCK (_consoleLock)
{
if (Console::_err == null)
{
StreamPtr stream = OpenStandardError();
EncodingPtr enc = new CodePageEncoding(Pal::GetConsoleOutputCodePage());
StreamWriterPtr writer = new StreamWriter(stream, enc, ConsoleBufferSize);
writer->AutoFlush = true;
Console::_err = writer;
}
}
}
return Console::_err;
}
/*static*/ void Console::SetIn(TextReader* newIn)
{
if (newIn == null)
throw ArgumentNullException();
Console::_in = newIn;
}
/*static*/ void Console::SetOut(TextWriter* newOut)
{
if (newOut == null)
throw ArgumentNullException();
Console::_out = newOut;
}
/*static*/ void Console::SetErr(TextWriter* newErr)
{
if (newErr == null)
throw ArgumentNullException();
Console::_err = newErr;
}
inline StreamPtr OpenStdStream(int stdHandle, FileAccess access)
{
intptr_t handle = Pal::GetStdHandle(stdHandle);
if (handle == Pal::InvalidHandle || handle == null)
throw InvalidOperationException();
return new __ConsoleStream(handle, access);
}
/*static*/ StreamPtr Console::OpenStandardInput()
{
return OpenStdStream(Pal::StdHandleIn, FileAccess::Read);
}
/*static*/ StreamPtr Console::OpenStandardOutput()
{
return OpenStdStream(Pal::StdHandleOut, FileAccess::Write);
}
/*static*/ StreamPtr Console::OpenStandardError()
{
return OpenStdStream(Pal::StdHandleErr, FileAccess::Write);
}
/*static*/ int Console::Read()
{
TextReader* in = get_In();
LOCK (in)
return in->Read();
}
/*static*/ StringPtr Console::ReadLine()
{
TextReader* in = get_In();
LOCK (in)
return in->ReadLine();
}
/*static*/ void Console::Write(bool value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(wchar_t value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(int value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(uint value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(int64 value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(uint64 value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(float value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(double value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(Array<wchar_t>* buffer)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(buffer);
}
/*static*/ void Console::Write(Array<wchar_t>* buffer, int index, int count)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(buffer, index, count);
}
/*static*/ void Console::Write(Object* value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(String* value)
{
TextWriter* out = get_Out();
LOCK (out)
out->Write(value);
}
/*static*/ void Console::Write(const wchar_t* value)
{
StringPtr s = new String(value);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(String* format, Object* arg0)
{
StringPtr s = String::Format(format, arg0);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(String* format, Object* arg0, Object* arg1)
{
StringPtr s = String::Format(format, arg0, arg1);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(String* format, Object* arg0, Object* arg1, Object* arg2)
{
StringPtr s = String::Format(format, arg0, arg1, arg2);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(String* format, Array<ObjectPtr>* args)
{
StringPtr s = String::Format(format, args);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(const wchar_t* format, Object* arg0)
{
StringPtr s = String::Format(format, arg0);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(const wchar_t* format, Object* arg0, Object* arg1)
{
StringPtr s = String::Format(format, arg0, arg1);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(const wchar_t* format, Object* arg0, Object* arg1, Object* arg2)
{
StringPtr s = String::Format(format, arg0, arg1, arg2);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::Write(const wchar_t* format, Array<ObjectPtr>* args)
{
StringPtr s = String::Format(format, args);
TextWriter* out = get_Out();
LOCK (out)
out->Write(s);
}
/*static*/ void Console::WriteLine()
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine();
}
/*static*/ void Console::WriteLine(bool value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(wchar_t value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(int value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(uint value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(int64 value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(uint64 value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(float value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(double value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(Array<wchar_t>* buffer)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(buffer);
}
/*static*/ void Console::WriteLine(Array<wchar_t>* buffer, int index, int count)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(buffer, index, count);
}
/*static*/ void Console::WriteLine(Object* value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(String* value)
{
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(value);
}
/*static*/ void Console::WriteLine(const wchar_t* value)
{
StringPtr s = new String(value);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(String* format, Object* arg0)
{
StringPtr s = String::Format(format, arg0);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(String* format, Object* arg0, Object* arg1)
{
StringPtr s = String::Format(format, arg0, arg1);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(String* format, Object* arg0, Object* arg1, Object* arg2)
{
StringPtr s = String::Format(format, arg0, arg1, arg2);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(String* format, Array<ObjectPtr>* args)
{
StringPtr s = String::Format(format, args);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(const wchar_t* format, Object* arg0)
{
StringPtr s = String::Format(format, arg0);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(const wchar_t* format, Object* arg0, Object* arg1)
{
StringPtr s = String::Format(format, arg0, arg1);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(const wchar_t* format, Object* arg0, Object* arg1, Object* arg2)
{
StringPtr s = String::Format(format, arg0, arg1, arg2);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
/*static*/ void Console::WriteLine(const wchar_t* format, Array<ObjectPtr>* args)
{
StringPtr s = String::Format(format, args);
TextWriter* out = get_Out();
LOCK (out)
out->WriteLine(s);
}
} // namespace Acf