Initial Commit

This commit is contained in:
Reece Wilson 2021-06-27 22:25:29 +01:00
parent 9b575eb021
commit eb4a495199
333 changed files with 19626 additions and 0 deletions

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
Build_CompilerWorkingDirectory/*
Build_Developers/*
Build_Ship/*
Build_Internal/*
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.licenseheader
*.dll
*.exe
*.obj
*.so
*.dynlib
*.lib
*.d
*.o
*.out
.vs

20
Aurora.json Normal file
View File

@ -0,0 +1,20 @@
{
"type": "aurora",
"name": "AuroraRuntime",
"dllexport": ["AURORA_ENGINE_KERNEL_EXPORT"],
"dllimport": [],
"impDefines": ["AURORA_ENGINE_KERNEL"],
"staticImpDefines": "AURORA_ENGINE_KERNEL_STATIC",
"defines": [],
"soft-depends": ["wxwidgets"],
"depends": ["glm", "asio", "mimalloc", "uuid", "fmt", "json", "bzip2", "ltc", "o1heap", "zstd", "zlib", "lz4", "mbedtls"],
"features": ["remove-platform-code", "guess-platform-code"],
"actions": [
{
"if": "win32",
"then": {
"links": "Bcrypt.lib"
}
}
]
}

View File

@ -0,0 +1,319 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Async.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Async
{
class IWorkItem;
class IAsyncApp;
using AVoid = AuUInt8;
AUKN_SYM IAsyncApp *GetAsyncApp();
using ThreadGroup_t = AuUInt8;
using ThreadId_t = AuUInt16;
using WorkerId_t = std::pair<ThreadGroup_t, ThreadId_t>;
using DispatchTarget_t = std::pair<ThreadGroup_t, std::optional<ThreadId_t>>;
struct IWorkItemHandler
{
enum class EProcessNext
{
eInvalid = -1,
eFinished = 0,
eRerun,
eSchedule,
eFailed
};
struct ProcessInfo
{
ProcessInfo(bool finished) : type(finished ? EProcessNext::eFinished : EProcessNext::eFailed) {}
ProcessInfo(EProcessNext type) : type(type) {}
ProcessInfo(const AuList<AuSPtr<IWorkItem>> &blockedBy) : type(EProcessNext::eSchedule), waitFor(blockedBy) {}
// ...
EProcessNext type;
AuList<AuSPtr<IWorkItem>> waitFor;
AuUInt32 reschedMs;
//AuUInt64 reschedNs;
};
virtual void DispatchFrame(ProcessInfo &info) = 0;
virtual void Shutdown() = 0;
};
template<typename Info_t = AVoid, typename Result_t = AVoid>
struct FJob
{
std::function<void(const Info_t &, const Result_t &)> onSuccess = 0;
std::function<void(const Info_t &, bool)> onFailure = 0;
};
template<typename Info_t = AVoid, typename Result_t = AVoid>
struct CJob
{
void(* onSuccess)(const Info_t &, const Result_t &); //
void(* onFailure)(const Info_t &, bool taskNeverDispatched); // called from caller thread if taskNeverDispatched
};
template<typename Info_t = AVoid, typename Result_t = AVoid>
struct FTask
{
std::function<std::optional<Result_t>(const Info_t &)> onFrame = 0;
};
template<typename Info_t = AVoid, typename Result_t = AVoid>
struct CTask
{
std::optional<Result_t>(* onFrame)(const Info_t &);
};
class IWorkItem
{
public:
virtual void WaitFor(const AuSPtr<IWorkItem> &workItem) = 0;
virtual void WaitFor(const AuList<AuSPtr<IWorkItem>> &workItem) = 0;
virtual void SetSchedTime(AuUInt32 ms) = 0;
virtual void Dispatch() = 0;
virtual bool BlockUntilComplete() = 0;
virtual bool HasFinished() = 0;
virtual bool HasFailed() = 0;
};
AUKN_SYM AuSPtr<IWorkItem> NewWorkItem(const DispatchTarget_t &worker, const AuSPtr<IWorkItemHandler> &task, bool supportsBlocking = false);
struct BasicWorkStdFunc : IWorkItemHandler
{
std::function<void()> callback;
std::function<void()> error;
BasicWorkStdFunc(std::function<void()> &&callback, std::function<void()> &&error) : callback(std::move(callback)), error(std::move(error))
{}
BasicWorkStdFunc(std::function<void()> &&callback) : callback(std::move(callback))
{}
BasicWorkStdFunc(const std::function<void()> &callback) : callback(callback)
{}
BasicWorkStdFunc(const std::function<void()> &callback, const std::function<void()> &error) : callback(callback), error(error)
{}
private:
void DispatchFrame(ProcessInfo &info) override
{
try
{
callback();
}
catch (...)
{
Debug::PrintError();
}
}
void Shutdown() override
{
try
{
error();
}
catch (...)
{
Debug::PrintError();
}
}
};
template<typename Info_t, typename Result_t, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>>
struct BasicWorkCallback : IWorkItemHandler, std::enable_shared_from_this<IWorkItemHandler>
{
BasicWorkCallback()
{
caller = GetAsyncApp()->GetCurrentThread();
}
Task_t task;
Job_t callback;
Info_t input;
private:
static constexpr bool IsCallbackPtr = std::is_pointer_v<Job_t> || is_base_of_template<AuSPtr, Job_t>;
static constexpr bool IsTaskPtr = std::is_pointer_v<Task_t> || is_base_of_template<AuSPtr, Task_t>;
WorkerId_t caller;
void DispatchFrame(ProcessInfo &info) override
{
std::optional<Result_t> ret;
if constexpr (IsTaskPtr)
{
ret = task->onFrame(input);
}
else
{
ret = task.onFrame(input);
}
auto pin = this->shared_from_this();
std::function<void()> func = [ret, &callback, &input, pin]()
{
try
{
if (ret.has_value())
{
if constexpr (IsCallbackPtr)
{
callback->onSuccess(input, *ret);
}
else
{
callback.onSuccess(input, *ret);
}
}
else
{
if constexpr (IsCallbackPtr)
{
callback->onFailure(input, false);
}
else
{
callback.onFailure(input, false);
}
}
}
catch (...)
{
Debug::PrintError();
}
};
try
{
if (caller == GetAsyncApp()->GetCurrentThread())
{
func();
}
else
{
std::function<void()> err = [&callback, &input, pin]()
{
// TODO: we shold probably pass: is caller thread: false, has finished: true
if constexpr (IsCallbackPtr)
{
callback->onFailure(input, false);
}
else
{
callback.onFailure(input, false);
}
};
// TODO: this is somewhat evil. double alloc when we could reuse this
WorkItemShared(caller, std::make_shared<BasicWorkStdFunc>(func, err))->Dispatch();
}
}
catch (...)
{
Debug::PrintError();
Shutdown();
}
}
void Shutdown() override
{
try
{
if constexpr (IsCallbackPtr)
{
callback->onFailure(true);
}
else
{
callback.onFailure(true);
}
}
catch (...)
{
Debug::PrintError();
}
}
};
template<typename Frame_t = std::function<void()>, typename Cleanup_t = std::function<void()>>
struct WorkItemCallabale : IWorkItemHandler
{
Frame_t frame;
Cleanup_t cleanup;
private:
void DispatchFrame(ProcessInfo &info) override
{
frame();
info.type = IWorkItemHandler::EProcessNext::eFinished;
}
void Shutdown() override
{
cleanup();
}
};
template<typename B, typename... Args>
static void TranslateAsyncFunctionToDispatcher()
{
}
class IAsyncApp
{
public:
// Main thread logic
virtual void Main() = 0;
virtual void Shutdown() = 0;
virtual bool Exiting() = 0;
// Spawning
virtual bool Spawn(WorkerId_t) = 0;
virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) = 0;
virtual AuBST<ThreadGroup_t, AuList<AuUInt8>> GetThreads() = 0;
virtual WorkerId_t GetCurrentThread() = 0;
// Synchronization
virtual bool Sync(ThreadGroup_t group, bool requireSignal = false, AuUInt32 timeout = 0) = 0;
virtual void Signal(ThreadGroup_t group) = 0;
virtual bool WaitFor(DispatchTarget_t unlocker, Threading::IWaitable *primitive, int ms) = 0; // when unlocker = this, pump event loop
virtual bool SyncTimeout(ThreadGroup_t group, AuUInt32 ms) = 0;
virtual void SyncAllSafe() = 0;
// Features
virtual void AddFeature(WorkerId_t id, AuSPtr<Threading::Threads::IThreadFeature> feature, bool async = false) = 0;
// Debug
virtual void AssertInThreadGroup(ThreadGroup_t thread) = 0;
virtual void AssertWorker(WorkerId_t id) = 0;
};
}

View File

@ -0,0 +1,31 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BasicCompression.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Compression
{
/**
Compresses an in memory blob with zstandard
*/
AUKN_SYM bool Compress(const void *buffer, AuUInt32 length, AuList<AuUInt8> &out, int compressionLevel = 3);
/**
Compresses an in memory blob with zstandard
*/
AUKN_SYM bool Compress(const AuList<AuUInt8> &in, AuList<AuUInt8> &out, int compressionLevel = 3);
/**
Decompresses an in memory blob with zstandard
*/
AUKN_SYM bool Decompress(const void *buffer, AuUInt32 length, AuList<AuUInt8> &out);
/**
Decompresses an in memory blob with zstandard
*/
AUKN_SYM bool Decompress(const AuList<AuUInt8> &in, AuList<AuUInt8> &out);
}

View File

@ -0,0 +1,36 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Compression.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
/*
Ballpark figures of real world performance:
https://www.gaia-gis.it/fossil/librasterlite2/wiki?name=benchmarks+(2019+update)
RELATIVE
Useful for compression ratio variation and realistic igors lzma decompression perf values
9th gen intel benchmark figures in MB/s:
https://github.com/lz4/lz4
Similar to above, i7 bin:
https://facebook.github.io/zstd/
LZMA -> Large packages. Sony conures. (Reliable 2.3 - 2.5. Scales all the way up to 20+. Extremely slow but scalable)
LZ4 -> Network compression and other large data streams (~4.5GB/s, 2.884 compression ratio)
ZSTD -> Standard use (~1.5GB/s to 2.5GB/s, respective compression ratios 2.4 and 2.1. Can be pushed to ~10 at around 750MB/s. Great general use. )
ZIP -> Zlib has a disgusting decompression upper limit of around 450MB/s for 2.7
*/
#include "BasicCompression.hpp"
#include "ECompresionType.hpp"
#include "CompressionInfo.hpp"
#include "StreamPipeProcessor.hpp"
#include "ICompressionStream.hpp"
#include "StreamProcessor.hpp"

View File

@ -0,0 +1,34 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CompressionInfo.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Compression
{
struct CompressionInfo
{
ECompresionType type;
/// ZSTD: -5 <= level <= 22
/// recommended: ZSTD_CLEVEL_DEFAULT
/// LZMA: 0 <= level <= 9
/// LZ4 : N/A
/// ZLIB: 0 <= x >= 9
/// recommended: 6
/// BZIP: 0 <= x >= 9
AuInt8 compressionLevel{};
/// LZMA: 5 <= fb <= 273, default = 32
AuUInt32 fbWordSize{};
/// LZMA only
/// (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
/// (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
/// default = (1 << 24)
AuUInt32 dictSize{};
};
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECompresionType.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Compression
{
enum class ECompresionType
{
eLZMA,
eZSTD,
eDeflate,
eLZ4,
eBZIP2
};
}

View File

@ -0,0 +1,24 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ICompressionStream.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Compression
{
class ICompressionStream
{
public:
virtual bool Ingest(AuUInt32 minimum, AuUInt32 request) = 0;
virtual bool Read(void * /*opt*/, AuUInt32 &len, bool ingestUntilEOS = true) = 0;
};
class ICompressionStreamEx : public ICompressionStream
{
public:
virtual void Flush() = 0;
};
}

View File

@ -0,0 +1,32 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: StreamPipeProcessor.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Compression
{
struct CompressionPipe
{
/// algorithm
ECompresionType type;
/// LZMA decompression + compression, and ZSTD compression only
AuUInt32 threads;
/// consume from stream callback
std::function<AuUInt(void *, AuUInt)> inPipe;
/// write to stream callback
std::function<void(const void *, AuUInt)> writePipe;
/// preemption and reporting
std::function<bool(AuUInt, AuUInt)> reportProgress;
};
AUKN_SYM bool Decompress(const CompressionPipe &stream);
AUKN_SYM bool Compress(const CompressionPipe &stream, const CompressionInfo &info);
}

View File

@ -0,0 +1,16 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: StreamProcessor.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include <Aurora/IO/IO.hpp>
namespace Aurora::Compression
{
AUKN_SHARED_API(Decompressor, ICompressionStream, Aurora::IO::IStreamReader *reader, ECompresionType type);
AUKN_SHARED_API(Compressor, ICompressionStreamEx, Aurora::IO::IStreamReader *reader, const CompressionInfo &info);
}

View File

@ -0,0 +1,18 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Commands.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
#include <Aurora/Parse/Parse.hpp>
namespace Aurora::Console::Commands
{
using CommandCallback_cb = std::function<void(const Parse::ParsedObject &)>;
AUKN_SYM void AddCommand(const AuString &tag, const Parse::ParseObject &commandStructure, const CommandCallback_cb &callback);
AUKN_SYM bool DispatchCommand(const AuString &string);
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Console.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "EAnsiColor.hpp"
#include "ConsoleMessage.hpp"
namespace Aurora::Console
{
AUKN_SYM void WriteLine(const ConsoleMessage &msg);
}
#include "Commands/Commands.hpp"
#include "Hooks/Hooks.hpp"
#include "Logging/Logging.hpp"

View File

@ -0,0 +1,55 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ConsoleMessage.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
//#include <Aurora/Time/Time.hpp>
namespace Aurora::Threading::Threads
{
AUKN_SYM AuThreadId_t GetThreadId();
}
namespace Aurora::Time
{
AUKN_SYM AuUInt64 CurrentClockMS();
}
namespace Aurora::Console
{
class AUKN_SYM ConsoleMessage
{
public:
EAnsiColor color;
AuString prefix;
AuString line;
AuUInt64 time;
AuThreadId_t tid;
ConsoleMessage()
{
color = EAnsiColor::eReset;
}
ConsoleMessage(const AuString &prefix, const AuString &line) : prefix(prefix), line(line), color(EAnsiColor::eReset)
{
time = Time::CurrentClockMS();
tid = Threading::Threads::GetThreadId();
}
ConsoleMessage(const EAnsiColor color, const AuString &prefix, const AuString &line) : prefix(prefix), line(line), color(color)
{
time = Time::CurrentClockMS();
tid = Threading::Threads::GetThreadId();
}
AuString StringifyTime(bool simple = false) const;
AuString GetWrappedTag() const;
AuString ToConsole() const;
AuString ToSimplified() const;
};
}

View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EAnsiColor.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Console
{
enum class EAnsiColor
{
eRed,
eBoldRed,
eGreen,
eBoldGreen,
eYellow,
eBoldYellow,
eBlue,
eBoldBlue,
eMagenta,
eBoldMagenta,
eCyan,
eBoldCyan,
eReset,
eCount
};
}

View File

@ -0,0 +1,15 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Hooks.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Console::Hooks
{
using LineHook_cb = std::function<void(const ConsoleMessage &string)>;
AUKN_SYM void AddHook(LineHook_cb hook);
}

View File

@ -0,0 +1,47 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Logging.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Console::Logging
{
template<typename ... T>
static inline void WriteLinef(const AuString &tag, const AuString &msg, T... args)
{
Aurora::Console::WriteLine(ConsoleMessage(EAnsiColor::eReset, tag, fmt::format(msg, args...)));
}
template<typename ... T>
static inline void WriteLinef(EAnsiColor color, const AuString &tag, const AuString &msg, T... args)
{
Aurora::Console::WriteLine(ConsoleMessage(color, tag, fmt::format(msg, args...)));
}
template<typename ... T>
static inline void LogInfo(const AuString &line, T... args)
{
Aurora::Console::Logging::WriteLinef(EAnsiColor::eGreen, "Info", line, args...);
}
template<typename ... T>
static inline void LogDbg(const AuString &line, T... args)
{
Aurora::Console::Logging::WriteLinef(EAnsiColor::eYellow, "Debug", line, args...);
}
template<typename ... T>
static inline void LogWarn(const AuString &line, T... args)
{
Aurora::Console::Logging::WriteLinef(EAnsiColor::eRed, "Warn", line, args...);
}
template<typename ... T>
static inline void LogGame(const AuString &line, T... args)
{
Aurora::Console::Logging::WriteLinef(EAnsiColor::eBlue, "Game", line, args...);
}
}

View File

@ -0,0 +1,35 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AES.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::AES
{
AUKN_SYM AuUInt GetSafeCipherPadding(const void* plainText,
AuUInt plainTextLength);
// Remember: AES works in chunks of 128 bits
// IVS are 16 bytes long
// Chunks are 16 bytes long
// Keys are 16, 24, or 32 bytes long
// Initialization vectors must never be constant
// Initialization vectors should be determined by a handshaake
// It is not the end of the world if an IV is made public by design
// Keys must be random
// Initialization vectors could be derived from SHA1, Tiger, or SHA2 digests
AUKN_SYM bool Encrypt(const void* plainText, AuUInt plainTextLength,
const void* iv, void* outIv, AuUInt ivLength,
const void* key, AuUInt keyLength,
AuList<AuUInt8>& out,
bool safe);
AUKN_SYM bool Decrypt(const void* cipherText, AuUInt cipherTextLength,
const void* iv, void* outIv, AuUInt ivLength,
const void* key, AuUInt keyLength,
AuList<AuUInt8>& plainText,
bool safe);
}

View File

@ -0,0 +1,28 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CA.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::CA
{
class ICertificateStore
{
public:
virtual void AddSignature(const PublicRSAKey& CA, const AuList<AuUInt8>& sig,
EHashType method, EPaddingType type) = 0;
virtual void AddPublicCert(const X509::Certificate& cert) = 0;
/// For future support of http gets of the CA list
virtual bool& AllowHTTPTree() = 0;
virtual bool CheckKey(const PublicKey& pub) = 0;
virtual bool CheckCert(const X509::Certificate& cert) = 0;
};
AUKN_SHARED_API(NewCA, ICertificateStore);
}

View File

@ -0,0 +1,40 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Crypto.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto
{
using DerBuffer = AuList<AuUInt8>;
using PrivateRSAKey = DerBuffer; // a/k/a "RSA", OpenSSL, private key in mbedtls, PKCS1
using PublicRSAKey = DerBuffer;
using PrivateECCKey = DerBuffer;
using PublicECCKey = DerBuffer;
using PrivateKey = DerBuffer; // PKCS8
using PublicKey = DerBuffer;
namespace X509
{
using Certificate = AuList<AuUInt8>;
}
struct RSAPair
{
X509::Certificate pub;
PrivateRSAKey priv;
};
}
#include "EHashType.hpp"
#include "EPaddingType.hpp"
#include "AES/AES.hpp"
#include "X509/X509.hpp"
#include "CA/CA.hpp"
#include "ECC25519/ECC25519.hpp"
#include "ECCNIST/ECCNIST.hpp"
#include "PEM/PEM.hpp"
#include "RSA/RSA.hpp"

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECC25519.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::ECC25519
{
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ECCNIST.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::ECCNIST
{
}

View File

@ -0,0 +1,19 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EHashType.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto
{
enum class EHashType
{
eSHA1_20_160,
eTiger_24_192,
eSHA2_32_256,
eSHA2_64_512
};
}

View File

@ -0,0 +1,24 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EPaddingType.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto
{
enum class EPaddingType
{
ePaddingNone,
// For use with encryption
ePKCS_OAEP,
// For use with signing and encryption
ePKCS_1_5,
// For use with signing
ePKCS_1_PSS,
// For use with signing
ePKCS_1_5_NA1
};
}

View File

@ -0,0 +1,23 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: PEM.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::PEM
{
AUKN_SYM AuString ToString(const Aurora::Crypto::X509::Certificate &in);
AUKN_SYM AuString PublicToString(const PublicKey &in);
AUKN_SYM AuString PrivateToString(const PrivateKey &in);
AUKN_SYM AuString PublicRSAToString(const PrivateRSAKey &in);
AUKN_SYM AuString PrivateRSAToString(const PublicRSAKey &in);
AUKN_SYM bool FromString(const AuString &in, Aurora::Crypto::X509::Certificate &out);
AUKN_SYM bool PublicFromString(const AuString &in, PublicKey &out);
AUKN_SYM bool PrivateFromString(const AuString &in, PrivateKey &out);
AUKN_SYM bool PublicRSAFromString(const AuString &in, PrivateRSAKey &out);
AUKN_SYM bool PrivateRSAFromString(const AuString &in, PublicRSAKey &out);
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: RSA.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::RSA
{
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ESignatureAlgorithm.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::X509
{
enum class ESignatureAlgorithm
{
eInvalidAlgorithm,
eMD5WithRSA,
eSHA1WithRSA,
eSHA256WithRSA,
eECDSAWithRSA
};
}

View File

@ -0,0 +1,62 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: X509.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
#include "ESignatureAlgorithm.hpp"
namespace Aurora::Crypto::X509
{
// yes, these structure completely disregards the principles of the x509 structure and the rationales behind certain extensions
// however, this is not intended to be a grandiose TLS stack
//
// PKSC#1 and #8, and x509 extensions (ie: rfc5280 key-ids, v3 exts) are not supported in our deps
// we had to reimplement them ourselves >:(
// lets worry about the more important issues
struct CertName
{
AuString commonName; // Tbs
AuString department; // Tbs
AuString organization; // Tbs
AuString state; // Tbs
AuString countryCode; // Tbs
AuString name; // Tbs
AuString email; // Tbs
AuString title; // Tbs
};
struct DecodedCertificate
{
// TODO:
//SignatureAlgorithm signature;
struct Issuer : CertName
{
AuList<AuUInt8> id;
} issuer;
struct Subject : CertName
{
AuList<AuUInt8> id;
} subject;
struct Vaildity // Tbs
{ // Tbs
AuUInt issued; // Tbs
AuUInt expire; // Tbs
} validity; // Tbs
AuList<AuUInt8> serialNumber; // Tbs
AuList<AuUInt8> algorithmOid; // Tbs
// TODO: usage // extension
AuList<AuString> AIAs;
// TODO: AuString CRL;
// TODO: AuList<String> subjectNames;
};
AUKN_SYM bool Decode(const Certificate &der, DecodedCertificate &out);
AUKN_SYM bool Validate(const Certificate &der, const Certificate &parentDer);
}

View File

@ -0,0 +1,137 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Data.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Data
{
enum class DataType
{
kTypeUInt, // Human friendly types
kTypeSInt,
kTypeNumber,
kTypeString,
kTypeBoolean,
kTypeUUID,
kTypeVec3,
kTypeVec4,
kTypeGenericMax, // Binary serialization
kTypeStructFloat,
kTypeStructUInt8,
kTypeStructInt8,
kTypeStructUInt16,
kTypeStructInt16,
kTypeStructUInt32,
kTypeStructInt32,
kTypeSpecialComponent, // Special QST
kTypeSpecialArray, //
kTypeSpecialObject, //
kTypeEND,
kTypeStructDouble = kTypeNumber, // overlap bin serial with human friendly aliases
kTypeStructUInt64 = kTypeUInt, //
kTypeStructInt64 = kTypeSInt, //
};
union PrimitiveValue
{
AuUInt64 uint;
AuInt64 sint;
double number;
bool boolean;
glm::vec3 vec3;
glm::vec4 vec4;
};
struct Value
{
#define CONSTRUCTOR(type, member)\
Value(type val)\
{\
primitive.member = val;\
}
CONSTRUCTOR(const glm::vec3 &, vec3);
CONSTRUCTOR(const glm::vec4 &, vec4);
CONSTRUCTOR(bool, boolean);
CONSTRUCTOR(double, number);
CONSTRUCTOR(AuInt64, sint);
CONSTRUCTOR(AuUInt64, uint);
#undef CONSTRUCTOR
Value(uuids::uuid val)
{
UUID = val;
}
Value(const AuString &val)
{
string = val;
}
Value()
{
}
PrimitiveValue primitive;
uuids::uuid UUID;
AuString string;
};
struct TypedValue
{
DataType type;
Value value;
};
template<DataType type>
static constexpr AuUInt GetDatatypeLength()
{
switch /*constexpr*/ (type)
{
case DataType::kTypeBoolean: return 1;
case DataType::kTypeStructFloat: return 4;
case DataType::kTypeStructDouble: return 8;
case DataType::kTypeVec3: return 3 * 4;
case DataType::kTypeVec4: return 4 * 4;
case DataType::kTypeStructUInt8: return 1;
case DataType::kTypeStructInt8: return 1;
case DataType::kTypeStructUInt16: return 2;
case DataType::kTypeStructInt16: return 2;
case DataType::kTypeStructUInt32: return 4;
case DataType::kTypeStructInt32: return 4;
case DataType::kTypeStructUInt64: return 8;
case DataType::kTypeStructInt64: return 8;
default: static_assert(false, "invalid datatype");
}
}
static AuUInt GetDatatypeLength(Data::DataType type)
{
switch /*constexpr*/ (type)
{
case DataType::kTypeBoolean: return 1;
case DataType::kTypeStructFloat: return 4;
case DataType::kTypeStructDouble: return 8;
case DataType::kTypeVec3: return 3 * 4;
case DataType::kTypeVec4: return 4 * 4;
case DataType::kTypeStructUInt8: return 1;
case DataType::kTypeStructInt8: return 1;
case DataType::kTypeStructUInt16: return 2;
case DataType::kTypeStructInt16: return 2;
case DataType::kTypeStructUInt32: return 4;
case DataType::kTypeStructInt32: return 4;
case DataType::kTypeStructUInt64: return 8;
case DataType::kTypeStructInt64: return 8;
default: return 0;
}
}
}

View File

@ -0,0 +1,58 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Debug.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include <Aurora/Console/Console.hpp>
#include "StackTrace.hpp"
#include "FailureCategory.hpp"
namespace Aurora::Debug
{
/**
Retrieves a print-friendly callstack of the last trap (either innocent exception or fatal mem access) <br>
On Win32, this information is always available <br>
On other platforms, this function will likely yield no valuable information
*/
AUKN_SYM AuString GetLastErrorStack();
AUKN_SYM StackTrace GetLastStackTrace();
/**
Retrieve information about the last exception. <br>
On Win32, this information is always available <br>
On other platforms, this information is only available within C++14 catch blocks
*/
AUKN_SYM AuString GetLastException();
/**
Retrieve the last system error (IE: Win32, GetLastError())
*/
AUKN_SYM AuString GetLastSystemMessage();
/**
Prints the current error state of the thread including: <br>
Current System Error, <br>
Current Runtime Error, <br>
Last Exception Call Stack, <br>
Last major ring notification
*/
AUKN_SYM void PrintError();
/**
Immediately terminates the process.
May attempt some hardened telemetry debug ops
*/
AUKN_SYM AU_NORETURN void Panic();
}
#include "SysPanic.hpp"
#include "SysAssertions.hpp"
#include "SysErrors.hpp"

View File

@ -0,0 +1,39 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FailureCategory.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Debug
{
enum FailureCategory
{
kFailureGeneric,
kFailureNested,
kFailureMemory,
kFailureIO,
kFailureFIO,
kFailureNet,
kFailureAudio,
kFailureHAL,
kFailureHALContext,
kFailureCrypto,
kFailureParam,
kFailureLogicError,
kFailureMathError,
kFailureUnavailableError,
kFailureTimeoutError,
kFailureWatchdogError,
kFailureServiceError,
kFailurePermissionError,
kFailureOutOfRange,
kFailureSyntaxError,
kFailureDisconnected,
kFailureUninitialized,
kFailureUserBegin = 256
};
}

View File

@ -0,0 +1,24 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: StackTrace.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Debug
{
struct StackTraceEntry
{
std::optional<AuString> label;
AuUInt64 address;
std::optional<AuString> module;
std::optional<std::tuple<AuString, int, int>> file; // file, line, offset
AUKN_SYM AuString Stringify() const;
};
using StackTrace = AuList<StackTraceEntry>;
AUKN_SYM AuString StringifyStackTrace(const StackTrace &backtrace);
}

View File

@ -0,0 +1,193 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SysAssertions.hpp
Date: 2021-6-10
Author: Reece
***/
//#pragma once <- AURORA_NO_ASSERTIONS may be redefined. do not cache
#if !defined(AURORA_NO_ASSERTIONS)
// defines SysAssert and SysAssertDbg
#if defined(DEBUG)
/// @private
template<typename ... T>
static inline void SysAssertFileEx(const char *file, int fileno, const char *func, bool tru, T... args)
{
if (tru)
{
return;
}
Aurora::Console::Logging::WriteLinef(
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression address: {} {}:{}", func, file, fileno);
if constexpr (sizeof...(T) == 0)
{
SysPanic("That's all folks");
}
else
{
SysPanic(args...);
}
}
/**
A simple assertion with an optional message
*/
#define SysAssert(tru, ...) \
do \
{ \
SysAssertFileEx(__FILE__, __LINE__, __FUNCTION__, tru, ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with an optional message under debug targets
*/
#define SysAssertDbg SysAssert
#else
/// @private
template<typename ... T>
static inline void SysAssertEx(bool tru, T... args)
{
if (tru)
{
return;
}
if constexpr (sizeof...(T) == 0)
{
SysPanic("That's all folks");
}
else
{
SysPanic(args...);
}
}
/**
A simple assertion with an optional message
*/
#define SysAssert(tru, ...) \
do \
{ \
SysAssertEx(tru, ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with an optional message under debug targets
*/
#define SysAssertDbg(tru, ...) do {} while (0)
#endif
// defines SysAssertExp and SysAssertDbgExp
#if defined(DEBUG)
/// @private
template<typename ... T>
static inline void SysAssertFileExpEx(const char *file, int fileno, const char *func, const char *exp, bool tru, T... args)
{
if (tru)
{
return;
}
Aurora::Console::Logging::WriteLinef(
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression address: {} {}:{}", func, file, fileno);
Aurora::Console::Logging::WriteLinef(
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression failed: {}", exp);
if constexpr (sizeof...(T) == 0)
{
SysPanic("That's all folks");
}
else
{
SysPanic(args...);
}
}
/**
A simple assertion with a debug expresison and optional message debugging
*/
#define SysAssertExp(tru, ...) \
do \
{ \
SysAssertFileExpEx(__FILE__, __LINE__, __FUNCTION__, _AUKCON_STRINGIFY_X(tru), tru, ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with a debug expresison and optional message debugging under debug targets only
*/
#define SysAssertDbgExp SysAssertExp
#else
/// @private
template<typename ... T>
static inline void SysAssertExpEx(const char *exp, bool tru, T... args)
{
if (tru)
{
return;
}
Aurora::Console::Logging::WriteLinef(
Aurora::Console::EAnsiColor::eBoldRed,
"Fatal",
"Expression failed: {}", exp);
if constexpr (sizeof...(T) == 0)
{
SysPanic("That's all folks");
}
else
{
SysPanic(args...);
}
}
/**
A simple assertion with a debug expresison and optional message debugging
*/
#define SysAssertExp(tru, ...) \
do \
{ \
SysAssertExpEx(_AUKCON_STRINGIFY_X(tru), tru, ## __VA_ARGS__); \
} while (0)
/**
A simple assertion with a debug expresison and optional message debugging under debug targets only
*/
#define SysAssertDbgExp(tru, ...) do {} while (0)
#endif
#endif

View File

@ -0,0 +1,161 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SysErrors.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Debug
{
AUKN_SYM void _PushError(AuUInt address, FailureCategory category, const char *msg);
#if defined(AURORA_COMPILER_MSVC)
#define _DBG_RET_ADDR (AuUInt)_ReturnAddress()
#elif defined(AURORA_COMPILER_CLANG)
#define _DBG_RET_ADDR (AuUInt)__builtin_return_address(0)
#else
#define _DBG_RET_ADDR AuUInt(0)
#endif
#if defined(AURORA_COMPILER_MSVC)
#pragma optimize("", off)
#define _FREECOMPILER_OPTIMIZE_OFF
#else
#define _FREECOMPILER_OPTIMIZE_OFF [[gnu::optimize(0)]]
#endif
static AU_NOINLINE void ErrorMakeNested() _FREECOMPILER_OPTIMIZE_OFF
{
_PushError(_DBG_RET_ADDR, FailureCategory::kFailureNested, nullptr);
}
template<typename ... T>
static AU_NOINLINE void SysPushError(FailureCategory category, const AuString &msg, T... args) _FREECOMPILER_OPTIMIZE_OFF
{
if constexpr (sizeof...(T) == 0)
{
_PushError(_DBG_RET_ADDR, category, msg.c_str());
}
else
{
_PushError(_DBG_RET_ADDR, category, fmt::format(msg, args...).c_str());
}
}
static AU_NOINLINE void SysPushError(FailureCategory category) _FREECOMPILER_OPTIMIZE_OFF
{
_PushError(_DBG_RET_ADDR, category, nullptr);
}
#if defined(AURORA_COMPILER_MSVC)
#pragma optimize("", on)
#endif
}
#define SysCheckReturn(x, ...) if (!(x)) { Aurora::Debug::ErrorMakeNested(); return ##__VA_ARGS__; }
#define SysPushErrorError(error, ...) Aurora::Debug::SysPushError(Aurora::Debug::error, ## __VA_ARGS__)
// legacy
#define SysPushErrorArg(...) SysPushErrorError(kFailureParam, ## __VA_ARGS__)
#define SysPushErrorGen(...) SysPushErrorError(kFailureGeneric, ## __VA_ARGS__)
#define SysPushErrorCrypt(...) SysPushErrorError(kFailureCrypto, ## __VA_ARGS__)
#define SysPushErrorNet(...) SysPushErrorError(kFailureNet, ## __VA_ARGS__)
#define SysPushErrorMem(...) SysPushErrorError(kFailureMemory, ## __VA_ARGS__)
// edge case
#define SysPushErrorNested() Aurora::Debug::ErrorMakeNested();
// enums
#define SysPushErrorGeneric(...) SysPushErrorError(kFailureGeneric, ## __VA_ARGS__)
#define SysPushErrorMemory(...) SysPushErrorError(kFailureMemory, ## __VA_ARGS__)
#define SysPushErrorIO(...) SysPushErrorError(kFailureIO, ## __VA_ARGS__)
#define SysPushErrorFIO(...) SysPushErrorError(kFailureFIO, ## __VA_ARGS__)
#define SysPushErrorNet(...) SysPushErrorError(kFailureNet, ## __VA_ARGS__)
#define SysPushErrorAudio(...) SysPushErrorError(kFailureAudio, ## __VA_ARGS__)
#define SysPushErrorHAL(...) SysPushErrorError(kFailureHAL, ## __VA_ARGS__)
#define SysPushErrorHALContext(...) SysPushErrorError(kFailureHALContext, ## __VA_ARGS__)
#define SysPushErrorCrypto(...) SysPushErrorError(kFailureCrypto, ## __VA_ARGS__)
#define SysPushErrorParam(...) SysPushErrorError(kFailureParam, ## __VA_ARGS__)
#define SysPushErrorLogicError(...) SysPushErrorError(kFailureLogicError, ## __VA_ARGS__)
#define SysPushErrorMathError(...) SysPushErrorError(kFailureMathError, ## __VA_ARGS__)
#define SysPushErrorUnavailableError(...) SysPushErrorError(kFailureUnavailableError, ## __VA_ARGS__)
#define SysPushErrorTimeoutError(...) SysPushErrorError(kFailureTimeoutError, ## __VA_ARGS__)
#define SysPushErrorWatchdogError(...) SysPushErrorError(kFailureWatchdogError, ## __VA_ARGS__)
#define SysPushErrorServiceError(...) SysPushErrorError(kFailureServiceError, ## __VA_ARGS__)
#define SysPushErrorPermissionError(...) SysPushErrorError(kFailurePermissionError, ## __VA_ARGS__)
#define SysPushErrorOutOfRange(...) SysPushErrorError(kFailureOutOfRange, ## __VA_ARGS__)
#define SysPushErrorSyntaxError(...) SysPushErrorError(kFailureSyntaxError, ## __VA_ARGS__)
#define SysPushErrorDisconnected(...) SysPushErrorError(kFailureDisconnected, ## __VA_ARGS__)
#define SysPushErrorUninitialized(...) SysPushErrorError(kFailureUninitialized, ## __VA_ARGS__)
#if defined(DEBUG) || defined(INTERNAL)
#define SysPushErrorArgDbg SysPushErrorArg
#define SysPushErrorGenDbg SysPushErrorGen
#define SysPushErrorCryptDbg SysPushErrorCrypt
#define SysPushErrorNetDbg SysPushErrorNet
#define SysPushErrorMemDbg SysPushErrorMem
#define SysPushErrorGenericDbg SysPushErrorGeneric
#define SysPushErrorNestedDbg SysPushErrorNested
#define SysPushErrorMemoryDbg SysPushErrorMemory
#define SysPushErrorIODbg SysPushErrorIO
#define SysPushErrorFIODbg SysPushErrorFIO
#define SysPushErrorNetDbg SysPushErrorNet
#define SysPushErrorAudioDbg SysPushErrorAudio
#define SysPushErrorHALDbg SysPushErrorHAL
#define SysPushErrorHALContextDbg SysPushErrorHALContext
#define SysPushErrorCryptoDbg SysPushErrorCrypto
#define SysPushErrorParamDbg SysPushErrorParam
#define SysPushErrorLogicErrorDbg SysPushErrorLogicError
#define SysPushErrorMathErrorDbg SysPushErrorMathError
#define SysPushErrorUnavailableErrorDbg SysPushErrorUnavailableError
#define SysPushErrorTimeoutErrorDbg SysPushErrorTimeoutError
#define SysPushErrorWatchdogErrorDbg SysPushErrorWatchdogError
#define SysPushErrorServiceErrorDbg SysPushErrorServiceError
#define SysPushErrorPermissionErrorDbg SysPushErrorPermissionError
#define SysPushErrorOutOfRangeDbg SysPushErrorOutOfRange
#define SysPushErrorSyntaxErrorDbg SysPushErrorSyntaxError
#define SysPushErrorDisconnectedDbg SysPushErrorDisconnected
#define SysPushErrorUninitializedDbg SysPushErrorUninitialized
#else
#define SysPushErrorArgDbg(...)
#define SysPushErrorGenDbg(...)
#define SysPushErrorCryptDbg(...)
#define SysPushErrorNetDbg(...)
#define SysPushErrorMemDbg(...)
#define SysPushErrorGenericDbg(...)
#define SysPushErrorNestedDbg(...)
#define SysPushErrorMemoryDbg(...)
#define SysPushErrorIODbg(...)
#define SysPushErrorFIODbg(...)
#define SysPushErrorNetDbg(...)
#define SysPushErrorAudioDbg(...)
#define SysPushErrorHALDbg(...)
#define SysPushErrorHALContextDbg(...)
#define SysPushErrorCryptoDbg(...)
#define SysPushErrorParamDbg(...)
#define SysPushErrorLogicErrorDbg(...)
#define SysPushErrorMathErrorDbg(...)
#define SysPushErrorUnavailableErrorDbg(...)
#define SysPushErrorTimeoutErrorDbg(...)
#define SysPushErrorWatchdogErrorDbg(...)
#define SysPushErrorServiceErrorDbg(...)
#define SysPushErrorPermissionErrorDbg(...)
#define SysPushErrorOutOfRangeDbg(...)
#define SysPushErrorSyntaxErrorDbg(...)
#define SysPushErrorDisconnectedDbg(...)
#define SysPushErrorUninitializedDbg(...)
#endif

View File

@ -0,0 +1,15 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SysPanic.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
template<typename ... T>
static inline void __declspec(noreturn) SysPanic(T... args)
{
Aurora::Console::Logging::WriteLinef(Aurora::Console::EAnsiColor::eBoldRed, "Fatal", args...);
Aurora::Debug::Panic();
}

View File

@ -0,0 +1,26 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CpuInfo.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::HWInfo
{
struct CpuInfo
{
Aurora::Build::EArchitecture cpuArch;
AuUInt8 socket;
AuUInt8 cores;
AuUInt8 threads;
AuUInt32 cpuId[4];
char vendor[12];
unsigned features;
};
AUKN_SYM const CpuInfo &GetCPUInfo();
}

View File

@ -0,0 +1,11 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: HWInfo.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "CpuInfo.hpp"
#include "RamInfo.hpp"

View File

@ -0,0 +1,15 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: RamInfo.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::HWInfo
{
AUKN_SYM AuUInt32 GetRamAvailableMb();
AUKN_SYM AuUInt32 GetRamStartupAvailableMb();
AUKN_SYM AuUInt32 GetRamTotalMb();
}

View File

@ -0,0 +1,10 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CE.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
#include "fnv1.hpp"

View File

@ -0,0 +1,35 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: fnv1.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Hashing
{
namespace CE
{
constexpr uint64_t val_64_const = 0xcbf29ce484222325;
constexpr uint64_t prime_64_const = 0x100000001b3;
inline constexpr uint64_t fnv1a(const char *const str, const uint64_t value = val_64_const) noexcept
{
return (str[0] == '\0') ? value : fnv1a(&str[1], (value ^ uint64_t(str[0])) * prime_64_const);
}
inline constexpr uint32_t fnv1a_trunc(const char *const str) noexcept
{
return static_cast<uint32_t>(fnv1a(str));
}
constexpr uint64_t val_32_const = 0x811c9dc5;
constexpr uint64_t prime_32_const = 0x01000193;
inline constexpr uint32_t fnv1a_32(const char *const str, const uint32_t value = val_32_const) noexcept
{
return (str[0] == '\0') ? value : fnv1a_32(&str[1], (value ^ uint32_t(str[0])) * prime_32_const);
}
}
}

View File

@ -0,0 +1,61 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CommonDigests.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Hashing
{
AUKN_SYM void MD5(const void *buffer, AuMach length, std::array<AuUInt8, 16> &md5);
static void MD5(const AuList<AuUInt8> &bytebuffer, std::array<AuUInt8, 16> &md5)
{
return MD5(bytebuffer.data(), bytebuffer.size(), md5);
}
static void MD5(const AuString &bytebuffer, std::array<AuUInt8, 16> &md5)
{
return MD5(bytebuffer.data(), bytebuffer.size(), md5);
}
AUKN_SYM void SHA1(const void *buffer, AuMach length, std::array<AuUInt8, 20> &sha1);
static void SHA1(const AuList<AuUInt8> &bytebuffer, std::array<AuUInt8, 20> &sha1)
{
return SHA1(bytebuffer.data(), bytebuffer.size(), sha1);
}
static void SHA1(const AuString &bytebuffer, std::array<AuUInt8, 20> &sha1)
{
return SHA1(bytebuffer.data(), bytebuffer.size(), sha1);
}
AUKN_SYM void Tiger(const void *buffer, AuMach length, std::array<AuUInt8, 24> &tiger);
static void Tiger(const AuList<AuUInt8> &bytebuffer, std::array<AuUInt8, 24> &tiger)
{
return Tiger(bytebuffer.data(), bytebuffer.size(), tiger);
}
static void Tiger(const AuString &bytebuffer, std::array<AuUInt8, 24> &tiger)
{
return Tiger(bytebuffer.data(), bytebuffer.size(), tiger);
}
AUKN_SYM void SHA2(const void *buffer, AuMach length, std::array<AuUInt8, 32> &sha2);
static void SHA2(const AuList<AuUInt8> &bytebuffer, std::array<AuUInt8, 32> &sha2)
{
return SHA2(bytebuffer.data(), bytebuffer.size(), sha2);
}
static void SHA2(const AuString &bytebuffer, std::array<AuUInt8, 32> &sha2)
{
return SHA2(bytebuffer.data(), bytebuffer.size(), sha2);
}
AUKN_SYM void SHA2_64(const void *buffer, AuMach length, std::array<AuUInt8, 64> &sha2);
static void SHA2_64(const AuList<AuUInt8> &bytebuffer, std::array<AuUInt8, 64> &sha2)
{
return SHA2_64(bytebuffer.data(), bytebuffer.size(), sha2);
}
static void SHA2_64(const AuString &bytebuffer, std::array<AuUInt8, 64> &sha2)
{
return SHA2_64(bytebuffer.data(), bytebuffer.size(), sha2);
}
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EHashType.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Hashing
{
enum class EHashType
{
eMD5,
eSHA1,
eSHA2_32,
eSHA2_64,
eTiger
};
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: HashStream.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Hashing
{
class IHashStream
{
public:
virtual void Ingest(const void *, AuUInt32) = 0;
virtual AuUInt8 *GetBytes(AuUInt32 &length) = 0;
};
AUKN_SHARED_API(HashStream, IHashStream, EHashType type);
}

View File

@ -0,0 +1,14 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Hashing.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
#include "EHashType.hpp"
#include "HashStream.hpp"
#include "CommonDigests.hpp"
#include "CE/fnv1.hpp"

View File

@ -0,0 +1,51 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BlobArbitraryReader.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::Buffered
{
class BlobArbitraryReader : public IArbitraryStreamer
{
public:
AU_NO_COPY_NO_MOVE(BlobArbitraryReader)
BlobArbitraryReader(const AuList<AuUInt8> &buffer) : buffer_(buffer) {}
BlobArbitraryReader() {}
~BlobArbitraryReader(){}
virtual EStreamError Open() override
{
return EStreamError::eErrorNone;
}
virtual EStreamError ArbitraryRead(AuUInt32 offset, void *buffer, AuUInt32 &len) override
{
auto oldLen = std::exchange(len, 0);
if (buffer_.empty()) return EStreamError::eErrorEndOfStream;
auto endOffset = offset + oldLen;
auto realEndOffset = std::min(AuUInt32(buffer_.size()), endOffset);
auto actualLength = realEndOffset - offset;
if (actualLength < 0) return EStreamError::eErrorEndOfStream;
len = actualLength;
std::memcpy(buffer, buffer_.data() + offset, len);
return EStreamError::eErrorNone;
}
virtual void Close() override
{
buffer_.clear();
}
private:
AuList<AuUInt8> buffer_;
};
}

View File

@ -0,0 +1,48 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BlobReader.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::Buffered
{
class BlobReader : public IStreamReader
{
public:
AU_NO_COPY_NO_MOVE(BlobReader)
BlobReader(const AuList<AuUInt8> &buffer) : buffer_(buffer) {}
BlobReader() {}
~BlobReader() {}
virtual EStreamError Open() override
{
return EStreamError::eErrorNone;
}
virtual EStreamError Read(void *buffer, AuUInt32 &len) override
{
auto oldLen = std::exchange(len, 0);
if (buffer_.empty()) return EStreamError::eErrorEndOfStream;
auto realEndOffset = std::min(AuUInt32(buffer_.size()), oldLen);
len = realEndOffset;
std::memcpy(buffer, buffer_.data(), len);
return EStreamError::eErrorNone;
}
virtual void Close() override
{
buffer_.clear();
}
private:
AuList<AuUInt8> buffer_;
};
}

View File

@ -0,0 +1,49 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BlobWriter.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::Buffered
{
class BlobWriter : public IStreamWriter
{
public:
AU_NO_COPY_NO_MOVE(BlobWriter)
BlobWriter() {}
~BlobWriter() {}
virtual EStreamError Open() override
{
return EStreamError::eErrorNone;
}
virtual EStreamError Write(const void *buffer, AuUInt32 len) override
{
auto idx = buffer_.size();
buffer_.resize(idx + len);
std::memcpy(buffer_.data() + idx, buffer, len);
return EStreamError::eErrorNone;
}
virtual void Flush() override
{
}
virtual void Close() override
{
}
const AuList<AuUInt8> &GetBuffer()
{
return this->buffer_;
}
private:
AuList<AuUInt8> buffer_;
};
}

View File

@ -0,0 +1,14 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Buffered.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
// Most internal transactions will be buffered.
// For sake of being able to mix network, file, serial, and other code, its nice to use the same reader interface for buffered and streams where read/write until EOS is required
#include "BlobArbitraryReader.hpp"
#include "BlobReader.hpp"
#include "BlobWriter.hpp"

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EStreamError.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO
{
enum class EStreamError
{
eErrorNone,
eErrorEndOfStream,
eErrorStreamNotOpen,
eErrorStreamInterrupted,
eErrorHandleClosed
};
}

View File

@ -0,0 +1,47 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FS.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
/**
Lists files with respect to a given partial or full path of a directory
@param files relative address of an entry
*/
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files);
/**
Lists directories with respect to a given partial or full path of a directory
@param files relative address of an entry
*/
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs);
AUKN_SYM bool WriteFile(const AuString &path, const void *data, size_t length);
AUKN_SYM bool WriteString(const AuString &path, const AuString &str);
AUKN_SYM bool ReadFile(const AuString &path, AuList<uint8_t> &buffer);
AUKN_SYM bool ReadString(const AuString &path, AuString &buffer);
AUKN_SYM bool FileExists(const AuString &path);
AUKN_SYM bool DirExists(const AuString &path);
AUKN_SYM bool DirMk(const AuString &path);
AUKN_SYM bool Remove(const AuString &path);
AUKN_SYM bool Relink(const AuString &src, const AuString &dest);
AUKN_SYM bool Copy(const AuString &src, const AuString &dest);
}
#include "FileStream.hpp"
#include "FileArbitraryReader.hpp"
#include "FileReader.hpp"
#include "FileWriter.hpp"
#include "Resources.hpp"
#include "Stat.hpp"

View File

@ -0,0 +1,50 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FileArbitraryReader.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
class FileArbitraryReader : public IArbitraryStreamer
{
public:
AU_NO_COPY_NO_MOVE(FileArbitraryReader)
FileArbitraryReader() {}
~FileArbitraryReader() {}
template<typename... T>
bool OpenFile(T... args)
{
stream_ = OpenReadUnique(args...);
return stream_ != nullptr;
}
virtual EStreamError Open() override
{
return stream_ ? EStreamError::eErrorNone : EStreamError::eErrorStreamInterrupted;
}
virtual EStreamError ArbitraryRead(AuUInt32 offset, void *buffer, AuUInt32 &len) override
{
auto oldLen = std::exchange(len, 0);
if (!stream_) return EStreamError::eErrorStreamNotOpen;
stream_->SetOffset(offset);
len = stream_->Read(buffer, oldLen);
if (len == 0) return EStreamError::eErrorEndOfStream;
return EStreamError::eErrorNone;
}
virtual void Close() override
{
stream_.reset();
}
private:
OpenReadUnique_t stream_{};
};
}

View File

@ -0,0 +1,49 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FileReader.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
class FileReader : public IStreamReader
{
public:
AU_NO_COPY_NO_MOVE(FileReader)
FileReader() {}
~FileReader() {}
template<typename... T>
bool OpenFile(T... args)
{
stream_ = OpenReadUnique(args...);
return stream_ != nullptr;
}
virtual EStreamError Open() override
{
return stream_ ? EStreamError::eErrorNone : EStreamError::eErrorStreamInterrupted;
}
virtual EStreamError Read(void *buffer, AuUInt32 &len) override
{
auto oldLen = std::exchange(len, 0);
if (!stream_) return EStreamError::eErrorStreamNotOpen;
len = stream_->Read(buffer, oldLen);
if (len == 0) return EStreamError::eErrorEndOfStream;
return EStreamError::eErrorNone;
}
virtual void Close() override
{
stream_.reset();
}
private:
OpenReadUnique_t stream_{};
};
}

View File

@ -0,0 +1,26 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FileStream.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
class IFileStream
{
public:
virtual AuUInt64 GetOffset() = 0;
virtual bool SetOffset(AuUInt64 offset) = 0;
virtual AuUInt64 GetLength() = 0;
virtual AuUInt64 Read(void *in, AuUInt64 length) = 0;
virtual AuUInt64 Write(const void *out, AuUInt64 length) = 0;
virtual void Close() = 0;
virtual void Flush() = 0;
};
AUKN_SHARED_API(OpenRead, IFileStream, const AuString &path);
AUKN_SHARED_API(OpenWrite, IFileStream, const AuString &path);
}

View File

@ -0,0 +1,54 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FileWriter.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
class FileWriter : public IStreamWriter
{
public:
AU_NO_COPY_NO_MOVE(FileWriter)
FileWriter() {}
~FileWriter() {}
template<typename... T>
bool OpenFile(T... args)
{
stream_ = OpenWriteUnique(args...);
return stream_ != nullptr;
}
virtual EStreamError Open() override
{
return stream_ ? EStreamError::eErrorNone : EStreamError::eErrorStreamInterrupted;
}
virtual EStreamError Write(const void *buffer, AuUInt32 len) override
{
if (!stream_) return EStreamError::eErrorStreamNotOpen;
len = stream_->Write(buffer, len);
if (len == 0) return EStreamError::eErrorEndOfStream;
if (len != len) return EStreamError::eErrorStreamInterrupted;
return EStreamError::eErrorNone;
}
virtual void Flush() override
{
if (stream_) stream_->Flush();
}
virtual void Close() override
{
stream_.reset();
}
private:
OpenWriteUnique_t stream_{};
};
}

View File

@ -0,0 +1,25 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Resources.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
/**
Suffixes a global read/writable path with nameSpace and a splitter
*/
AUKN_SYM bool GetSystemDomain(AuString& path);
/**
Suffixes a global read/writable path with within a home/sandbox directory
*/
AUKN_SYM bool GetProfileDomain(AuString& path);
AUKN_SYM bool GetSystemResourcePath(const AuString& fileName, AuString& path);
}

View File

@ -0,0 +1,27 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Stat.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
struct Stat
{
bool exists;
bool existsFile, existsDirectory, existsSystemResource;
bool symLink;
AuInt64 created;
AuInt64 modified;
AuInt64 accessed;
AuUInt64 size;
};
/**
Classic file stat function
*/
AUKN_SYM bool StatFile(const AuString &path, Stat &stat);
}

View File

@ -0,0 +1,19 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IArbitraryStreamer.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO
{
class IArbitraryStreamer
{
public:
virtual EStreamError Open() = 0;
virtual EStreamError ArbitraryRead(AuUInt32 offset, void *buffer, AuUInt32 &len) = 0;
virtual void Close() = 0;
};
}

19
Include/Aurora/IO/IO.hpp Normal file
View File

@ -0,0 +1,19 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IO.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "EStreamError.hpp"
#include "IStreamReader.hpp"
#include "IStreamWriter.hpp"
#include "IArbitraryStreamer.hpp" // arbitrary read stream, dunno what you would want to call thousands_sep
#include "Buffered/Buffered.hpp"
#include "FS/FS.hpp"
#include "Net/Net.hpp"

View File

@ -0,0 +1,39 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IStreamReader.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO
{
class IStreamReader
{
public:
virtual EStreamError Open() = 0;
virtual EStreamError Read(void *buffer, AuUInt32 &len) = 0;
virtual void Close() = 0;
EStreamError ReadAll(AuList<AuUInt8> &buffer)
{
static const int kBufferSize = 2048;
AuUInt8 temp[kBufferSize];
AuUInt32 len = kBufferSize;
EStreamError ret = EStreamError::eErrorEndOfStream;
while ((ret = Read(temp, len)) == EStreamError::eErrorNone)
{
if (len == 0) break;
buffer.insert(buffer.end(), temp, temp + len);
if (len != kBufferSize) break;
}
return ret;
}
};
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IStreamWriter.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::IO
{
class IStreamWriter
{
public:
virtual EStreamError Open() = 0;
virtual EStreamError Write(const void *buffer, AuUInt32 len) = 0;
virtual void Flush() = 0;
virtual void Close() = 0;
};
}

View File

@ -0,0 +1,183 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Net.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::IO::Net
{
enum TransportProtocol
{
kProtocolUDP,
kProtocolTCP
};
enum IPProtocol
{
kIPProtocolV4,
kIPProtocolV6
};
struct IPAddress
{
IPProtocol ip;
bool hasIP;
AuString address;
union
{
AuUInt8 v4[4];
AuUInt16 v6[8];
};
AUKN_SYM AuString toString();
};
struct Endpoint
{
TransportProtocol protocol;
IPAddress address;
AuUInt16 port;
// 0 - destination is a stateless datagram server
// 1 - destination is a psuedo-stateful server
AuUInt UDPTimeout;
AUKN_SYM AuString toString();
};
class INetworkStream;
class IBasicSocket;
class IClientSocket;
using StreamHasData_cb = std::function<bool(AuSPtr<IClientSocket> socket)>; // DTLS/UDP/TCP/TLS -> TRUE = expects another frame or stream buffer, FALSE = end of socket life
using InitializeSocket_cb = std::function<bool(AuSPtr<IClientSocket> socket)>;
using ShutdownSocket_cb = std::function<void(AuSPtr<IBasicSocket> socket)>;
using Error_t = std::error_code;
class IBasicSocket
{
public:
virtual bool IsActive() = 0;
virtual Error_t GetLastError() = 0;
virtual void Shutdown() = 0;
virtual bool GetLocalEndpoint(Endpoint &out) = 0;
};
class IClientSocket : public IBasicSocket
{
public:
// called during loop pump
struct ClientCallbacks
{
StreamHasData_cb hasData; // on data available
ShutdownSocket_cb onShutdown; // Socket shutdown or otherwise dead
ShutdownSocket_cb onStreamOverSaturation; // DoS?
ShutdownSocket_cb onTLSHandshakeAbort;
};
virtual bool Initialize(const ClientCallbacks &callbacks) = 0;
virtual bool Initialize() = 0;
virtual bool GetRemoteEndpoint(Endpoint &out) = 0;
virtual bool ReadAsync(AuUInt8 *buffer, bool all, AuUInt32 &length) = 0;
virtual bool WriteAsync(const AuUInt8 *buffer, AuUInt32 length) = 0;
virtual bool WriteAsync(const AuUInt8 *buffer, AuUInt32 length, std::function<void(bool)>) = 0;
virtual AuUInt GetInternalRecvBuffer() = 0;
virtual bool SetInternalRecvBuffer(AuUInt bytes) = 0;
};
class ILocalClientSocket : public IClientSocket
{
public:
using ConnectCallback_cb = std::function<void(bool success)>;
virtual bool Connect() = 0;
virtual void ConnectAsync(ConnectCallback_cb cb) = 0;
};
struct TlsConnect
{
Aurora::Crypto::X509::Certificate serverCertificate;
AuSPtr<IBasicSocket> socket;
};
using TlsConnect_cb = std::function<bool(const TlsConnect &info)>;
struct ServerInfo
{
Endpoint listen;
};
struct TLSServerInfo : ServerInfo
{
Aurora::Crypto::RSAPair cert;
};
struct ClientInfo
{
Endpoint socket;
AuString service;
};
struct TLSClientInfo : ClientInfo
{
TlsConnect_cb pinning;
};
class IServer : public IBasicSocket
{
public:
virtual bool AddAcceptCallback(const InitializeSocket_cb &accept) = 0; // on accept*
virtual bool AddExitCallback(const ShutdownSocket_cb &accept) = 0; // server shutdown*
virtual void GetClients(AuList<AuSPtr<IClientSocket>> &soccies) = 0;
virtual bool Listen() = 0;
};
class INetworkingPool
{
public:
/**
Supported thread models:
while (true)
{
// read from sockets pre-frame
PumpSOL();
// process other async network logic here
// process writes and a few early reads before we sleep
PumpEOL();
// yield
Yield();
}
while (true)
{
// process other async network logic here
// run
Run()
}
*/
virtual void PumpSOL() = 0;
virtual void PumpEOL() = 0;
virtual void Run() = 0;
virtual bool NewServer(const ServerInfo &listen, IServer *&out) = 0;
virtual bool NewTlsServer(const TLSServerInfo &keys, IServer *&out) = 0;
virtual void DeleteServer(IServer *socket) = 0;
virtual bool NewClient(const ClientInfo &info, ILocalClientSocket *&out) = 0;
virtual bool NewTlsClient(const TLSClientInfo &info, ILocalClientSocket *&out) = 0;
virtual void DeleteClient(ILocalClientSocket *socket) = 0;
};
}

View File

@ -0,0 +1,9 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BIMap.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once

View File

@ -0,0 +1,9 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IDMap.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once

View File

@ -0,0 +1,11 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Legacy.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "BIMap.hpp"
#include "IDMap.hpp"

View File

@ -0,0 +1,34 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Locale.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Locale
{
struct LocalizationInfo
{
LocalizationInfo(const AuString& language, const AuString& country, const AuString& codeset) : Language(language), Country(country), Codeset(codeset) {}
const AuString& Language;
const AuString& Country;
const AuString& Codeset;
};
/*
Retrieves information about the current system <br>
This function will never fail <br>
This function will never release memory
*/
AUKN_SYM LocalizationInfo GetLocale();
#if defined(AURORA_PLATFORM_WIN32) || defined(I_REALLY_NEED_WIDECHAR_PUBAPI)
AUKN_SYM std::wstring ConvertFromUTF8(const AuString &in);
AUKN_SYM AuString ConvertFromWChar(const wchar_t *in, AuMach length);
AUKN_SYM AuString ConvertFromWChar(const wchar_t *in);
#endif
}

View File

@ -0,0 +1,8 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Handles.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once

View File

@ -0,0 +1,139 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Heap.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
class Heap
{
public:
virtual Types::size_t GetChunkSize(const void *head) = 0;
template<typename T = void *>
T ZAlloc(Types::size_t length)
{
return reinterpret_cast<T>(_ZAlloc(length));
}
template<typename T = void *>
T ZAlloc(Types::size_t length, Types::size_t align)
{
return reinterpret_cast<T>(_ZAlloc(length, align));
}
template<typename T>
T *ZAlloc()
{
return reinterpret_cast<T *>(_ZAlloc(sizeof(T)));
}
template<typename T>
T *NewArray(Types::size_t count)
{
return ZAlloc<T *>(count * sizeof(T));
}
template<typename T>
T *NewArray(Types::size_t count, Types::size_t align)
{
return ZAlloc<T *>(count * sizeof(T), align);
}
/// Fast, unsafe alloc
template<typename T = void *>
T FAlloc(Types::size_t length)
{
return reinterpret_cast<T>(_FAlloc(length));
}
template<typename T = void *>
T FAlloc(Types::size_t length, Types::size_t align)
{
return reinterpret_cast<T>(_FAlloc(length, align));
}
template<typename T>
T ZRealloc(T in, Types::size_t length)
{
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(in), length));
}
template<typename T>
T ZRealloc(T in, Types::size_t length, Types::size_t alloc)
{
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(in), length), alloc);
}
template<typename T>
T FRealloc(T in, Types::size_t length)
{
return reinterpret_cast<T>(_SRealloc(reinterpret_cast<void *>(in), length));
}
template<typename T>
T FRealloc(T in, Types::size_t length, Types::size_t alloc)
{
return reinterpret_cast<T>(_SRealloc(reinterpret_cast<void *>(in), length), alloc);
}
template<typename T>
void Free(T in)
{
_Free(reinterpret_cast<void *>(in));
}
template<typename T>
AuSPtr<T> ToSmartPointer(T *in)
{
if (in == nullptr) return {};
return
std::shared_ptr<T>(in,
[=](T *delt)
{
if constexpr (std::is_class_v<T>)
{
delt->~T();
}
this->Free(delt);
});
}
template<typename T>
static AuSPtr<T> ToSmartPointer(AuSPtr<Heap> heap, T *in)
{
return
std::shared_ptr<T>(in,
[=](T *delt)
{
heap->Free(delt);
});
}
private:
virtual AU_ALLOC void *_ZAlloc(Types::size_t length) = 0;
virtual AU_ALLOC void *_ZAlloc(Types::size_t length, Types::size_t align) = 0;
virtual AU_ALLOC void *_FAlloc(Types::size_t length) = 0;
virtual AU_ALLOC void *_FAlloc(Types::size_t length, Types::size_t align) = 0;
virtual AU_ALLOC void *_ZRealloc(void *buffer, Types::size_t length, Types::size_t align) = 0;
virtual AU_ALLOC void *_ZRealloc(void *buffer, Types::size_t length) = 0;
virtual AU_ALLOC void *_FRealloc(void *buffer, Types::size_t length, Types::size_t align) = 0;
virtual AU_ALLOC void *_FRealloc(void *buffer, Types::size_t length) = 0;
virtual void _Free(void* buffer) = 0;
};
/**
Returns a heap interface backed by the default allocator
*/
AUKN_SHARED_API(GetDefaultDiscontiguousHeap, Heap);
/**
Allocates Fize amount of memory
@return a heap backed by allocated memory
*/
AUKN_SHARED_API(AllocHeap, Heap, AuUInt size);
}

View File

@ -0,0 +1,32 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: MemRef.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Memory
{
template<typename T>
struct MemRef
{
MemRef(T *val)
{
Pointer = val;
}
MemRef(T &val)
{
Pointer = &val;
}
T *operator->() const
{
return Pointer;
}
T *Pointer;
};
}

View File

@ -0,0 +1,143 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Memory.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include <Aurora/Data/Data.hpp>
#include "MemRef.hpp"
#include "Heap.hpp"
#include "Handles.hpp"
namespace Aurora::Memory
{
AUKN_SYM AU_ALLOC void *_ZAlloc(Types::size_t length);
AUKN_SYM AU_ALLOC void *_ZAlloc(Types::size_t length, Types::size_t align);
AUKN_SYM AU_ALLOC void *_FAlloc(Types::size_t length);
AUKN_SYM AU_ALLOC void *_FAlloc(Types::size_t length, Types::size_t align);
AUKN_SYM AU_ALLOC void *_ZRealloc(void *buffer, Types::size_t length, Types::size_t align);
AUKN_SYM AU_ALLOC void *_ZRealloc(void *buffer, Types::size_t length);
AUKN_SYM AU_ALLOC void *_FRealloc(void *buffer, Types::size_t length, Types::size_t align);
AUKN_SYM AU_ALLOC void *_FRealloc(void *buffer, Types::size_t length);
AUKN_SYM void _Free(void *buffer);
AUKN_SYM Types::size_t GetChunkSize(const void *head);
// These memory management APIs do not support class types, and will likely *never* support them
// QST already handles dynamic allocation of structs in a given heap properly (afaik)
// _new, new, et al are backed by operator overloads directed towards these functions
// -> do not double init
// TODO: ensure typeof(T) is not a pointer of a class
template<typename T>
T ZAlloc(Types::size_t length)
{
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
return reinterpret_cast<T>(_ZAlloc(length));
}
template<typename T>
T ZAlloc(Types::size_t length, Types::size_t align)
{
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
return reinterpret_cast<T>(_ZAlloc(length, align));
}
template<typename T>
T *NewArray(Types::size_t count)
{
static_assert(!std::is_class<T>::value, "Do not use heap/kmem apis with classes");
return FAlloc<T *>(count * sizeof(T));
}
template<typename T>
T *NewArray(Types::size_t count, Types::size_t align)
{
static_assert(!std::is_class<T>::value, "Do not use heap/kmem apis with classes");
return FAlloc<T *>(count * sizeof(T), align);
}
template<typename T>
AuSPtr<T> AllocateFastArray(Types::size_t length, Types::size_t align = sizeof(T))
{
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
return AuSPtr<T>(reinterpret_cast<T *>(_FAlloc(length)), [](T *ptr)
{
_Free(ptr);
});
}
template <class T>
struct SpeedyArrayAllocator
{
typedef T value_type;
SpeedyArrayAllocator() = default;
template <class U> constexpr SpeedyArrayAllocator(const SpeedyArrayAllocator <U> &) noexcept
{
}
[[nodiscard]] T *allocate(std::size_t n)
{
if (auto p = (NewArray<T>(n)))
{
return p;
}
throw std::bad_alloc();
}
void deallocate(T *p, std::size_t n) noexcept
{
_Free(p);
}
};
template<typename T>
T FAlloc(Types::size_t length)
{
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
return reinterpret_cast<T>(_FAlloc(length));
}
template<typename T>
T FAlloc(Types::size_t length, Types::size_t align)
{
static_assert(!std::is_class<std::remove_pointer<T>::type>::value, "Do not use heap/kmem apis with classes");
return reinterpret_cast<T>(_FAlloc(length, align));
}
template<typename T>
T ZRealloc(T in, Types::size_t length)
{
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(in), length));
}
template<typename T>
T ZRealloc(T in, Types::size_t length, Types::size_t alloc)
{
return reinterpret_cast<T>(_ZRealloc(reinterpret_cast<void *>(in), length), alloc);
}
template<typename T>
T SRealloc(T in, Types::size_t length)
{
return reinterpret_cast<T>(_SRealloc(reinterpret_cast<void *>(in), length));
}
template<typename T>
T SRealloc(T in, Types::size_t length, Types::size_t alloc)
{
return reinterpret_cast<T>(_SRealloc(reinterpret_cast<void *>(in), length), alloc);
}
template<typename T>
void Free(T in)
{
_Free(reinterpret_cast<void *>(in));
}
}

View File

@ -0,0 +1,23 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Base32.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Parse
{
AUKN_SYM bool Base32Decode(const AuString &in, AuList<AuUInt8> &decoded);
AUKN_SYM bool Base32Encode(const void *buffer, AuMach length, AuString &encoded);
static bool Base32Encode(const AuString &in, AuString &encoded)
{
return Base32Encode(in.data(), in.size(), encoded);
}
static bool Base32Encode(const AuList<AuUInt8> &in, AuString &encoded)
{
return Base32Encode(in.data(), in.size(), encoded);
}
}

View File

@ -0,0 +1,23 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Base64.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Parse
{
AUKN_SYM bool Base64Decode(const AuString &in, AuList<AuUInt8> &decoded, bool url = false);
AUKN_SYM bool Base64Encode(const void *buffer, AuMach length, AuString &encoded, bool url = false);
static bool Base64Encode(const AuString &in, AuString &encoded, bool url = false)
{
return Base64Encode(in.data(), in.size(), encoded, url);
}
static bool Base64Encode(const AuList<AuUInt8> &in, AuString &encoded, bool url = false)
{
return Base64Encode(in.data(), in.size(), encoded, url);
}
}

View File

@ -0,0 +1,32 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: LineParser.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Parse
{
static void SplitNewlines(const AuString &in, std::function<void(const AuString &)> lineCallback)
{
AuMach index = 0;
AuString cpy = in;
while ((index = cpy.find("\n")) != AuString::npos)
{
auto line = cpy.substr(0, index);
cpy = cpy.substr(index + 1);
if (line[line.size() - 1] == '\r')
{
line.pop_back();
}
lineCallback(line);
}
lineCallback(cpy);
}
}

View File

@ -0,0 +1,14 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Parse.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "Base32.hpp"
#include "Base64.hpp"
#include "LineParser.hpp"
#include "Parser.hpp"

View File

@ -0,0 +1,163 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Parser.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include <Aurora/Data/Data.hpp>
namespace Aurora::Parse
{
enum class ParsableTag
{
kParseUInt = (const int)Aurora::Data::DataType::kTypeUInt,
kParseSInt = (const int)Aurora::Data::DataType::kTypeSInt,
kParseNumber = (const int)Aurora::Data::DataType::kTypeNumber,
kParseString = (const int)Aurora::Data::DataType::kTypeString,
kParseBoolean = (const int)Aurora::Data::DataType::kTypeBoolean,
kParseUUID = (const int)Aurora::Data::DataType::kTypeUUID,
kParseVec3 = (const int)Aurora::Data::DataType::kTypeVec3,
kParseVec4 = (const int)Aurora::Data::DataType::kTypeVec4,
kParseObject,
kParseStringVararg
};
struct ParseBit;
struct ParsedBit;
using ParseObject = AuList<ParseBit>;
using ParsedObject = AuList<ParsedBit>;
using ParsePrimativeValue = Aurora::Data::PrimitiveValue;
using ParseValue = Aurora::Data::Value;
struct ParseValueEx : ParseValue
{
ParsedObject Object;
};
struct ParseBit
{
ParseBit(ParsableTag _Tag, const AuString &_Label) : tag(_Tag), label(_Label)
{
}
ParseBit(ParsableTag _Tag, const AuString &_Label, bool _Array, bool _Optional, bool _vararg) : tag(_Tag), label(_Label), array(_Array), optional(_Optional), vararg(_vararg)
{
}
ParseBit(ParsableTag _Tag) : tag(_Tag)
{
}
ParseBit(ParsableTag _Tag, bool _Array, bool _Optional, bool _vararg) : tag(_Tag), array(_Array), optional(_Optional), vararg(_vararg)
{
}
ParseBit(ParseObject _ObjectParse) : tag(ParsableTag::kParseObject), objectParse(_ObjectParse)
{
}
ParseBit(ParseObject _ObjectParse, const AuString &_Label) : tag(ParsableTag::kParseObject), objectParse(_ObjectParse), label(_Label)
{
}
// marks this "parse bit" and all following part bits optional
bool optional = false;
// if true, the lexer yoinks a length prefix token before iterating over array length
bool array = false;
// if true, the lexer parses tag or object parse until EOS
bool vararg = false;
// parse defintion
ParsableTag tag;
ParseObject objectParse;
// optional:
AuString label = "";
// parse object
// {...}
// single parse bit:
// <tag-label: value>
// optional:
// <max-number: value> <min-number: value> (<min-number: value>)
// var arg:
// <max-number: value> <min-number: value> (<min-number: value> ...)
// arrays
// <max-number: value> <min-number: value> [<array count> <min-number: value>]
};
struct ParsedBit
{
ParsedBit()
{
}
ParsedBit(ParsableTag _tag) : tag(_tag)
{
}
AuMach count;
ParsableTag tag;
bool isArray;
struct
{
ParseValueEx single;
AuList<ParseValueEx> array;
} value;
};
struct ParseResult
{
AuString SyntaxError;
AuString DebugTree;
ParsedObject result;
};
using ConsumeStream_cb = std::function<bool(AuUInt8 &)>;
static ConsumeStream_cb StringToConsumable(const AuString &str, AuMach &index)
{
auto getc = [&](AuUInt8 &byt) mutable
{
if (index == str.length())
{
return false;
}
byt = str[index];
index++;
return true;
};
return getc;
}
AUKN_SYM void VaildateStructure(const ParseObject &object);
AUKN_SYM bool ConsumeToken(ParsableTag type, ConsumeStream_cb getc, ParseValue &out);
static bool ConsumeToken(ParsableTag type, const AuString &str, AuMach &index, ParseValueEx &out)
{
return ConsumeToken(type, StringToConsumable(str, index), out);
}
static bool ConsumeToken(ParsableTag type, const AuString &str, ParseValueEx &out)
{
AuMach index{};
return ConsumeToken(type, StringToConsumable(str, index), out);
}
AUKN_SYM bool Parse(ParseResult &result, const ParseObject &structure, ConsumeStream_cb getc);
static bool Parse(ParseResult &result, const ParseObject &structure, const AuString &str, AuMach &index)
{
return Parse(result, structure, StringToConsumable(str, index));
}
static bool Parse(ParseResult &result, const ParseObject &structure, const AuString &str)
{
AuMach index{};
return Parse(result, structure, StringToConsumable(str, index));
}
AUKN_SYM void SerializeToken(ParsableTag type, const ParseValue &value, AuString &str);
AUKN_SYM void Serialize(const ParsedObject &structure, AuString &ret);
}

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Paths.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Process
{
/**
Retrieves the applications current working directory
*/
AUKN_SYM bool GetWorkingDirectory(AuString &path);
AUKN_SYM bool GetProcName(AuString &executable);
AUKN_SYM bool GetProcPath(AuString &path);
AUKN_SYM bool GetProcFullPath(AuString &path);
}

View File

@ -0,0 +1,11 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Process.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
#include "Paths.hpp"
#include "ProcessMap.hpp"

View File

@ -0,0 +1,24 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ModuleInfo.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Process
{
struct Segment
{
AuUInt base;
AuUInt size;
char perms[6];
AuString module;
};
using Segments = AuList<Segment>;
AUKN_SYM std::optional<Segment> GetSegment(AuUInt pointer);
AUKN_SYM Segments DumpExecutableRoot();
AUKN_SYM Segments DumpExecutableAll();
}

View File

@ -0,0 +1,18 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ESpawnType.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Processes
{
enum class ESpawnType
{
eSpawnAtomicOvermap, // posix: exec, win32: i dunno
eSpawnChildProcessWorker, // posix: thread, win32: job process
eSpawnThreadLeader // posix: thread leader / new sid / pid != 0 daemon, win32: process
};
}

View File

@ -0,0 +1,41 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IProcess.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading
{
class IWaitable;
}
namespace Aurora::Processes
{
class IProcess
{
public:
///
/// @return the waitable of a waitable child process or thread leader
virtual Threading::IWaitable *AsWaitable() = 0;
/// Assuming AsWaitable()->TryLock() && Spawn != SpawnType::kSpawnAtomicOvermap,
/// returns the true return value of the process
/// otherwise returns zero
virtual AuSInt GetExitCode() = 0;
///
/// @param exitOnSpawn atomically destroys the current process <br>
/// some platforms only support this
///
virtual bool Start(enum ESpawnType, bool fwdOut, bool fwdErr, bool fwdIn) = 0;
virtual bool Terminate() = 0;
virtual bool TryKill() = 0;
virtual bool Read(bool error, void *buffer, AuUInt32 &len) = 0;
virtual bool Write(const void *buffer, AuUInt32 len) = 0;
};
}

View File

@ -0,0 +1,17 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Open.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Processes
{
/// opens a standard uri formatted string (eg, protocol://endpoint/path)
AUKN_SYM void OpenUri(const AuString &uri);
/// opens a file given a relative path or abs path
AUKN_SYM void OpenFile(const AuString &file);
}

View File

@ -0,0 +1,14 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Processes.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "ESpawnType.hpp"
#include "IProcess.hpp"
#include "Spawn.hpp"
#include "Open.hpp"

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Spawn.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Processes
{
AUKN_SHARED_API(Spawn, IProcess, const AuString &app, const AuList<AuString> &args);
}

View File

@ -0,0 +1,53 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: RNG.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::RNG
{
AUKN_SYM void ReadSecureRNG(void *in, AuUInt length);
template<typename T, int N>
void Read(T(&array)[N])
{
ReadSecureRNG(array, N * sizeof(T));
}
template<typename T>
void Read(T *array, AuUInt length)
{
ReadSecureRNG(array, length * sizeof(T));
}
enum class RngStringCharacters
{
eAlphaCharacters,
eAlphaNumericCharacters,
eExtendedEntropy,
MAX
};
static void RngString(char *string, AuUInt length, RngStringCharacters type = RngStringCharacters::eAlphaCharacters)
{
static std::pair<const char *, int> rngSequence[static_cast<int>(RngStringCharacters::MAX)] =
{
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 52},
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62},
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-+!$%^*.[];:", 75}
};
ReadSecureRNG(string, length);
const auto &pair = rngSequence[static_cast<int>(type)];
for (auto i = 0; i < length; i++)
{
auto idx = static_cast<float>(reinterpret_cast<AuUInt8 *>(string)[i]) / 255.f * static_cast<float>(pair.second);
string[i] = pair.first[static_cast<int>(idx)];
}
}
}

View File

@ -0,0 +1,18 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ERegistrySource.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Registry
{
enum ERegistrySource
{
eFSGlobal,
eFSProfile,
eGlobal
};
}

View File

@ -0,0 +1,23 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IRegistry.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Registry
{
using RegistryType = Aurora::Data::DataType;
using RegistryValue = Aurora::Data::Value;
class IRegistry
{
public:
virtual bool KeyExists(const AuString &key, RegistryType &type) = 0;
virtual bool GetOrCreateKey(const AuString &key, const RegistryValue &def, RegistryValue &value) = 0;
virtual bool SetKey(const AuString &key, const RegistryValue &value) = 0;
virtual bool GetKey(const AuString &key, RegistryValue &value) = 0;
};
}

View File

@ -0,0 +1,18 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Registry.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include <Aurora/Parse/Parse.hpp>
#include "ERegistrySource.hpp"
#include "IRegistry.hpp"
namespace Aurora::Registry
{
AUKN_SHARED_API(Registry, IRegistry, ERegistrySource source, const AuString &name);
}

138
Include/Aurora/Runtime.hpp Normal file
View File

@ -0,0 +1,138 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Runtime.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#if defined(AURORA_ENGINE_KERNEL_STATIC)
#define AUKN_SYM
#else
#if defined(AURORA_ENGINE_KERNEL_EXPORT)
#define AUKN_SYM AURORA_SYMBOL_EXPORT
#else
#define AUKN_SYM AURORA_SYMBOL_IMPORT
#endif
#endif
#include "../AuroraMacros.hpp"
#if defined(_AUHAS_ASIO)
#include <asio.hpp>
#endif
#include <optional>
#include <functional>
#include "../AuroraTypedefs.hpp"
#include <glm/glm.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
#include <fmt/chrono.h>
#include <uuid.h>
#define AUKN_SHARED_API(name, type, ...) AU_SHARED_API_EX(AUKN_SYM, name, type, ## __VA_ARGS__)
#include "Memory/Memory.hpp"
#include "Console/Console.hpp"
#include "Crypto/Crypto.hpp"
#include "Compression/Compression.hpp"
#include "Data/Data.hpp"
#include "Debug/Debug.hpp"
#include "Hashing/Hashing.hpp"
#include "HWInfo/HWInfo.hpp"
#include "IO/IO.hpp"
#include "Legacy/Legacy.hpp"
#include "Locale/Locale.hpp"
#include "Parse/Parse.hpp"
#include "Process/Process.hpp"
#include "Processes/Processes.hpp"
#include "Registry/Registry.hpp"
#include "RNG/RNG.hpp"
#include "Telemetry/Telemetery.hpp"
#include "Threading/Threading.hpp"
#include "Async/Async.hpp"
#include "Time/Time.hpp"
#include "../AuroraUtils.hpp"
namespace Aurora
{
struct LocalLogInfo
{
bool enableLogging {true};
bool autoCompressOldLogs {false};
AuUInt32 maxSizeMB {128 * 1024 * 1024}; // these numbers feel insane, but at least we have a max threshold
int maxLogs {1024}; // by default, we neither leak disk space or waste opportunities of being able to dig through old data
};
struct TelemetryConfigDoc
{
LocalLogInfo localLogging;
bool enabled {false};
AuString address;
AuUInt16 port {45069};
AuString serviceIdnt {"7b5f7a54-7122-4489-ac1a-3d75884b307e"};
bool wantsActiveMonitoring {false};
bool privacyNoData {false};
bool privacyNoMod {false};
bool privacyNoLog {false};
bool privacyNoWarn {false};
bool alwaysCrashdump {true};
bool alwaysDisableCrashdump {false};
};
struct TelemetryConfig
{
bool readModNameJsonConfig {};
TelemetryConfigDoc defaultConfig;
};
struct ConsoleConfig
{
LocalLogInfo logging;
bool disableAll {};
bool forceConsoleWindow {};
bool forceToolKitWindow {};
bool attemptDarkTheme {true};
AuString supportPublic {"https://jira.reece.sx"};
AuString supportInternal {"https://jira.reece.sx"};
};
struct CryptoConfig
{
bool allowChineseCerts {false};
bool allowRussianCerts {true};
bool allowHTTPRetrievalOfCerts {true};
bool enablePinning {true};
AuList<AuString> blacklistedCerts{};
AuList<AuString> whitelistedCerts{};
};
struct RuntimeStartInfo
{
ConsoleConfig console;
CryptoConfig crypto;
TelemetryConfig telemetry;
};
AUKN_SYM void RuntimeStart(const RuntimeStartInfo &info);
AUKN_SYM void RuntimeShutdown();
AUKN_SYM void RuntimeSysPump();
}

View File

@ -0,0 +1,168 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: BlackBox.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Telemetry
{
enum class ENewBlackBoxEntry
{
eSpecsMetadata,
eMessage,
eStackWarning,
eWinCxxException,
eAccessViolation,
eAssertion,
ePanic,
eLog,
eScreenshot,
eMinidump,
eAnnounceMap,
eAnnounceThreadName,
eAnnounceApplication,
eAnnounceSymbols
};
struct NewBlockboxEntryMessage
{
AuUInt address;
AuUInt32 category;
AuString message;
AuUInt32 threadId;
};
struct NewBlockBoxEntryStackReport
{
Debug::StackTrace backtrace;
};
struct NewBlackboxEntryUpdateMapEntry
{
AuUInt base;
AuUInt size;
char perms[6];
AuString module;
};
struct NewBlackboxEntryUpdateMap
{
Aurora::Process::Segments map;
};
enum class ENewBlackBoxAccessViolation
{
eUnknown,
eNXViolation,
eWriteViolation,
eMissingPage
};
struct NewBlockBoxEntryMemoryViolation
{
AuUInt address;
AuUInt code;
ENewBlackBoxAccessViolation type;
NewBlockBoxEntryStackReport stack;
};
struct NewBlockBoxEntryWin32CxxException
{
NewBlockBoxEntryStackReport stack;
AuString str;
};
struct NewBlockboxEntryBasicMessage
{
Console::ConsoleMessage message;
};
enum class ENewBlackBoxResourceType
{
eLocal,
eResource
};
struct NewBlackBoxResource
{
ENewBlackBoxResourceType type;
AuString path;
int resourceId;
};
struct NewBlackBoxEntryScreenshot
{
NewBlackBoxResource resource;
};
enum class MinidumpType
{
eMSVC,
eBreakpadMSVC,
eBrokenElfRamDump,
eMagicalMinidump,
eExternalEcosystemTransaction
};
struct NewBlackBoxEntryMinidump
{
MinidumpType type;
bool includesRx;
Aurora::Build::EPlatform platform;
NewBlackBoxResource resource;
};
struct NewBlockboxEntryReportSpecs
{
Aurora::Build::EPlatform platform;
Aurora::Build::ECompiler compiler;
Aurora::Build::EABI abi;
Aurora::HWInfo::CpuInfo cpuInfo;
AuUInt16 ramMb;
AuUInt16 remainingMb;
AuUInt16 pageSize;
};
struct NewBlackBoxEntryReportApplication
{
AuUInt16 applicationServiceNumber;
AuString applicationExecutableName;
AuString applicationPath;
AuString locality;
};
struct NewBlackBoxEntryMapThread
{
AuUInt64 id;
AuUInt64 name;
};
struct NewBlockboxEntry
{
ENewBlackBoxEntry type;
NewBlackBoxEntryReportApplication process;
NewBlockboxEntryReportSpecs specs;
NewBlockboxEntryMessage message;
NewBlockboxEntryMessage assertion;
NewBlockBoxEntryStackReport stack;
NewBlockBoxEntryWin32CxxException wincxx;
NewBlockboxEntryBasicMessage log;
NewBlockboxEntryBasicMessage panic;
NewBlockBoxEntryMemoryViolation violation;
NewBlackBoxEntryMinidump minidump;
NewBlackboxEntryUpdateMap map;
};
using StreamWriter = std::function<void(AuUInt8 stream, const AuUInt8 *buffer, AuUInt32 length)>;
using StreamReader = std::function<void(AuUInt8 stream, AuUInt8 *buffer, AuUInt32 &length)>;
AUKN_SYM AuList<NewBlockboxEntry> ReadBlackboxStream(const StreamReader &reader);
AUKN_SYM void WriteBlackboxStream(const AuList<NewBlockboxEntry> &, StreamWriter writer);
}

View File

@ -0,0 +1,15 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Telemetery.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "BlackBox.hpp"
namespace Aurora::Telemetry
{
AUKN_SYM void Mayday();
}

View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: IWaitable.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Threading
{
/**
IWaitable represents a generic waitable primitive <br>
There is no guarantee of any specific underlying primitive or backing by the operating system directly <br>
*All* methods **must** be supported on all platforms. If they don't, think harder! <br>
Implementable on: NX, Win32 via CVs, and others via pthreads <br>
Zero timeout = infinity <br>
*/
class IWaitable
{
public:
virtual bool HasOSHandle(AuMach &mach) = 0;
virtual bool HasLockImplementation() = 0;
virtual void Lock() = 0;
virtual bool Lock(AuUInt64 timeout /*=0*/) = 0;
virtual bool TryLock() = 0;
virtual void Unlock() = 0;
};
}

View File

@ -0,0 +1,31 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: LockGuard.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Threading
{
template<typename T>
class LockGuard
{
public:
LockGuard(Aurora::Memory::MemRef<T> lock) : lockReference_(lock)
{
lockReference_->Lock();
}
~LockGuard()
{
lockReference_->Unlock();
}
private:
Aurora::Memory::MemRef<T> lockReference_;
};
using WaitableLockGuard = LockGuard<IWaitable>;
}

View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: LockGuardPtr.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Threading
{
template<typename T>
class LockGuardPtr
{
public:
LockGuardPtr(T *lock) : lockReference_(lock)
{
lockReference_->Lock();
}
~LockGuardPtr()
{
lockReference_->Unlock();
}
private:
T *lockReference_;
};
}

View File

@ -0,0 +1,28 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ConditionalEx.hpp
Date: 2021-6-11
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
/**
A comprehensive CV that does not strictly abide by typical assumptions. <br>
This object is not optimal; however, it will work with any or no IWaitable <br>
On systems where context switches are expensive, this object should be avoided at all costs <br>
This object depends on the synchronization of primitives within our abstraction layer rather than the OS's implementation of condition variables <br>
*/
class ConditionEx
{
public:
virtual void WaitForSignal() = 0;
virtual void WaitForSignal(Aurora::Threading::IWaitable *waitable) = 0;
virtual void Broadcast() = 0;
virtual void Signal() = 0;
};
AUKN_SHARED_API(FeaturefulCondition, ConditionEx);
}

View File

@ -0,0 +1,27 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ConditionMutex.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
/**
An extremely basic mutex primitive. <br>
This should be used with the traditional CV idiom of lock(), while(cond) { cv.wait() }, unlock() . <br>
For other use cases, you should use the alternative mutex. <br>
Note the usage of *should*; you could use this as a replacement to the standard mutex should there be no<br>
desire of the IWaitable interface.
*/
class IConditionMutex
{
public:
virtual void Lock() = 0;
virtual void Unlock() = 0;
};
AUKN_SHARED_API(ConditionMutex, IConditionMutex);
}

View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ConditionVariable.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
/**
A standard conditional variable tied to IConditionalMutex <br>
Multiple conditionals may use a common IConditionalMutex. <br>
Unlike the POSIX standard, <br>
1) we define no waitable as illegal <br>
2) conditional variables may not rebind their mutex
*/
class IConditionVariable
{
public:
virtual IConditionMutex* GetMutex() = 0;
virtual bool WaitForSignal(AuUInt32 timeout = 0) = 0;
virtual void Broadcast() = 0;
virtual void Signal() = 0;
};
AUKN_SHARED_API(ConditionVariable, IConditionVariable, IConditionMutex *);
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CriticalSection.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
AUKN_SHARED_API(CriticalSection, IWaitable);
}

View File

@ -0,0 +1,38 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Event.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
/**
Event synchronization primitive
*/
class IEvent : public IWaitable
{
public:
// Unlike the other types, unlock is always a nop. It makes sense for the schedular or any other caller to not automatically reset an event, contrary to `::Lock(); work; ::Unlock();`
// Ordinarily, we would expect the thread responsible for dispatching work to Unlock, and the caller Reset, at least in principle. This, however, does not account for reusability.
// It makes sense to implement reset-on-worker-acknowledge, permit-multiple-triggers (a kind of countless semaphores), and any combination thereof
// Besides from atomicRelease, Reset and Set is on your watch.
inline void Wait()
{
Lock();
}
inline void Wait(AuUInt32 ms)
{
Lock(ms);
}
virtual void Reset() = 0;
virtual void Set() = 0;
};
AUKN_SHARED_API(Event, IEvent, bool triggerd, bool atomicRelease, bool permitMultipleTriggers = false);
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Mutex.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
AUKN_SHARED_API(Mutex, IWaitable);
}

View File

@ -0,0 +1,19 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Primitives.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
#include "ConditionMutex.hpp"
#include "ConditionVariable.hpp"
#include "Mutex.hpp"
#include "Event.hpp"
#include "Semaphore.hpp"
#include "RWLock.hpp"
#include "SpinLock.hpp"
#include "CriticalSection.hpp"
#include "ConditionEx.hpp"

View File

@ -0,0 +1,20 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: RWLock.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
class RWLock
{
public:
virtual IWaitable *AsReadable() = 0;
virtual IWaitable *AsWritable() = 0;
};
AUKN_SHARED_API(RWLock, RWLock);
}

View File

@ -0,0 +1,19 @@
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Semaphore.hpp
Date: 2021-6-9
Author: Reece
***/
#pragma once
namespace Aurora::Threading::Primitives
{
class ISemaphore : public IWaitable
{
public:
virtual void Unlock(long count) = 0;
};
AUKN_SHARED_API(Semaphore, ISemaphore, int initialCount = 0);
}

Some files were not shown because too many files have changed in this diff Show More