799 lines
22 KiB
C++
799 lines
22 KiB
C++
|
#include "ehs/io/Console.h"
|
||
|
#include "ehs/Log.h"
|
||
|
#include "ehs/io/File.h"
|
||
|
|
||
|
#if defined(EHS_OS_LINUX)
|
||
|
#include <fcntl.h>
|
||
|
#include <unistd.h>
|
||
|
#include <cerrno>
|
||
|
#endif
|
||
|
|
||
|
namespace ehs
|
||
|
{
|
||
|
ConsoleHdl Console::hdlOut = 0;
|
||
|
ConsoleHdl Console::hdlIn = 0;
|
||
|
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
bool Console::isConsole = true;
|
||
|
#endif
|
||
|
|
||
|
void Console::Attach()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (!AttachConsole(ATTACH_PARENT_PROCESS))
|
||
|
{
|
||
|
DWORD code = GetLastError();
|
||
|
if (code == ERROR_INVALID_HANDLE)
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
hdlIn = GetStdHandle(STD_INPUT_HANDLE);
|
||
|
hdlOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
|
||
|
DWORD mode = 0;
|
||
|
|
||
|
if (!GetConsoleMode(hdlOut, &mode))
|
||
|
{
|
||
|
if (GetLastError() == ERROR_INVALID_HANDLE)
|
||
|
isConsole = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//DWORD code = WaitForSingleObject(hdlIn, 15000);
|
||
|
//if (code == WAIT_FAILED || code == WAIT_TIMEOUT || code == WAIT_ABANDONED)
|
||
|
// EHS_LOG_INT("Error", 0, "Failed to wait for console input.");
|
||
|
|
||
|
isConsole = true;
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
hdlOut = open("/dev/stdout", O_WRONLY | O_SYNC);
|
||
|
hdlIn = open("/dev/stdin", O_RDONLY);
|
||
|
#else
|
||
|
return;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
bool Console::Create()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (!AllocConsole())
|
||
|
return false;
|
||
|
|
||
|
hdlIn = GetStdHandle(STD_INPUT_HANDLE);
|
||
|
hdlOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
|
||
|
if (WaitForSingleObject(hdlIn, EHS_INFINITE) == WAIT_FAILED)
|
||
|
EHS_LOG_INT("Error", 2, "Failed to wait for console input.");
|
||
|
|
||
|
//if (!SetConsoleActiveScreenBuffer(hdlOut))
|
||
|
// EHS_LOG_INT("Error", 3, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
isConsole = true;
|
||
|
#endif
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void Console::Free()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (!FreeConsole())
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
int code = close(hdlOut);
|
||
|
if (code == -1)
|
||
|
EHS_LOG_INT("Error", 0, "Failed to free the console output with error #" + Str_8::FromNum(errno) + ".");
|
||
|
|
||
|
code = close(hdlIn);
|
||
|
if (code == -1)
|
||
|
EHS_LOG_INT("Error", 0, "Failed to free the console input with error #" + Str_8::FromNum(errno) + ".");
|
||
|
#endif
|
||
|
|
||
|
hdlOut = 0;
|
||
|
hdlIn = 0;
|
||
|
}
|
||
|
|
||
|
bool Console::CanRead()
|
||
|
{
|
||
|
return hdlIn;
|
||
|
}
|
||
|
|
||
|
bool Console::CanWrite()
|
||
|
{
|
||
|
return hdlOut;
|
||
|
}
|
||
|
|
||
|
void Console::Write_32(const Str_32& str, const bool newLine)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (isConsole)
|
||
|
{
|
||
|
Str_16 r = UTF::To_16(str);
|
||
|
if (newLine)
|
||
|
r += L"\r\n";
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DWORD written = 0;
|
||
|
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < r.Size());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Str_8 r = UTF::To_8(str);
|
||
|
if (newLine)
|
||
|
r += "\r\n";
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DWORD written = 0;
|
||
|
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < r.Size(true));
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_32 result = str;
|
||
|
if (newLine)
|
||
|
result += U"\n";
|
||
|
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, result, result.Size(true));
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < result.Size(true));
|
||
|
#else
|
||
|
return;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void Console::Write_16(const Str_16& str, const bool newLine)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (isConsole)
|
||
|
{
|
||
|
Str_16 r = str;
|
||
|
if (newLine)
|
||
|
r += L"\r\n";
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DWORD written = 0;
|
||
|
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < r.Size());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Str_8 r = UTF::To_8(str);
|
||
|
if (newLine)
|
||
|
r += "\r\n";
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DWORD written = 0;
|
||
|
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < r.Size(true));
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_16 result = str;
|
||
|
if (newLine)
|
||
|
result += L"\n";
|
||
|
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, result, result.Size(true));
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < result.Size(true));
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void Console::Write_8(const Str_8& str, const bool newLine)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (isConsole)
|
||
|
{
|
||
|
Str_16 r = UTF::To_16(str);
|
||
|
if (newLine)
|
||
|
r += L"\r\n";
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DWORD written = 0;
|
||
|
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < r.Size());
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Str_8 r = str;
|
||
|
if (newLine)
|
||
|
r += "\r\n";
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DWORD written = 0;
|
||
|
if (!WriteFile(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < r.Size());
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_8 result = str;
|
||
|
if (newLine)
|
||
|
result += "\n";
|
||
|
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, result, result.Size());
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < result.Size());
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Str_32 Console::Read_32(const UInt_64 bufferSize)
|
||
|
{
|
||
|
if (!hdlIn)
|
||
|
return U"";
|
||
|
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (isConsole)
|
||
|
{
|
||
|
Str_16 result;
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result.Resize(result.Size() + bufferSize);
|
||
|
|
||
|
DWORD read = 0;
|
||
|
|
||
|
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return U"";
|
||
|
}
|
||
|
|
||
|
offset += read;
|
||
|
}
|
||
|
while (result[offset - 1] != L'\n');
|
||
|
|
||
|
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
||
|
result.Resize(offset - 2);
|
||
|
else
|
||
|
result.Resize(offset - 1);
|
||
|
|
||
|
return UTF::To_32(result);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Str_8 result;
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result.Resize(result.Size() + bufferSize);
|
||
|
|
||
|
DWORD read = 0;
|
||
|
|
||
|
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return U"";
|
||
|
}
|
||
|
|
||
|
offset += read;
|
||
|
}
|
||
|
while (result[offset - 1] != '\n');
|
||
|
|
||
|
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
||
|
result.Resize(offset - 2);
|
||
|
else
|
||
|
result.Resize(offset - 1);
|
||
|
|
||
|
return UTF::To_32(result);
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_32 result;
|
||
|
Str_32 input(bufferSize);
|
||
|
ssize_t read = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
read = ::read(hdlIn, input, bufferSize);
|
||
|
if (read == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return result;
|
||
|
}
|
||
|
result.Push(input, read);
|
||
|
}
|
||
|
while (input[read - 1] != U'\n');
|
||
|
|
||
|
return result;
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Str_16 Console::Read_16(const UInt_64 bufferSize)
|
||
|
{
|
||
|
if (!hdlIn)
|
||
|
return L"";
|
||
|
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (isConsole)
|
||
|
{
|
||
|
Str_16 result;
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result.Resize(result.Size() + bufferSize);
|
||
|
|
||
|
DWORD read = 0;
|
||
|
|
||
|
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return L"";
|
||
|
}
|
||
|
|
||
|
offset += read;
|
||
|
}
|
||
|
while (result[offset - 1] != L'\n');
|
||
|
|
||
|
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
||
|
result.Resize(offset - 2);
|
||
|
else
|
||
|
result.Resize(offset - 1);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Str_8 result;
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result.Resize(result.Size() + bufferSize);
|
||
|
|
||
|
DWORD read = 0;
|
||
|
|
||
|
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return L"";
|
||
|
}
|
||
|
|
||
|
offset += read;
|
||
|
}
|
||
|
while (result[offset - 1] != '\n');
|
||
|
|
||
|
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
||
|
result.Resize(offset - 2);
|
||
|
else
|
||
|
result.Resize(offset - 1);
|
||
|
|
||
|
return UTF::To_16(result);
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_16 result;
|
||
|
Str_16 input(bufferSize);
|
||
|
ssize_t read = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
read = ::read(hdlIn, input, bufferSize);
|
||
|
if (read == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return result;
|
||
|
}
|
||
|
result.Push(input, read);
|
||
|
}
|
||
|
while (input[read - 1] != L'\n');
|
||
|
|
||
|
return result;
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Str_8 Console::Read_8(const UInt_64 bufferSize)
|
||
|
{
|
||
|
if (!hdlIn)
|
||
|
return "";
|
||
|
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (isConsole)
|
||
|
{
|
||
|
Str_16 result;
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result.Resize(result.Size() + bufferSize);
|
||
|
|
||
|
DWORD read = 0;
|
||
|
|
||
|
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
offset += read;
|
||
|
}
|
||
|
while (result[offset - 1] != L'\n');
|
||
|
|
||
|
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
||
|
result.Resize(offset - 2);
|
||
|
else
|
||
|
result.Resize(offset - 1);
|
||
|
|
||
|
return UTF::To_8(result);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Str_8 result;
|
||
|
|
||
|
DWORD offset = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
result.Resize(result.Size() + bufferSize);
|
||
|
|
||
|
DWORD read = 0;
|
||
|
|
||
|
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
offset += read;
|
||
|
}
|
||
|
while (result[offset - 1] != '\n');
|
||
|
|
||
|
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
||
|
result.Resize(offset - 2);
|
||
|
else
|
||
|
result.Resize(offset - 1);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_8 result;
|
||
|
Str_8 input(bufferSize);
|
||
|
ssize_t read = 0;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
read = ::read(hdlIn, input, bufferSize);
|
||
|
if (read == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return result;
|
||
|
}
|
||
|
result.Push(input, read);
|
||
|
}
|
||
|
while (input[read - 1] != '\n');
|
||
|
|
||
|
return result.Sub(0, result.Size() - 1);
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void Console::Clear()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||
|
if (!GetConsoleScreenBufferInfo(hdlOut, &info))
|
||
|
return;
|
||
|
|
||
|
DWORD size = info.dwSize.X * info.dwSize.Y;
|
||
|
|
||
|
DWORD written = 0;
|
||
|
if (!FillConsoleOutputCharacterW(hdlOut, L' ', size, {0, 0}, &written))
|
||
|
return;
|
||
|
|
||
|
if (!GetConsoleScreenBufferInfo(hdlOut, &info))
|
||
|
return;
|
||
|
|
||
|
if (!FillConsoleOutputAttribute(hdlOut, info.wAttributes, size, {0, 0}, &written))
|
||
|
return;
|
||
|
|
||
|
SetConsoleCursorPosition(hdlOut, {0, 0});
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
const Char_8 code[] = "\033[2J\033[1;1H";
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, code, sizeof(code));
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to clear console with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < sizeof(code));
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void Console::SetTitle_32(const Str_32& title)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (!SetConsoleTitleW(UTF::To_16(title)))
|
||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_32 code = U"\033]0;" + title + U"\007";
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, code, code.Size(true));
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < code.Size(true));
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void Console::SetTitle_16(const Str_16& title)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (!SetConsoleTitleW(title))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_16 code = L"\033]0;" + title + L"\007";
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, code, code.Size(true));
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < code.Size(true));
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void Console::SetTitle_8(const Str_8& title)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
if (!SetConsoleTitleW(UTF::To_16(title)))
|
||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
Str_8 code = "\033]0;" + title + "\007";
|
||
|
UInt_64 offset = 0;
|
||
|
do {
|
||
|
ssize_t written = write(hdlOut, code, code.Size());
|
||
|
if (written == -1)
|
||
|
{
|
||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||
|
return;
|
||
|
}
|
||
|
offset += written;
|
||
|
}
|
||
|
while (offset < code.Size());
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Str_32 Console::GetTitle_32()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
Str_16 title(EHS_MAX_PATH);
|
||
|
|
||
|
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
||
|
|
||
|
title.Resize(size);
|
||
|
|
||
|
return UTF::To_32(title);
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Str_16 Console::GetTitle_16()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
Str_16 title(EHS_MAX_PATH);
|
||
|
|
||
|
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
||
|
|
||
|
title.Resize(size);
|
||
|
|
||
|
return title;
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Str_8 Console::GetTitle_8()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
Str_16 title(EHS_MAX_PATH);
|
||
|
|
||
|
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
||
|
|
||
|
title.Resize(size);
|
||
|
|
||
|
return UTF::To_8(title);
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Vector<Str_32> Console::GetArgs_32(const UInt_64 bufferSize)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
return UTF::To_32(GetCommandLineW()).Split(U" ");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
||
|
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
||
|
cmdFile.Release();
|
||
|
|
||
|
Vector<Str_32> args;
|
||
|
|
||
|
UInt_64 o = 0;
|
||
|
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
||
|
{
|
||
|
if (data[i] != '\0')
|
||
|
continue;
|
||
|
|
||
|
|
||
|
|
||
|
args.Push(UTF::To_32((Char_8*)&data[o], i - o));
|
||
|
o = i + sizeof(Char_8);
|
||
|
}
|
||
|
|
||
|
if (o < data.Size())
|
||
|
args.Push(UTF::To_32((Char_8*)&data[o], data.Size() - o - 1));
|
||
|
|
||
|
return args;
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
return Str_16(GetCommandLineW()).Split(L" ");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
||
|
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
||
|
cmdFile.Release();
|
||
|
|
||
|
Vector<Str_16> args;
|
||
|
|
||
|
UInt_64 o = 0;
|
||
|
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
||
|
{
|
||
|
if (data[i] != '\0')
|
||
|
continue;
|
||
|
|
||
|
args.Push(UTF::To_16((Char_8*)&data[o], i - o));
|
||
|
o = i + sizeof(Char_8);
|
||
|
}
|
||
|
|
||
|
if (o < data.Size())
|
||
|
args.Push(UTF::To_16((Char_8*)&data[o], data.Size() - o - 1));
|
||
|
|
||
|
return args;
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize)
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
return UTF::To_8(GetCommandLineW()).Split(" ");
|
||
|
#elif defined(EHS_OS_LINUX)
|
||
|
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
||
|
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
||
|
cmdFile.Release();
|
||
|
|
||
|
Vector<Str_8> args;
|
||
|
|
||
|
UInt_64 o = 0;
|
||
|
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
||
|
{
|
||
|
if (data[i] != '\0')
|
||
|
continue;
|
||
|
|
||
|
args.Push(Str_8((Char_8*)&data[o], i - o));
|
||
|
o = i + sizeof(Char_8);
|
||
|
}
|
||
|
|
||
|
if (o < data.Size())
|
||
|
args.Push(Str_8((Char_8*)&data[o], data.Size() - o - 1));
|
||
|
|
||
|
return args;
|
||
|
#else
|
||
|
return {};
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
void* Console::GetHandle()
|
||
|
{
|
||
|
#if defined(EHS_OS_WINDOWS)
|
||
|
void* hdl = FindWindowW(nullptr, GetTitle_16());
|
||
|
if (hdl == nullptr)
|
||
|
EHS_LOG_INT("Error", 0, "Failed to retrieve native handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||
|
|
||
|
return hdl;
|
||
|
#else
|
||
|
return nullptr;
|
||
|
#endif
|
||
|
}
|
||
|
*/
|
||
|
}
|