Overhaul cmake configuration, add console api, fix http code that caused issues with cgi-bin

This commit is contained in:
2026-05-27 03:02:16 -05:00
parent 266ef5f830
commit 8413c67ec6
177 changed files with 20088 additions and 17948 deletions

View File

@@ -1,13 +1,31 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Common.hpp"
namespace Tesses::Framework {
class Args {
public:
Args(std::vector<std::string> args);
Args(int argc, char** argv);
std::string filename;
std::vector<std::string> positional;
std::vector<std::string> flags;
std::vector<std::pair<std::string,std::string>> options;
};
}
class Args {
public:
Args(std::vector<std::string> args);
Args(int argc, char **argv);
std::string filename;
std::vector<std::string> positional;
std::vector<std::string> flags;
std::vector<std::pair<std::string, std::string>> options;
};
} // namespace Tesses::Framework

View File

@@ -1,70 +1,98 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Serialization/Bencode.hpp"
#include "TorrentStream.hpp"
namespace Tesses::Framework::BitTorrent
{
constexpr int DEFAULT_PIECE_LENGTH = 524288;
class TorrentFileInfo {
Serialization::Bencode::BeDictionary info;
public:
TorrentFileInfo();
TorrentFileInfo(const Serialization::Bencode::BeDictionary& tkn);
int64_t piece_length=DEFAULT_PIECE_LENGTH;
Serialization::Bencode::BeString pieces;
int64_t isPrivate=0;
Serialization::Bencode::BeString name;
std::variant<int64_t, std::vector<TorrentFileEntry>> fileListOrLength;
int64_t GetTorrentFileSize();
/// @brief Generate the info
/// @return the dictionary containing the info
Serialization::Bencode::BeDictionary& GenerateInfoDictionary();
/// @brief Get the info hash for info (if you are filling out the fields, you need to call GenerateInfoDictionary first)
/// @return the 20 byte info hash
Serialization::Bencode::BeString GetInfoHash();
/// @brief Get the info (does not regenerate info from the fields)
/// @return the dictionary containing the info
Serialization::Bencode::BeDictionary& GetInfoDictionary();
namespace Tesses::Framework::BitTorrent {
constexpr int DEFAULT_PIECE_LENGTH = 524288;
/// @brief Used to load a dictionary in, will overwrite all the fields
/// @param dict the dictionary to load
void Load(const Serialization::Bencode::BeDictionary& dict);
/// @brief Gets a read write based on this info object
/// @param vfs the vfs object
/// @param path file or directory inside vfs
/// @return The read write at object
std::shared_ptr<ReadWriteAt> GetStreamFromFilesystem(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, const Tesses::Framework::Filesystem::VFSPath& path);
class TorrentFileInfo {
/// @brief Create info from file/directory
/// @param vfs the vfs object
/// @param path file or directory inside vfs
/// @param isPrivate whether you use private trackers
/// @param pieceLength length of pieces
void CreateFromFilesystem(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, const Tesses::Framework::Filesystem::VFSPath& path, bool isPrivate=false, int64_t pieceLength=DEFAULT_PIECE_LENGTH);
};
class TorrentFile {
public:
TorrentFile();
TorrentFile(const Serialization::Bencode::BeDictionary& tkn);
Serialization::Bencode::BeDictionary info;
public:
TorrentFileInfo();
TorrentFileInfo(const Serialization::Bencode::BeDictionary &tkn);
Serialization::Bencode::BeString announce;
std::vector<Serialization::Bencode::BeString> announce_list;
std::vector<Serialization::Bencode::BeString> url_list;
Serialization::Bencode::BeString comment;
Serialization::Bencode::BeString created_by;
int64_t creation_date=0;
TorrentFileInfo info;
int64_t piece_length = DEFAULT_PIECE_LENGTH;
Serialization::Bencode::BeString pieces;
int64_t isPrivate = 0;
Serialization::Bencode::BeString name;
std::variant<int64_t, std::vector<TorrentFileEntry>> fileListOrLength;
int64_t GetTorrentFileSize();
/// @brief Generate the info
/// @return the dictionary containing the info
Serialization::Bencode::BeDictionary &GenerateInfoDictionary();
/// @brief Get the info hash for info (if you are filling out the fields,
/// you need to call GenerateInfoDictionary first)
/// @return the 20 byte info hash
Serialization::Bencode::BeString GetInfoHash();
/// @brief Get the info (does not regenerate info from the fields)
/// @return the dictionary containing the info
Serialization::Bencode::BeDictionary &GetInfoDictionary();
/// @brief Used to load a dictionary in, will overwrite all the fields
/// @param dict the dictionary to load
void Load(const Serialization::Bencode::BeDictionary &dict);
/// @brief Gets a read write based on this info object
/// @param vfs the vfs object
/// @param path file or directory inside vfs
/// @return The read write at object
std::shared_ptr<ReadWriteAt> GetStreamFromFilesystem(
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
const Tesses::Framework::Filesystem::VFSPath &path);
Serialization::Bencode::BeDictionary ToDictionary();
/// @brief Create info from file/directory
/// @param vfs the vfs object
/// @param path file or directory inside vfs
/// @param isPrivate whether you use private trackers
/// @param pieceLength length of pieces
void CreateFromFilesystem(
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
const Tesses::Framework::Filesystem::VFSPath &path,
bool isPrivate = false, int64_t pieceLength = DEFAULT_PIECE_LENGTH);
};
class TorrentFile {
public:
TorrentFile();
TorrentFile(const Serialization::Bencode::BeDictionary &tkn);
void Print(std::shared_ptr<TextStreams::TextWriter> writer);
Serialization::Bencode::BeString announce;
std::vector<Serialization::Bencode::BeString> announce_list;
std::vector<Serialization::Bencode::BeString> url_list;
Serialization::Bencode::BeString comment;
Serialization::Bencode::BeString created_by;
int64_t creation_date = 0;
TorrentFileInfo info;
static void CreateTorrent(std::shared_ptr<Tesses::Framework::Streams::Stream> torrent_file_stream,const std::vector<Serialization::Bencode::BeString>& trackers,const std::vector<Serialization::Bencode::BeString>& webseeds, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, const Tesses::Framework::Filesystem::VFSPath& path, bool isPrivate=false, int64_t pieceLength=DEFAULT_PIECE_LENGTH, Serialization::Bencode::BeString comment="", Serialization::Bencode::BeString created_by = "TessesFrameworkTorrent");
};
}
Serialization::Bencode::BeDictionary ToDictionary();
void Print(std::shared_ptr<TextStreams::TextWriter> writer);
static void CreateTorrent(
std::shared_ptr<Tesses::Framework::Streams::Stream> torrent_file_stream,
const std::vector<Serialization::Bencode::BeString> &trackers,
const std::vector<Serialization::Bencode::BeString> &webseeds,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
const Tesses::Framework::Filesystem::VFSPath &path,
bool isPrivate = false, int64_t pieceLength = DEFAULT_PIECE_LENGTH,
Serialization::Bencode::BeString comment = "",
Serialization::Bencode::BeString created_by = "TessesFrameworkTorrent");
};
} // namespace Tesses::Framework::BitTorrent

View File

@@ -1,46 +1,68 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "TessesFramework/Http/HttpClient.hpp"
#include "TessesFramework/Streams/NetworkStream.hpp"
namespace Tesses::Framework::BitTorrent
{
class TorrentFileEntry {
public:
TorrentFileEntry();
TorrentFileEntry(Tesses::Framework::Filesystem::VFSPath path, int64_t length);
Tesses::Framework::Filesystem::VFSPath path;
int64_t length=0;
};
class ReadWriteAt {
public:
virtual bool ReadBlockAt(uint64_t offset, uint8_t* data, size_t len)=0;
virtual void WriteBlockAt(uint64_t offset, const uint8_t* data, size_t len)=0;
virtual ~ReadWriteAt();
namespace Tesses::Framework::BitTorrent {
class TorrentFileEntry {
public:
TorrentFileEntry();
TorrentFileEntry(Tesses::Framework::Filesystem::VFSPath path,
int64_t length);
Tesses::Framework::Filesystem::VFSPath path;
int64_t length = 0;
};
class ReadWriteAt {
public:
virtual bool ReadBlockAt(uint64_t offset, uint8_t *data, size_t len) = 0;
virtual void WriteBlockAt(uint64_t offset, const uint8_t *data,
size_t len) = 0;
virtual ~ReadWriteAt();
};
};
class TorrentFileStream : public ReadWriteAt {
Tesses::Framework::Threading::Mutex mtx;
class TorrentFileStream : public ReadWriteAt
{
Tesses::Framework::Threading::Mutex mtx;
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
uint64_t length;
TorrentFileStream(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path, uint64_t length);
bool ReadBlockAt(uint64_t offset, uint8_t* data, size_t len);
void WriteBlockAt(uint64_t offset, const uint8_t* data, size_t len);
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
uint64_t length;
TorrentFileStream(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
Tesses::Framework::Filesystem::VFSPath path,
uint64_t length);
bool ReadBlockAt(uint64_t offset, uint8_t *data, size_t len);
void WriteBlockAt(uint64_t offset, const uint8_t *data, size_t len);
};
class TorrentDirectoryStream : public ReadWriteAt {
};
class TorrentDirectoryStream : public ReadWriteAt
{
std::vector<Tesses::Framework::Threading::Mutex> mtxs;
std::vector<Tesses::Framework::Threading::Mutex> mtxs;
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
std::vector<TorrentFileEntry> entries;
TorrentDirectoryStream(std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path,std::vector<TorrentFileEntry> entries);
bool ReadBlockAt(uint64_t offset, uint8_t* data, size_t len);
void WriteBlockAt(uint64_t offset, const uint8_t* data, size_t len);
};
}
public:
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
Tesses::Framework::Filesystem::VFSPath path;
std::vector<TorrentFileEntry> entries;
TorrentDirectoryStream(
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
Tesses::Framework::Filesystem::VFSPath path,
std::vector<TorrentFileEntry> entries);
bool ReadBlockAt(uint64_t offset, uint8_t *data, size_t len);
void WriteBlockAt(uint64_t offset, const uint8_t *data, size_t len);
};
} // namespace Tesses::Framework::BitTorrent

View File

@@ -1,98 +1,119 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Threading/Mutex.hpp"
#include <atomic>
#include <chrono>
#include <cstring>
#include <cstdint>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <filesystem>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <ratio>
#include <string>
#include <filesystem>
#include <map>
#include <vector>
#include <functional>
#include "Threading/Mutex.hpp"
#include <optional>
#include <atomic>
namespace Tesses::Framework
{
std::optional<std::string> TF_GetCommandName();
class TF_Timer_Handle;
//Used for internal purposes, don't use unless you want to run timer events on another thread
class TF_Timer_Handler {
private:
std::vector<std::weak_ptr<TF_Timer_Handle>> handles;
public:
void Update();
static std::shared_ptr<TF_Timer_Handle> Make(std::shared_ptr<TF_Timer_Handler> handler);
friend class TF_Timer_Handle;
};
namespace Tesses::Framework {
class TF_Timer_Handle {
private:
std::shared_ptr<TF_Timer_Handler> timerHandler;
std::function<void()> cb;
std::chrono::milliseconds interval;
std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds> last;
bool enabled;
TF_Timer_Handle() = delete;
class TF_Timer_Handle;
// Used for internal purposes, don't use unless you want to run timer events on
// another thread
TF_Timer_Handle(std::shared_ptr<TF_Timer_Handler> timerHandler);
class TF_Timer_Handler {
private:
std::vector<std::weak_ptr<TF_Timer_Handle>> handles;
public:
void SetCallback(std::function<void()> cb);
public:
void Update();
int64_t GetIntervalMilliseconds();
std::chrono::duration<int64_t,std::milli> GetIntervalDuration();
static std::shared_ptr<TF_Timer_Handle>
Make(std::shared_ptr<TF_Timer_Handler> handler);
friend class TF_Timer_Handle;
};
void SetIntervalFromMilliseconds(int64_t ms);
void SetIntervalFromDuration(std::chrono::milliseconds dur);
class TF_Timer_Handle {
void SetEnabled(bool enabled);
bool GetEnabled();
friend class TF_Timer_Handler;
};
private:
std::shared_ptr<TF_Timer_Handler> timerHandler;
std::function<void()> cb;
std::chrono::milliseconds interval;
std::chrono::time_point<std::chrono::steady_clock,
std::chrono::milliseconds>
last;
bool enabled;
TF_Timer_Handle() = delete;
TF_Timer_Handle(std::shared_ptr<TF_Timer_Handler> timerHandler);
std::shared_ptr<TF_Timer_Handle> TF_Timer();
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, int64_t interval=1000, bool enabled=true);
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, std::chrono::milliseconds interval, bool enabled=true);
void TF_Init();
void TF_InitWithConsole();
void TF_AllowPortable(std::string argv0);
void TF_ConnectToSelf(uint16_t port);
void TF_InitEventLoop();
void TF_RunEventLoop();
void TF_RunEventLoopItteration();
bool TF_IsRunning();
void TF_Sleep(uint32_t sleepMS);
void TF_SetIsRunning(bool _isRunning);
void TF_Quit();
bool TF_GetConsoleEventsEnabled();
void TF_SetConsoleEventsEnabled(bool flag);
void TF_InitConsole();
void TF_Invoke(std::function<void()> cb);
std::string TF_FileSize(uint64_t bytes, bool usesBin=true);
#if defined(TESSESFRAMEWORK_LOGTOFILE)
void TF_Log(std::string dataToLog);
#endif
public:
void SetCallback(std::function<void()> cb);
int64_t GetIntervalMilliseconds();
std::chrono::duration<int64_t, std::milli> GetIntervalDuration();
#if defined(TESSESFRAMEWORK_LOGTOFILE)
#define TF_LOG(log) Tesses::Framework::TF_Log(log)
#else
#define TF_LOG(log)
#endif
}
void SetIntervalFromMilliseconds(int64_t ms);
void SetIntervalFromDuration(std::chrono::milliseconds dur);
void SetEnabled(bool enabled);
bool GetEnabled();
friend class TF_Timer_Handler;
};
std::shared_ptr<TF_Timer_Handle> TF_Timer();
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb,
int64_t interval = 1000,
bool enabled = true);
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb,
std::chrono::milliseconds interval,
bool enabled = true);
void TF_Init();
void TF_InitWithConsole();
std::string TF_GetExecutableName();
void TF_AllowPortable();
void TF_AllowPortable(std::string argv0);
void TF_ConnectToSelf(uint16_t port);
void TF_InitEventLoop();
void TF_RunEventLoop();
void TF_RunEventLoopItteration();
bool TF_IsRunning();
void TF_Sleep(uint32_t sleepMS);
void TF_SetIsRunning(bool _isRunning);
void TF_Quit();
bool TF_GetConsoleEventsEnabled();
void TF_SetConsoleEventsEnabled(bool flag);
void TF_InitConsole();
void TF_Invoke(std::function<void()> cb);
std::string TF_FileSize(uint64_t bytes, bool usesBin = true);
#if defined(TESSESFRAMEWORK_LOGTOFILE)
void TF_Log(std::string dataToLog);
#endif
#if defined(TESSESFRAMEWORK_LOGTOFILE)
#define TF_LOG(log) Tesses::Framework::TF_Log(log)
#else
#define TF_LOG(log)
#endif
} // namespace Tesses::Framework

View File

@@ -0,0 +1,79 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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 "Common.hpp"
#include <cstdio>
namespace Tesses::Framework {
enum class ConsoleColor {
CC_BLACK,
CC_RED,
CC_GREEN,
CC_YELLOW,
CC_BLUE,
CC_MAGENTA,
CC_CYAN,
CC_WHITE
};
enum class ClearBehaviour {
CB_CURSORANDBELOW,
CB_CURSORANDABOVE,
CB_ENTIRESCREEN
};
struct Console {
static bool IsTTY();
static std::pair<int,int> GetSize();
static void ProgressBar(double);
static void ProgressBar(int);
static void Write(std::string text);
static void WriteLine(std::string text);
static void WriteView(std::string_view text);
static void WriteLineView(std::string_view text);
static void Error(std::string text);
static void ErrorLine(std::string text);
static void ErrorView(std::string_view text);
static void ErrorLineView(std::string_view text);
static int Read();
static std::string ReadLine();
static bool GetEcho();
static bool SetEcho(bool echo);
static bool GetCanonical();
static bool SetCanonical(bool can);
static bool GetSignals();
static bool SetSignals(bool sig);
static void SetPosition(int x, int y);
static void SetBackgroundColor(ConsoleColor c, bool alt);
static void SetForegroundColor(ConsoleColor c, bool alt);
static void Clear();
static void MoveToHome();
static void ClearRetainPosition(ClearBehaviour clearBehaviour);
static void Flush();
//returns std::string::npos if no tty
static size_t List(std::vector<std::string>& strs);
static std::string ReadPassword();
private:
static void WriteToStream(std::string_view text, bool isStderr);
};
}

View File

@@ -1,22 +1,43 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/Stream.hpp"
namespace Tesses::Framework::Crypto {
class ClientTLSStream : public Tesses::Framework::Streams::Stream {
void *privateData;
namespace Tesses::Framework::Crypto
{
class ClientTLSStream : public Tesses::Framework::Streams::Stream {
void* privateData;
public:
static std::string GetCertChain();
public:
static std::string GetCertChain();
ClientTLSStream(std::shared_ptr<Tesses::Framework::Streams::Stream> innerStream, bool verify, std::string domain);
ClientTLSStream(std::shared_ptr<Tesses::Framework::Streams::Stream> innerStream, bool verify, std::string domain, std::string cert);
size_t Read(uint8_t* buff, size_t sz);
size_t Write(const uint8_t* buff, size_t sz);
bool CanRead();
bool CanWrite();
bool EndOfStream();
~ClientTLSStream();
};
ClientTLSStream(
std::shared_ptr<Tesses::Framework::Streams::Stream> innerStream,
bool verify, std::string domain);
ClientTLSStream(
std::shared_ptr<Tesses::Framework::Streams::Stream> innerStream,
bool verify, std::string domain, std::string cert);
size_t Read(uint8_t *buff, size_t sz);
size_t Write(const uint8_t *buff, size_t sz);
bool CanRead();
bool CanWrite();
bool EndOfStream();
~ClientTLSStream();
};
}
} // namespace Tesses::Framework::Crypto

View File

@@ -1,60 +1,87 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/Stream.hpp"
namespace Tesses::Framework::Crypto
{
bool HaveCrypto();
std::string Base64_Encode(std::vector<uint8_t> data);
std::vector<uint8_t> Base64_Decode(std::string str);
class Sha1 {
void* inner;
public:
Sha1();
bool Start();
bool Update(const uint8_t* buffer, size_t sz);
bool Update(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::vector<uint8_t> Finish();
~Sha1();
static std::vector<uint8_t> ComputeHash(const uint8_t* buffer, size_t len);
static std::vector<uint8_t> ComputeHash(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
};
class Sha256 {
void* inner;
bool is224;
public:
Sha256();
bool Start(bool is224=false);
bool Is224();
bool Update(const uint8_t* buffer, size_t sz);
bool Update(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::vector<uint8_t> Finish();
~Sha256();
static std::vector<uint8_t> ComputeHash(const uint8_t* buffer, size_t len,bool is224=false);
static std::vector<uint8_t> ComputeHash(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,bool is224=false);
};
class Sha512 {
void* inner;
bool is384;
public:
Sha512();
bool Start(bool is384=false);
bool Is384();
bool Update(const uint8_t* buffer, size_t sz);
bool Update(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::vector<uint8_t> Finish();
~Sha512();
namespace Tesses::Framework::Crypto {
bool HaveCrypto();
std::string Base64_Encode(std::vector<uint8_t> data);
std::vector<uint8_t> Base64_Decode(std::string str);
class Sha1 {
void *inner;
static std::vector<uint8_t> ComputeHash(const uint8_t* buffer, size_t len,bool is384=false);
static std::vector<uint8_t> ComputeHash(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,bool is384=false);
};
typedef enum {
VERSION_SHA1=1,
VERSION_SHA224=224,
VERSION_SHA256=256,
VERSION_SHA384=384,
VERSION_SHA512=512
} ShaVersion;
bool PBKDF2(std::vector<uint8_t>& output,std::string pass, std::vector<uint8_t>& salt, long itterations, ShaVersion version);
public:
Sha1();
bool Start();
bool Update(const uint8_t *buffer, size_t sz);
bool Update(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::vector<uint8_t> Finish();
~Sha1();
static std::vector<uint8_t> ComputeHash(const uint8_t *buffer, size_t len);
static std::vector<uint8_t>
ComputeHash(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
};
class Sha256 {
void *inner;
bool is224;
bool RandomBytes(std::vector<uint8_t>& output, std::string personal_str);
}
public:
Sha256();
bool Start(bool is224 = false);
bool Is224();
bool Update(const uint8_t *buffer, size_t sz);
bool Update(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::vector<uint8_t> Finish();
~Sha256();
static std::vector<uint8_t> ComputeHash(const uint8_t *buffer, size_t len,
bool is224 = false);
static std::vector<uint8_t>
ComputeHash(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
bool is224 = false);
};
class Sha512 {
void *inner;
bool is384;
public:
Sha512();
bool Start(bool is384 = false);
bool Is384();
bool Update(const uint8_t *buffer, size_t sz);
bool Update(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::vector<uint8_t> Finish();
~Sha512();
static std::vector<uint8_t> ComputeHash(const uint8_t *buffer, size_t len,
bool is384 = false);
static std::vector<uint8_t>
ComputeHash(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
bool is384 = false);
};
typedef enum {
VERSION_SHA1 = 1,
VERSION_SHA224 = 224,
VERSION_SHA256 = 256,
VERSION_SHA384 = 384,
VERSION_SHA512 = 512
} ShaVersion;
bool PBKDF2(std::vector<uint8_t> &output, std::string pass,
std::vector<uint8_t> &salt, long itterations, ShaVersion version);
bool RandomBytes(std::vector<uint8_t> &output, std::string personal_str);
} // namespace Tesses::Framework::Crypto

View File

@@ -1,142 +1,146 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <string>
#include <chrono>
#include <cstdint>
#include <string>
namespace Tesses::Framework::Date
{
int GetTimeZone();
bool TimeZoneSupportDST();
class DateTime {
int year=1970;
int month=1;
int day=1;
int hour=0;
int minute=0;
int second=0;
bool isLocal=false;
int64_t ToEpochNoConvert() const;
void FromEpochNoConvert(int64_t gmt);
public:
DateTime();
DateTime(int year, int month, int day, int hour, int minute, int seconds, bool isLocal=true);
DateTime(int64_t epoch);
int Year() const;
int Month() const;
int Day() const;
int Hour() const;
int Minute() const;
int Second() const;
int DayOfWeek() const;
bool IsLocal() const;
int64_t ToEpoch() const;
DateTime ToLocal() const;
DateTime ToUTC() const;
void SetToLocal();
void SetToUTC();
void SetYear(int y);
void SetMonth(int m);
void SetDay(int d);
void SetHour(int h);
void SetMinute(int m);
void SetSecond(int s);
void SetLocal(bool local);
void Set(int64_t epoch);
void Set(int year, int month, int day, int hour, int minute, int seconds, bool isLocal=true);
namespace Tesses::Framework::Date {
int GetTimeZone();
bool TimeZoneSupportDST();
class DateTime {
int year = 1970;
int month = 1;
int day = 1;
int hour = 0;
int minute = 0;
int second = 0;
bool isLocal = false;
int64_t ToEpochNoConvert() const;
void FromEpochNoConvert(int64_t gmt);
void SetToNow();
void SetToNowUTC();
static DateTime Now();
static DateTime NowUTC();
public:
DateTime();
DateTime(int year, int month, int day, int hour, int minute, int seconds,
bool isLocal = true);
DateTime(int64_t epoch);
int Year() const;
int Month() const;
int Day() const;
int Hour() const;
int Minute() const;
int Second() const;
int DayOfWeek() const;
bool IsLocal() const;
int64_t ToEpoch() const;
DateTime ToLocal() const;
DateTime ToUTC() const;
void SetToLocal();
void SetToUTC();
void SetYear(int y);
void SetMonth(int m);
void SetDay(int d);
void SetHour(int h);
void SetMinute(int m);
void SetSecond(int s);
void SetLocal(bool local);
void Set(int64_t epoch);
void Set(int year, int month, int day, int hour, int minute, int seconds,
bool isLocal = true);
std::string ToString() const;
std::string ToString(std::string fmt) const;
void SetToNow();
void SetToNowUTC();
static DateTime Now();
static DateTime NowUTC();
std::string ToString() const;
std::string ToString(std::string fmt) const;
std::string ToHttpDate() const;
static bool TryParseHttpDate(std::string txt, DateTime& dt);
std::string ToHttpDate() const;
static bool TryParseHttpDate(std::string txt, DateTime &dt);
};
class TimeSpan {
int64_t totalSeconds;
};
class TimeSpan {
int64_t totalSeconds;
public:
TimeSpan();
TimeSpan(int64_t totalSeconds);
TimeSpan(int hours, int minutes, int seconds);
TimeSpan(int days,int hours, int minutes, int seconds);
void Set(int days, int hours, int minutes, int seconds);
void Set(int hours, int minutes, int seconds);
public:
TimeSpan();
TimeSpan(int64_t totalSeconds);
TimeSpan(int hours, int minutes, int seconds);
TimeSpan(int days, int hours, int minutes, int seconds);
void SetDays(int d);
void SetHours(int h);
void SetMinutes(int m);
void SetSeconds(int s);
int Days() const;
int Hours() const;
int Minutes() const;
int Seconds() const;
void Set(int days, int hours, int minutes, int seconds);
void Set(int hours, int minutes, int seconds);
void SetDays(int d);
void SetHours(int h);
void SetMinutes(int m);
void SetSeconds(int s);
int64_t TotalSeconds() const;
int64_t TotalMinutes() const;
int64_t TotalHours() const;
int Days() const;
int Hours() const;
int Minutes() const;
int Seconds() const;
int64_t TotalSeconds() const;
int64_t TotalMinutes() const;
int64_t TotalHours() const;
void SetTotalSeconds(int64_t totalSeconds);
void SetTotalMinutes(int64_t totalMinutes);
void SetTotalHours(int64_t totalHours);
void AddSeconds(int64_t seconds);
void AddMinutes(int64_t minutes);
void AddHours(int64_t hours);
void AddDays(int64_t days);
void SetTotalSeconds(int64_t totalSeconds);
void SetTotalMinutes(int64_t totalMinutes);
void SetTotalHours(int64_t totalHours);
std::string ToString(bool slim=true) const;
void AddSeconds(int64_t seconds);
void AddMinutes(int64_t minutes);
void AddHours(int64_t hours);
void AddDays(int64_t days);
static bool TryParse(std::string text, TimeSpan& span);
std::string ToString(bool slim = true) const;
};
static bool TryParse(std::string text, TimeSpan &span);
};
inline DateTime operator+(const DateTime& dt, const TimeSpan& ts)
{
DateTime dt2(dt.ToEpoch() + ts.TotalSeconds());
if(dt.IsLocal())
dt2.SetToLocal();
return dt2;
}
inline DateTime operator+(const TimeSpan& ts,const DateTime& dt)
{
DateTime dt2(dt.ToEpoch() + ts.TotalSeconds());
if(dt.IsLocal())
dt2.SetToLocal();
return dt2;
}
inline TimeSpan operator+(const TimeSpan& ts, const TimeSpan& ts2)
{
return ts.TotalSeconds() + ts2.TotalSeconds();
}
inline DateTime operator-(const DateTime& dt, const TimeSpan& ts)
{
DateTime dt2(dt.ToEpoch() - ts.TotalSeconds());
if(dt.IsLocal())
dt2.SetToLocal();
return dt2;
}
inline TimeSpan operator-(const DateTime& dt, const DateTime& dt2)
{
return dt.ToEpoch() - dt2.ToEpoch();
}
inline TimeSpan operator-(const TimeSpan& ts, const TimeSpan& ts2)
{
return ts.TotalSeconds() - ts2.TotalSeconds();
}
};
inline DateTime operator+(const DateTime &dt, const TimeSpan &ts) {
DateTime dt2(dt.ToEpoch() + ts.TotalSeconds());
if (dt.IsLocal())
dt2.SetToLocal();
return dt2;
}
inline DateTime operator+(const TimeSpan &ts, const DateTime &dt) {
DateTime dt2(dt.ToEpoch() + ts.TotalSeconds());
if (dt.IsLocal())
dt2.SetToLocal();
return dt2;
}
inline TimeSpan operator+(const TimeSpan &ts, const TimeSpan &ts2) {
return ts.TotalSeconds() + ts2.TotalSeconds();
}
inline DateTime operator-(const DateTime &dt, const TimeSpan &ts) {
DateTime dt2(dt.ToEpoch() - ts.TotalSeconds());
if (dt.IsLocal())
dt2.SetToLocal();
return dt2;
}
inline TimeSpan operator-(const DateTime &dt, const DateTime &dt2) {
return dt.ToEpoch() - dt2.ToEpoch();
}
inline TimeSpan operator-(const TimeSpan &ts, const TimeSpan &ts2) {
return ts.TotalSeconds() - ts2.TotalSeconds();
}
}; // namespace Tesses::Framework::Date

View File

@@ -1,33 +1,68 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "TempFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem::Helpers
{
void ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path, std::string& text);
void ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path, std::vector<std::string>& lines);
void ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path, std::vector<uint8_t>& array);
std::string ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path);
std::vector<std::string> ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path);
std::vector<uint8_t> ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path);
void WriteAllText(std::shared_ptr<VFS> vfs, VFSPath path, const std::string& text);
void WriteAllLines(std::shared_ptr<VFS> vfs, VFSPath path, const std::vector<std::string>& parts);
void WriteAllBytes(std::shared_ptr<VFS> vfs, VFSPath path, const std::vector<uint8_t>& bytes);
namespace Tesses::Framework::Filesystem::Helpers {
void ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path, std::string &text);
void ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path,
std::vector<std::string> &lines);
void ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path,
std::vector<uint8_t> &array);
std::string ReadAllText(std::shared_ptr<VFS> vfs, VFSPath path);
std::vector<std::string> ReadAllLines(std::shared_ptr<VFS> vfs, VFSPath path);
std::vector<uint8_t> ReadAllBytes(std::shared_ptr<VFS> vfs, VFSPath path);
void WriteAllText(std::shared_ptr<VFS> vfs, VFSPath path,
const std::string &text);
void WriteAllLines(std::shared_ptr<VFS> vfs, VFSPath path,
const std::vector<std::string> &parts);
void WriteAllBytes(std::shared_ptr<VFS> vfs, VFSPath path,
const std::vector<uint8_t> &bytes);
void CopyStreamProgress(std::shared_ptr<Streams::Stream> src,std::shared_ptr<Streams::Stream> dest, std::function<void(int64_t offset, int64_t length)> progress);
void CopyStreamProgress(
std::shared_ptr<Streams::Stream> src, std::shared_ptr<Streams::Stream> dest,
std::function<void(int64_t offset, int64_t length)> progress);
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, bool overwrite=true);
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, std::function<void(int64_t offset, int64_t length)> progress, bool overwrite=true);
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, bool overwrite=true);
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest, VFSPath pathDest, std::function<void(int64_t offset, int64_t length, VFSPath currentFile)> progress, bool overwrite=true);
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc,
std::shared_ptr<VFS> vfsDest, VFSPath pathDest,
bool overwrite = true);
void CopyFile(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc,
std::shared_ptr<VFS> vfsDest, VFSPath pathDest,
std::function<void(int64_t offset, int64_t length)> progress,
bool overwrite = true);
void CopyDirectory(std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc,
std::shared_ptr<VFS> vfsDest, VFSPath pathDest,
bool overwrite = true);
void CopyDirectory(
std::shared_ptr<VFS> vfsSrc, VFSPath pathSrc, std::shared_ptr<VFS> vfsDest,
VFSPath pathDest,
std::function<void(int64_t offset, int64_t length, VFSPath currentFile)>
progress,
bool overwrite = true);
inline std::shared_ptr<TempFS> CreateTempFS(bool deleteOnDestroy=true)
{
return std::make_shared<TempFS>(deleteOnDestroy);
}
inline std::shared_ptr<TempFS> CreateTempFS(std::shared_ptr<VFS> vfs,bool deleteOnDestroy=true)
{
return std::make_shared<TempFS>(vfs,deleteOnDestroy);
}
inline std::shared_ptr<TempFS> CreateTempFS(bool deleteOnDestroy = true) {
return std::make_shared<TempFS>(deleteOnDestroy);
}
inline std::shared_ptr<TempFS> CreateTempFS(std::shared_ptr<VFS> vfs,
bool deleteOnDestroy = true) {
return std::make_shared<TempFS>(vfs, deleteOnDestroy);
}
}
} // namespace Tesses::Framework::Filesystem::Helpers

View File

@@ -1,46 +1,62 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "VFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
class LocalFilesystem : public VFS
{
public:
namespace Tesses::Framework::Filesystem {
class LocalFilesystem : public VFS {
public:
std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode);
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveDirectory(VFSPath src, VFSPath dest);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
void MoveFile(VFSPath src, VFSPath dest);
void SetDate(VFSPath path, Date::DateTime lastWrite,
Date::DateTime lastAccess);
bool Stat(VFSPath path, StatData &stat);
bool StatVFS(VFSPath path, StatVFSData &vfsData);
void MoveDirectory(VFSPath src, VFSPath dest);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
void Chmod(VFSPath path, uint32_t mode);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
bool Stat(VFSPath path, StatData& stat);
bool StatVFS(VFSPath path, StatVFSData& vfsData);
void Lock(VFSPath path);
void Unlock(VFSPath path);
void Chmod(VFSPath path, uint32_t mode);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mod);
void Lock(VFSPath path);
void Unlock(VFSPath path);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mod);
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
};
extern std::shared_ptr<LocalFilesystem> LocalFS;
}
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs,
VFSPath path);
};
extern std::shared_ptr<LocalFilesystem> LocalFS;
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,59 +1,75 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "VFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
class MountableDirectory {
public:
std::string name;
std::shared_ptr<VFS> vfs;
bool owns;
std::vector<MountableDirectory*> dirs;
void GetFS(VFSPath srcPath, VFSPath curDir, VFSPath& destRoot, VFSPath& destPath, std::shared_ptr<VFS>& vfs);
~MountableDirectory();
};
namespace Tesses::Framework::Filesystem {
class MountableDirectory {
public:
std::string name;
std::shared_ptr<VFS> vfs;
bool owns;
std::vector<MountableDirectory *> dirs;
void GetFS(VFSPath srcPath, VFSPath curDir, VFSPath &destRoot,
VFSPath &destPath, std::shared_ptr<VFS> &vfs);
~MountableDirectory();
};
class MountableFilesystem : public VFS
{
std::shared_ptr<VFS> root;
class MountableFilesystem : public VFS {
std::shared_ptr<VFS> root;
std::vector<MountableDirectory*> directories;
std::vector<MountableDirectory *> directories;
void GetFS(VFSPath srcPath, VFSPath& destRoot, VFSPath& destPath, std::shared_ptr<VFS>& vfs);
void GetFS(VFSPath srcPath, VFSPath &destRoot, VFSPath &destPath,
std::shared_ptr<VFS> &vfs);
public:
MountableFilesystem();
MountableFilesystem(std::shared_ptr<VFS> root);
void Mount(VFSPath path, std::shared_ptr<VFS> vfs);
void Unmount(VFSPath path);
std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
bool Stat(VFSPath path, StatData &data);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
~MountableFilesystem();
void SetDate(VFSPath path, Date::DateTime lastWrite,
Date::DateTime lastAccess);
public:
MountableFilesystem();
MountableFilesystem(std::shared_ptr<VFS> root);
void Mount(VFSPath path, std::shared_ptr<VFS> vfs);
void Unmount(VFSPath path);
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
bool Stat(VFSPath path, StatData& data);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
~MountableFilesystem();
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData &vfsData);
bool StatVFS(VFSPath path, StatVFSData& vfsData);
void Chmod(VFSPath path, uint32_t mode);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Chmod(VFSPath path, uint32_t mode);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
};
}
void Lock(VFSPath path);
void Unlock(VFSPath path);
};
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,16 +1,33 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "VFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
class NullFilesystem : public VFS
{
public:
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
VFSPathEnumerator EnumeratePaths(VFSPath path);
bool Stat(VFSPath path, StatData& data);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
};
}
namespace Tesses::Framework::Filesystem {
class NullFilesystem : public VFS {
public:
std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode);
VFSPathEnumerator EnumeratePaths(VFSPath path);
bool Stat(VFSPath path, StatData &data);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
};
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,54 +1,78 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "VFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
class RelativeFilesystem : public VFS {
Tesses::Framework::Threading::Mutex mtx;
VFSPath working;
std::shared_ptr<VFS> vfs;
private:
VFSPath ToParent(VFSPath path);
public:
RelativeFilesystem(std::shared_ptr<VFS> vfs, VFSPath working);
VFSPath GetWorking();
void SetWorking(VFSPath path);
std::shared_ptr<VFS> GetVFS();
namespace Tesses::Framework::Filesystem {
class RelativeFilesystem : public VFS {
Tesses::Framework::Threading::Mutex mtx;
VFSPath working;
std::shared_ptr<VFS> vfs;
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
void DeleteDirectoryRecurse(VFSPath path);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData& vfsData);
bool Stat(VFSPath path, StatData& data);
private:
VFSPath ToParent(VFSPath path);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
void Chmod(VFSPath path, uint32_t mode);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
public:
RelativeFilesystem(std::shared_ptr<VFS> vfs, VFSPath working);
VFSPath GetWorking();
void SetWorking(VFSPath path);
std::shared_ptr<VFS> GetVFS();
std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
void DeleteDirectoryRecurse(VFSPath path);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
void SetDate(VFSPath path, Date::DateTime lastWrite,
Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData &vfsData);
bool Stat(VFSPath path, StatData &data);
class Watcher : public FSWatcher {
std::shared_ptr<FSWatcher> watcher;
protected:
void SetEnabledImpl(bool enabled);
public:
Watcher(std::shared_ptr<RelativeFilesystem> vfs, VFSPath path);
~Watcher();
};
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
void Chmod(VFSPath path, uint32_t mode);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs,
VFSPath path);
class Watcher : public FSWatcher {
std::shared_ptr<FSWatcher> watcher;
protected:
void SetEnabledImpl(bool enabled);
public:
Watcher(std::shared_ptr<RelativeFilesystem> vfs, VFSPath path);
~Watcher();
};
}
};
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,53 +1,73 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "VFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
class SubdirFilesystem : public VFS
{
std::shared_ptr<VFS> parent;
VFSPath path;
VFSPath ToParent(VFSPath path);
VFSPath FromParent(VFSPath path);
public:
SubdirFilesystem(std::shared_ptr<VFS> parent, VFSPath path);
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
void DeleteDirectoryRecurse(VFSPath path);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
~SubdirFilesystem();
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData& vfsData);
bool Stat(VFSPath path, StatData& data);
namespace Tesses::Framework::Filesystem {
class SubdirFilesystem : public VFS {
std::shared_ptr<VFS> parent;
VFSPath path;
VFSPath ToParent(VFSPath path);
VFSPath FromParent(VFSPath path);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
void Chmod(VFSPath path, uint32_t mode);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
public:
SubdirFilesystem(std::shared_ptr<VFS> parent, VFSPath path);
std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
void DeleteDirectoryRecurse(VFSPath path);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
~SubdirFilesystem();
void SetDate(VFSPath path, Date::DateTime lastWrite,
Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData &vfsData);
bool Stat(VFSPath path, StatData &data);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
void Chmod(VFSPath path, uint32_t mode);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs,
VFSPath path);
class Watcher : public FSWatcher {
std::shared_ptr<FSWatcher> watcher;
class Watcher : public FSWatcher {
std::shared_ptr<FSWatcher> watcher;
protected:
void SetEnabledImpl(bool enabled);
public:
Watcher(std::shared_ptr<SubdirFilesystem> vfs, VFSPath path);
~Watcher();
};
protected:
void SetEnabledImpl(bool enabled);
public:
Watcher(std::shared_ptr<SubdirFilesystem> vfs, VFSPath path);
~Watcher();
};
}
};
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,52 +1,71 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
#include "VFS.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
void UniqueString(std::string& text);
namespace Tesses::Framework::Filesystem {
void UniqueString(std::string &text);
class TempFS : public VFS
{
std::shared_ptr<VFS> vfs;
bool deleteOnDestroy;
std::shared_ptr<VFS> parent;
std::string tmp_str;
public:
std::string TempDirectoryName();
TempFS(bool deleteOnDestroy=true);
TempFS(std::shared_ptr<VFS> vfs,bool deleteOnDestroy=true);
class TempFS : public VFS {
std::shared_ptr<VFS> vfs;
bool deleteOnDestroy;
std::shared_ptr<VFS> parent;
std::string tmp_str;
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
void DeleteDirectoryRecurse(VFSPath path);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
public:
std::string TempDirectoryName();
TempFS(bool deleteOnDestroy = true);
TempFS(std::shared_ptr<VFS> vfs, bool deleteOnDestroy = true);
void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData& vfsData);
bool Stat(VFSPath path, StatData& data);
std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode);
void CreateDirectory(VFSPath path);
void DeleteDirectory(VFSPath path);
void DeleteFile(VFSPath path);
void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
VFSPathEnumerator EnumeratePaths(VFSPath path);
void CreateHardlink(VFSPath existingFile, VFSPath newName);
void MoveFile(VFSPath src, VFSPath dest);
void MoveDirectory(VFSPath src, VFSPath dest);
void DeleteDirectoryRecurse(VFSPath path);
VFSPath ReadLink(VFSPath path);
std::string VFSPathToSystem(VFSPath path);
VFSPath SystemToVFSPath(std::string path);
void Chmod(VFSPath path, uint32_t mode);
void SetDate(VFSPath path, Date::DateTime lastWrite,
Date::DateTime lastAccess);
bool StatVFS(VFSPath path, StatVFSData &vfsData);
bool Stat(VFSPath path, StatData &data);
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Close();
void Chmod(VFSPath path, uint32_t mode);
void Lock(VFSPath path);
void Unlock(VFSPath path);
~TempFS();
void Chown(VFSPath path, uint32_t uid, uint32_t gid);
FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
void Close();
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
void Lock(VFSPath path);
void Unlock(VFSPath path);
~TempFS();
};
}
protected:
std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs,
VFSPath path);
};
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,343 +1,336 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
#include "../Date/Date.hpp"
#include "../Streams/Stream.hpp"
#include "VFSFix.hpp"
#include <TessesFramework/Common.hpp>
#include <TessesFramework/Date/Date.hpp>
#include <functional>
#include <memory>
#include "../Date/Date.hpp"
#include "VFSFix.hpp"
namespace Tesses::Framework::Filesystem
{
namespace Tesses::Framework::Filesystem {
struct StatVFSData {
struct StatVFSData {
uint64_t BlockSize;
uint64_t FragmentSize;
uint64_t Blocks;
uint64_t BlocksFree;
uint64_t BlocksAvailable;
uint64_t TotalInodes;
uint64_t FreeInodes;
uint64_t AvailableInodes;
uint64_t Id;
uint64_t Flags;
uint64_t MaxNameLength;
};
uint64_t BlockSize;
uint64_t FragmentSize;
uint64_t Blocks;
uint64_t BlocksFree;
uint64_t BlocksAvailable;
uint64_t TotalInodes;
uint64_t FreeInodes;
uint64_t AvailableInodes;
uint64_t Id;
uint64_t Flags;
uint64_t MaxNameLength;
};
constexpr uint32_t MODE_USER_READ = 0400;
constexpr uint32_t MODE_USER_WRITE = 0200;
constexpr uint32_t MODE_USER_EXEC = 0100;
constexpr uint32_t MODE_USER_READ = 0400;
constexpr uint32_t MODE_USER_WRITE = 0200;
constexpr uint32_t MODE_USER_EXEC = 0100;
constexpr uint32_t MODE_GROUP_READ = (MODE_USER_READ >> 3);
constexpr uint32_t MODE_GROUP_WRITE = (MODE_USER_WRITE >> 3);
constexpr uint32_t MODE_GROUP_EXEC = (MODE_USER_EXEC >> 3);
constexpr uint32_t MODE_GROUP_READ = (MODE_USER_READ >> 3);
constexpr uint32_t MODE_GROUP_WRITE = (MODE_USER_WRITE >> 3);
constexpr uint32_t MODE_GROUP_EXEC = (MODE_USER_EXEC >> 3);
constexpr uint32_t MODE_OTHER_READ = (MODE_GROUP_READ >> 3);
constexpr uint32_t MODE_OTHER_WRITE = (MODE_GROUP_WRITE >> 3);
constexpr uint32_t MODE_OTHER_EXEC = (MODE_GROUP_EXEC >> 3);
constexpr uint32_t MODE_OTHER_READ = (MODE_GROUP_READ >> 3);
constexpr uint32_t MODE_OTHER_WRITE = (MODE_GROUP_WRITE >> 3);
constexpr uint32_t MODE_OTHER_EXEC = (MODE_GROUP_EXEC >> 3);
constexpr uint32_t MODE_REGULAR = 0100000;
constexpr uint32_t MODE_DIRECTORY = 0040000;
constexpr uint32_t MODE_CHAR_DEVICE = 0020000;
constexpr uint32_t MODE_BLOCK_DEVICE = 0060000;
constexpr uint32_t MODE_SOCKET = 0140000;
constexpr uint32_t MODE_FIFO = 0010000;
constexpr uint32_t MODE_SYMLINK = 0120000;
constexpr uint32_t MODE_REGULAR = 0100000;
constexpr uint32_t MODE_DIRECTORY = 0040000;
constexpr uint32_t MODE_CHAR_DEVICE = 0020000;
constexpr uint32_t MODE_BLOCK_DEVICE = 0060000;
constexpr uint32_t MODE_SOCKET = 0140000;
constexpr uint32_t MODE_FIFO = 0010000;
constexpr uint32_t MODE_SYMLINK = 0120000;
struct StatData {
uint64_t Device;
uint64_t Inode;
uint32_t Mode;
uint64_t HardLinks;
uint32_t UserId;
uint32_t GroupId;
uint64_t DeviceId;
uint64_t Size;
uint64_t BlockSize;
uint64_t BlockCount;
Date::DateTime LastAccess;
Date::DateTime LastModified;
Date::DateTime LastStatus;
struct StatData {
uint64_t Device;
uint64_t Inode;
uint32_t Mode;
uint64_t HardLinks;
uint32_t UserId;
uint32_t GroupId;
uint64_t DeviceId;
uint64_t Size;
uint64_t BlockSize;
uint64_t BlockCount;
Date::DateTime LastAccess;
Date::DateTime LastModified;
Date::DateTime LastStatus;
bool IsRegularFile() { return (Mode & MODE_REGULAR) > 0; }
bool IsDirectory() { return (Mode & MODE_DIRECTORY) > 0; }
bool IsRegularFile()
{
return (Mode & MODE_REGULAR) > 0;
}
bool IsDirectory()
{
return (Mode & MODE_DIRECTORY) > 0;
}
bool IsCharDevice() { return (Mode & MODE_CHAR_DEVICE) > 0; }
bool IsCharDevice()
{
return (Mode & MODE_CHAR_DEVICE) > 0;
}
bool IsBlockDevice() { return (Mode & MODE_BLOCK_DEVICE) > 0; }
bool IsBlockDevice()
{
return (Mode & MODE_BLOCK_DEVICE) > 0;
}
bool IsSocket() { return (Mode & MODE_SOCKET) > 0; }
bool IsFIFO() { return (Mode & MODE_FIFO) > 0; }
bool IsSocket()
{
return (Mode & MODE_SOCKET) > 0;
}
bool IsFIFO()
{
return (Mode & MODE_FIFO) > 0;
}
bool IsSymlink() { return (Mode & MODE_SYMLINK) > 0; }
bool IsSymlink()
{
return (Mode & MODE_SYMLINK) > 0;
}
bool IsSpecial()
{
if(IsRegularFile()) return false;
if(IsDirectory()) return false;
return true;
}
std::string ToSizeString(bool usesBin=true)
{
return TF_FileSize(this->Size, usesBin);
}
};
class VFSPath {
public:
static VFSPath CurrentDirectoryAsRelative();
bool relative;
static std::vector<std::string> SplitPath(std::string path);
std::vector<std::string> path;
VFSPath();
explicit VFSPath(const char* path) : VFSPath(std::string(path))
{}
VFSPath(std::vector<std::string> path);
VFSPath(std::string path);
VFSPath(VFSPath p, std::string subent);
VFSPath(VFSPath p, VFSPath p2);
//does not check for ?
static VFSPath ParseUriPath(std::string path);
VFSPath GetParent() const;
VFSPath CollapseRelativeParents() const;
std::string GetFileName() const;
bool HasExtension() const;
std::string GetExtension() const;
void ChangeExtension(std::string ext);
void RemoveExtension();
std::string ToString() const;
static VFSPath GetAbsoluteCurrentDirectory();
static void SetAbsoluteCurrentDirectory(VFSPath path);
VFSPath MakeAbsolute() const;
VFSPath MakeAbsolute(VFSPath curDir) const;
VFSPath MakeRelative() const;
VFSPath MakeRelative(VFSPath toMakeRelativeTo) const;
};
VFSPath operator/(VFSPath p, VFSPath p2);
VFSPath operator/(VFSPath p, std::string p2);
VFSPath operator/(std::string p, VFSPath p2);
VFSPath operator+(VFSPath p, VFSPath p2);
VFSPath operator+(VFSPath p, std::string p2);
VFSPath operator+(std::string p, VFSPath p2);
bool operator==(VFSPath p,VFSPath p2);
bool operator!=(VFSPath p,VFSPath p2);
bool operator==(std::string p,VFSPath p2);
bool operator!=(std::string p,VFSPath p2);
bool operator==(VFSPath p,std::string p2);
bool operator!=(VFSPath p,std::string p2);
class VFSPathEnumeratorData {
public:
VFSPathEnumeratorData(std::function<bool(VFSPath&)> moveNext, std::function<void()> destroy)
{
this->eof=false;
this->moveNext=moveNext;
this->destroy=destroy;
}
bool eof;
std::function<bool(VFSPath&)> moveNext;
std::function<void()> destroy;
~VFSPathEnumeratorData()
{
this->destroy();
}
};
class VFSPathEnumerator;
class VFSPathEnumeratorItterator
{
VFSPath e;
VFSPathEnumerator* enumerator;
public:
VFSPathEnumeratorItterator();
VFSPathEnumeratorItterator(VFSPathEnumerator* enumerator);
VFSPathEnumeratorItterator& operator++();
VFSPathEnumeratorItterator& operator++(int);
VFSPath& operator*();
VFSPath* operator->();
bool operator!=(VFSPathEnumeratorItterator right);
bool operator==(VFSPathEnumeratorItterator right);
};
class VFSPathEnumerator {
std::shared_ptr<VFSPathEnumeratorData> data;
public:
VFSPathEnumerator();
VFSPathEnumerator* MakePointer();
VFSPathEnumerator(std::function<bool(VFSPath&)> moveNext, std::function<void()> destroy);
VFSPath Current;
bool MoveNext();
bool IsDone();
VFSPathEnumeratorItterator begin();
VFSPathEnumeratorItterator end();
};
enum class FSWatcherEventType {
None = 0,
//IN_ACCESS
Accessed=1,
//IN_ATTRIB
AttributeChanged =2,
//IN_CLOSE_WRITE
Writen = 4,
//IN_CLOSE_NOWRITE
Read = 8,
//IN_CREATE
Created = 16,
//IN_DELETE
Deleted = 32,
//IN_DELETE_SELF
WatchEntryDeleted = 64,
//IN_MODIFY
Modified = 128,
//IN_MOVE_SELF
WatchEntryMoved = 256,
//IN_MOVED_FROM
MoveOld = 512,
//IN_MOVED_TO
MoveNew = 1024,
//IN_OPEN
Opened = 2048,
//IN_CLOSE
Closed = Writen | Read,
//IN_MOVE
Moved = MoveOld | MoveNew,
//IN_ALL_EVENTS
All = Accessed | AttributeChanged | Created | Deleted | WatchEntryDeleted | Modified | WatchEntryMoved | Opened | Closed | Moved
};
struct FSWatcherEvent {
//the file or source on move
VFSPath src;
//the dest when moving
VFSPath dest;
FSWatcherEventType type;
bool isDir;
bool IsEvent(FSWatcherEventType e);
std::string ToString();
};
class VFS;
class FSWatcher {
private:
std::shared_ptr<VFS> vfs;
VFSPath path;
protected:
std::atomic<bool> enabled=false;
virtual void SetEnabledImpl(bool enabled);
public:
FSWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
std::function<void(FSWatcherEvent&)> event;
FSWatcherEventType events = FSWatcherEventType::All;
bool GetEnabled();
void SetEnabled(bool val);
std::shared_ptr<VFS> GetFilesystem();
const VFSPath& GetPath();
virtual ~FSWatcher() = default;
static std::shared_ptr<FSWatcher> Create(std::shared_ptr<VFS> vfs, VFSPath path);
};
enum class FIFOCreationResult {
Success=0,
Exists = 1,
ReadOnlyFS = 2,
Denied = 3,
OutOfInodes = 4,
UnknownError = 5,
Unsupported = 255
};
class VFS {
public:
virtual std::shared_ptr<Tesses::Framework::Streams::Stream> OpenFile(VFSPath path, std::string mode)=0;
virtual void CreateDirectory(VFSPath path);
virtual void DeleteDirectory(VFSPath path);
bool DirectoryExists(VFSPath path);
bool RegularFileExists(VFSPath path);
bool SymlinkExists(VFSPath path);
bool CharacterDeviceExists(VFSPath path);
bool BlockDeviceExists(VFSPath path);
bool SocketFileExists(VFSPath path);
bool FIFOFileExists(VFSPath path);
bool FileExists(VFSPath path);
bool SpecialFileExists(VFSPath path);
virtual void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
virtual void CreateHardlink(VFSPath existingFile, VFSPath newName);
virtual void DeleteFile(VFSPath path);
virtual void DeleteDirectoryRecurse(VFSPath path);
virtual VFSPathEnumerator EnumeratePaths(VFSPath path) = 0;
virtual void MoveFile(VFSPath src, VFSPath dest);
virtual void MoveDirectory(VFSPath src, VFSPath dest);
virtual VFSPath ReadLink(VFSPath path);
virtual std::string VFSPathToSystem(VFSPath path)=0;
virtual VFSPath SystemToVFSPath(std::string path)=0;
void GetDate(VFSPath path, Date::DateTime& lastWrite, Date::DateTime& lastAccess);
virtual void SetDate(VFSPath path, Date::DateTime lastWrite, Date::DateTime lastAccess);
virtual bool Stat(VFSPath path, StatData& data) = 0;
virtual bool StatVFS(VFSPath path, StatVFSData& data);
virtual void Chmod(VFSPath path, uint32_t mode);
virtual void Chown(VFSPath path, uint32_t userId, uint32_t groupId);
virtual void Lock(VFSPath path);
virtual void Unlock(VFSPath path);
virtual FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
virtual ~VFS();
virtual void Close();
protected:
virtual std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
friend class FSWatcher;
};
namespace Literals
{
inline VFSPath operator""_tpath(const char* path)
{
return VFSPath(path);
}
bool IsSpecial() {
if (IsRegularFile())
return false;
if (IsDirectory())
return false;
return true;
}
}
std::string ToSizeString(bool usesBin = true) {
return TF_FileSize(this->Size, usesBin);
}
};
class VFSPath {
public:
static VFSPath CurrentDirectoryAsRelative();
bool relative;
static std::vector<std::string> SplitPath(std::string path);
std::vector<std::string> path;
VFSPath();
explicit VFSPath(const char *path) : VFSPath(std::string(path)) {}
VFSPath(std::vector<std::string> path);
VFSPath(std::string path);
VFSPath(VFSPath p, std::string subent);
VFSPath(VFSPath p, VFSPath p2);
// does not check for ?
static VFSPath ParseUriPath(std::string path);
VFSPath GetParent() const;
VFSPath CollapseRelativeParents() const;
std::string GetFileName() const;
bool HasExtension() const;
std::string GetExtension() const;
void ChangeExtension(std::string ext);
void RemoveExtension();
std::string ToString() const;
static VFSPath GetAbsoluteCurrentDirectory();
static void SetAbsoluteCurrentDirectory(VFSPath path);
VFSPath MakeAbsolute() const;
VFSPath MakeAbsolute(VFSPath curDir) const;
VFSPath MakeRelative() const;
VFSPath MakeRelative(VFSPath toMakeRelativeTo) const;
};
VFSPath operator/(VFSPath p, VFSPath p2);
VFSPath operator/(VFSPath p, std::string p2);
VFSPath operator/(std::string p, VFSPath p2);
VFSPath operator+(VFSPath p, VFSPath p2);
VFSPath operator+(VFSPath p, std::string p2);
VFSPath operator+(std::string p, VFSPath p2);
bool operator==(VFSPath p, VFSPath p2);
bool operator!=(VFSPath p, VFSPath p2);
bool operator==(std::string p, VFSPath p2);
bool operator!=(std::string p, VFSPath p2);
bool operator==(VFSPath p, std::string p2);
bool operator!=(VFSPath p, std::string p2);
class VFSPathEnumeratorData {
public:
VFSPathEnumeratorData(std::function<bool(VFSPath &)> moveNext,
std::function<void()> destroy) {
this->eof = false;
this->moveNext = moveNext;
this->destroy = destroy;
}
bool eof;
std::function<bool(VFSPath &)> moveNext;
std::function<void()> destroy;
~VFSPathEnumeratorData() { this->destroy(); }
};
class VFSPathEnumerator;
class VFSPathEnumeratorItterator {
VFSPath e;
VFSPathEnumerator *enumerator;
public:
VFSPathEnumeratorItterator();
VFSPathEnumeratorItterator(VFSPathEnumerator *enumerator);
VFSPathEnumeratorItterator &operator++();
VFSPathEnumeratorItterator &operator++(int);
VFSPath &operator*();
VFSPath *operator->();
bool operator!=(VFSPathEnumeratorItterator right);
bool operator==(VFSPathEnumeratorItterator right);
};
class VFSPathEnumerator {
std::shared_ptr<VFSPathEnumeratorData> data;
public:
VFSPathEnumerator();
VFSPathEnumerator *MakePointer();
VFSPathEnumerator(std::function<bool(VFSPath &)> moveNext,
std::function<void()> destroy);
VFSPath Current;
bool MoveNext();
bool IsDone();
VFSPathEnumeratorItterator begin();
VFSPathEnumeratorItterator end();
};
enum class FSWatcherEventType {
None = 0,
// IN_ACCESS
Accessed = 1,
// IN_ATTRIB
AttributeChanged = 2,
// IN_CLOSE_WRITE
Writen = 4,
// IN_CLOSE_NOWRITE
Read = 8,
// IN_CREATE
Created = 16,
// IN_DELETE
Deleted = 32,
// IN_DELETE_SELF
WatchEntryDeleted = 64,
// IN_MODIFY
Modified = 128,
// IN_MOVE_SELF
WatchEntryMoved = 256,
// IN_MOVED_FROM
MoveOld = 512,
// IN_MOVED_TO
MoveNew = 1024,
// IN_OPEN
Opened = 2048,
// IN_CLOSE
Closed = Writen | Read,
// IN_MOVE
Moved = MoveOld | MoveNew,
// IN_ALL_EVENTS
All = Accessed | AttributeChanged | Created | Deleted | WatchEntryDeleted |
Modified | WatchEntryMoved | Opened | Closed | Moved
};
struct FSWatcherEvent {
// the file or source on move
VFSPath src;
// the dest when moving
VFSPath dest;
FSWatcherEventType type;
bool isDir;
bool IsEvent(FSWatcherEventType e);
std::string ToString();
};
class VFS;
class FSWatcher {
private:
std::shared_ptr<VFS> vfs;
VFSPath path;
protected:
std::atomic<bool> enabled = false;
virtual void SetEnabledImpl(bool enabled);
public:
FSWatcher(std::shared_ptr<VFS> vfs, VFSPath path);
std::function<void(FSWatcherEvent &)> event;
FSWatcherEventType events = FSWatcherEventType::All;
bool GetEnabled();
void SetEnabled(bool val);
std::shared_ptr<VFS> GetFilesystem();
const VFSPath &GetPath();
virtual ~FSWatcher() = default;
static std::shared_ptr<FSWatcher> Create(std::shared_ptr<VFS> vfs,
VFSPath path);
};
enum class FIFOCreationResult {
Success = 0,
Exists = 1,
ReadOnlyFS = 2,
Denied = 3,
OutOfInodes = 4,
UnknownError = 5,
Unsupported = 255
};
class VFS {
public:
virtual std::shared_ptr<Tesses::Framework::Streams::Stream>
OpenFile(VFSPath path, std::string mode) = 0;
virtual void CreateDirectory(VFSPath path);
virtual void DeleteDirectory(VFSPath path);
bool DirectoryExists(VFSPath path);
bool RegularFileExists(VFSPath path);
bool SymlinkExists(VFSPath path);
bool CharacterDeviceExists(VFSPath path);
bool BlockDeviceExists(VFSPath path);
bool SocketFileExists(VFSPath path);
bool FIFOFileExists(VFSPath path);
bool FileExists(VFSPath path);
bool SpecialFileExists(VFSPath path);
virtual void CreateSymlink(VFSPath existingFile, VFSPath symlinkFile);
virtual void CreateHardlink(VFSPath existingFile, VFSPath newName);
virtual void DeleteFile(VFSPath path);
virtual void DeleteDirectoryRecurse(VFSPath path);
virtual VFSPathEnumerator EnumeratePaths(VFSPath path) = 0;
virtual void MoveFile(VFSPath src, VFSPath dest);
virtual void MoveDirectory(VFSPath src, VFSPath dest);
virtual VFSPath ReadLink(VFSPath path);
virtual std::string VFSPathToSystem(VFSPath path) = 0;
virtual VFSPath SystemToVFSPath(std::string path) = 0;
void GetDate(VFSPath path, Date::DateTime &lastWrite,
Date::DateTime &lastAccess);
virtual void SetDate(VFSPath path, Date::DateTime lastWrite,
Date::DateTime lastAccess);
virtual bool Stat(VFSPath path, StatData &data) = 0;
virtual bool StatVFS(VFSPath path, StatVFSData &data);
virtual void Chmod(VFSPath path, uint32_t mode);
virtual void Chown(VFSPath path, uint32_t userId, uint32_t groupId);
virtual void Lock(VFSPath path);
virtual void Unlock(VFSPath path);
virtual FIFOCreationResult CreateFIFO(VFSPath path, uint32_t mode);
virtual ~VFS();
virtual void Close();
protected:
virtual std::shared_ptr<FSWatcher> CreateWatcher(std::shared_ptr<VFS> vfs,
VFSPath path);
friend class FSWatcher;
};
namespace Literals {
inline VFSPath operator""_tpath(const char *path) { return VFSPath(path); }
} // namespace Literals
} // namespace Tesses::Framework::Filesystem

View File

@@ -1,3 +1,21 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#undef CreateDirectory
#undef DeleteDirectory
#undef DeleteFile

View File

@@ -1,32 +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
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/>.
*/
#pragma once
#include <functional>
namespace Tesses::Framework {
class HiddenFieldData {
public:
virtual ~HiddenFieldData();
public:
virtual ~HiddenFieldData();
};
class HiddenField {
private:
HiddenFieldData* ptr;
public:
HiddenField();
HiddenField(HiddenFieldData* data);
void SetField(HiddenFieldData* data);
template<typename T>
T GetField()
{
return dynamic_cast<T>(ptr);
}
template<typename T>
T* AllocField()
{
auto v = new T();
SetField(v);
return v;
}
~HiddenField();
private:
HiddenFieldData *ptr;
public:
HiddenField();
HiddenField(HiddenFieldData *data);
void SetField(HiddenFieldData *data);
template <typename T> T GetField() { return dynamic_cast<T>(ptr); }
template <typename T> T *AllocField() {
auto v = new T();
SetField(v);
return v;
}
~HiddenField();
};
}
} // namespace Tesses::Framework

View File

@@ -1,18 +1,39 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "HttpServer.hpp"
namespace Tesses::Framework::Http {
class BasicAuthServer : public Tesses::Framework::Http::IHttpServer
{
public:
std::shared_ptr<IHttpServer> server;
std::function<bool(std::string username, std::string password)> authorization;
std::string realm;
class BasicAuthServer : public Tesses::Framework::Http::IHttpServer {
public:
std::shared_ptr<IHttpServer> server;
std::function<bool(std::string username, std::string password)>
authorization;
std::string realm;
BasicAuthServer();
BasicAuthServer(std::shared_ptr<IHttpServer> server, std::function<bool(std::string username, std::string password)> auth,std::string realm="Protected Content");
bool Handle(ServerContext& ctx);
BasicAuthServer();
BasicAuthServer(
std::shared_ptr<IHttpServer> server,
std::function<bool(std::string username, std::string password)> auth,
std::string realm = "Protected Content");
bool Handle(ServerContext &ctx);
static bool GetCreds(ServerContext& ctx, std::string& user, std::string& pass);
};
}
static bool GetCreds(ServerContext &ctx, std::string &user,
std::string &pass);
};
} // namespace Tesses::Framework::Http

View File

@@ -1,23 +1,42 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Filesystem/VFS.hpp"
#include "../Filesystem/VFSFix.hpp"
#include "HttpServer.hpp"
#include <optional>
namespace Tesses::Framework::Http {
struct CGIParams {
std::optional<Tesses::Framework::Filesystem::VFSPath> document_root;
Tesses::Framework::Filesystem::VFSPath program;
std::optional<std::string> adminEmail;
std::optional<Tesses::Framework::Filesystem::VFSPath> workingDirectory;
};
class CGIServer : public Tesses::Framework::Http::IHttpServer {
Tesses::Framework::Filesystem::VFSPath dir;
public:
std::optional<Tesses::Framework::Filesystem::VFSPath> document_root;
std::optional<std::string> adminEmail;
std::optional<Tesses::Framework::Filesystem::VFSPath> workingDirectory;
CGIServer(Tesses::Framework::Filesystem::VFSPath dir);
bool Handle(ServerContext& ctx);
static bool ServeCGIRequest(ServerContext& ctx, CGIParams& params);
};
}
struct CGIParams {
std::optional<Tesses::Framework::Filesystem::VFSPath> document_root;
Tesses::Framework::Filesystem::VFSPath program;
std::optional<std::string> adminEmail;
std::optional<Tesses::Framework::Filesystem::VFSPath> workingDirectory;
};
class CGIServer : public Tesses::Framework::Http::IHttpServer {
Tesses::Framework::Filesystem::VFSPath dir;
public:
std::optional<Tesses::Framework::Filesystem::VFSPath> document_root;
std::optional<std::string> adminEmail;
std::optional<Tesses::Framework::Filesystem::VFSPath> workingDirectory;
CGIServer(Tesses::Framework::Filesystem::VFSPath dir);
bool Handle(ServerContext &ctx);
static bool ServeCGIRequest(ServerContext &ctx, CGIParams &params);
};
} // namespace Tesses::Framework::Http

View File

@@ -1,16 +1,34 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "HttpServer.hpp"
namespace Tesses::Framework::Http
{
class CallbackServer : public IHttpServer
{
std::function<bool(ServerContext&)> cb;
std::function<void()> destroy;
public:
CallbackServer(std::function<bool(ServerContext&)> cb);
CallbackServer(std::function<bool(ServerContext&)> cb,std::function<void()> destroy);
bool Handle(ServerContext& ctx);
~CallbackServer();
};
}
namespace Tesses::Framework::Http {
class CallbackServer : public IHttpServer {
std::function<bool(ServerContext &)> cb;
std::function<void()> destroy;
public:
CallbackServer(std::function<bool(ServerContext &)> cb);
CallbackServer(std::function<bool(ServerContext &)> cb,
std::function<void()> destroy);
bool Handle(ServerContext &ctx);
~CallbackServer();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,14 +1,31 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "HttpServer.hpp"
namespace Tesses::Framework::Http
{
class ChangeableServer {
public:
ChangeableServer();
ChangeableServer(std::shared_ptr<IHttpServer> original);
std::shared_ptr<IHttpServer> server;
bool Handle(ServerContext& ctx);
~ChangeableServer();
};
}
namespace Tesses::Framework::Http {
class ChangeableServer {
public:
ChangeableServer();
ChangeableServer(std::shared_ptr<IHttpServer> original);
std::shared_ptr<IHttpServer> server;
bool Handle(ServerContext &ctx);
~ChangeableServer();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,13 +1,30 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
namespace Tesses::Framework::Http
{
class ContentDisposition {
public:
std::string filename;
std::string type;
std::string fieldName;
static bool TryParse(std::string str, ContentDisposition& cd);
std::string ToString();
};
}
namespace Tesses::Framework::Http {
class ContentDisposition {
public:
std::string filename;
std::string type;
std::string fieldName;
static bool TryParse(std::string str, ContentDisposition &cd);
std::string ToString();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,25 +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
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/>.
*/
#pragma once
#include "../Filesystem/VFS.hpp"
#include "HttpServer.hpp"
namespace Tesses::Framework::Http
{
class FileServer : public IHttpServer
{
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
namespace Tesses::Framework::Http {
class FileServer : public IHttpServer {
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs;
bool SendFile(ServerContext& ctx,Tesses::Framework::Filesystem::VFSPath path);
public:
bool allowListing;
bool spa;
std::vector<std::string> defaultNames;
FileServer(std::filesystem::path path,bool allowListing,bool spa);
FileServer(std::filesystem::path path,bool allowListing, bool spa, std::vector<std::string> defaultNames);
FileServer(std::shared_ptr<Tesses::Framework::Filesystem::VFS> fs, bool allowListing, bool spa);
FileServer(std::shared_ptr<Tesses::Framework::Filesystem::VFS> fs, bool allowListing, bool spa, std::vector<std::string> defaultNames);
bool Handle(ServerContext& ctx);
~FileServer();
};
}
bool SendFile(ServerContext &ctx,
Tesses::Framework::Filesystem::VFSPath path);
public:
bool allowListing;
bool spa;
std::vector<std::string> defaultNames;
FileServer(std::filesystem::path path, bool allowListing, bool spa);
FileServer(std::filesystem::path path, bool allowListing, bool spa,
std::vector<std::string> defaultNames);
FileServer(std::shared_ptr<Tesses::Framework::Filesystem::VFS> fs,
bool allowListing, bool spa);
FileServer(std::shared_ptr<Tesses::Framework::Filesystem::VFS> fs,
bool allowListing, bool spa,
std::vector<std::string> defaultNames);
bool Handle(ServerContext &ctx);
~FileServer();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,95 +1,139 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/Stream.hpp"
#include "HttpUtils.hpp"
#include "WebSocket.hpp"
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Filesystem/VFSFix.hpp"
namespace Tesses::Framework::Http
{
class HttpRequestBody {
public:
virtual void HandleHeaders(HttpDictionary& dict);
virtual void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)=0;
virtual ~HttpRequestBody();
};
#include "WebSocket.hpp"
namespace Tesses::Framework::Http {
class StreamHttpRequestBody : public HttpRequestBody {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::string mimeType;
public:
StreamHttpRequestBody(std::shared_ptr<Tesses::Framework::Streams::Stream> strm, std::string mimeType);
void HandleHeaders(HttpDictionary& dict);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
~StreamHttpRequestBody();
};
class HttpRequestBody {
public:
virtual void HandleHeaders(HttpDictionary &dict);
virtual void
Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) = 0;
virtual ~HttpRequestBody();
};
class TextHttpRequestBody : public HttpRequestBody {
std::string text;
std::string mimeType;
public:
TextHttpRequestBody(std::string text, std::string mimeType);
void HandleHeaders(HttpDictionary& dict);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
~TextHttpRequestBody();
};
class StreamHttpRequestBody : public HttpRequestBody {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::string mimeType;
class HttpRequest {
public:
HttpRequest();
std::string trusted_root_cert_bundle;
bool ignoreSSLErrors;
bool followRedirects;
public:
StreamHttpRequestBody(
std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
std::string mimeType);
void HandleHeaders(HttpDictionary &dict);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
~StreamHttpRequestBody();
};
std::string method;
std::string url;
std::string unixSocket;
HttpDictionary requestHeaders;
HttpRequestBody* body;
class TextHttpRequestBody : public HttpRequestBody {
std::string text;
std::string mimeType;
static std::shared_ptr<Tesses::Framework::Streams::Stream> EstablishConnection(Uri uri,bool ignoreSSLErrors,std::string trusted_root_cert_bundle);
static std::shared_ptr<Tesses::Framework::Streams::Stream> EstablishUnixPathConnection(std::string unixPath, Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle);
public:
TextHttpRequestBody(std::string text, std::string mimeType);
void HandleHeaders(HttpDictionary &dict);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
~TextHttpRequestBody();
};
void SendRequest(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
};
class HttpRequest {
public:
HttpRequest();
std::string trusted_root_cert_bundle;
bool ignoreSSLErrors;
bool followRedirects;
class HttpResponse {
private:
bool owns;
std::shared_ptr<Tesses::Framework::Streams::Stream> handleStrm;
public:
HttpResponse(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
HttpResponse(HttpRequest& request);
std::string version;
StatusCode statusCode;
HttpDictionary responseHeaders;
std::string ReadAsString();
std::shared_ptr<Tesses::Framework::Streams::Stream> ReadAsStream();
void CopyToStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::shared_ptr<Tesses::Framework::Streams::Stream> GetInternalStream();
~HttpResponse();
};
std::string method;
std::string url;
std::string unixSocket;
HttpDictionary requestHeaders;
HttpRequestBody *body;
void DownloadToStreamSimple(std::string url, std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
static std::shared_ptr<Tesses::Framework::Streams::Stream>
EstablishConnection(Uri uri, bool ignoreSSLErrors,
std::string trusted_root_cert_bundle);
static std::shared_ptr<Tesses::Framework::Streams::Stream>
EstablishUnixPathConnection(std::string unixPath, Uri uri,
bool ignoreSSLErrors,
std::string trusted_root_cert_bundle);
void DownloadToFileSimple(std::string url, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path);
void SendRequest(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
};
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFSPath path);
std::string DownloadToStringSimple(std::string url);
bool WebSocketClientSuccessDefault(HttpDictionary& dict,bool v);
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, std::shared_ptr<WebSocketConnection> wsc, std::function<bool(HttpDictionary&,bool)> cb=WebSocketClientSuccessDefault);
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
class HttpResponse {
private:
bool owns;
std::shared_ptr<Tesses::Framework::Streams::Stream> handleStrm;
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs, Tesses::Framework::Filesystem::VFSPath path);
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFSPath path);
std::string DownloadUnixSocketToStringSimple(std::string unixSocket,std::string url);
public:
HttpResponse(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
HttpResponse(HttpRequest &request);
std::string version;
StatusCode statusCode;
HttpDictionary responseHeaders;
std::string ReadAsString();
std::shared_ptr<Tesses::Framework::Streams::Stream> ReadAsStream();
void CopyToStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::shared_ptr<Tesses::Framework::Streams::Stream> GetInternalStream();
~HttpResponse();
};
void DownloadToStreamSimple(
std::string url, std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, std::shared_ptr<WebSocketConnection> wsc, std::function<bool(HttpDictionary&,bool)> cb=WebSocketClientSuccessDefault);
}
void DownloadToFileSimple(
std::string url, std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
Tesses::Framework::Filesystem::VFSPath path);
void DownloadToFileSimple(std::string url,
Tesses::Framework::Filesystem::VFSPath path);
std::string DownloadToStringSimple(std::string url);
bool WebSocketClientSuccessDefault(HttpDictionary &dict, bool v);
void WebSocketClient(std::string url, HttpDictionary &requestHeaders,
std::shared_ptr<WebSocketConnection> wsc,
std::function<bool(HttpDictionary &, bool)> cb =
WebSocketClientSuccessDefault);
void DownloadUnixSocketToStreamSimple(
std::string unixSocket, std::string url,
std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
void DownloadUnixSocketToFileSimple(
std::string unixSocket, std::string url,
std::shared_ptr<Tesses::Framework::Filesystem::VFS> vfs,
Tesses::Framework::Filesystem::VFSPath path);
void DownloadUnixSocketToFileSimple(
std::string unixSocket, std::string url,
Tesses::Framework::Filesystem::VFSPath path);
std::string DownloadUnixSocketToStringSimple(std::string unixSocket,
std::string url);
void WebSocketUnixSocketClient(std::string unixSocket, std::string url,
HttpDictionary &requestHeaders,
std::shared_ptr<WebSocketConnection> wsc,
std::function<bool(HttpDictionary &, bool)> cb =
WebSocketClientSuccessDefault);
} // namespace Tesses::Framework::Http

View File

@@ -1,138 +1,170 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/NetworkStream.hpp"
#include "HttpUtils.hpp"
#include "../Threading/Thread.hpp"
#include "../Date/Date.hpp"
#include <unordered_map>
#include "../Threading/Thread.hpp"
#include "HttpUtils.hpp"
#include "WebSocket.hpp"
#include <queue>
namespace Tesses::Framework::Http
{
class ServerContextData {
public:
virtual ~ServerContextData();
};
class ServerContext;
class ServerSentEvents {
std::vector<std::shared_ptr<Tesses::Framework::Streams::Stream>> strms;
Tesses::Framework::Threading::Mutex mtx;
private:
void SendEventRaw(const std::string& evt);
public:
void SendRetry(uint32_t ms);
void SendRetry(std::chrono::milliseconds ms);
void SendRetry(Tesses::Framework::Date::TimeSpan ts);
void SendData(const std::string& message);
void SendData(const std::string& message, const std::string& dataType);
void SendId(const std::string& idVal);
void SendCustomEvent(const std::string& type, const std::string& value);
void SendComment(const std::string& comment);
friend class ServerContext;
};
#include <unordered_map>
namespace Tesses::Framework::Http {
class ServerContextData {
public:
virtual ~ServerContextData();
};
class ServerContext;
class ServerSentEvents {
std::vector<std::shared_ptr<Tesses::Framework::Streams::Stream>> strms;
Tesses::Framework::Threading::Mutex mtx;
private:
void SendEventRaw(const std::string &evt);
class ServerContext {
bool sent;
bool debug;
std::vector<std::shared_ptr<ServerSentEvents>> sse;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::map<std::string,ServerContextData*> data;
std::queue<std::function<bool(ServerContext& ctx)>> headerhandlers;
public:
HttpDictionary requestHeaders;
HttpDictionary responseHeaders;
HttpDictionary queryParams;
//used by path
HttpDictionary pathArguments;
std::string path;
std::string originalPath;
std::string method;
StatusCode statusCode;
std::string ip;
uint16_t port;
uint16_t serverPort;
std::string version;
bool encrypted;
ServerContext(std::shared_ptr<Tesses::Framework::Streams::Stream> strm, bool debug=false);
~ServerContext();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
std::string GetOriginalPathWithQuery();
std::string GetUrlWithQuery();
bool Sent();
bool NeedToParseFormData();
void ParseFormData(std::function<std::shared_ptr<Tesses::Framework::Streams::Stream>(std::string mime, std::string filename, std::string name)> cb);
void ReadStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::string ReadString();
void SendBytes(std::vector<uint8_t> buffer);
void SendText(std::string text);
void SendStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
void SendErrorPage(bool showPath);
void SendNotFound();
void SendBadRequest();
void SendException(std::exception& ex);
void SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse);
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
ServerContext& WithStatusCode(StatusCode code);
ServerContext& WithLastModified(Date::DateTime time);
ServerContext& WithHeader(std::string key, std::string value);
ServerContext& WithSingleHeader(std::string key, std::string value);
ServerContext& WithMimeType(std::string mime);
ServerContext& WithContentDisposition(std::string filename, bool isInline);
ServerContext& WriteHeaders();
ServerContext& WithLocationHeader(std::string url);
ServerContext& WithLocationHeader(std::string url,StatusCode sc);
ServerContext& WithHeaderIntercepter(std::function<bool(ServerContext&)> cb);
ServerContext& WithDebug(bool debug=true);
bool Debug();
void StartWebSocketSession(std::function<void(std::function<void(WebSocketMessage&)>,std::function<void()>,std::function<void()>)> onOpen, std::function<void(WebSocketMessage&)> onReceive, std::function<void(bool)> onClose);
void StartWebSocketSession(std::shared_ptr<WebSocketConnection> connection);
std::string GetServerRoot();
std::string MakeAbsolute(std::string path);
void SendRedirect(std::string url);
void SendRedirect(std::string url, StatusCode sc);
public:
void SendRetry(uint32_t ms);
void SendRetry(std::chrono::milliseconds ms);
void SendRetry(Tesses::Framework::Date::TimeSpan ts);
void SendData(const std::string &message);
void SendData(const std::string &message, const std::string &dataType);
void SendId(const std::string &idVal);
void SendCustomEvent(const std::string &type, const std::string &value);
void SendComment(const std::string &comment);
friend class ServerContext;
};
class ServerContext {
template<class T>
T* GetServerContentData(std::string tag)
{
std::string name = typeid(T).name();
name.push_back(' ');
name.append(tag);
if(data.count(name) > 0) return dynamic_cast<T*>(data[name]);
T* item = new T();
data[name] = item;
return item;
}
friend class ServerSentEvents;
bool sent;
bool debug;
std::vector<std::shared_ptr<ServerSentEvents>> sse;
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
std::map<std::string, ServerContextData *> data;
std::queue<std::function<bool(ServerContext &ctx)>> headerhandlers;
};
public:
HttpDictionary requestHeaders;
HttpDictionary responseHeaders;
HttpDictionary queryParams;
// used by path
HttpDictionary pathArguments;
std::string path;
std::string originalPath;
std::string method;
StatusCode statusCode;
std::string ip;
uint16_t port;
uint16_t serverPort;
std::string version;
bool encrypted;
ServerContext(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
bool debug = false);
~ServerContext();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
std::string GetOriginalPathWithQuery();
std::string GetUrlWithQuery();
bool Sent();
bool NeedToParseFormData();
void ParseFormData(
std::function<std::shared_ptr<Tesses::Framework::Streams::Stream>(
std::string mime, std::string filename, std::string name)>
cb);
void ReadStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::string ReadString();
void SendBytes(std::vector<uint8_t> buffer);
void SendText(std::string text);
void SendStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
void SendErrorPage(bool showPath);
void SendNotFound();
void SendBadRequest();
void SendException(std::exception &ex);
void SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse);
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
ServerContext &WithStatusCode(StatusCode code);
ServerContext &WithLastModified(Date::DateTime time);
ServerContext &WithHeader(std::string key, std::string value);
ServerContext &WithSingleHeader(std::string key, std::string value);
ServerContext &WithMimeType(std::string mime);
ServerContext &WithContentDisposition(std::string filename, bool isInline);
ServerContext &WriteHeaders();
ServerContext &WithLocationHeader(std::string url);
ServerContext &WithLocationHeader(std::string url, StatusCode sc);
ServerContext &
WithHeaderIntercepter(std::function<bool(ServerContext &)> cb);
ServerContext &WithDebug(bool debug = true);
bool Debug();
void StartWebSocketSession(
std::function<void(std::function<void(WebSocketMessage &)>,
std::function<void()>, std::function<void()>)>
onOpen,
std::function<void(WebSocketMessage &)> onReceive,
std::function<void(bool)> onClose);
void StartWebSocketSession(std::shared_ptr<WebSocketConnection> connection);
std::string GetServerRoot();
std::string MakeAbsolute(std::string path);
void SendRedirect(std::string url);
void SendRedirect(std::string url, StatusCode sc);
class IHttpServer {
public:
virtual bool Handle(ServerContext& ctx)=0;
virtual ~IHttpServer();
};
template <class T> T *GetServerContentData(std::string tag) {
std::string name = typeid(T).name();
name.push_back(' ');
name.append(tag);
if (data.count(name) > 0)
return dynamic_cast<T *>(data[name]);
T *item = new T();
data[name] = item;
return item;
}
friend class ServerSentEvents;
};
class HttpServer {
std::shared_ptr<Tesses::Framework::Streams::TcpServer> server;
std::shared_ptr<IHttpServer> http;
Tesses::Framework::Threading::Thread* thrd;
class IHttpServer {
public:
virtual bool Handle(ServerContext &ctx) = 0;
virtual ~IHttpServer();
};
bool showIPs;
bool showARTL;
bool debug;
class HttpServer {
std::shared_ptr<Tesses::Framework::Streams::TcpServer> server;
std::shared_ptr<IHttpServer> http;
Tesses::Framework::Threading::Thread *thrd;
public:
HttpServer(std::shared_ptr<Tesses::Framework::Streams::TcpServer> tcpServer, std::shared_ptr<IHttpServer> http, bool showIPs=true, bool debug=false);
HttpServer(uint16_t port, std::shared_ptr<IHttpServer> http, bool showIPs=true, bool debug=false);
HttpServer(std::string unixPath, std::shared_ptr<IHttpServer> http, bool debug=false);
uint16_t GetPort();
void StartAccepting();
static void Process(std::shared_ptr<Tesses::Framework::Streams::Stream> strm, std::shared_ptr<IHttpServer> server, std::string ip, uint16_t port,uint16_t serverPort, bool encrypted, bool debug=false);
~HttpServer();
};
}
bool showIPs;
bool showARTL;
bool debug;
public:
HttpServer(std::shared_ptr<Tesses::Framework::Streams::TcpServer> tcpServer,
std::shared_ptr<IHttpServer> http, bool showIPs = true,
bool debug = false);
HttpServer(uint16_t port, std::shared_ptr<IHttpServer> http,
bool showIPs = true, bool debug = false);
HttpServer(std::string unixPath, std::shared_ptr<IHttpServer> http,
bool debug = false);
uint16_t GetPort();
void StartAccepting();
static void
Process(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
std::shared_ptr<IHttpServer> server, std::string ip, uint16_t port,
uint16_t serverPort, bool encrypted, bool debug = false);
~HttpServer();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,31 +1,49 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/Stream.hpp"
namespace Tesses::Framework::Http
{
class HttpStream : public Tesses::Framework::Streams::Stream {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
size_t offset;
size_t read;
int64_t length;
int64_t position;
bool recv;
bool http1_1;
bool done;
namespace Tesses::Framework::Http {
class HttpStream : public Tesses::Framework::Streams::Stream {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
public:
HttpStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm, int64_t length, bool recv, bool http1_1);
bool CanRead();
bool CanWrite();
bool EndOfStream();
int64_t GetLength();
int64_t GetPosition();
size_t Read(uint8_t* buffer, size_t len);
size_t Write(const uint8_t* buffer, size_t len);
void Close();
~HttpStream();
};
}
size_t offset;
size_t read;
int64_t length;
int64_t position;
bool recv;
bool http1_1;
bool done;
public:
HttpStream(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
int64_t length, bool recv, bool http1_1);
bool CanRead();
bool CanWrite();
bool EndOfStream();
int64_t GetLength();
int64_t GetPosition();
size_t Read(uint8_t *buffer, size_t len);
size_t Write(const uint8_t *buffer, size_t len);
void Close();
~HttpStream();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,181 +1,196 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
#include "../Date/Date.hpp"
#include <algorithm>
namespace Tesses::Framework::Http
{
typedef enum StatusCode {
Continue=100,
SwitchingProtocols=101,
Processing=102,
EarlyHints=103,
OK=200,
Created=201,
Accepted=202,
NonAuthoritativeInformation=203,
NoContent=204,
ResetContent=205,
PartialContent=206,
MultiStatus=207,
AlreadyReported=208,
IMUsed=226,
MultipleChoices=300,
MovedPermanently=301,
Found=302,
SeeOther=303,
NotModified=304,
UseProxy=305,
TemporaryRedirect=307,
PermanentRedirect=308,
BadRequest=400,
Unauthorized=401,
PaymentRequired=402,
Forbidden=403,
NotFound=404,
MethodNotAllowed=405,
NotAcceptable=406,
ProxyAuthenticationRequired=407,
RequestTimeout=408,
Conflict=409,
Gone=410,
LengthRequired=411,
PreconditionFailed=412,
PayloadTooLarge=413,
URITooLong=414,
UnsupportedMediaType=415,
RangeNotSatisfiable=416,
ExpectationFailed=417,
ImATeapot=418,
MisdirectedRequest=421,
UnprocessableContent=422,
Locked=423,
FailedDependency=424,
TooEarly=425,
UpgradeRequired=426,
PreconditionRequired=428,
TooManyRequests=429,
RequestHeaderFieldsTooLarge=431,
UnavailableForLegalReasons=451,
InternalServerError=500,
NotImplemented=501,
BadGateway=502,
ServiceUnavailable=503,
GatewayTimeout=504,
HTTPVersionNotSupported=505,
VariantAlsoNegotiates=506,
InsufficientStorage=507,
LoopDetected=508,
NotExtended=510,
NetworkAuthenticationRequired=511
namespace Tesses::Framework::Http {
typedef enum StatusCode {
Continue = 100,
SwitchingProtocols = 101,
Processing = 102,
EarlyHints = 103,
OK = 200,
Created = 201,
Accepted = 202,
NonAuthoritativeInformation = 203,
NoContent = 204,
ResetContent = 205,
PartialContent = 206,
MultiStatus = 207,
AlreadyReported = 208,
IMUsed = 226,
MultipleChoices = 300,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
UseProxy = 305,
TemporaryRedirect = 307,
PermanentRedirect = 308,
BadRequest = 400,
Unauthorized = 401,
PaymentRequired = 402,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
ProxyAuthenticationRequired = 407,
RequestTimeout = 408,
Conflict = 409,
Gone = 410,
LengthRequired = 411,
PreconditionFailed = 412,
PayloadTooLarge = 413,
URITooLong = 414,
UnsupportedMediaType = 415,
RangeNotSatisfiable = 416,
ExpectationFailed = 417,
ImATeapot = 418,
MisdirectedRequest = 421,
UnprocessableContent = 422,
Locked = 423,
FailedDependency = 424,
TooEarly = 425,
UpgradeRequired = 426,
PreconditionRequired = 428,
TooManyRequests = 429,
RequestHeaderFieldsTooLarge = 431,
UnavailableForLegalReasons = 451,
InternalServerError = 500,
NotImplemented = 501,
BadGateway = 502,
ServiceUnavailable = 503,
GatewayTimeout = 504,
HTTPVersionNotSupported = 505,
VariantAlsoNegotiates = 506,
InsufficientStorage = 507,
LoopDetected = 508,
NotExtended = 510,
NetworkAuthenticationRequired = 511
} StatusCode;
struct CaseInsensitiveLess {
CaseInsensitiveLess(const CaseInsensitiveLess& str);
CaseInsensitiveLess(const CaseInsensitiveLess &str);
CaseInsensitiveLess();
CaseInsensitiveLess* offset;
CaseInsensitiveLess *offset;
bool caseSensitive;
bool operator() (const std::string& s1, const std::string& s2) const;
bool operator()(const std::string &s1, const std::string &s2) const;
};
class HttpDictionary {
public:
HttpDictionary();
HttpDictionary(bool caseSensitive);
std::map<std::string,std::vector<std::string>,CaseInsensitiveLess> kvp;
void SetCaseSensitive(bool isCaseSensitive);
void Clear();
void Clear(std::string key, bool kvpExistsAfter);
void SetValue(std::string key, std::string value);
void SetValue(std::string key, int64_t v);
void SetValue(std::string key, double v);
void SetValue(std::string key, Date::DateTime v);
void SetValue(std::string key, std::vector<std::string> value);
template<typename Itterator>
void SetValue(std::string key, Itterator begin, Itterator end)
{
Clear(key,true);
AddValue(key, begin, end);
}
void AddValue(std::string key, std::string value);
void AddValue(std::string key, int64_t v);
void AddValue(std::string key, double v);
void AddValue(std::string key, Date::DateTime v);
void AddValue(std::string key, std::vector<std::string> value);
template<typename Itterator>
void AddValue(std::string key, Itterator begin, Itterator end)
{
auto& ls = kvp[key];
ls.insert(ls.end(), begin, end);
}
bool TryGetFirst(std::string key, std::string& value);
class HttpDictionary {
public:
HttpDictionary();
HttpDictionary(bool caseSensitive);
std::map<std::string, std::vector<std::string>, CaseInsensitiveLess> kvp;
void SetCaseSensitive(bool isCaseSensitive);
void Clear();
void Clear(std::string key, bool kvpExistsAfter);
void SetValue(std::string key, std::string value);
void SetValue(std::string key, int64_t v);
void SetValue(std::string key, double v);
void SetValue(std::string key, Date::DateTime v);
void SetValue(std::string key, std::vector<std::string> value);
template <typename Itterator>
void SetValue(std::string key, Itterator begin, Itterator end) {
Clear(key, true);
AddValue(key, begin, end);
}
void AddValue(std::string key, std::string value);
void AddValue(std::string key, int64_t v);
void AddValue(std::string key, double v);
void AddValue(std::string key, Date::DateTime v);
void AddValue(std::string key, std::vector<std::string> value);
bool TryGetFirstInt(std::string key, int64_t& value);
template <typename Itterator>
void AddValue(std::string key, Itterator begin, Itterator end) {
auto &ls = kvp[key];
ls.insert(ls.end(), begin, end);
}
bool TryGetFirstDouble(std::string key, double& value);
bool TryGetFirstDate(std::string key, Date::DateTime& value);
bool TryGetFirst(std::string key, std::string &value);
bool GetFirstBoolean(std::string key);
bool TryGetFirstInt(std::string key, int64_t &value);
bool AnyEquals(std::string key, std::string value);
};
bool TryGetFirstDouble(std::string key, double &value);
bool TryGetFirstDate(std::string key, Date::DateTime &value);
class Uri {
public:
Uri();
std::string GetQuery();
std::string GetPathAndQuery();
uint16_t GetPort();
std::string HostPort();
bool Relative(std::string url, Uri& uri);
std::string ToString();
static bool TryParse(std::string url, Uri& uri);
std::string scheme;
std::string host;
uint16_t port;
std::string path;
HttpDictionary query;
std::string hash;
};
bool GetFirstBoolean(std::string key);
class HttpUtils
{
public:
static char NibbleToHex(uint8_t b, bool isUppercase);
static char NibbleToHex(uint8_t nibble);
static uint8_t HexToNibble(char c);
static std::string BytesToHex(const std::vector<uint8_t>& data);
static void BytesToHex(std::string& text,const std::vector<uint8_t>& data);
bool AnyEquals(std::string key, std::string value);
};
static std::string BytesToHex(const std::vector<uint8_t>& data,bool isUppercase);
static void BytesToHex(std::string& text,const std::vector<uint8_t>& data, bool isUppercase);
static std::vector<uint8_t> HexToBytes(const std::string& text);
static void HexToBytes(std::vector<uint8_t>& data,const std::string& text);
static std::string MimeType(std::filesystem::path p);
static bool Invalid(char c);
static std::string Sanitise(std::string text);
static void QueryParamsDecode(HttpDictionary& dict,std::string query);
static std::string Join(std::string joinStr, std::vector<std::string> ents);
static std::string QueryParamsEncode(HttpDictionary& dict);
static std::string UrlDecode(std::string v);
static std::string UrlEncode(std::string v);
static std::string UrlPathDecode(std::string v);
static std::string UrlPathEncode(std::string v, bool ignoreSpace=false);
static std::string HtmlEncode(std::string v);
static std::string HtmlP(std::string text);
static std::string HtmlDecodeOnlyEntityNumber(std::string v);
static std::vector<std::string> SplitString(std::string text, std::string delimiter,std::size_t maxCnt = std::string::npos);
static std::string Replace(std::string str, std::string find, std::string replace);
static std::string StatusCodeString(StatusCode code);
static std::string ToLower(std::string str);
static std::string ToUpper(std::string str);
static std::string LeftPad(std::string text, int count, char c);
};
class Uri {
public:
Uri();
std::string GetQuery();
std::string GetPathAndQuery();
uint16_t GetPort();
std::string HostPort();
bool Relative(std::string url, Uri &uri);
std::string ToString();
static bool TryParse(std::string url, Uri &uri);
std::string scheme;
std::string host;
uint16_t port;
std::string path;
HttpDictionary query;
std::string hash;
};
class HttpUtils {
public:
static char NibbleToHex(uint8_t b, bool isUppercase);
static char NibbleToHex(uint8_t nibble);
static uint8_t HexToNibble(char c);
static std::string BytesToHex(const std::vector<uint8_t> &data);
static void BytesToHex(std::string &text, const std::vector<uint8_t> &data);
}
static std::string BytesToHex(const std::vector<uint8_t> &data,
bool isUppercase);
static void BytesToHex(std::string &text, const std::vector<uint8_t> &data,
bool isUppercase);
static std::vector<uint8_t> HexToBytes(const std::string &text);
static void HexToBytes(std::vector<uint8_t> &data, const std::string &text);
static std::string MimeType(std::filesystem::path p);
static bool Invalid(char c);
static std::string Sanitise(std::string text);
static void QueryParamsDecode(HttpDictionary &dict, std::string query);
static std::string Join(std::string joinStr, std::vector<std::string> ents);
static std::string QueryParamsEncode(HttpDictionary &dict);
static std::string UrlDecode(std::string v);
static std::string UrlEncode(std::string v);
static std::string UrlPathDecode(std::string v);
static std::string UrlPathEncode(std::string v, bool ignoreSpace = false);
static std::string HtmlEncode(std::string v);
static std::string HtmlP(std::string text);
static std::string HtmlDecodeOnlyEntityNumber(std::string v);
static std::vector<std::string>
SplitString(std::string text, std::string delimiter,
std::size_t maxCnt = std::string::npos);
static std::string Replace(std::string str, std::string find,
std::string replace);
static std::string StatusCodeString(StatusCode code);
static std::string ToLower(std::string str);
static std::string ToUpper(std::string str);
static std::string LeftPad(std::string text, int count, char c);
};
} // namespace Tesses::Framework::Http

View File

@@ -1,22 +1,41 @@
#pragma once
#include "HttpServer.hpp"
#include "../Filesystem/VFSFix.hpp"
#include "../Filesystem/VFS.hpp"
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
namespace Tesses::Framework::Http
{
class MountableServer : public IHttpServer
{
std::shared_ptr<IHttpServer> root;
std::vector<std::pair<std::string,std::shared_ptr<IHttpServer>>> servers;
std::string Subpath(Filesystem::VFSPath fullPath, Filesystem::VFSPath offsetPath);
bool StartsWith(Filesystem::VFSPath fullPath, Filesystem::VFSPath offsetPath);
public:
MountableServer();
MountableServer(std::shared_ptr<IHttpServer> root);
void Mount(std::string path, std::shared_ptr<IHttpServer> server);
void Unmount(std::string path);
bool Handle(ServerContext& ctx);
~MountableServer();
};
}
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/>.
*/
#pragma once
#include "../Filesystem/VFS.hpp"
#include "../Filesystem/VFSFix.hpp"
#include "HttpServer.hpp"
namespace Tesses::Framework::Http {
class MountableServer : public IHttpServer {
std::shared_ptr<IHttpServer> root;
std::vector<std::pair<std::string, std::shared_ptr<IHttpServer>>> servers;
std::string Subpath(Filesystem::VFSPath fullPath,
Filesystem::VFSPath offsetPath);
bool StartsWith(Filesystem::VFSPath fullPath,
Filesystem::VFSPath offsetPath);
public:
MountableServer();
MountableServer(std::shared_ptr<IHttpServer> root);
void Mount(std::string path, std::shared_ptr<IHttpServer> server);
void Unmount(std::string path);
bool Handle(ServerContext &ctx);
~MountableServer();
};
} // namespace Tesses::Framework::Http

View File

@@ -1,41 +1,59 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "HttpServer.hpp"
#include "../Filesystem/VFSFix.hpp"
#include "../Filesystem/VFS.hpp"
#include "../Filesystem/VFSFix.hpp"
#include "HttpServer.hpp"
namespace Tesses::Framework::Http
{
using ServerRequestHandler = std::function<bool(ServerContext&)>;
class RouteServer : public IHttpServer
{
class RouteServerRoute {
public:
std::vector<std::pair<std::string,bool>> parts;
std::string method;
ServerRequestHandler handler;
namespace Tesses::Framework::Http {
using ServerRequestHandler = std::function<bool(ServerContext &)>;
RouteServerRoute() = default;
RouteServerRoute(std::string route, std::string method, ServerRequestHandler handler);
bool Equals(Tesses::Framework::Filesystem::VFSPath& path, HttpDictionary& args);
};
std::vector<RouteServerRoute> routes;
std::shared_ptr<IHttpServer> root;
public:
RouteServer() = default;
RouteServer(std::shared_ptr<IHttpServer> root);
void Get(std::string pattern, ServerRequestHandler handler);
void Post(std::string pattern, ServerRequestHandler handler);
void Put(std::string pattern, ServerRequestHandler handler);
void Patch(std::string pattern, ServerRequestHandler handler);
class RouteServer : public IHttpServer {
class RouteServerRoute {
public:
std::vector<std::pair<std::string, bool>> parts;
std::string method;
ServerRequestHandler handler;
void Delete(std::string pattern, ServerRequestHandler handler);
void Trace(std::string pattern, ServerRequestHandler handler);
void Options(std::string pattern, ServerRequestHandler handler);
void Add(std::string method, std::string pattern, ServerRequestHandler handler);
bool Handle(ServerContext& ctx);
RouteServerRoute() = default;
RouteServerRoute(std::string route, std::string method,
ServerRequestHandler handler);
bool Equals(Tesses::Framework::Filesystem::VFSPath &path,
HttpDictionary &args);
};
}
std::vector<RouteServerRoute> routes;
std::shared_ptr<IHttpServer> root;
public:
RouteServer() = default;
RouteServer(std::shared_ptr<IHttpServer> root);
void Get(std::string pattern, ServerRequestHandler handler);
void Post(std::string pattern, ServerRequestHandler handler);
void Put(std::string pattern, ServerRequestHandler handler);
void Patch(std::string pattern, ServerRequestHandler handler);
void Delete(std::string pattern, ServerRequestHandler handler);
void Trace(std::string pattern, ServerRequestHandler handler);
void Options(std::string pattern, ServerRequestHandler handler);
void Add(std::string method, std::string pattern,
ServerRequestHandler handler);
bool Handle(ServerContext &ctx);
};
} // namespace Tesses::Framework::Http

View File

@@ -1,43 +1,68 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <functional>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <string>
#include <vector>
#include <cstddef>
namespace Tesses::Framework::Http
{
class WebSocketMessage {
public:
std::vector<uint8_t> data;
bool isBinary;
WebSocketMessage();
WebSocketMessage(std::vector<uint8_t> data);
WebSocketMessage(const void* data, size_t len);
WebSocketMessage(std::string message);
std::string ToString();
namespace Tesses::Framework::Http {
class WebSocketMessage {
public:
std::vector<uint8_t> data;
bool isBinary;
WebSocketMessage();
WebSocketMessage(std::vector<uint8_t> data);
WebSocketMessage(const void *data, size_t len);
WebSocketMessage(std::string message);
std::string ToString();
};
void SendWebSocketMessage(std::function<void(WebSocketMessage &)> cb,
std::string text);
class WebSocketConnection {
};
void SendWebSocketMessage(std::function<void(WebSocketMessage&)> cb, std::string text);
class WebSocketConnection {
public:
virtual void OnOpen(std::function<void(WebSocketMessage&)> sendMessage, std::function<void()> ping,std::function<void()> close)=0;
virtual void OnReceive(WebSocketMessage& message)=0;
virtual void OnClose(bool clean)=0;
virtual ~WebSocketConnection();
};
class CallbackWebSocketConnection : public WebSocketConnection {
public:
std::function<void(std::function<void(WebSocketMessage&)>,std::function<void()>,std::function<void()>)> onOpen;
std::function<void(WebSocketMessage&)> onReceive;
std::function<void(bool)> onClose;
CallbackWebSocketConnection();
CallbackWebSocketConnection(std::function<void(std::function<void(WebSocketMessage&)>,std::function<void()>,std::function<void()>)> onOpen, std::function<void(WebSocketMessage&)> onReceive, std::function<void(bool)> onClose);
public:
virtual void OnOpen(std::function<void(WebSocketMessage &)> sendMessage,
std::function<void()> ping,
std::function<void()> close) = 0;
virtual void OnReceive(WebSocketMessage &message) = 0;
virtual void OnClose(bool clean) = 0;
virtual ~WebSocketConnection();
};
class CallbackWebSocketConnection : public WebSocketConnection {
public:
std::function<void(std::function<void(WebSocketMessage &)>,
std::function<void()>, std::function<void()>)>
onOpen;
std::function<void(WebSocketMessage &)> onReceive;
std::function<void(bool)> onClose;
CallbackWebSocketConnection();
CallbackWebSocketConnection(
std::function<void(std::function<void(WebSocketMessage &)>,
std::function<void()>, std::function<void()>)>
onOpen,
std::function<void(WebSocketMessage &)> onReceive,
std::function<void(bool)> onClose);
void OnOpen(std::function<void(WebSocketMessage&)> sendMessage, std::function<void()> ping,std::function<void()> closeFn);
void OnReceive(WebSocketMessage& message);
void OnClose(bool clean);
};
}
void OnOpen(std::function<void(WebSocketMessage &)> sendMessage,
std::function<void()> ping, std::function<void()> closeFn);
void OnReceive(WebSocketMessage &message);
void OnClose(bool clean);
};
} // namespace Tesses::Framework::Http

View File

@@ -1,52 +1,61 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Common.hpp"
#include "Threading/Mutex.hpp"
#include <functional>
namespace Tesses::Framework {
template<typename T>
class Lazy {
Threading::Mutex mtx;
T value;
bool hasInit=false;
std::function<T()> init;
std::function<void(T)> free;
public:
Lazy(std::function<T()> init, std::function<void(T)> free)
{
this->init = init;
this->free = free;
}
Lazy(std::function<T()> init) : Lazy(init, [](T item)->void {})
{
template <typename T> class Lazy {
Threading::Mutex mtx;
T value;
bool hasInit = false;
std::function<T()> init;
std::function<void(T)> free;
}
bool HasInit()
{
mtx.Lock();
bool hI = this->hasInit;
mtx.Unlock();
return hI;
}
T& GetValue()
{
mtx.Lock();
if(hasInit)
{
mtx.Unlock();
return this->value;
}
else
{
this->value = this->init();
this->hasInit=true;
mtx.Unlock();
return this->value;
}
mtx.Unlock();
}
~Lazy()
{
if(hasInit) this->free(this->value);
}
};
}
public:
Lazy(std::function<T()> init, std::function<void(T)> free) {
this->init = init;
this->free = free;
}
Lazy(std::function<T()> init) : Lazy(init, [](T item) -> void {}) {}
bool HasInit() {
mtx.Lock();
bool hI = this->hasInit;
mtx.Unlock();
return hI;
}
T &GetValue() {
mtx.Lock();
if (hasInit) {
mtx.Unlock();
return this->value;
} else {
this->value = this->init();
this->hasInit = true;
mtx.Unlock();
return this->value;
}
mtx.Unlock();
}
~Lazy() {
if (hasInit)
this->free(this->value);
}
};
} // namespace Tesses::Framework

View File

@@ -1,51 +1,66 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/Stream.hpp"
namespace Tesses::Framework::Mail
{
class SMTPBody
{
public:
std::string mimeType;
virtual void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm)=0;
virtual ~SMTPBody();
namespace Tesses::Framework::Mail {
class SMTPBody {
public:
std::string mimeType;
virtual void
Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm) = 0;
virtual ~SMTPBody();
};
class SMTPStringBody : public SMTPBody
{
public:
SMTPStringBody();
SMTPStringBody(std::string text, std::string mimeType);
std::string text;
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
class SMTPStringBody : public SMTPBody {
public:
SMTPStringBody();
SMTPStringBody(std::string text, std::string mimeType);
std::string text;
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
};
class SMTPStreamBody : public SMTPBody
{
class SMTPStreamBody : public SMTPBody {
std::shared_ptr<Tesses::Framework::Streams::Stream> stream;
public:
SMTPStreamBody(std::string mimeType,std::shared_ptr<Tesses::Framework::Streams::Stream> stream);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
~SMTPStreamBody();
public:
SMTPStreamBody(std::string mimeType,
std::shared_ptr<Tesses::Framework::Streams::Stream> stream);
void Write(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
~SMTPStreamBody();
};
class SMTPClient {
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
public:
SMTPClient(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::string domain;
std::string username;
std::string password;
std::string from;
std::string from_name;
std::string to;
std::string subject;
std::shared_ptr<SMTPBody> body;
std::vector<std::pair<std::string,std::shared_ptr<SMTPBody>>> attachments;
void Send();
~SMTPClient();
public:
SMTPClient(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
std::string domain;
std::string username;
std::string password;
std::string from;
std::string from_name;
std::string to;
std::string subject;
std::shared_ptr<SMTPBody> body;
std::vector<std::pair<std::string, std::shared_ptr<SMTPBody>>> attachments;
void Send();
~SMTPClient();
};
}
} // namespace Tesses::Framework::Mail

View File

@@ -1,51 +1,69 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "TessesFramework/Filesystem/VFSFix.hpp"
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Filesystem/VFSFix.hpp"
#include <optional>
namespace Tesses::Framework::Platform::Environment
{
extern const char EnvPathSeperator;
namespace Tesses::Framework::Platform::Environment {
extern const char EnvPathSeperator;
struct PortableAppConfig {
std::optional<Tesses::Framework::Filesystem::VFSPath> desktop;
std::optional<Tesses::Framework::Filesystem::VFSPath> documents;
std::optional<Tesses::Framework::Filesystem::VFSPath> music;
std::optional<Tesses::Framework::Filesystem::VFSPath> pictures;
std::optional<Tesses::Framework::Filesystem::VFSPath> videos;
std::optional<Tesses::Framework::Filesystem::VFSPath> downloads;
std::optional<Tesses::Framework::Filesystem::VFSPath> user;
std::optional<Tesses::Framework::Filesystem::VFSPath> config;
std::optional<Tesses::Framework::Filesystem::VFSPath> state;
std::optional<Tesses::Framework::Filesystem::VFSPath> data;
std::optional<Tesses::Framework::Filesystem::VFSPath> cache;
std::optional<Tesses::Framework::Filesystem::VFSPath> temp;
};
struct PortableAppConfig {
extern PortableAppConfig portable_config;
std::optional<Tesses::Framework::Filesystem::VFSPath> desktop;
std::optional<Tesses::Framework::Filesystem::VFSPath> documents;
std::optional<Tesses::Framework::Filesystem::VFSPath> music;
std::optional<Tesses::Framework::Filesystem::VFSPath> pictures;
std::optional<Tesses::Framework::Filesystem::VFSPath> videos;
std::optional<Tesses::Framework::Filesystem::VFSPath> downloads;
std::optional<Tesses::Framework::Filesystem::VFSPath> user;
std::optional<Tesses::Framework::Filesystem::VFSPath> config;
std::optional<Tesses::Framework::Filesystem::VFSPath> state;
std::optional<Tesses::Framework::Filesystem::VFSPath> data;
std::optional<Tesses::Framework::Filesystem::VFSPath> cache;
std::optional<Tesses::Framework::Filesystem::VFSPath> temp;
};
namespace SpecialFolders {
Tesses::Framework::Filesystem::VFSPath GetTemp();
Tesses::Framework::Filesystem::VFSPath GetHomeFolder();
Tesses::Framework::Filesystem::VFSPath GetDownloads();
Tesses::Framework::Filesystem::VFSPath GetMusic();
Tesses::Framework::Filesystem::VFSPath GetPictures();
Tesses::Framework::Filesystem::VFSPath GetVideos();
Tesses::Framework::Filesystem::VFSPath GetDocuments();
Tesses::Framework::Filesystem::VFSPath GetConfig();
Tesses::Framework::Filesystem::VFSPath GetDesktop();
Tesses::Framework::Filesystem::VFSPath GetState();
Tesses::Framework::Filesystem::VFSPath GetCache();
Tesses::Framework::Filesystem::VFSPath GetData();
}
extern PortableAppConfig portable_config;
std::string GetPlatform();
namespace SpecialFolders {
Tesses::Framework::Filesystem::VFSPath GetTemp();
Tesses::Framework::Filesystem::VFSPath GetHomeFolder();
Tesses::Framework::Filesystem::VFSPath GetDownloads();
Tesses::Framework::Filesystem::VFSPath GetMusic();
Tesses::Framework::Filesystem::VFSPath GetPictures();
Tesses::Framework::Filesystem::VFSPath GetVideos();
Tesses::Framework::Filesystem::VFSPath GetDocuments();
Tesses::Framework::Filesystem::VFSPath GetConfig();
Tesses::Framework::Filesystem::VFSPath GetDesktop();
Tesses::Framework::Filesystem::VFSPath GetState();
Tesses::Framework::Filesystem::VFSPath GetCache();
Tesses::Framework::Filesystem::VFSPath GetData();
} // namespace SpecialFolders
Tesses::Framework::Filesystem::VFSPath GetRealExecutablePath(Tesses::Framework::Filesystem::VFSPath realPath);
std::string GetPlatform();
std::optional<std::string> GetVariable(std::string name);
void SetVariable(std::string name, std::optional<std::string> var);
Tesses::Framework::Filesystem::VFSPath
GetRealExecutablePath(Tesses::Framework::Filesystem::VFSPath realPath);
void GetEnvironmentVariables(std::vector<std::pair<std::string,std::string>>& env);
}
std::optional<std::string> GetVariable(std::string name);
void SetVariable(std::string name, std::optional<std::string> var);
void GetEnvironmentVariables(
std::vector<std::pair<std::string, std::string>> &env);
} // namespace Tesses::Framework::Platform::Environment

View File

@@ -1,50 +1,71 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <vector>
#include <string>
#include "TessesFramework/Streams/Stream.hpp"
#include "TessesFramework/HiddenField.hpp"
#include "TessesFramework/Streams/Stream.hpp"
#include <signal.h>
#include <string>
#include <vector>
#if defined(_WIN32)
#define SIGKILL 9
#endif
namespace Tesses::Framework::Platform {
class Process {
private:
HiddenField hidden;
bool exited = false;
int exitCode=0;
public:
std::string name;
std::vector<std::string> args;
std::string workingDirectory;
std::vector<std::pair<std::string,std::string>> env;
bool includeThisEnv;
bool redirectStdIn=false;
bool redirectStdOut=false;
bool redirectStdErr=false;
bool HasExited();
private:
HiddenField hidden;
bool exited = false;
int exitCode = 0;
public:
std::string name;
std::vector<std::string> args;
std::string workingDirectory;
std::vector<std::pair<std::string, std::string>> env;
bool includeThisEnv;
bool redirectStdIn = false;
bool redirectStdOut = false;
bool redirectStdErr = false;
bool HasExited();
void CloseStdInNow();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStdinStream();
void CloseStdInNow();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStdoutStream();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStderrStream();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStdinStream();
Process();
Process(std::string name, std::vector<std::string> args,bool includeThisEnv=true);
Process(std::string name, std::vector<std::string> args, std::vector<std::pair<std::string,std::string>> env,bool includeThisEnv=false);
Process(std::string name, std::vector<std::string> args, std::vector<std::string> env,bool includeThisEnv=false);
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStdoutStream();
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStderrStream();
bool Start();
Process();
Process(std::string name, std::vector<std::string> args,
bool includeThisEnv = true);
Process(std::string name, std::vector<std::string> args,
std::vector<std::pair<std::string, std::string>> env,
bool includeThisEnv = false);
Process(std::string name, std::vector<std::string> args,
std::vector<std::string> env, bool includeThisEnv = false);
void Kill(int signal);
bool Start();
int WaitForExit();
void Kill(int signal);
~Process();
int WaitForExit();
~Process();
};
}
} // namespace Tesses::Framework::Platform

View File

@@ -1,15 +1,34 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Common.hpp"
namespace Tesses::Framework {
class Random {
uint64_t num;
public:
Random();
Random(uint64_t seed);
uint64_t Next();
uint32_t Next(uint32_t max);
int32_t Next(int32_t min,int32_t max);
uint8_t NextByte();
};
}
class Random {
uint64_t num;
public:
Random();
Random(uint64_t seed);
uint64_t Next();
uint32_t Next(uint32_t max);
int32_t Next(int32_t min, int32_t max);
uint8_t NextByte();
};
} // namespace Tesses::Framework

View File

@@ -1,59 +1,83 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <cstdint>
#include <vector>
#include <variant>
#include <string>
#include "../Streams/Stream.hpp"
#include "../TextStreams/TextWriter.hpp"
#include "Json.hpp"
#include <cstdint>
#include <string>
#include <variant>
#include <vector>
namespace Tesses::Framework::Serialization::Bencode {
class BeArray;
class BeDictionary;
class BeString;
using BeUndefined = std::monostate;
class BeArray;
class BeDictionary;
class BeString;
using BeUndefined = std::monostate;
using BeToken = std::variant<BeUndefined,BeArray,BeDictionary,BeString,int64_t>;
using BeToken =
std::variant<BeUndefined, BeArray, BeDictionary, BeString, int64_t>;
class BeArray {
public:
std::vector<BeToken> tokens;
};
class BeArray {
public:
std::vector<BeToken> tokens;
};
class BeDictionary {
public:
std::vector<std::pair<BeString,BeToken>> tokens;
BeToken GetValue(BeString key) const;
void SetValue(BeString key, BeToken value);
};
class BeString {
public:
BeString();
BeString(const std::string& text);
BeString(const char* text);
BeString(const std::vector<uint8_t>& data);
std::vector<uint8_t> data;
class BeDictionary {
public:
std::vector<std::pair<BeString, BeToken>> tokens;
BeToken GetValue(BeString key) const;
void SetValue(BeString key, BeToken value);
};
class BeString {
public:
BeString();
BeString(const std::string &text);
BeString(const char *text);
BeString(const std::vector<uint8_t> &data);
std::vector<uint8_t> data;
operator std::string() const;
};
bool operator==(const BeString& lStr, const BeString& rStr);
bool operator==(const BeString& lStr, const std::string& rStr);
bool operator==(const std::string& lStr, const BeString& rStr);
bool operator==(const BeString& lStr, const char* rStr);
bool operator==(const char* lStr, const BeString& rStr);
bool operator!=(const BeString& lStr, const BeString& rStr);
bool operator!=(const BeString& lStr, const std::string& rStr);
bool operator!=(const std::string& lStr, const BeString& rStr);
bool operator!=(const BeString& lStr, const char* rStr);
bool operator!=(const char* lStr, const BeString& rStr);
class Bencode {
public:
static void Save(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,const BeToken& value);
static BeToken Load(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
//This cannot be converted back to torrent, this may (probably will) be out of order
static Json::JToken ToJson(const BeToken& tkn);
//This may (probably will) be out of order
static void Print(std::shared_ptr<Tesses::Framework::TextStreams::TextWriter> writer, BeToken tkn);
};
}
operator std::string() const;
};
bool operator==(const BeString &lStr, const BeString &rStr);
bool operator==(const BeString &lStr, const std::string &rStr);
bool operator==(const std::string &lStr, const BeString &rStr);
bool operator==(const BeString &lStr, const char *rStr);
bool operator==(const char *lStr, const BeString &rStr);
bool operator!=(const BeString &lStr, const BeString &rStr);
bool operator!=(const BeString &lStr, const std::string &rStr);
bool operator!=(const std::string &lStr, const BeString &rStr);
bool operator!=(const BeString &lStr, const char *rStr);
bool operator!=(const char *lStr, const BeString &rStr);
class Bencode {
public:
static void Save(std::shared_ptr<Tesses::Framework::Streams::Stream> strm,
const BeToken &value);
static BeToken
Load(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
// This cannot be converted back to torrent, this may (probably will) be out
// of order
static Json::JToken ToJson(const BeToken &tkn);
// This may (probably will) be out of order
static void
Print(std::shared_ptr<Tesses::Framework::TextStreams::TextWriter> writer,
BeToken tkn);
};
} // namespace Tesses::Framework::Serialization::Bencode

View File

@@ -1,82 +1,93 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
#include "../Uuid.hpp"
namespace Tesses::Framework::Serialization
{
namespace Tesses::Framework::Serialization {
/**
* @brief A bit converter
*
*
*/
class BitConverter {
public:
static double ToDoubleBits(uint64_t v);
static uint64_t ToUintBits(double v);
static float ToFloatBits(uint32_t v);
static uint32_t ToUint32Bits(float v);
static double ToDoubleBE(uint8_t& b);
static float ToFloatBE(uint8_t& b);
static uint64_t ToUint64BE(uint8_t& b);
static uint32_t ToUint32BE(uint8_t& b);
static uint16_t ToUint16BE(uint8_t& b);
public:
static double ToDoubleBits(uint64_t v);
static double ToDoubleLE(uint8_t& b);
static float ToFloatLE(uint8_t& b);
static uint64_t ToUint64LE(uint8_t& b);
static uint32_t ToUint32LE(uint8_t& b);
static uint16_t ToUint16LE(uint8_t& b);
static uint64_t ToUintBits(double v);
static float ToFloatBits(uint32_t v);
static int64_t ToSint64BE(uint8_t& b);
static int32_t ToSint32BE(uint8_t& b);
static int16_t ToSint16BE(uint8_t& b);
static int64_t ToSint64LE(uint8_t& b);
static int32_t ToSint32LE(uint8_t& b);
static int16_t ToSint16LE(uint8_t& b);
static uint32_t ToUint32Bits(float v);
static Uuid ToUuid(uint8_t& b);
static double ToDoubleBE(uint8_t &b);
static float ToFloatBE(uint8_t &b);
static uint64_t ToUint64BE(uint8_t &b);
static uint32_t ToUint32BE(uint8_t &b);
static uint16_t ToUint16BE(uint8_t &b);
static void ToUuid(uint8_t& b, Uuid& uuid);
static double ToDoubleLE(uint8_t &b);
static float ToFloatLE(uint8_t &b);
static uint64_t ToUint64LE(uint8_t &b);
static uint32_t ToUint32LE(uint8_t &b);
static uint16_t ToUint16LE(uint8_t &b);
static int64_t ToSint64BE(uint8_t &b);
static int32_t ToSint32BE(uint8_t &b);
static int16_t ToSint16BE(uint8_t &b);
static int64_t ToSint64LE(uint8_t &b);
static int32_t ToSint32LE(uint8_t &b);
static int16_t ToSint16LE(uint8_t &b);
static void FromDoubleBE(uint8_t& b, double v);
static void FromFloatBE(uint8_t& b, float v);
static void FromUint64BE(uint8_t& b, uint64_t v);
static void FromUint32BE(uint8_t& b, uint32_t v);
static void FromUint16BE(uint8_t& b, uint16_t v);
static Uuid ToUuid(uint8_t &b);
static void FromDoubleLE(uint8_t& b, double v);
static void FromFloatLE(uint8_t& b, float v);
static void FromUint64LE(uint8_t& b, uint64_t v);
static void FromUint32LE(uint8_t& b, uint32_t v);
static void FromUint16LE(uint8_t& b, uint16_t v);
static void FromSint64BE(uint8_t& b, int64_t v);
static void FromSint32BE(uint8_t& b, int32_t v);
static void FromSint16BE(uint8_t& b, int16_t v);
static void FromSint64LE(uint8_t& b, int64_t v);
static void FromSint32LE(uint8_t& b, int32_t v);
static void FromSint16LE(uint8_t& b, int16_t v);
static void FromUuid(uint8_t& b, const Uuid& uuid);
static void ToUuid(uint8_t &b, Uuid &uuid);
static void FromDoubleBE(uint8_t &b, double v);
static void FromFloatBE(uint8_t &b, float v);
static void FromUint64BE(uint8_t &b, uint64_t v);
static void FromUint32BE(uint8_t &b, uint32_t v);
static void FromUint16BE(uint8_t &b, uint16_t v);
static void FromDoubleLE(uint8_t &b, double v);
static void FromFloatLE(uint8_t &b, float v);
static void FromUint64LE(uint8_t &b, uint64_t v);
static void FromUint32LE(uint8_t &b, uint32_t v);
static void FromUint16LE(uint8_t &b, uint16_t v);
static inline bool IsLittleEndian()
{
uint8_t a[2];
a[0] = 0x01;
a[1] = 0xA4;
uint16_t num=0;
memcpy(&num,&a, 2);
return num != 420;
}
static void FromSint64BE(uint8_t &b, int64_t v);
static void FromSint32BE(uint8_t &b, int32_t v);
static void FromSint16BE(uint8_t &b, int16_t v);
static void FromSint64LE(uint8_t &b, int64_t v);
static void FromSint32LE(uint8_t &b, int32_t v);
static void FromSint16LE(uint8_t &b, int16_t v);
static void FromUuid(uint8_t &b, const Uuid &uuid);
static inline bool IsLittleEndian() {
uint8_t a[2];
a[0] = 0x01;
a[1] = 0xA4;
uint16_t num = 0;
memcpy(&num, &a, 2);
return num != 420;
}
};
}
} // namespace Tesses::Framework::Serialization

View File

@@ -1,94 +1,101 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <string>
#include <vector>
#include <variant>
#include <map>
#include <iostream>
#include <cstdint>
namespace Tesses::Framework::Serialization::Json
{
class JArray;
class JObject;
using JUndefined = std::monostate;
#include <iostream>
#include <map>
#include <string>
#include <variant>
#include <vector>
namespace Tesses::Framework::Serialization::Json {
class JArray;
class JObject;
using JUndefined = std::monostate;
using JToken = std::variant<JUndefined,std::nullptr_t,bool,int64_t,double,std::string, JArray, JObject>;
using JToken = std::variant<JUndefined, std::nullptr_t, bool, int64_t, double,
std::string, JArray, JObject>;
class JOItem;
class JOItem;
class JArray
{
std::vector<JToken> items;
public:
JArray();
JArray(std::initializer_list<JToken> items);
std::vector<JToken>& GetVector();
void Add(JToken item);
void RemoveAt(size_t index);
size_t Count();
void SetAt(size_t index, JToken item);
JToken GetAt(size_t index);
void Clear();
class JArray {
std::vector<JToken> items;
std::vector<JToken>::iterator begin();
std::vector<JToken>::iterator end();
};
public:
JArray();
JArray(std::initializer_list<JToken> items);
std::vector<JToken> &GetVector();
void Add(JToken item);
void RemoveAt(size_t index);
size_t Count();
void SetAt(size_t index, JToken item);
JToken GetAt(size_t index);
void Clear();
std::vector<JToken>::iterator begin();
std::vector<JToken>::iterator end();
};
class JObject {
std::map<std::string,JToken> map;
public:
JObject();
JObject(std::initializer_list<JOItem> items);
void SetValue(std::string key, JToken item);
template<typename T>
bool TryGetValueAsType(std::string key, T& value)
{
auto obj = GetValue(key);
if(std::holds_alternative<T>(obj))
{
value = std::get<T>(obj);
return true;
}
return false;
}
class JObject {
std::map<std::string, JToken> map;
JToken GetValue(std::string key);
void Remove(std::string key);
std::map<std::string,JToken>& GetMap();
std::map<std::string,JToken>::iterator begin();
std::map<std::string,JToken>::iterator end();
};
template<typename T>
bool TryGetJToken(JToken json, T& item)
{
if(std::holds_alternative<T>(json))
{
item = std::get<T>(json);
public:
JObject();
JObject(std::initializer_list<JOItem> items);
void SetValue(std::string key, JToken item);
template <typename T> bool TryGetValueAsType(std::string key, T &value) {
auto obj = GetValue(key);
if (std::holds_alternative<T>(obj)) {
value = std::get<T>(obj);
return true;
}
return false;
}
class JOItem {
public:
JOItem();
JOItem(std::string key, JToken value);
std::string key;
JToken value;
};
class Json
{
static std::string tab(std::string str);
public:
static JToken Decode(std::string str);
static std::string Encode(JToken tkn, bool indent=true);
static JArray DocDecode(std::string str);
static std::string DocEncode(JArray array,bool indent=true);
};
JToken GetValue(std::string key);
void Remove(std::string key);
std::map<std::string, JToken> &GetMap();
std::map<std::string, JToken>::iterator begin();
std::map<std::string, JToken>::iterator end();
};
template <typename T> bool TryGetJToken(JToken json, T &item) {
if (std::holds_alternative<T>(json)) {
item = std::get<T>(json);
return true;
}
return false;
}
class JOItem {
public:
JOItem();
JOItem(std::string key, JToken value);
std::string key;
JToken value;
};
class Json {
static std::string tab(std::string str);
public:
static JToken Decode(std::string str);
static std::string Encode(JToken tkn, bool indent = true);
static JArray DocDecode(std::string str);
static std::string DocEncode(JArray array, bool indent = true);
};
} // namespace Tesses::Framework::Serialization::Json

View File

@@ -1,18 +1,42 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "TessesFramework/Filesystem/VFSFix.hpp"
#include "TessesFramework/Filesystem/VFS.hpp"
#include "TessesFramework/Filesystem/VFSFix.hpp"
#include <optional>
namespace Tesses::Framework::Serialization {
class SQLiteDatabase {
private:
void* data;
static int collector(void* user, int count,char** vals, char** keys);
public:
SQLiteDatabase(Tesses::Framework::Filesystem::VFSPath path);
static std::string Escape(std::string text);
static bool IsEnabled();
void Exec(std::string statement,std::vector<std::vector<std::pair<std::string,std::optional<std::string>>>>& results);
std::vector<std::vector<std::pair<std::string,std::optional<std::string>>>> Exec(std::string statement);
~SQLiteDatabase();
};
}
class SQLiteDatabase {
private:
void *data;
static int collector(void *user, int count, char **vals, char **keys);
public:
SQLiteDatabase(Tesses::Framework::Filesystem::VFSPath path);
static std::string Escape(std::string text);
static bool IsEnabled();
void
Exec(std::string statement,
std::vector<
std::vector<std::pair<std::string, std::optional<std::string>>>>
&results);
std::vector<std::vector<std::pair<std::string, std::optional<std::string>>>>
Exec(std::string statement);
~SQLiteDatabase();
};
} // namespace Tesses::Framework::Serialization

View File

@@ -1,26 +1,43 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Stream.hpp"
namespace Tesses::Framework::Streams
{
class BufferedStream : public Stream
{
private:
std::shared_ptr<Stream> strm;
uint8_t* buffer;
size_t bufferSize;
size_t offset;
size_t read;
public:
BufferedStream(std::shared_ptr<Stream> strm, size_t bufferSize=1024);
bool EndOfStream();
bool CanRead();
bool CanWrite();
size_t Read(uint8_t* buff, size_t sz);
size_t Write(const uint8_t* buff, size_t sz);
namespace Tesses::Framework::Streams {
class BufferedStream : public Stream {
private:
std::shared_ptr<Stream> strm;
uint8_t *buffer;
size_t bufferSize;
size_t offset;
size_t read;
~BufferedStream();
void Close();
};
public:
BufferedStream(std::shared_ptr<Stream> strm, size_t bufferSize = 1024);
bool EndOfStream();
bool CanRead();
bool CanWrite();
size_t Read(uint8_t *buff, size_t sz);
size_t Write(const uint8_t *buff, size_t sz);
}
~BufferedStream();
void Close();
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,33 +1,51 @@
#pragma once
#include "Stream.hpp"
#include "../Uuid.hpp"
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
namespace Tesses::Framework::Streams
{
class ByteReader {
std::shared_ptr<Stream> strm;
public:
std::shared_ptr<Stream> GetStream();
ByteReader(std::shared_ptr<Stream> strm);
uint8_t ReadU8();
uint16_t ReadU16BE();
uint16_t ReadU16LE();
uint32_t ReadU32BE();
uint32_t ReadU32LE();
uint64_t ReadU64BE();
uint64_t ReadU64LE();
int8_t ReadI8();
int16_t ReadI16BE();
int16_t ReadI16LE();
int32_t ReadI32BE();
int32_t ReadI32LE();
int64_t ReadI64BE();
int64_t ReadI64LE();
float ReadF32BE();
float ReadF32LE();
double ReadF64BE();
double ReadF64LE();
Uuid ReadUuid();
void ReadUuid(Uuid& uuid);
};
}
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/>.
*/
#pragma once
#include "../Uuid.hpp"
#include "Stream.hpp"
namespace Tesses::Framework::Streams {
class ByteReader {
std::shared_ptr<Stream> strm;
public:
std::shared_ptr<Stream> GetStream();
ByteReader(std::shared_ptr<Stream> strm);
uint8_t ReadU8();
uint16_t ReadU16BE();
uint16_t ReadU16LE();
uint32_t ReadU32BE();
uint32_t ReadU32LE();
uint64_t ReadU64BE();
uint64_t ReadU64LE();
int8_t ReadI8();
int16_t ReadI16BE();
int16_t ReadI16LE();
int32_t ReadI32BE();
int32_t ReadI32LE();
int64_t ReadI64BE();
int64_t ReadI64LE();
float ReadF32BE();
float ReadF32LE();
double ReadF64BE();
double ReadF64LE();
Uuid ReadUuid();
void ReadUuid(Uuid &uuid);
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,32 +1,49 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Stream.hpp"
#include "../Uuid.hpp"
namespace Tesses::Framework::Streams
{
class ByteWriter {
std::shared_ptr<Stream> strm;
public:
std::shared_ptr<Stream> GetStream();
ByteWriter(std::shared_ptr<Stream> strm);
void WriteU8(uint8_t v);
void WriteU16BE(uint16_t v);
void WriteU16LE(uint16_t v);
void WriteU32BE(uint32_t v);
void WriteU32LE(uint32_t v);
void WriteU64BE(uint64_t v);
void WriteU64LE(uint64_t v);
void WriteI8(int8_t v);
void WriteI16BE(int16_t v);
void WriteI16LE(int16_t v);
void WriteI32BE(int32_t v);
void WriteI32LE(int32_t v);
void WriteI64BE(int64_t v);
void WriteI64LE(int64_t v);
void WriteF32BE(float v);
void WriteF32LE(float v);
void WriteF64BE(double v);
void WriteF64LE(double v);
void WriteUuid(const Uuid& uuid);
};
}
#include "Stream.hpp"
namespace Tesses::Framework::Streams {
class ByteWriter {
std::shared_ptr<Stream> strm;
public:
std::shared_ptr<Stream> GetStream();
ByteWriter(std::shared_ptr<Stream> strm);
void WriteU8(uint8_t v);
void WriteU16BE(uint16_t v);
void WriteU16LE(uint16_t v);
void WriteU32BE(uint32_t v);
void WriteU32LE(uint32_t v);
void WriteU64BE(uint64_t v);
void WriteU64LE(uint64_t v);
void WriteI8(int8_t v);
void WriteI16BE(int16_t v);
void WriteI16LE(int16_t v);
void WriteI32BE(int32_t v);
void WriteI32LE(int32_t v);
void WriteI64BE(int64_t v);
void WriteI64LE(int64_t v);
void WriteF32BE(float v);
void WriteF32LE(float v);
void WriteF64BE(double v);
void WriteF64LE(double v);
void WriteUuid(const Uuid &uuid);
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,28 +1,46 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Stream.hpp"
#include <cstdio>
namespace Tesses::Framework::Streams
{
class FileStream : public Stream {
bool canRead;
bool canWrite;
bool canSeek;
bool owns;
FILE* f;
void SetMode(std::string mode);
public:
FileStream(std::filesystem::path p, std::string mode);
FileStream(FILE* f, bool owns, std::string mode , bool canSeek=true);
size_t Read(uint8_t* buff, size_t sz);
size_t Write(const uint8_t* buff, size_t sz);
bool EndOfStream();
bool CanRead();
bool CanWrite();
bool CanSeek();
int64_t GetPosition();
void Flush();
void Seek(int64_t pos, SeekOrigin whence);
~FileStream();
void Close();
};
}
namespace Tesses::Framework::Streams {
class FileStream : public Stream {
bool canRead;
bool canWrite;
bool canSeek;
bool owns;
FILE *f;
void SetMode(std::string mode);
public:
FileStream(std::filesystem::path p, std::string mode);
FileStream(FILE *f, bool owns, std::string mode, bool canSeek = true);
size_t Read(uint8_t *buff, size_t sz);
size_t Write(const uint8_t *buff, size_t sz);
bool EndOfStream();
bool CanRead();
bool CanWrite();
bool CanSeek();
int64_t GetPosition();
void Flush();
void Seek(int64_t pos, SeekOrigin whence);
~FileStream();
void Close();
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,22 +1,40 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Stream.hpp"
namespace Tesses::Framework::Streams
{
class MemoryStream : public Stream {
std::vector<uint8_t> buffer;
size_t offset;
bool writable;
public:
MemoryStream(bool isWritable);
std::vector<uint8_t>& GetBuffer();
size_t Read(uint8_t* buff, size_t sz);
size_t Write(const uint8_t* buff, size_t sz);
bool CanRead();
bool CanWrite();
bool CanSeek();
int64_t GetLength();
int64_t GetPosition();
void Seek(int64_t pos, SeekOrigin whence);
void Close();
};
}
namespace Tesses::Framework::Streams {
class MemoryStream : public Stream {
std::vector<uint8_t> buffer;
size_t offset;
bool writable;
public:
MemoryStream(bool isWritable);
std::vector<uint8_t> &GetBuffer();
size_t Read(uint8_t *buff, size_t sz);
size_t Write(const uint8_t *buff, size_t sz);
bool CanRead();
bool CanWrite();
bool CanSeek();
int64_t GetLength();
int64_t GetPosition();
void Seek(int64_t pos, SeekOrigin whence);
void Close();
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,64 +1,87 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Stream.hpp"
namespace Tesses::Framework::Streams
{
class NetworkStream;
namespace Tesses::Framework::Streams {
class NetworkStream;
class TcpServer {
int32_t sock;
bool owns;
bool valid;
public:
TcpServer(int32_t backlog);
TcpServer(int32_t sock,bool owns);
TcpServer(uint16_t port, int32_t backlog);
TcpServer(std::string ip, uint16_t port, int32_t backlog);
TcpServer(std::string unixPath,int32_t backlog);
std::shared_ptr<NetworkStream> GetStream(std::string& ip, uint16_t& port);
uint16_t GetPort();
~TcpServer();
bool IsValid();
void Close();
};
enum class SocketType {
ST_IPv4_TCP,
ST_IPv4_UDP,
ST_IPv6_TCP,
ST_IPv6_UDP,
ST_UNIX
};
class NetworkStream : public Stream {
int32_t sock;
bool owns;
bool success;
bool endOfStream;
public:
bool DataAvailable(int timeout=0);
bool EndOfStream();
bool CanRead();
bool CanWrite();
NetworkStream(SocketType type);
NetworkStream(std::string unixPath,bool isServer);
NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,bool broadcast,bool supportIPv6);
NetworkStream(int32_t sock, bool owns);
uint16_t GetPort();
void Listen(int32_t backlog);
void Bind(std::string ip, uint16_t port);
void SetBroadcast(bool bC);
void SetReuseAddress(bool reuse);
void SetReusePort(bool reuse);
void SetMulticastTTL(uint8_t ttl);
void SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0");
std::shared_ptr<NetworkStream> Accept(std::string& ip, uint16_t& port);
size_t Read(uint8_t* buff, size_t sz);
size_t Write(const uint8_t* buff, size_t sz);
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
class TcpServer {
int32_t sock;
bool owns;
bool valid;
~NetworkStream();
void SetNoDelay(bool noDelay);
void Close();
};
}
public:
TcpServer(int32_t backlog);
TcpServer(int32_t sock, bool owns);
TcpServer(uint16_t port, int32_t backlog);
TcpServer(std::string ip, uint16_t port, int32_t backlog);
TcpServer(std::string unixPath, int32_t backlog);
std::shared_ptr<NetworkStream> GetStream(std::string &ip, uint16_t &port);
uint16_t GetPort();
~TcpServer();
bool IsValid();
void Close();
};
enum class SocketType {
ST_IPv4_TCP,
ST_IPv4_UDP,
ST_IPv6_TCP,
ST_IPv6_UDP,
ST_UNIX
};
class NetworkStream : public Stream {
int32_t sock;
bool owns;
bool success;
bool endOfStream;
public:
bool DataAvailable(int timeout = 0);
bool EndOfStream();
bool CanRead();
bool CanWrite();
NetworkStream(SocketType type);
NetworkStream(std::string unixPath, bool isServer);
NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,
bool broadcast, bool supportIPv6);
NetworkStream(int32_t sock, bool owns);
uint16_t GetPort();
void Listen(int32_t backlog);
void Bind(std::string ip, uint16_t port);
void SetBroadcast(bool bC);
void SetReuseAddress(bool reuse);
void SetReusePort(bool reuse);
void SetMulticastTTL(uint8_t ttl);
void SetMulticastMembership(std::string multicastAddress,
std::string ifaceIP = "0.0.0.0");
std::shared_ptr<NetworkStream> Accept(std::string &ip, uint16_t &port);
size_t Read(uint8_t *buff, size_t sz);
size_t Write(const uint8_t *buff, size_t sz);
size_t ReadFrom(uint8_t *buff, size_t sz, std::string &ip, uint16_t &port);
size_t WriteTo(const uint8_t *buff, size_t sz, std::string ip,
uint16_t port);
static std::vector<std::pair<std::string, std::string>>
GetIPs(bool ipV6 = false);
~NetworkStream();
void SetNoDelay(bool noDelay);
void Close();
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,30 +1,47 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Stream.hpp"
namespace Tesses::Framework::Streams
{
struct WindowSize {
uint16_t Width;
uint16_t Height;
uint16_t Columns;
uint16_t Rows;
};
class PtyStream : public Stream
{
int socket;
int64_t pid;
bool eos;
WindowSize wS;
public:
PtyStream(WindowSize sz,std::string filename, std::vector<std::string> args,std::vector<std::string> env);
bool EndOfStream();
bool CanRead();
bool CanWrite();
size_t Read(uint8_t* buff, size_t sz);
size_t Write(const uint8_t* buff, size_t sz);
void Resize(WindowSize sz);
WindowSize GetWindowSize();
~PtyStream();
void Close();
};
}
namespace Tesses::Framework::Streams {
struct WindowSize {
uint16_t Width;
uint16_t Height;
uint16_t Columns;
uint16_t Rows;
};
class PtyStream : public Stream {
int socket;
int64_t pid;
bool eos;
WindowSize wS;
public:
PtyStream(WindowSize sz, std::string filename,
std::vector<std::string> args, std::vector<std::string> env);
bool EndOfStream();
bool CanRead();
bool CanWrite();
size_t Read(uint8_t *buff, size_t sz);
size_t Write(const uint8_t *buff, size_t sz);
void Resize(WindowSize sz);
WindowSize GetWindowSize();
~PtyStream();
void Close();
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,31 +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
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/>.
*/
#pragma once
#include "../Common.hpp"
namespace Tesses::Framework::Streams
{
enum class SeekOrigin : uint8_t {
Begin=0,
Current=1,
End=2
};
class Stream {
public:
int32_t ReadByte();
void WriteByte(uint8_t b);
virtual bool EndOfStream();
virtual size_t Read(uint8_t* buff, size_t sz);
virtual size_t Write(const uint8_t* buff, size_t sz);
size_t ReadBlock(uint8_t* buff, size_t sz);
void WriteBlock(const uint8_t* buff, size_t sz);
virtual bool CanRead();
virtual bool CanWrite();
virtual bool CanSeek();
virtual int64_t GetPosition();
virtual int64_t GetLength();
virtual void Flush();
virtual void Seek(int64_t pos, SeekOrigin whence);
void CopyTo(std::shared_ptr<Stream> strm, size_t buffSize=1024);
void CopyToLimit(std::shared_ptr<Stream> strm,uint64_t len, size_t buffSize=1024);
virtual void Close();
virtual ~Stream();
};
}
namespace Tesses::Framework::Streams {
enum class SeekOrigin : uint8_t { Begin = 0, Current = 1, End = 2 };
class Stream {
public:
int32_t ReadByte();
void WriteByte(uint8_t b);
virtual bool EndOfStream();
virtual size_t Read(uint8_t *buff, size_t sz);
virtual size_t Write(const uint8_t *buff, size_t sz);
size_t ReadBlock(uint8_t *buff, size_t sz);
void WriteBlock(const uint8_t *buff, size_t sz);
virtual bool CanRead();
virtual bool CanWrite();
virtual bool CanSeek();
virtual int64_t GetPosition();
virtual int64_t GetLength();
virtual void Flush();
virtual void Seek(int64_t pos, SeekOrigin whence);
void CopyTo(std::shared_ptr<Stream> strm, size_t buffSize = 1024);
void CopyToLimit(std::shared_ptr<Stream> strm, uint64_t len,
size_t buffSize = 1024);
virtual void Close();
virtual ~Stream();
};
} // namespace Tesses::Framework::Streams

View File

@@ -1,49 +1,68 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Args.hpp"
#include "BitTorrent/TorrentFile.hpp"
#include "Crypto/ClientTLSStream.hpp"
#include "Crypto/Crypto.hpp"
#include "Date/Date.hpp"
#include "Http/HttpServer.hpp"
#include "Http/HttpClient.hpp"
#include "Http/FileServer.hpp"
#include "Http/CallbackServer.hpp"
#include "Http/MountableServer.hpp"
#include "Http/ContentDisposition.hpp"
#include "Http/ChangeableServer.hpp"
#include "Http/CGIServer.hpp"
#include "Filesystem/FSHelpers.hpp"
#include "Filesystem/LocalFS.hpp"
#include "Filesystem/MountableFilesystem.hpp"
#include "Filesystem/NullFilesystem.hpp"
#include "Filesystem/RelativeFilesystem.hpp"
#include "Filesystem/SubdirFilesystem.hpp"
#include "HiddenField.hpp"
#include "Http/BasicAuthServer.hpp"
#include "Http/CGIServer.hpp"
#include "Http/CallbackServer.hpp"
#include "Http/ChangeableServer.hpp"
#include "Http/ContentDisposition.hpp"
#include "Http/FileServer.hpp"
#include "Http/HttpClient.hpp"
#include "Http/HttpServer.hpp"
#include "Http/MountableServer.hpp"
#include "Http/RouteServer.hpp"
#include "Streams/FileStream.hpp"
#include "Streams/MemoryStream.hpp"
#include "Streams/NetworkStream.hpp"
#include "Lazy.hpp"
#include "Mail/Smtp.hpp"
#include "Platform/Environment.hpp"
#include "Platform/Process.hpp"
#include "Random.hpp"
#include "Serialization/Bencode.hpp"
#include "Serialization/BitConverter.hpp"
#include "Serialization/Json.hpp"
#include "Serialization/SQLite.hpp"
#include "Streams/BufferedStream.hpp"
#include "Streams/ByteReader.hpp"
#include "Streams/ByteWriter.hpp"
#include "TextStreams/StreamReader.hpp"
#include "TextStreams/StreamWriter.hpp"
#include "Streams/FileStream.hpp"
#include "Streams/MemoryStream.hpp"
#include "Streams/NetworkStream.hpp"
#include "Text/HeaderGenerator.hpp"
#include "Text/StringConverter.hpp"
#include "TextStreams/StdIOReader.hpp"
#include "TextStreams/StdIOWriter.hpp"
#include "TextStreams/StreamReader.hpp"
#include "TextStreams/StreamWriter.hpp"
#include "TextStreams/StringReader.hpp"
#include "TextStreams/StringWriter.hpp"
#include "Text/StringConverter.hpp"
#include "Text/HeaderGenerator.hpp"
#include "Threading/Thread.hpp"
#include "Threading/Mutex.hpp"
#include "Threading/Thread.hpp"
#include "Threading/ThreadPool.hpp"
#include "Filesystem/LocalFS.hpp"
#include "Filesystem/SubdirFilesystem.hpp"
#include "Filesystem/NullFilesystem.hpp"
#include "Filesystem/MountableFilesystem.hpp"
#include "Filesystem/RelativeFilesystem.hpp"
#include "Filesystem/FSHelpers.hpp"
#include "Crypto/ClientTLSStream.hpp"
#include "Crypto/Crypto.hpp"
#include "Lazy.hpp"
#include "Mail/Smtp.hpp"
#include "HiddenField.hpp"
#include "Serialization/Json.hpp"
#include "Serialization/SQLite.hpp"
#include "Serialization/Bencode.hpp"
#include "Platform/Environment.hpp"
#include "Platform/Process.hpp"
#include "Serialization/BitConverter.hpp"
#include "Args.hpp"
#include "BitTorrent/TorrentFile.hpp"
#include "Random.hpp"
#include "Console.hpp"

View File

@@ -1,11 +1,34 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/MemoryStream.hpp"
#include "../TextStreams/StringWriter.hpp"
namespace Tesses::Framework::Text {
void GenerateCHeaderFile(std::shared_ptr<Streams::Stream> strm,std::string name, std::shared_ptr<TextStreams::TextWriter> writer);
std::string GenerateCHeaderFile(std::shared_ptr<Streams::Stream> strm,std::string name);
void GenerateCHeaderFile(const std::vector<uint8_t>& data,std::string name, std::shared_ptr<TextStreams::TextWriter> writer);
std::string GenerateCHeaderFile(const std::vector<uint8_t>& data,std::string name);
}
void GenerateCHeaderFile(std::shared_ptr<Streams::Stream> strm,
std::string name,
std::shared_ptr<TextStreams::TextWriter> writer);
std::string GenerateCHeaderFile(std::shared_ptr<Streams::Stream> strm,
std::string name);
void GenerateCHeaderFile(const std::vector<uint8_t> &data, std::string name,
std::shared_ptr<TextStreams::TextWriter> writer);
std::string GenerateCHeaderFile(const std::vector<uint8_t> &data,
std::string name);
} // namespace Tesses::Framework::Text

View File

@@ -1,20 +1,44 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <string>
#include <cstdint>
#include <string>
namespace Tesses::Framework::Text::StringConverter {
class UTF8 {
public:
static void FromUTF16(std::basic_string<char>& utf8, const std::basic_string<char16_t>& utf16);
static void FromUTF32(std::basic_string<char>& utf8, const std::basic_string<char32_t>& utf32);
};
class UTF16 {
public:
static void FromUTF8(std::basic_string<char16_t>& utf16, const std::basic_string<char>& utf8);
static void FromUTF32(std::basic_string<char16_t>& utf16, const std::basic_string<char32_t>& utf32);
};
class UTF32 {
public:
static void FromUTF8(std::basic_string<char32_t>& utf32, const std::basic_string<char>& utf8);
static void FromUTF16(std::basic_string<char32_t>& utf32, const std::basic_string<char16_t>& utf16);
};
}
class UTF8 {
public:
static void FromUTF16(std::basic_string<char> &utf8,
const std::basic_string<char16_t> &utf16);
static void FromUTF32(std::basic_string<char> &utf8,
const std::basic_string<char32_t> &utf32);
};
class UTF16 {
public:
static void FromUTF8(std::basic_string<char16_t> &utf16,
const std::basic_string<char> &utf8);
static void FromUTF32(std::basic_string<char16_t> &utf16,
const std::basic_string<char32_t> &utf32);
};
class UTF32 {
public:
static void FromUTF8(std::basic_string<char32_t> &utf32,
const std::basic_string<char> &utf8);
static void FromUTF16(std::basic_string<char32_t> &utf32,
const std::basic_string<char16_t> &utf16);
};
} // namespace Tesses::Framework::Text::StringConverter

View File

@@ -1,13 +1,32 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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 "TextReader.hpp"
namespace Tesses::Framework::TextStreams {
class ConsoleReader : public TextReader {
public:
ConsoleReader();
bool ReadBlock(std::string &str, size_t sz);
};
namespace Tesses::Framework::TextStreams
{
class ConsoleReader : public TextReader {
public:
ConsoleReader();
bool ReadBlock(std::string& str,size_t sz);
};
ConsoleReader StdIn();
ConsoleReader StdIn();
}
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,15 +1,32 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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 "TextWriter.hpp"
namespace Tesses::Framework::TextStreams {
class ConsoleWriter : public TextWriter {
bool isError;
namespace Tesses::Framework::TextStreams
{
class ConsoleWriter : public TextWriter {
bool isError;
public:
ConsoleWriter(bool isError=false);
void WriteData(const char* text, size_t len);
};
public:
ConsoleWriter(bool isError = false);
void WriteData(const char *text, size_t len);
};
ConsoleWriter StdOut();
ConsoleWriter StdErr();
}
ConsoleWriter StdOut();
ConsoleWriter StdErr();
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,19 +1,36 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "TextReader.hpp"
#include "../Streams/Stream.hpp"
namespace Tesses::Framework::TextStreams
{
class StreamReader : public TextReader
{
private:
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
bool owns;
public:
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
StreamReader(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
StreamReader(std::filesystem::path filename);
bool ReadBlock(std::string& str,size_t sz);
bool Rewind();
~StreamReader();
};
}
#include "TextReader.hpp"
namespace Tesses::Framework::TextStreams {
class StreamReader : public TextReader {
private:
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
bool owns;
public:
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
StreamReader(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
StreamReader(std::filesystem::path filename);
bool ReadBlock(std::string &str, size_t sz);
bool Rewind();
~StreamReader();
};
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,17 +1,35 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Streams/Stream.hpp"
#include "TextWriter.hpp"
namespace Tesses::Framework::TextStreams
{
class StreamWriter : public TextWriter {
private:
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
public:
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
StreamWriter(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
StreamWriter(std::filesystem::path filename, bool append=false);
void WriteData(const char* text, size_t len);
~StreamWriter();
};
}
namespace Tesses::Framework::TextStreams {
class StreamWriter : public TextWriter {
private:
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
public:
std::shared_ptr<Tesses::Framework::Streams::Stream> GetStream();
StreamWriter(std::shared_ptr<Tesses::Framework::Streams::Stream> strm);
StreamWriter(std::filesystem::path filename, bool append = false);
void WriteData(const char *text, size_t len);
~StreamWriter();
};
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,15 +1,34 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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 "TextReader.hpp"
namespace Tesses::Framework::TextStreams {
class StringReader : public TextReader {
std::string str;
size_t offset;
public:
StringReader();
StringReader(std::string str);
size_t& GetOffset();
std::string& GetString();
bool Rewind();
bool ReadBlock(std::string& str,size_t sz);
};
}
class StringReader : public TextReader {
std::string str;
size_t offset;
public:
StringReader();
StringReader(std::string str);
size_t &GetOffset();
std::string &GetString();
bool Rewind();
bool ReadBlock(std::string &str, size_t sz);
};
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,15 +1,33 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "TextWriter.hpp"
namespace Tesses::Framework::TextStreams
{
class StringWriter : public TextWriter {
private:
std::string text;
public:
std::string& GetString();
StringWriter();
StringWriter(std::string str);
void WriteData(const char* text, size_t len);
};
}
namespace Tesses::Framework::TextStreams {
class StringWriter : public TextWriter {
private:
std::string text;
public:
std::string &GetString();
StringWriter();
StringWriter(std::string str);
void WriteData(const char *text, size_t len);
};
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,22 +1,39 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
#include "TextWriter.hpp"
namespace Tesses::Framework::TextStreams
{
class TextReader
{
bool eof=false;
public:
virtual bool Rewind();
virtual bool ReadBlock(std::string& str,size_t sz)=0;
int32_t ReadChar();
std::string ReadLine();
bool ReadLine(std::string& str);
bool ReadLineHttp(std::string& str);
void ReadAllLines(std::vector<std::string>& lines);
std::string ReadToEnd();
void ReadToEnd(std::string& str);
void CopyTo(TextWriter& writer, size_t bufSz=1024);
virtual ~TextReader();
};
}
namespace Tesses::Framework::TextStreams {
class TextReader {
bool eof = false;
public:
virtual bool Rewind();
virtual bool ReadBlock(std::string &str, size_t sz) = 0;
int32_t ReadChar();
std::string ReadLine();
bool ReadLine(std::string &str);
bool ReadLineHttp(std::string &str);
void ReadAllLines(std::vector<std::string> &lines);
std::string ReadToEnd();
void ReadToEnd(std::string &str);
void CopyTo(TextWriter &writer, size_t bufSz = 1024);
virtual ~TextReader();
};
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,75 +1,83 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../Common.hpp"
namespace Tesses::Framework::TextStreams
{
class NewLine {}; //dummy class
class TextWriter {
public:
TextWriter();
std::string newline;
virtual void WriteData(const char* text, size_t len)=0;
void Write(int64_t n);
void Write(uint64_t n);
void Write(const void* ptr);
void Write(const char* ptr);
void Write(char c);
void Write(double d);
void Write(std::string text);
inline TextWriter& operator<<(int64_t n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(uint64_t n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(const void* n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(const char* n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(char n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(double n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(std::string n)
{
Write(n);
return *this;
}
inline TextWriter& operator<<(NewLine nl)
{
WriteLine();
return *this;
}
void WriteLine(std::string txt);
void WriteLine(int64_t n);
void WriteLine(uint64_t n);
void WriteLine(const void* ptr);
void WriteLine(const char* ptr);
void WriteLine(char c);
void WriteLine(double d);
void WriteLine();
virtual ~TextWriter();
};
namespace Tesses::Framework::TextStreams {
class NewLine {}; // dummy class
class TextWriter {
public:
TextWriter();
std::string newline;
virtual void WriteData(const char *text, size_t len) = 0;
void Write(int64_t n);
void Write(uint64_t n);
void Write(const void *ptr);
void Write(const char *ptr);
void Write(char c);
void Write(double d);
void Write(std::string text);
inline TextWriter &operator<<(int64_t n) {
Write(n);
return *this;
}
inline TextWriter &operator<<(uint64_t n) {
Write(n);
return *this;
}
inline TextWriter &operator<<(const void *n) {
Write(n);
return *this;
}
inline TextWriter &operator<<(const char *n) {
Write(n);
return *this;
}
inline TextWriter &operator<<(char n) {
Write(n);
return *this;
}
inline TextWriter &operator<<(double n) {
Write(n);
return *this;
}
inline TextWriter &operator<<(std::string n) {
Write(n);
return *this;
}
}
inline TextWriter &operator<<(NewLine nl) {
WriteLine();
return *this;
}
void WriteLine(std::string txt);
void WriteLine(int64_t n);
void WriteLine(uint64_t n);
void WriteLine(const void *ptr);
void WriteLine(const char *ptr);
void WriteLine(char c);
void WriteLine(double d);
void WriteLine();
virtual ~TextWriter();
};
} // namespace Tesses::Framework::TextStreams

View File

@@ -1,15 +1,33 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "../HiddenField.hpp"
namespace Tesses::Framework::Threading
{
class Mutex {
HiddenField data;
public:
Mutex();
void Lock();
void Unlock();
bool TryLock();
~Mutex();
};
}
namespace Tesses::Framework::Threading {
class Mutex {
HiddenField data;
public:
Mutex();
void Lock();
void Unlock();
bool TryLock();
~Mutex();
};
} // namespace Tesses::Framework::Threading

View File

@@ -1,3 +1,21 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include <functional>
#if defined(_WIN32)
@@ -9,17 +27,15 @@
#else
#include <pthread.h>
#endif
#include <atomic>
#include "../HiddenField.hpp"
namespace Tesses::Framework::Threading
{
class Thread
{
HiddenField data;
public:
Thread(std::function<void()> fn);
void Join();
void Detach();
};
}
#include <atomic>
namespace Tesses::Framework::Threading {
class Thread {
HiddenField data;
public:
Thread(std::function<void()> fn);
void Join();
void Detach();
};
} // namespace Tesses::Framework::Threading

View File

@@ -1,25 +1,42 @@
#pragma once
#include <functional>
#include "Thread.hpp"
#include "Mutex.hpp"
#include <vector>
#include <queue>
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
namespace Tesses::Framework::Threading
{
class ThreadPool
{
std::vector<Thread*> threads;
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/>.
*/
#pragma once
#include "Mutex.hpp"
#include "Thread.hpp"
#include <functional>
#include <queue>
#include <vector>
namespace Tesses::Framework::Threading {
class ThreadPool {
std::vector<Thread *> threads;
std::queue<std::function<void(size_t)>> callbacks;
Mutex mtx;
volatile bool isRunning;
public:
static size_t GetNumberOfCores();
ThreadPool(size_t threads);
size_t ThreadCount();
bool Empty();
void Schedule(std::function<void(size_t)> cb);
~ThreadPool();
public:
static size_t GetNumberOfCores();
ThreadPool(size_t threads);
size_t ThreadCount();
bool Empty();
void Schedule(std::function<void(size_t)> cb);
~ThreadPool();
};
}
} // namespace Tesses::Framework::Threading

View File

@@ -1,37 +1,56 @@
/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
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/>.
*/
#pragma once
#include "Common.hpp"
namespace Tesses::Framework {
enum class UuidStringifyConfig {
IsUppercase=0b001,
HasCurly=0b010,
HasDashes=0b100,
UppercaseCompact = IsUppercase,
LowercaseCompact = 0,
UppercaseNoCurly = IsUppercase | HasDashes,
LowercaseNoCurly = HasDashes,
UppercaseCurly = IsUppercase | HasDashes | HasCurly,
LowercaseCurly = HasDashes | HasCurly
};
struct Uuid {
Uuid() = default;
uint32_t time_low = 0;
uint16_t time_mid = 0;
uint16_t time_hi_and_version = 0;
uint8_t clock_seq_hi_and_reserved = 0;
uint8_t clock_seq_low = 0;
uint8_t node[6] = {0,0,0,0,0,0};
static Uuid Generate();
static void Generate(Uuid& uuid);
enum class UuidStringifyConfig {
IsUppercase = 0b001,
HasCurly = 0b010,
HasDashes = 0b100,
UppercaseCompact = IsUppercase,
LowercaseCompact = 0,
UppercaseNoCurly = IsUppercase | HasDashes,
LowercaseNoCurly = HasDashes,
UppercaseCurly = IsUppercase | HasDashes | HasCurly,
LowercaseCurly = HasDashes | HasCurly
};
struct Uuid {
Uuid() = default;
uint32_t time_low = 0;
uint16_t time_mid = 0;
uint16_t time_hi_and_version = 0;
uint8_t clock_seq_hi_and_reserved = 0;
uint8_t clock_seq_low = 0;
uint8_t node[6] = {0, 0, 0, 0, 0, 0};
static bool TryParse(std::string text, Uuid& uuid);
static Uuid Generate();
static void Generate(Uuid &uuid);
std::string ToString(UuidStringifyConfig cfg = UuidStringifyConfig::UppercaseCurly) const;
static bool TryParse(std::string text, Uuid &uuid);
bool IsEmpty() const;
};
std::string ToString(
UuidStringifyConfig cfg = UuidStringifyConfig::UppercaseCurly) const;
bool operator==(const Uuid& left, const Uuid& right);
bool operator!=(const Uuid& left, const Uuid& right);
}
bool IsEmpty() const;
};
bool operator==(const Uuid &left, const Uuid &right);
bool operator!=(const Uuid &left, const Uuid &right);
} // namespace Tesses::Framework