Implement unicode on console, move readline into driver

This commit is contained in:
2023-05-18 17:14:55 -04:00
parent 2b03ca2eb6
commit fd137e8e74
12 changed files with 371 additions and 162 deletions

View File

@@ -229,38 +229,51 @@ static void init_winsock() {
}
}
static int console_write(const char *bytes, int nbytes) {
if (nbytes == 0) return 0;
static void console_write(const CodepointString &cps) {
if (cps.size() == 0) return;
// Convert to wstring.
// Any character outside the range 0xFFFF is replaced with a box.
std::wstring ws(cps.size());
for (int i = 0; i < cps.size(); i++) {
char32_t c = cps[i];
if ((c >= 0)&&(c <= 0xFFFF)) ws[i] = (wchar_t)c;
else ws[i] = 0x2610;
}
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
assert(hstdout != INVALID_HANDLE_VALUE);
DWORD nwrote;
if (nbytes > 10000) nbytes = 10000;
assert(WriteConsoleA(hstdout, bytes, nbytes, &nwrote, nullptr));
assert(nwrote > 0);
return nwrote;
std::wstring_view v(ws);
while (v.size() > 0) {
int nwrite = v.size();
if (nwrite > 10000) nwrite = 10000;
assert(WriteConsoleW(hstdout, v.data(), nwrite, &nwrote, nullptr));
assert(nwrote > 0);
v.remove_prefix(nwrote);
}
}
static int console_read(char *bytes, int nbytes) {
static CodepointString console_read() {
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
assert(hstdin != INVALID_HANDLE_VALUE);
INPUT_RECORD inrecords[512];
DWORD nread, nevents;
int nascii = 0;
if (GetNumberOfConsoleInputEvents(hstdin, &nevents)) {
if (int(nevents) > nbytes) nevents = nbytes;
ReadConsoleInputA(hstdin, inrecords, nevents, &nread);
for (int i = 0; i < int(nread); i++) {
const INPUT_RECORD &inr = inrecords[i];
if (inr.EventType != KEY_EVENT) continue;
const KEY_EVENT_RECORD &key = inr.Event.KeyEvent;
if (!key.bKeyDown) continue;
char c = key.uChar.AsciiChar;
bytes[nascii++] = c;
if (int(nevents) > 0) {
if (int(nevents) > 512) nevents = 512;
ReadConsoleInputW(hstdin, inrecords, nevents, &nread);
CodepointString result(nread, 0);
int len = 0;
for (int i = 0; i < int(nread); i++) {
const INPUT_RECORD &inr = inrecords[i];
if (inr.EventType != KEY_EVENT) continue;
const KEY_EVENT_RECORD &key = inr.Event.KeyEvent;
if (!key.bKeyDown) continue;
result[len++] = key.uChar.UnicodeChar;
}
return result.substr(0, len);
}
return nascii;
} else {
return 0;
}
return CodepointString();
}
static void ssl_load_certificate_authorities(SSL_CTX *ctx) {