-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommandLine.cpp
More file actions
148 lines (118 loc) · 4.11 KB
/
Copy pathcommandLine.cpp
File metadata and controls
148 lines (118 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <ios>
#include <sstream>
#include "commandLine.hpp"
#include "xString.hpp"
using std::make_unique, std::unique_ptr;
using std::hex, std::map, std::ostringstream, std::string, std::stringstream, std::to_string, std::wstring;
void CommandLine::setColor(const short color) const {
SetConsoleTextAttribute(console_handle_out, color);
}
void CommandLine::setCursorVisibility(const bool value) const {
const auto info = make_unique<CONSOLE_CURSOR_INFO>();
GetConsoleCursorInfo(console_handle_out, info.get());
info->bVisible = value;
SetConsoleCursorInfo(console_handle_out, info.get());
}
void CommandLine::setConInfo(CONSOLE_SCREEN_BUFFER_INFOEX& info) const {
info.srWindow.Bottom++;
SetConsoleScreenBufferInfoEx(console_handle_out, &info);
}
void CommandLine::setScreenDims(const COORD& dims) const {
const auto info = getConInfo();
info->dwSize = dims;
info->dwMaximumWindowSize = dims;
info->srWindow = {0, 0, dims.X, dims.Y};
setConInfo(*info);
}
void CommandLine::remapColors(const map<int, string>& colorMap) const {
const auto dims = getScreenDims();
const auto info = getConInfo();
stringstream stream;
for (auto& [key, color] : colorMap) {
short red, green, blue;
stream << hex << color.substr(0, 2);
stream >> red;
stream.clear();
stream << hex << color.substr(2, 2);
stream >> green;
stream.clear();
stream << hex << color.substr(4, 2);
stream >> blue;
stream.clear();
info->ColorTable[key] = RGB(red, green, blue);
}
setConInfo(*info);
}
void CommandLine::goTo(const COORD& pos) const {
SetConsoleCursorPosition(console_handle_out, pos);
}
void CommandLine::write(const string& text, const short color, const COORD& pos) const {
const wstring out = xString::toWide(text);
const auto bufferSize = static_cast<short>(out.size());
auto buffer = make_unique<CHAR_INFO[]>(bufferSize);
for (int i = 0; i < bufferSize; ++i) {
buffer[i].Char.UnicodeChar = out.at(i);
buffer[i].Attributes = color;
}
auto writeArea = SMALL_RECT{
pos.X,
pos.Y,
static_cast<short>(pos.X + bufferSize),
static_cast<short>(pos.Y + 1)
};
WriteConsoleOutputW(
console_handle_out,
buffer.get(),
COORD{bufferSize, 1},
COORD{0, 0},
&writeArea);
}
unique_ptr<CONSOLE_SCREEN_BUFFER_INFOEX> CommandLine::getConInfo() const {
auto info = make_unique<CONSOLE_SCREEN_BUFFER_INFOEX>();
info->cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
GetConsoleScreenBufferInfoEx(console_handle_out, info.get());
return info;
}
unique_ptr<COORD> CommandLine::getScreenDims() const {
auto [left, top, right, bottom] = getConInfo()->srWindow;
auto output = make_unique<COORD>(
static_cast<short>(right - left + 1),
static_cast<short>(bottom - top + 1)
);
return output;
}
string CommandLine::getEnvVar(const string& name) {
const auto buffer = make_unique<wchar_t[]>(LINE_SIZE);
GetEnvironmentVariableW(
xString::toWide(name).data(),
buffer.get(),
LINE_SIZE);
string out = xString::fromWide(buffer.get());
return out;
}
string CommandLine::expandEnvironmentVariables(const string& in) {
ostringstream out;
size_t offset = 0, i, percent1 = 44170;
auto expanded = false;
while ((i = in.find('%', offset)) != string::npos) {
expanded = true;
//Look for the 1st appearance of %
if (percent1 == 44170) {
percent1 = i; //First appearance of %
//Save everything before the char to the stream
out << in.substr(offset, i - offset);
offset = i + 1;
}
else {
const size_t percent2 = i; //Second appearance of %
offset = i + 1;
auto variable = in.substr(percent1 + 1, percent2 - percent1 - 1);
out << getEnvVar(variable);
percent1 = 44170;
}
}
out << in.substr(offset, in.size());
if (expanded)
return expandEnvironmentVariables(out.str());
return out.str();
}