Fix license compliance and fix things up

This commit is contained in:
2026-07-31 18:51:17 -05:00
parent bd0587779e
commit 313e75b14c
149 changed files with 8310 additions and 5093 deletions
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+484 -35
View File
@@ -1,26 +1,45 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Console.hpp"
#include "TessesFramework/Http/HttpUtils.hpp"
#include "TessesFramework/Text/StringConverter.hpp"
#if __has_include(<termios.h>)
#if defined(__SWITCH__)
extern "C" {
#include <switch.h>
}
#elif defined(GEKKO)
#include <gccore.h>
#include <ogc/pad.h>
#if defined(HW_RVL)
#include <wiikeyboard/keyboard.h>
#include <wiikeyboard/usbkeyboard.h>
#include <wiiuse/wpad.h>
#endif
#elif __has_include(<termios.h>)
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
@@ -33,13 +52,16 @@
#include <limits>
namespace Tesses::Framework {
#if defined(__SWITCH__)
extern bool initedConsole;
extern PadState default_pad;
constexpr int CONSOLE_READ_BUFFER_MAX = 32768;
#endif
class ConsoleHelpers {
bool canon;
bool echo;
bool signals;
#if defined(_WIN32)
WORD colorFlags;
@@ -47,9 +69,14 @@ class ConsoleHelpers {
public:
ConsoleHelpers() {
canon = Console::GetCanonical();
echo = Console::GetEcho();
signals = Console::GetSignals();
#if defined(HW_RVL)
KEYBOARD_Init(NULL);
#endif
#if defined(_WIN32)
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
@@ -82,11 +109,16 @@ class ConsoleHelpers {
Console::SetEcho(echo);
Console::SetSignals(signals);
reset();
#if defined(HW_RVL)
KEYBOARD_Deinit();
#endif
}
};
ConsoleHelpers consoleHelpers;
size_t Console::List(std::vector<std::string> &strs) {
if (!IsTTY())
return std::string::npos;
@@ -123,7 +155,77 @@ size_t Console::List(std::vector<std::string> &strs) {
}
Console::SetInvertedColors(false);
#if defined(__SWITCH__)
if (!appletMainLoop()) {
TF_Quit();
break;
}
padUpdate(&default_pad);
u64 kDown = padGetButtonsDown(&default_pad);
if (kDown & HidNpadButton_AnyUp) {
i--;
if (i >= strs.size())
i = strs.size() - 1;
} else if (kDown & HidNpadButton_AnyDown) {
i++;
if (i >= strs.size())
i = 0;
} else if (kDown & HidNpadButton_A) {
break;
}
consoleUpdate(NULL);
#elif defined(GEKKO)
PAD_ScanPads();
bool down = false;
bool up = false;
bool a = false;
bool exit = false;
auto gcdown = PAD_ButtonsDown(PAD_CHAN0);
if (gcdown & PAD_BUTTON_DOWN)
down = true;
if (gcdown & PAD_BUTTON_UP)
up = true;
if (gcdown & PAD_BUTTON_A)
a = true;
if (gcdown & PAD_BUTTON_START)
exit = true;
#if defined(HW_RVL)
WPAD_ScanPads();
auto wiidown = WPAD_ButtonsDown(WPAD_CHAN_0);
if (wiidown & WPAD_BUTTON_UP)
up = true;
if (wiidown & WPAD_BUTTON_DOWN)
down = true;
if (wiidown & WPAD_BUTTON_A)
a = true;
if (wiidown & WPAD_BUTTON_PLUS)
exit = true;
#endif
if (up) {
i--;
if (i >= strs.size())
i = strs.size() - 1;
} else if (down) {
i++;
if (i >= strs.size())
i = 0;
} else if (a) {
break;
} else if (exit) {
TF_Quit();
break;
}
VIDEO_WaitVSync();
#else
int code = Console::Read();
if (code == 10)
@@ -148,16 +250,52 @@ size_t Console::List(std::vector<std::string> &strs) {
} else if (code == -1)
break;
}
#endif
}
Console::SetEcho(echo);
Console::SetCanonical(canonical);
Console::SetInvertedColors(false);
#if defined(__SWITCH__)
consoleUpdate(NULL);
#endif
return i;
}
void Console::Reset() { consoleHelpers.reset(); }
#if defined(GEKKO)
static bool vt100_inverted = false;
#if defined(_WIN32)
static ConsoleColor fg_color = ConsoleColor::CC_WHITE;
static ConsoleColor bg_color = ConsoleColor::CC_BLACK;
static bool fg_intense = false;
static bool bg_intense = false;
#if defined(HW_RVL)
static bool wii_echo = true;
static bool wii_cannon = true;
#endif
static void _setcol(ConsoleColor col, bool alt, bool bg) {
if (bg) {
bg_color = col;
bg_intense = alt;
if (alt) {
printf("\x1b[%im", ((int)col) + 100); // this should be Write
} else {
printf("\x1b[%im", ((int)col) + 40); // this too
}
} else {
fg_color = col;
fg_intense = alt;
if (alt) {
printf("\x1b[%im", ((int)col) + 90); // this should be Write
} else {
printf("\x1b[%im", ((int)col) + 30); // this too
}
}
}
#elif defined(_WIN32)
static bool vt100_inverted = false;
static void _setcol(ConsoleColor col, bool alt, bool bg) {
if (bg) {
@@ -219,12 +357,22 @@ static void _setcol(ConsoleColor col, bool alt, bool bg) {
}
#endif
void Console::Reset() {
#if defined(GEKKO)
vt100_inverted = false;
Console::SetBackgroundColor(ConsoleColor::CC_BLACK, false);
Console::SetForegroundColor(ConsoleColor::CC_WHITE, false);
#elif defined(_WIN32)
vt100_inverted = false;
#endif
consoleHelpers.reset();
}
void Console::SetForegroundColor(ConsoleColor col, bool alt) {
if (!IsTTY())
return;
#if defined(_WIN32)
#if defined(_WIN32) || defined(GEKKO)
_setcol(col, alt, vt100_inverted);
@@ -241,7 +389,7 @@ void Console::SetBackgroundColor(ConsoleColor col, bool alt) {
if (!IsTTY())
return;
#if defined(_WIN32)
#if defined(_WIN32) || defined(GEKKO)
_setcol(col, alt, !vt100_inverted);
#else
if (alt) {
@@ -255,7 +403,30 @@ void Console::SetBackgroundColor(ConsoleColor col, bool alt) {
void Console::SetInvertedColors(bool inverted) {
if (!IsTTY())
return;
#if defined(_WIN32)
#if defined(GEKKO)
if (inverted != vt100_inverted) {
auto tmpC = fg_color;
auto tmpI = fg_intense;
fg_color = bg_color;
fg_intense = bg_intense;
bg_color = tmpC;
bg_intense = tmpI;
vt100_inverted = inverted;
if (bg_intense) {
printf("\x1b[%im", ((int)bg_color) + 100); // this should be Write
} else {
printf("\x1b[%im", ((int)bg_color) + 40); // this too
}
if (fg_intense) {
printf("\x1b[%im", ((int)fg_color) + 90); // this should be Write
} else {
printf("\x1b[%im", ((int)fg_color) + 30); // this too
}
}
#elif defined(_WIN32)
if (inverted != vt100_inverted) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
@@ -290,7 +461,15 @@ void Console::SetInvertedColors(bool inverted) {
bool Console::SetEcho(bool echo) {
if (!IsTTY())
return false;
#if __has_include(<termios.h>)
#if defined(__SWITCH__) || defined(GEKKO)
#if defined(HW_RVL)
wii_echo = echo;
return true;
#else
return false;
#endif
#elif __has_include(<termios.h>)
struct termios raw;
if (tcgetattr(0, &raw) != 0)
return false;
@@ -302,7 +481,7 @@ bool Console::SetEcho(bool echo) {
if (tcsetattr(0, TCSAFLUSH, &raw) != 0)
return false;
return true;
#elif defined(_WIN32)
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
if (hConsole == INVALID_HANDLE_VALUE)
@@ -323,7 +502,13 @@ bool Console::SetEcho(bool echo) {
bool Console::GetEcho() {
if (!IsTTY())
return false;
#if __has_include(<termios.h>)
#if defined(__SWITCH__) || defined(GEKKO)
#if defined(HW_RVL)
return wii_echo;
#else
return false;
#endif
#elif __has_include(<termios.h>)
struct termios raw;
if (tcgetattr(0, &raw) != 0)
@@ -345,7 +530,13 @@ bool Console::GetEcho() {
bool Console::GetCanonical() {
if (!IsTTY())
return false;
#if __has_include(<termios.h>)
#if defined(__SWITCH__) || defined(GEKKO)
#if defined(HW_RVL)
return wii_cannon;
#else
return true;
#endif
#elif __has_include(<termios.h>)
struct termios raw;
if (tcgetattr(0, &raw) != 0)
return false;
@@ -365,7 +556,14 @@ bool Console::GetCanonical() {
bool Console::SetCanonical(bool can) {
if (!IsTTY())
return false;
#if __has_include(<termios.h>)
#if defined(__SWITCH__) || defined(GEKKO)
#if defined(HW_RVL)
wii_cannon = can;
return true;
#else
return false;
#endif
#elif __has_include(<termios.h>)
struct termios raw;
if (tcgetattr(0, &raw) != 0)
return false;
@@ -399,7 +597,9 @@ bool Console::SetCanonical(bool can) {
bool Console::GetSignals() {
if (!IsTTY())
return true;
#if __has_include(<termios.h>)
#if defined(__SWITCH__) || defined(GEKKO)
return false;
#elif __has_include(<termios.h>)
struct termios raw;
if (tcgetattr(0, &raw) != 0)
return false;
@@ -411,7 +611,9 @@ bool Console::GetSignals() {
bool Console::SetSignals(bool sig) {
if (!IsTTY())
return false;
#if __has_include(<termios.h>)
#if defined(__SWITCH__) || defined(GEKKO)
return false;
#elif __has_include(<termios.h>)
struct termios raw;
if (tcgetattr(0, &raw) != 0)
return false;
@@ -431,6 +633,33 @@ bool Console::SetSignals(bool sig) {
// ISIG
std::string Console::ReadPassword() {
#if defined(__SWITCH__)
consoleUpdate(NULL);
// bring up nx keyboard
SwkbdConfig kbd;
Result rc = swkbdCreate(&kbd, 0);
if (R_SUCCEEDED(rc)) {
swkbdConfigMakePresetPassword(&kbd);
char *text = new char[CONSOLE_READ_BUFFER_MAX];
rc = swkbdShow(&kbd, text, CONSOLE_READ_BUFFER_MAX);
if (R_SUCCEEDED(rc)) {
swkbdClose(&kbd);
std::string str = text;
delete[] text;
Console::WriteLine("");
return str;
}
delete[] text;
swkbdClose(&kbd);
}
Console::WriteLine("");
return "";
#else
bool echo = GetEcho();
if (!SetEcho(false)) {
Write("\nWARN: the password will be visible: ");
@@ -440,6 +669,7 @@ std::string Console::ReadPassword() {
Write("\n");
return text;
#endif
}
#if defined(_WIN32)
@@ -447,8 +677,72 @@ thread_local std::string key;
thread_local int keyOffset = -1;
#endif
#if defined(HW_RVL)
static std::vector<char> keybuffer;
static bool ready = false;
static bool amEof = false;
static int read_char_wiikeyboard() {
if (Console::GetCanonical()) {
if (ready && keybuffer.empty())
ready = false;
if (!ready) {
if (amEof)
return -1;
while (1) {
auto val = fgetc(stdin);
if (val == 127 || val == 8) {
keybuffer.pop_back();
if (Console::GetEcho())
printf("\x08");
} else if (val == '\n') {
if (Console::GetEcho())
printf("\n");
keybuffer.push_back('\n');
ready = true;
break;
} else if (val == -1) {
ready = true;
amEof = true;
break;
} else {
keybuffer.push_back((char)val);
if (Console::GetEcho())
printf("%c", (char)val);
}
}
}
if (ready) {
char c = keybuffer.front();
keybuffer.erase(keybuffer.begin());
return c;
}
} else {
int c = fgetc(stdin);
if (c == -1)
return -1;
if (Console::GetEcho())
printf("%c", (char)c);
return c;
}
}
#endif
int Console::Read() {
#if defined(WIN32)
#if defined(__SWITCH__) || defined(GEKKO)
#if defined(HW_RVL)
if (USBKeyboard_IsConnected()) {
return read_char_wiikeyboard();
}
#endif
return -1;
#elif defined(WIN32)
if (keyOffset >= 0 && keyOffset < key.size()) {
return (int)key[keyOffset++];
} else {
@@ -609,6 +903,48 @@ int Console::Read() {
}
std::string Console::ReadLine() {
#if defined(GEKKO)
#if defined(HW_RVL)
if (USBKeyboard_IsConnected()) {
std::string text;
while (true) {
int chr = read_char_wiikeyboard();
if (chr == '\n' || chr == -1)
break;
else
text.push_back((char)chr);
}
return text;
}
#endif
return "";
#elif defined(__SWITCH__)
consoleUpdate(NULL);
// bring up nx keyboard
SwkbdConfig kbd;
Result rc = swkbdCreate(&kbd, 0);
if (R_SUCCEEDED(rc)) {
swkbdConfigMakePresetDefault(&kbd);
// swkbdConfigMakePresetPassword(&kbd);
char *text = new char[CONSOLE_READ_BUFFER_MAX];
rc = swkbdShow(&kbd, text, CONSOLE_READ_BUFFER_MAX);
if (R_SUCCEEDED(rc)) {
swkbdClose(&kbd);
std::string str = text;
delete[] text;
Console::WriteLine(str);
return str;
}
delete[] text;
swkbdClose(&kbd);
}
Console::WriteLine("");
return "";
#else
std::string text;
int c = Read();
while (c != '\n' && c != -1) {
@@ -619,6 +955,7 @@ std::string Console::ReadLine() {
if (!text.empty() && text.back() == '\r')
text.resize(text.size() - 1);
return text;
#endif
}
#if defined(_WIN32)
void writeTextWin32(HANDLE hndl, const std::string &text) {
@@ -651,7 +988,100 @@ void writeTextUnix(FILE *f, std::string_view view) {
}
#endif
void Console::WriteToStream(std::string_view view, bool isStderr) {
#if defined(_WIN32)
#if defined(GEKKO) // BECAUSE GEKKO's console doesn't allow you to switch chars,
// we must emulate
std::string text;
for (size_t i = 0; i < view.size(); ++i) {
if (view[i] == '\x1b') {
if (!text.empty()) {
writeTextUnix(isStderr ? stderr : stdout, text);
// fwrite(text.c_str(), 1, text.size(), f);
text.clear();
}
i++;
if (i < view.size()) {
if (view[i] == '[') {
i++;
for (; i < view.size(); ++i) {
text += view[i];
if (view[i] >= 0x40 && view[i] <= 0x7e)
break;
}
if (text.size() > 0 && text.back() == 'H') {
MoveToHome();
}
if (text.size() > 0 && text.back() == 'J') {
if (text[0] == '2') {
ClearRetainPosition(
ClearBehaviour::CB_ENTIRESCREEN);
}
if (text[0] == '1') {
ClearRetainPosition(
ClearBehaviour::CB_CURSORANDABOVE);
}
if (text[0] == '0') {
ClearRetainPosition(
ClearBehaviour::CB_CURSORANDBELOW);
}
}
if (text.size() > 0 && text.back() == 'm') {
if (text.size() == 1) {
consoleHelpers.reset();
} else {
try {
auto num =
std::stol(text.substr(0, text.size() - 1));
if (num == 0)
consoleHelpers.reset();
if (num == 7)
Console::SetInvertedColors(true);
if (num == 27)
Console::SetInvertedColors(false);
if (num >= 30 && num <= 37) {
SetForegroundColor((ConsoleColor)(num - 30),
false);
} else if (num >= 40 && num <= 47) {
SetBackgroundColor((ConsoleColor)(num - 40),
false);
} else if (num >= 90 && num <= 97) {
SetForegroundColor((ConsoleColor)(num - 90),
true);
} else if (num >= 100 && num <= 107) {
SetBackgroundColor(
(ConsoleColor)(num - 100), true);
}
} catch (...) {
}
}
}
text.clear();
} else {
text += "\x1B";
text += view[i];
}
}
} else if (view[i] == '\n') {
text += "\r\n";
writeTextUnix(isStderr ? stderr : stdout, text);
text.clear();
} else {
text += view[i];
}
}
if (!text.empty()) {
writeTextUnix(isStderr ? stderr : stdout, text);
text.clear();
}
#elif defined(_WIN32)
HANDLE hOut = GetStdHandle(isStderr ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
return;
@@ -777,7 +1207,9 @@ void Console::ErrorLineView(std::string_view view) {
}
void Console::ErrorView(std::string_view view) { WriteToStream(view, true); }
bool Console::IsTTY() {
#if defined(_WIN32)
#if defined(GEKKO) || defined(__SWITCH__)
return true;
#elif defined(_WIN32)
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
return false;
@@ -829,8 +1261,16 @@ void Console::ProgressBar(int v) { ProgressBar((double)v / 100.0); }
std::pair<int, int> Console::GetSize() {
if (!Console::IsTTY())
return std::pair<int, int>(0, 0);
#if __has_include(<termios.h>)
#if defined(GEKKO)
int w, h;
CON_GetMetrics(&w, &h);
return std::pair<int, int>(w, h);
#elif defined(__SWITCH__)
PrintConsole *console = consoleGetDefault();
if (console == nullptr)
return std::pair<int, int>(0, 0);
return std::pair<int, int>(console->consoleWidth, console->consoleHeight);
#elif __has_include(<termios.h>)
struct winsize ws;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) {
return std::make_pair<int, int>(ws.ws_col, ws.ws_row);
@@ -854,7 +1294,7 @@ std::pair<int, int> Console::GetSize() {
void Console::SetPosition(int x, int y) {
if (!IsTTY())
return;
#if __has_include(<termios.h>)
#if __has_include(<termios.h>) || defined(__SWITCH__) || defined(GEKKO)
printf("\x1B[%i;%iH", y + 1, x + 1);
#elif defined(_WIN32)
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -876,7 +1316,10 @@ void Console::Clear() {
}
void Console::ClearRetainPosition(ClearBehaviour cb) {
#if __has_include(<termios.h>)
#if defined(GEKKO) || defined(__SWITCH__)
printf("\x1b[%iJ", (int)cb);
Flush();
#elif __has_include(<termios.h>)
if (isatty(STDOUT_FILENO)) {
printf("\x1b[%iJ", (int)cb);
Flush();
@@ -946,7 +1389,13 @@ void Console::ClearRetainPosition(ClearBehaviour cb) {
#endif
}
void Console::MoveToHome() {
#if __has_include(<termios.h>)
#if defined(GEKKO)
printf("\x1b[h");
fflush(stdout);
#elif defined(__SWITCH__)
Write("\x1b[H");
Flush();
#elif __has_include(<termios.h>)
if (isatty(STDOUT_FILENO)) {
Write("\x1b[H");
Flush();
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+6 -8
View File
@@ -27,16 +27,17 @@
#include <sstream>
using namespace std::chrono;
using namespace date;
#if defined(__FreeBSD__)
extern int tf_timezone;
extern bool tf_daylight;
#endif
namespace Tesses::Framework::Date {
int GetTimeZone() {
#if defined(__SWITCH__) || defined(_WIN32) || defined(GEKKO) || defined(__PS2__)
return (int)(-_timezone);
#elif defined(__FreeBSD__)
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return (tz.tz_minuteswest / 60);
return tf_timezone;
#else
return (int)(-timezone);
#endif
@@ -45,10 +46,7 @@ bool TimeZoneSupportDST() {
#if defined(__SWITCH__) || defined(_WIN32) || defined(GEKKO) || defined(__PS2__)
return _daylight == 1;
#elif defined(__FreeBSD__)
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
return tz.tz_dsttime != 0;
return tf_daylight;
#else
return daylight == 1;
#endif
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+7 -3
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -241,7 +244,7 @@ void LocalFilesystem::Chmod(VFSPath path, uint32_t mode) {
}
void LocalFilesystem::Chown(VFSPath path, uint32_t uid, uint32_t gid) {
auto pathStr = this->VFSPathToSystem(path);
#if defined(_WIN32)
#if defined(_WIN32) || defined(GEKKO) || defined(__SWITCH__)
#else
chown(pathStr.c_str(), (uid_t)uid, (gid_t)gid);
@@ -250,7 +253,8 @@ void LocalFilesystem::Chown(VFSPath path, uint32_t uid, uint32_t gid) {
FIFOCreationResult LocalFilesystem::CreateFIFO(VFSPath path, uint32_t mod) {
auto pathStr = this->VFSPathToSystem(path);
#if defined(_WIN32)
#if defined(_WIN32) || defined(GEKKO) || defined(__SWITCH__)
return FIFOCreationResult::Unsupported;
#else
int res = mkfifo(pathStr.c_str(), (mode_t)mod);
+21
View File
@@ -1,3 +1,24 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Filesystem/MountableFilesystem.hpp"
#include "TessesFramework/Filesystem/NullFilesystem.hpp"
#include <iostream>
+21
View File
@@ -1,3 +1,24 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Filesystem/NullFilesystem.hpp"
namespace Tesses::Framework::Filesystem {
+21
View File
@@ -1,3 +1,24 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Filesystem/RelativeFilesystem.hpp"
namespace Tesses::Framework::Filesystem {
+21
View File
@@ -1,3 +1,24 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Filesystem/SubdirFilesystem.hpp"
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include <iostream>
+21
View File
@@ -1,3 +1,24 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Filesystem/TempFS.hpp"
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Filesystem/SubdirFilesystem.hpp"
+21
View File
@@ -1,3 +1,24 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Filesystem/VFS.hpp"
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Http/HttpUtils.hpp"
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+16 -14
View File
@@ -963,8 +963,8 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last&
inline namespace literals
{
CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT;
CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT;
CONSTCD11 date::day operator ""_d(unsigned long long d) NOEXCEPT;
CONSTCD11 date::year operator ""_y(unsigned long long y) NOEXCEPT;
} // inline namespace literals
#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
@@ -1972,7 +1972,7 @@ inline namespace literals
CONSTCD11
inline
date::day
operator "" _d(unsigned long long d) NOEXCEPT
operator ""_d(unsigned long long d) NOEXCEPT
{
return date::day{static_cast<unsigned>(d)};
}
@@ -1980,7 +1980,7 @@ operator "" _d(unsigned long long d) NOEXCEPT
CONSTCD11
inline
date::year
operator "" _y(unsigned long long y) NOEXCEPT
operator ""_y(unsigned long long y) NOEXCEPT
{
return date::year(static_cast<int>(y));
}
@@ -6784,7 +6784,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
checked_set(m, static_cast<int>(i % 12 + 1), not_a_month, is);
ws(is);
int td = not_a_day;
read(is, rs{td, 1, 2});
read(is, ru{td, 1, 2});
checked_set(d, td, not_a_day, is);
ws(is);
using dfs = detail::decimal_format_seconds<Duration>;
@@ -6800,7 +6800,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
not_a_second, is);
ws(is);
int tY = not_a_year;
read(is, rs{tY, 1, 4u});
// No need for `rs` here, negative years can't parse
// with "%c" since `width` is hardcoded to 4
read(is, ru{tY, 1, 4u});
checked_set(Y, tY, not_a_year, is);
#endif
}
@@ -6834,7 +6836,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
int tm = not_a_month;
int td = not_a_day;
read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'},
rs{ty, 1, 2});
ru{ty, 1, 2});
checked_set(y, ty, not_a_2digit_year, is);
checked_set(m, tm, not_a_month, is);
checked_set(d, td, not_a_day, is);
@@ -6930,7 +6932,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
int ty = not_a_2digit_year;
read(is, ru{tn, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
rs{ty, 1, 2});
ru{ty, 1, 2});
checked_set(y, ty, not_a_2digit_year, is);
checked_set(m, tn, not_a_month, is);
checked_set(d, td, not_a_day, is);
@@ -6978,7 +6980,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
#endif
{
int td = not_a_day;
read(is, rs{td, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
read(is, ru{td, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
checked_set(d, td, not_a_day, is);
}
#if !ONLY_C_LOCALE
@@ -7042,7 +7044,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
{
int tI = not_a_hour_12_value;
// reads in an hour into I, but most be in [1, 12]
read(is, rs{tI, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
read(is, ru{tI, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
if (!(1 <= tI && tI <= 12))
is.setstate(ios::failbit);
checked_set(I, tI, not_a_hour_12_value, is);
@@ -7116,7 +7118,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
#endif
{
int tn = not_a_month;
read(is, rs{tn, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
read(is, ru{tn, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
checked_set(m, tn, not_a_month, is);
}
#if !ONLY_C_LOCALE
@@ -7536,7 +7538,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
}
if (modified == CharT{})
{
read(is, rs{tH, 2, 2});
read(is, ru{tH, 2, 2});
if (!is.fail())
toff = hours{std::abs(tH)};
if (is.good())
@@ -7556,7 +7558,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
}
else
{
read(is, rs{tH, 1, 2});
read(is, ru{tH, 1, 2});
if (!is.fail())
toff = hours{std::abs(tH)};
if (is.good())
@@ -7575,7 +7577,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
}
}
}
if (neg)
if (neg && !is.fail())
toff = -toff;
checked_set(temp_offset, toff, not_a_offset, is);
command = nullptr;
+4 -4
View File
@@ -758,8 +758,8 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last&
inline namespace literals
{
CONSTCD11 islamic::day operator "" _d(unsigned long long d) NOEXCEPT;
CONSTCD11 islamic::year operator "" _y(unsigned long long y) NOEXCEPT;
CONSTCD11 islamic::day operator ""_d(unsigned long long d) NOEXCEPT;
CONSTCD11 islamic::year operator ""_y(unsigned long long y) NOEXCEPT;
} // inline namespace literals
#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
@@ -1339,7 +1339,7 @@ inline namespace literals
CONSTCD11
inline
islamic::day
operator "" _d(unsigned long long d) NOEXCEPT
operator ""_d(unsigned long long d) NOEXCEPT
{
return islamic::day{static_cast<unsigned>(d)};
}
@@ -1347,7 +1347,7 @@ operator "" _d(unsigned long long d) NOEXCEPT
CONSTCD11
inline
islamic::year
operator "" _y(unsigned long long y) NOEXCEPT
operator ""_y(unsigned long long y) NOEXCEPT
{
return islamic::year(static_cast<int>(y));
}
+2 -2
View File
@@ -747,7 +747,7 @@ inline namespace literals
CONSTCD11
inline
iso_week::year
operator "" _y(unsigned long long y) NOEXCEPT
operator ""_y(unsigned long long y) NOEXCEPT
{
return iso_week::year(static_cast<int>(y));
}
@@ -755,7 +755,7 @@ operator "" _y(unsigned long long y) NOEXCEPT
CONSTCD11
inline
iso_week::weeknum
operator "" _w(unsigned long long wn) NOEXCEPT
operator ""_w(unsigned long long wn) NOEXCEPT
{
return iso_week::weeknum(static_cast<unsigned>(wn));
}
+4 -4
View File
@@ -758,8 +758,8 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last&
inline namespace literals
{
CONSTCD11 julian::day operator "" _d(unsigned long long d) NOEXCEPT;
CONSTCD11 julian::year operator "" _y(unsigned long long y) NOEXCEPT;
CONSTCD11 julian::day operator ""_d(unsigned long long d) NOEXCEPT;
CONSTCD11 julian::year operator ""_y(unsigned long long y) NOEXCEPT;
// CONSTDATA julian::month jan{1};
// CONSTDATA julian::month feb{2};
@@ -1333,7 +1333,7 @@ inline namespace literals
CONSTCD11
inline
julian::day
operator "" _d(unsigned long long d) NOEXCEPT
operator ""_d(unsigned long long d) NOEXCEPT
{
return julian::day{static_cast<unsigned>(d)};
}
@@ -1341,7 +1341,7 @@ operator "" _d(unsigned long long d) NOEXCEPT
CONSTCD11
inline
julian::year
operator "" _y(unsigned long long y) NOEXCEPT
operator ""_y(unsigned long long y) NOEXCEPT
{
return julian::year(static_cast<int>(y));
}
+4 -4
View File
@@ -792,8 +792,8 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last&
inline namespace literals
{
CONSTCD11 solar_hijri::day operator "" _d(unsigned long long d) NOEXCEPT;
CONSTCD11 solar_hijri::year operator "" _y(unsigned long long y) NOEXCEPT;
CONSTCD11 solar_hijri::day operator ""_d(unsigned long long d) NOEXCEPT;
CONSTCD11 solar_hijri::year operator ""_y(unsigned long long y) NOEXCEPT;
} // inline namespace literals
#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
@@ -1364,7 +1364,7 @@ inline namespace literals
CONSTCD11
inline
solar_hijri::day
operator "" _d(unsigned long long d) NOEXCEPT
operator ""_d(unsigned long long d) NOEXCEPT
{
return solar_hijri::day{static_cast<unsigned>(d)};
}
@@ -1372,7 +1372,7 @@ operator "" _d(unsigned long long d) NOEXCEPT
CONSTCD11
inline
solar_hijri::year
operator "" _y(unsigned long long y) NOEXCEPT
operator ""_y(unsigned long long y) NOEXCEPT
{
return solar_hijri::year(static_cast<int>(y));
}
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+8 -4
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -72,7 +75,7 @@ void StreamHttpRequestBody::Write(
this->strm->CopyTo(strm);
}
StreamHttpRequestBody::~StreamHttpRequestBody() {}
HttpRequest::HttpRequest() {
HttpRequest::HttpRequest() : requestHeaders(false) {
this->body = nullptr;
this->followRedirects = true;
this->ignoreSSLErrors = false;
@@ -151,7 +154,8 @@ HttpResponse::GetInternalStream() {
HttpResponse::~HttpResponse() {}
HttpResponse::HttpResponse(std::shared_ptr<Stream> strm) {
HttpResponse::HttpResponse(std::shared_ptr<Stream> strm)
: responseHeaders(false) {
this->handleStrm = nullptr;
StreamReader reader(strm);
std::string statusLine;
@@ -176,7 +180,7 @@ HttpResponse::HttpResponse(std::shared_ptr<Stream> strm) {
this->handleStrm = strm;
}
HttpResponse::HttpResponse(HttpRequest &req) {
HttpResponse::HttpResponse(HttpRequest &req) : responseHeaders(false) {
this->handleStrm = nullptr;
std::string url = req.url;
+62 -77
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -349,71 +352,6 @@ class WSServer {
}
};
/*
static int _header_field(multipart_parser* p, const char *at, size_t length)
{
UploadData* data = static_cast<UploadData*>(multipart_parser_get_data(p));
data->currentHeaderKey = std::string(at,length);
return 0;
}
static int _header_value(multipart_parser* p, const char *at, size_t length)
{
UploadData* data = static_cast<UploadData*>(multipart_parser_get_data(p));
data->currentHeaders.AddValue(data->currentHeaderKey,
std::string(at,length)); std::cout << data->currentHeaderKey << ": " <<
std::string(at,length) << std::endl; return 0;
}
static int _part_begin(multipart_parser* p)
{
UploadData* data = static_cast<UploadData*>(multipart_parser_get_data(p));
std::string cd0;
ContentDisposition cd1;
std::string ct;
if(!data->currentHeaders.TryGetFirst("Content-Type",ct))
ct = "application/octet-stream";
if(data->currentHeaders.TryGetFirst("Content-Disposition", cd0) &&
ContentDisposition::TryParse(cd0,cd1))
{
if(cd1.filename.empty())
{
data->isFile=false;
data->key = cd1.fieldName;
data->currentBody = new MemoryStream(true);
}
else
{
data->isFile = true;
data->currentBody = data->cb(ct, cd1.filename, cd1.fieldName);
}
}
return 0;
}
static int _part_end(multipart_parser* p)
{
UploadData* data = static_cast<UploadData*>(multipart_parser_get_data(p));
if(data->currentBody == nullptr) return 0;
if(data->isFile)
{
delete data->currentBody;
data->currentBody = nullptr;
}
else
{
MemoryStream* ms = dynamic_cast<MemoryStream*>(data->currentBody);
if(ms != nullptr)
{
ms->Seek(0, SeekOrigin::Begin);
auto& buff = ms->GetBuffer();
data->ctx->queryParams.AddValue(data->key,
std::string(buff.begin(),buff.end()));
}
delete data->currentBody;
data->currentBody=nullptr;
}
data->currentHeaders.Clear();
return 0;
}*/
std::string ServerContext::GetUrlWithQuery() {
if (this->queryParams.kvp.empty())
return this->path;
@@ -470,6 +408,8 @@ std::string ServerContext::ReadString() {
return {};
}
bool ServerContext::NeedToParseFormData() {
if (method == "GET" || method == "HEAD")
return false;
std::string ct;
if (this->requestHeaders.TryGetFirst("Content-Type", ct)) {
if (ct.find("multipart/form-data") == 0) {
@@ -478,6 +418,13 @@ bool ServerContext::NeedToParseFormData() {
}
return false;
}
/*
* The following function is adapted from SimpleHttp.
* Original C# Source:
* https://github.com/dajuric/simple-http/blob/master/Source/SimpleHTTP/Extensions/Request/RequestExtensions.Multipart.cs
* Original Author: Darko Jurić
* License: MIT
*/
static bool
parseUntillBoundaryEnd(std::shared_ptr<Tesses::Framework::Streams::Stream> src,
std::shared_ptr<Tesses::Framework::Streams::Stream> dest,
@@ -542,13 +489,19 @@ parseUntillBoundaryEnd(std::shared_ptr<Tesses::Framework::Streams::Stream> src,
}
return hasMore;
}
/*
* The following function is adapted from SimpleHttp.
* Original C# Source:
* https://github.com/dajuric/simple-http/blob/master/Source/SimpleHTTP/Extensions/Request/RequestExtensions.Multipart.cs
* Original Author: Darko Jurić
* License: MIT
*/
static bool
parseSection(ServerContext *ctx, std::string boundary,
std::function<std::shared_ptr<Tesses::Framework::Streams::Stream>(
std::string mime, std::string filename, std::string name)>
cb) {
HttpDictionary req;
HttpDictionary req(false);
StreamReader reader(ctx->GetStream());
std::string line;
while (reader.ReadLineHttp(line)) {
@@ -574,8 +527,8 @@ parseSection(ServerContext *ctx, std::string boundary,
parseUntillBoundaryEnd(ctx->GetStream(), ms, boundary);
auto &buff = ms->GetBuffer();
ctx->queryParams.AddValue(cd1.fieldName,
std::string(buff.begin(), buff.end()));
ctx->bodyParams.AddValue(cd1.fieldName,
std::string(buff.begin(), buff.end()));
return retVal;
@@ -591,11 +544,19 @@ parseSection(ServerContext *ctx, std::string boundary,
}
return false;
}
/*
* The following function is adapted from SimpleHttp.
* Original C# Source:
* https://github.com/dajuric/simple-http/blob/master/Source/SimpleHTTP/Extensions/Request/RequestExtensions.Multipart.cs
* Original Author: Darko Jurić
* License: MIT
*/
void ServerContext::ParseFormData(
std::function<std::shared_ptr<Tesses::Framework::Streams::Stream>(
std::string mime, std::string filename, std::string name)>
cb) {
if (method == "GET" || method == "HEAD")
return;
std::string ct;
if (this->requestHeaders.TryGetFirst("Content-Type", ct)) {
if (ct.find("multipart/form-data") != 0) {
@@ -731,13 +692,13 @@ HttpServer::~HttpServer() {
}
}
IHttpServer::~IHttpServer() {}
ServerContext::ServerContext(std::shared_ptr<Stream> strm, bool debug) {
ServerContext::ServerContext(std::shared_ptr<Stream> strm, bool debug)
: queryParams(true), bodyParams(true), pathArguments(true),
requestHeaders(false), responseHeaders(false) {
this->statusCode = OK;
this->strm = strm;
this->debug = debug;
this->sent = false;
this->queryParams.SetCaseSensitive(true);
this->pathArguments.SetCaseSensitive(true);
this->responseHeaders.AddValue("Server", "TessesFrameworkWebServer");
}
std::shared_ptr<Stream> ServerContext::GetStream() { return this->strm; }
@@ -788,6 +749,16 @@ ServerContext::~ServerContext() {
}
}
ServerContextData::~ServerContextData() {}
/*
* The following function is inspired or adapted from SimpleHttp.
* I don't remember if I used his range code or not but I am declaring this just
* in case Original C# Source:
* https://github.com/dajuric/simple-http/blob/master/Source/SimpleHTTP/Extensions/Response/ResponseExtensions.PartialStream.cs
*
* Original Author: Darko Jurić
* License: MIT
*/
void ServerContext::SendStream(std::shared_ptr<Stream> strm) {
if (sent)
return;
@@ -1053,7 +1024,20 @@ void HttpServer::Process(std::shared_ptr<Stream> strm,
.SendText("First line is not 3 elements");
return;
}
if (v[0] == "TRACE") {
std::string httpdata = line + "\r\n";
line.clear();
while (reader.ReadLineHttp(line)) {
httpdata += line + "\r\n";
line.clear();
}
ctx.WithMimeType("message/http").SendText(httpdata);
return;
}
ctx.method = v[0];
auto pp = HttpUtils::SplitString(v[1], "?", 2);
pp.resize(2);
@@ -1090,18 +1074,19 @@ void HttpServer::Process(std::shared_ptr<Stream> strm,
std::string type;
int64_t length;
if (ctx.requestHeaders.TryGetFirst("Content-Type", type) &&
if (!(ctx.method == "GET" || ctx.method == "HEAD") &&
ctx.requestHeaders.TryGetFirst("Content-Type", type) &&
type == "application/x-www-form-urlencoded" &&
ctx.requestHeaders.TryGetFirstInt("Content-Length", length)) {
size_t len = (size_t)length;
std::vector<uint8_t> buffer(len);
len = bStrm->ReadBlock(buffer.data(), len);
std::string query((const char *)buffer.data(), len);
HttpUtils::QueryParamsDecode(ctx.queryParams, query);
HttpUtils::QueryParamsDecode(ctx.bodyParams, query);
}
if (!server->Handle(ctx)) {
if ((int)ctx.statusCode < 400)
if ((int)ctx.statusCode == 200)
ctx.SendNotFound();
else
ctx.SendErrorPage(true);
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+9 -9
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -138,7 +141,7 @@ bool Uri::TryParse(std::string url, Uri &uri) {
return true;
}
Uri::Uri() { this->query.SetCaseSensitive(true); }
Uri::Uri() : query(true) {}
std::string Uri::GetPathAndQuery() { return this->path + this->GetQuery(); }
std::string Uri::GetQuery() {
if (this->query.kvp.empty())
@@ -180,7 +183,8 @@ std::string HttpUtils::Replace(std::string text, std::string find,
}
std::string HttpUtils::LeftPad(std::string text, int count, char c) {
if(text.size() >= (size_t)count) return text;
if (text.size() >= (size_t)count)
return text;
text.insert(text.begin(), (size_t)count - text.size(), c);
return text;
@@ -740,14 +744,10 @@ CaseInsensitiveLess::CaseInsensitiveLess() {
this->caseSensitive = false;
this->offset = this;
}
void HttpDictionary::SetCaseSensitive(bool isCaseSensitive) {
HttpDictionary::HttpDictionary(bool isCaseSensitive) {
this->kvp.key_comp().offset->caseSensitive = isCaseSensitive;
}
HttpDictionary::HttpDictionary(bool isCaseSensitive) {
this->SetCaseSensitive(isCaseSensitive);
}
HttpDictionary::HttpDictionary() : HttpDictionary(false) {}
bool HttpDictionary::AnyEquals(std::string key, std::string value) {
if (this->kvp.count(key) > 0)
for (auto v : this->kvp[key])
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+6 -3
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -95,8 +98,8 @@ void RouteServer::Delete(std::string pattern, ServerRequestHandler handler) {
Add("DELETE", pattern, handler);
}
void RouteServer::Trace(std::string pattern, ServerRequestHandler handler) {
Add("TRACE", pattern, handler);
void RouteServer::Query(std::string pattern, ServerRequestHandler handler) {
Add("QUERY", pattern, handler);
}
void RouteServer::Options(std::string pattern, ServerRequestHandler handler) {
Add("OPTIONS", pattern, handler);
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+6 -2
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,8 +28,9 @@
// clang-format off
#include <windows.h>
#include "TessesFramework/Text/StringConverter.hpp"
#include "TessesFramework/Filesystem/VFSFix.hpp"
#include "TessesFramework/Text/StringConverter.hpp"
// clang-format on
using namespace Tesses::Framework::Text::StringConverter;
+5 -3
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,7 +18,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Platform/Process.hpp"
#include "TessesFramework/Http/HttpUtils.hpp"
#include "TessesFramework/Platform/Environment.hpp"
@@ -41,7 +43,7 @@ static void escape_windows_args(std::string &str,
for (auto c : item) {
if (c == '"')
str.append("\\\"");
str.append("\"\"");
else
str.push_back(c);
}
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+44 -64
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,9 +18,11 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/Serialization/Json.hpp"
#include "TessesFramework/Http/HttpUtils.hpp"
#include "TessesFramework/TessesFramework.hpp"
#include "TessesFramework/Text/StringConverter.hpp"
#include <functional>
#include "TessesFramework/Common.hpp"
@@ -126,78 +131,53 @@ JToken Json::Decode(std::string str) {
uint16_t v = 0;
if (i + 4 <= str.size()) {
for (size_t i2 = 0; i2 < 4; i2++, i++) {
if (!((str[i] >= '0' && str[i] <= '9') ||
(str[i] >= 'A' && str[i] <= 'F') ||
(str[i] >= 'a' && str[i] <= 'f')))
throw std::runtime_error(
"Invalid hex value");
v |= HttpUtils::HexToNibble(str[i])
<< ((3 - i2) * 4);
}
i--;
uint32_t v2 = v;
if ((v & 0xFC00) == 0xD800) {
v2 = (v & 0x03FF) << 10;
if (i + 6 <= str.size() &&
str.substr(i, 2) == "\\u") {
i += 2;
v = 0;
for (size_t i2 = 0; i2 < 4; i2++, i++) {
v |= HttpUtils::HexToNibble(str[i])
<< ((3 - i2) * 4);
}
if ((v & 0xFC00) != 0xDC00) {
throw std::runtime_error(
"Not a lower utf-16 surrogate "
"pair.");
}
v2 |= (v & 0x03FF);
v2 += 0x10000;
} else {
std::u16string unicode = {(char16_t)v};
std::string utf8;
if ((v >= 0xD800) && (v <= 0xDBFF)) {
v = 0;
i++;
if (i + 6 > str.size())
throw std::runtime_error(
"Could not read lower utf-16 "
"surrogate pair.");
}
if (v2 <= 0x7F) {
str2.push_back((char)v2);
} else if (v2 >= 0x80 && v2 <= 0x7FF) {
uint8_t high = 0b11000000 |
((v2 >> 6) & 0b00011111);
uint8_t low =
0b10000000 | (v2 & 0b00111111);
str2.push_back((char)high);
str2.push_back((char)low);
} else if (v2 >= 0x800 && v2 <= 0xFFFF) {
uint8_t highest =
0b11100000 |
((v2 >> 12) & 0b00001111);
uint8_t high = 0b10000000 |
((v2 >> 6) & 0b00111111);
uint8_t low =
0b10000000 | (v2 & 0b00111111);
str2.push_back((char)highest);
str2.push_back((char)high);
str2.push_back((char)low);
} else if (v2 >= 0x010000 &&
v2 <= 0x10FFFF) {
uint8_t highest =
0b11110000 |
((v2 >> 18) & 0b00000111);
uint8_t high =
0b10000000 |
((v2 >> 12) & 0b00111111);
uint8_t low = 0b10000000 |
((v2 >> 6) & 0b00111111);
uint8_t lowest =
0b10000000 | (v2 & 0b00111111);
str2.push_back((char)highest);
str2.push_back((char)high);
str2.push_back((char)low);
str2.push_back((char)lowest);
"Not enough chars");
if (str[i] != '\\' || str[i + 1] != 'u')
throw std::runtime_error(
"Low surogate must begin with \\u");
i += 2;
for (size_t i2 = 0; i2 < 4; i2++, i++) {
if (!((str[i] >= '0' &&
str[i] <= '9') ||
(str[i] >= 'A' &&
str[i] <= 'F') ||
(str[i] >= 'a' && str[i] <= 'f')))
throw std::runtime_error(
"Invalid hex value");
v |= HttpUtils::HexToNibble(str[i])
<< ((3 - i2) * 4);
}
i--;
unicode.push_back(v);
}
Text::StringConverter::UTF8::FromUTF16(utf8,
unicode);
str2.append(utf8);
} else {
throw std::runtime_error("Not enough chars");
}
} else {
str2.push_back(str[i]);
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+6 -3
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -40,8 +43,8 @@ using HttpUtils = Tesses::Framework::Http::HttpUtils;
#else
#if defined(_WIN32)
#include <winsock2.h>
#include <iphlpapi.h>
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -886,7 +889,7 @@ void NetworkStream::SetReuseAddress(bool reuse) {}
void NetworkStream::SetReusePort(bool reuse) {}
void NetworkStream::SetMulticastTTL(uint8_t ttl) {}
void NetworkStream::SetMulticastMembership(std::string multicastAddress,
std::string ifaceIP = "0.0.0.0") {}
std::string ifaceIP) {}
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string &ip,
uint16_t &port) {
+19 -23
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,9 +20,8 @@
*/
#include "TessesFramework/Streams/PtyStream.hpp"
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if __has_include(<util.h>)
#include <util.h>
#elif __has_include(<pty.h>)
@@ -29,18 +31,17 @@
#endif
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#endif
namespace Tesses::Framework::Streams {
PtyStream::PtyStream(WindowSize windowSize, std::string filename,
std::vector<std::string> args,
std::vector<std::string> env) {
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
this->wS = windowSize;
this->eos = false;
winsize sz;
@@ -96,9 +97,8 @@ bool PtyStream::CanWrite() { return true; }
size_t PtyStream::Read(uint8_t *buff, size_t sz) {
if (this->eos)
return 0;
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
auto res = read(this->socket, buff, sz);
if (res == -1) {
@@ -112,9 +112,8 @@ size_t PtyStream::Read(uint8_t *buff, size_t sz) {
#endif
}
size_t PtyStream::Write(const uint8_t *buff, size_t sz) {
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
auto res = write(this->socket, buff, sz);
return res;
#else
@@ -123,9 +122,8 @@ size_t PtyStream::Write(const uint8_t *buff, size_t sz) {
}
WindowSize PtyStream::GetWindowSize() { return this->wS; }
void PtyStream::Resize(WindowSize windowSize) {
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
this->wS = windowSize;
winsize sz;
sz.ws_col = (unsigned short)windowSize.Columns;
@@ -140,9 +138,8 @@ PtyStream::~PtyStream() {
if (this->eos)
return;
this->eos = true;
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
close(this->socket);
kill((pid_t)this->pid, SIGHUP);
@@ -152,9 +149,8 @@ void PtyStream::Close() {
if (this->eos)
return;
this->eos = true;
#if !defined(GEKKO) && !defined(__PS2__) && \
!defined(_WIN32) && !defined(__SWITCH__) && \
defined(TESSESFRAMEWORK_ENABLE_PROCESS)
#if !defined(GEKKO) && !defined(__PS2__) && !defined(_WIN32) && \
!defined(__SWITCH__) && defined(TESSESFRAMEWORK_ENABLE_PROCESS)
close(this->socket);
kill((pid_t)this->pid, SIGHUP);
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+20 -10
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,6 +49,9 @@
#if defined(__FreeBSD__)
#include <sys/sysctl.h>
int tf_timezone = 0;
bool tf_daylight = false;
#endif
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
@@ -262,8 +268,7 @@ int64_t TF_Timer_Handle::GetIntervalMilliseconds() {
}
void TF_RunEventLoopItteration() {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && \
(defined(GEKKO) || defined(__SWITCH__))
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(__SWITCH__))
Tesses::Framework::Threading::LookForFinishedThreads();
#endif
@@ -314,8 +319,7 @@ void TF_RunEventLoopItteration() {
void TF_SetIsRunning(bool _isRunning) { isRunning = _isRunning; }
void TF_Quit() {
isRunning = false;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && \
(defined(GEKKO) || defined(__SWITCH__))
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(__SWITCH__))
Tesses::Framework::Threading::JoinAllThreads();
#endif
}
@@ -330,8 +334,15 @@ void TF_Init() {
sqlite3_vfs_register(sqlite3_demovfs(), 1);
#endif
#endif
#if defined(__FreeBSD__)
time_t t = 0;
auto tz = localtime(&t);
tf_timezone = tz->tm_gmtoff;
tf_daylight = tz->tm_isdst;
#else
tzset();
#endif
#if defined(_WIN32)
signal(SIGINT, _sigInt);
signal(SIGTERM, _sigInt);
@@ -510,7 +521,7 @@ std::string TF_GetExecutableName() {
if (sysctl(mib, 4, path.data(), &len, NULL, 0) < 0) {
return "";
}
path.resize(len-1);
path.resize(strlen(path.c_str()));
return path;
#elif defined(__NetBSD__)
auto path = Filesystem::LocalFS->ReadLink(
@@ -526,13 +537,12 @@ std::string TF_GetExecutableName() {
path.resize(1025);
uint32_t bufsize = (uint32_t)path.size();
if (_NSGetExecutablePath(path.data(), &bufsize) == 0) {
path.resize(bufsize-1);
path.resize(strlen(path.c_str()));
return path;
} else {
path.resize(bufsize);
if (_NSGetExecutablePath(path.data(), &bufsize) == 0)
{
path.resize(bufsize-1);
if (_NSGetExecutablePath(path.data(), &bufsize) == 0) {
path.resize(strlen(path.c_str()));
return path;
}
}
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+29 -202
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,228 +20,52 @@
*/
#include "TessesFramework/Text/StringConverter.hpp"
#include "icubaby.hpp"
namespace Tesses::Framework::Text::StringConverter {
void UTF8::FromUTF16(std::basic_string<char> &utf8,
const std::basic_string<char16_t> &utf16) {
for (size_t i = 0; i < utf16.size(); i++) {
char32_t c = utf16[i];
if ((c & 0xFC00) == 0xD800) {
c = (c & 0x03FF) << 10;
i++;
if (i >= utf16.size())
return;
char32_t c2 = utf16[i];
if ((c2 & 0xFC00) != 0xDC00)
continue;
c |= (c2 & 0x03FF);
c += 0x10000;
}
if (c <= 0x7F) {
utf8.push_back((char)c);
} else if (c >= 0x80 && c <= 0x7FF) {
uint8_t high = 0b11000000 | ((c >> 6) & 0b00011111);
uint8_t low = 0b10000000 | (c & 0b00111111);
utf8.push_back((char)high);
utf8.push_back((char)low);
} else if (c >= 0x800 && c <= 0xFFFF) {
uint8_t highest = 0b11100000 | ((c >> 12) & 0b00001111);
uint8_t high = 0b10000000 | ((c >> 6) & 0b00111111);
uint8_t low = 0b10000000 | (c & 0b00111111);
utf8.push_back((char)highest);
utf8.push_back((char)high);
utf8.push_back((char)low);
} else if (c >= 0x010000 && c <= 0x10FFFF) {
uint8_t highest = 0b11110000 | ((c >> 18) & 0b00000111);
uint8_t high = 0b10000000 | ((c >> 12) & 0b00111111);
uint8_t low = 0b10000000 | ((c >> 6) & 0b00111111);
uint8_t lowest = 0b10000000 | (c & 0b00111111);
utf8.push_back((char)highest);
utf8.push_back((char)high);
utf8.push_back((char)low);
utf8.push_back((char)lowest);
}
}
icubaby::t16_8 t;
auto it = icubaby::iterator{&t, std::back_inserter(utf8)};
std::copy(std::begin(utf16), std::end(utf16), it);
t.end_cp(it);
}
void UTF8::FromUTF32(std::basic_string<char> &utf8,
const std::basic_string<char32_t> &utf32) {
for (auto c : utf32) {
if (c <= 0x7F) {
utf8.push_back((char)c);
} else if (c >= 0x80 && c <= 0x7FF) {
uint8_t high = 0b11000000 | ((c >> 6) & 0b00011111);
uint8_t low = 0b10000000 | (c & 0b00111111);
utf8.push_back((char)high);
utf8.push_back((char)low);
} else if (c >= 0x800 && c <= 0xFFFF) {
uint8_t highest = 0b11100000 | ((c >> 12) & 0b00001111);
uint8_t high = 0b10000000 | ((c >> 6) & 0b00111111);
uint8_t low = 0b10000000 | (c & 0b00111111);
utf8.push_back((char)highest);
utf8.push_back((char)high);
utf8.push_back((char)low);
} else if (c >= 0x010000 && c <= 0x10FFFF) {
uint8_t highest = 0b11110000 | ((c >> 18) & 0b00000111);
uint8_t high = 0b10000000 | ((c >> 12) & 0b00111111);
uint8_t low = 0b10000000 | ((c >> 6) & 0b00111111);
uint8_t lowest = 0b10000000 | (c & 0b00111111);
utf8.push_back((char)highest);
utf8.push_back((char)high);
utf8.push_back((char)low);
utf8.push_back((char)lowest);
}
}
icubaby::t32_8 t;
auto it = icubaby::iterator{&t, std::back_inserter(utf8)};
std::copy(std::begin(utf32), std::end(utf32), it);
t.end_cp(it);
}
void UTF16::FromUTF8(std::basic_string<char16_t> &utf16,
const std::basic_string<char> &utf8) {
for (size_t i = 0; i < utf8.size(); i++) {
uint8_t c = (uint8_t)utf8[i];
char32_t cres = 0;
if (c <= 127) {
cres = (char32_t)c;
} else if ((c & 0b11100000) == 0b11000000) {
if (i + 1 < utf8.size()) {
uint8_t c2 = (uint8_t)utf8[++i];
cres |= c2 & 0b00111111;
cres |= (c & 0b00011111) << 6;
} else {
i++;
continue;
};
} else if ((c & 0b11110000) == 0b11100000) {
if (i + 2 < utf8.size()) {
uint8_t c2 = (uint8_t)utf8[++i];
uint8_t c3 = (uint8_t)utf8[++i];
cres |= c3 & 0b00111111;
cres |= (c2 & 0b00111111) << 6;
cres |= (c & 0b00001111) << 12;
} else {
i += 2;
continue;
}
} else if ((c & 0b11111000) == 0b11110000) {
if (i + 3 < utf8.size()) {
uint8_t c2 = (uint8_t)utf8[++i];
uint8_t c3 = (uint8_t)utf8[++i];
uint8_t c4 = (uint8_t)utf8[++i];
cres |= c4 & 0b00111111;
cres |= (c3 & 0b00111111) << 6;
cres |= (c2 & 0b00111111) << 12;
cres |= (c & 0b00000111) << 18;
} else {
i += 3;
continue;
}
}
if (cres >= 0x10000 && cres <= 0x10FFFF) {
auto subtracted = cres - 0x10000;
auto high = (0x3FF & (subtracted >> 10)) | 0xD800;
auto low = (0x3FF & subtracted) | 0xDC00;
utf16.push_back(high);
utf16.push_back(low);
} else {
utf16.push_back((char16_t)cres);
}
}
icubaby::t8_16 t;
auto it = icubaby::iterator{&t, std::back_inserter(utf16)};
std::copy(std::begin(utf8), std::end(utf8), it);
t.end_cp(it);
}
void UTF16::FromUTF32(std::basic_string<char16_t> &utf16,
const std::basic_string<char32_t> &utf32) {
for (auto cres : utf32) {
if (cres >= 0x10000 && cres <= 0x10FFFF) {
auto subtracted = cres - 0x10000;
auto high = (0x3FF & (subtracted >> 10)) | 0xD800;
auto low = (0x3FF & subtracted) | 0xDC00;
utf16.push_back(high);
utf16.push_back(low);
} else {
utf16.push_back((char16_t)cres);
}
}
icubaby::t32_16 t;
auto it = icubaby::iterator{&t, std::back_inserter(utf16)};
std::copy(std::begin(utf32), std::end(utf32), it);
t.end_cp(it);
}
void UTF32::FromUTF8(std::basic_string<char32_t> &utf32,
const std::basic_string<char> &utf8) {
for (size_t i = 0; i < utf8.size(); i++) {
uint8_t c = (uint8_t)utf8[i];
char32_t cres = 0;
if (c <= 127) {
cres = (char32_t)c;
} else if ((c & 0b11100000) == 0b11000000) {
if (i + 1 < utf8.size()) {
uint8_t c2 = (uint8_t)utf8[++i];
cres |= c2 & 0b00111111;
cres |= (c & 0b00011111) << 6;
} else {
i++;
continue;
};
} else if ((c & 0b11110000) == 0b11100000) {
if (i + 2 < utf8.size()) {
uint8_t c2 = (uint8_t)utf8[++i];
uint8_t c3 = (uint8_t)utf8[++i];
cres |= c3 & 0b00111111;
cres |= (c2 & 0b00111111) << 6;
cres |= (c & 0b00001111) << 12;
} else {
i += 2;
continue;
}
} else if ((c & 0b11111000) == 0b11110000) {
if (i + 3 < utf8.size()) {
uint8_t c2 = (uint8_t)utf8[++i];
uint8_t c3 = (uint8_t)utf8[++i];
uint8_t c4 = (uint8_t)utf8[++i];
cres |= c4 & 0b00111111;
cres |= (c3 & 0b00111111) << 6;
cres |= (c2 & 0b00111111) << 12;
cres |= (c & 0b00000111) << 18;
} else {
i += 3;
continue;
}
}
utf32.push_back(cres);
}
icubaby::t8_32 t;
auto it = icubaby::iterator{&t, std::back_inserter(utf32)};
std::copy(std::begin(utf8), std::end(utf8), it);
t.end_cp(it);
}
void UTF32::FromUTF16(std::basic_string<char32_t> &utf32,
const std::basic_string<char16_t> &utf16) {
for (size_t i = 0; i < utf16.size(); i++) {
char32_t c = utf16[i];
if ((c & 0xFC00) == 0xD800) {
c = (c & 0x03FF) << 10;
i++;
if (i >= utf16.size())
return;
char32_t c2 = utf16[i];
if ((c2 & 0xFC00) != 0xDC00)
continue;
c |= (c2 & 0x03FF);
c += 0x10000;
}
utf32.push_back(c);
}
icubaby::t16_32 t;
auto it = icubaby::iterator{&t, std::back_inserter(utf32)};
std::copy(std::begin(utf16), std::end(utf16), it);
t.end_cp(it);
}
} // namespace Tesses::Framework::Text::StringConverter
+2404
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,6 +18,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "TessesFramework/TextStreams/StdIOReader.hpp"
#include "TessesFramework/Console.hpp"
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+14 -11
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -63,16 +66,17 @@ bool TextReader::ReadLine(std::string &str) {
r = ReadChar();
if (r == -1)
break;
if (r == '\n')
{
if(!str.empty() && str.back() == '\r') str.resize(str.size()-1);
if (r == '\n') {
if (!str.empty() && str.back() == '\r')
str.resize(str.size() - 1);
return true;
}
str.push_back((char)(uint8_t)r);
ret = true;
} while (r != -1);
if(!str.empty() && str.back() == '\r') str.resize(str.size()-1);
if (!str.empty() && str.back() == '\r')
str.resize(str.size() - 1);
return ret;
}
void TextReader::ReadAllLines(std::vector<std::string> &lines) {
@@ -84,12 +88,11 @@ void TextReader::ReadAllLines(std::vector<std::string> &lines) {
r = ReadChar();
if (r == -1)
break;
if (r == '\n') {
if(!builder.empty() && builder.back() == '\r')
builder.resize(builder.size()-1);
if (r == '\n') {
if (!builder.empty() && builder.back() == '\r')
builder.resize(builder.size() - 1);
lines.push_back(builder);
builder.clear();
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -5
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -51,10 +54,6 @@ Mutex::Mutex() {
auto md = this->data.AllocField<MutexHiddenFieldData>();
#if defined(_WIN32)
md->mtx = CreateMutex(NULL, false, NULL);
#elif defined(GEKKO)
md->mtx = LWP_MUTEX_NULL;
LWP_MutexInit(&md->mtx, true);
#else
pthread_mutexattr_init(&md->attr);
pthread_mutexattr_settype(&md->attr, PTHREAD_MUTEX_RECURSIVE);
+11 -3
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,12 +24,18 @@
#include "TessesFramework/Threading/Mutex.hpp"
#include <iostream>
#include <memory>
#if defined(__SWITCH__)
#if defined(_WIN32)
#include <windows.h>
#undef min
#elif defined(__SWITCH__)
extern "C" {
#include <pthread.h>
#include <switch.h>
}
#else
#include <pthread.h>
#endif
namespace Tesses::Framework::Threading {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
@@ -61,7 +70,6 @@ class NeedToBeJoinnedThread {
hasExited = false;
pthread_create(&thrd, NULL, this->cb, static_cast<void *>(this));
}
std::atomic<bool> joinned;
std::atomic<bool> joinning;
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
+4 -1
View File
@@ -1,6 +1,9 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
https://git.tesses.org/tesses50/crosslang
Copyright (C) 2026 Mike Nolan
SPDX-License-Identifier: GPL-3.0-or-later WITH TessesFramework-Exception-1.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by