diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
| commit | 83d870e58457a1d335a1d9b9966a6a1887cc297b (patch) | |
| tree | 72888f88c7728c82f3f6df1f4f70591de15eab36 /src/kernel/NeKit | |
| parent | ab37adbacf0f33845804c788b39680cd754752a8 (diff) | |
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'src/kernel/NeKit')
| -rw-r--r-- | src/kernel/NeKit/Array.h | 46 | ||||
| -rw-r--r-- | src/kernel/NeKit/ArrayList.h | 44 | ||||
| -rw-r--r-- | src/kernel/NeKit/Atom.h | 33 | ||||
| -rw-r--r-- | src/kernel/NeKit/Crc32.h | 20 | ||||
| -rw-r--r-- | src/kernel/NeKit/CxxAbi.h | 26 | ||||
| -rw-r--r-- | src/kernel/NeKit/Defines.h | 179 | ||||
| -rw-r--r-- | src/kernel/NeKit/ErrorOr.h | 62 | ||||
| -rw-r--r-- | src/kernel/NeKit/Function.h | 51 | ||||
| -rw-r--r-- | src/kernel/NeKit/Json.h | 146 | ||||
| -rw-r--r-- | src/kernel/NeKit/KString.h | 92 | ||||
| -rw-r--r-- | src/kernel/NeKit/KString.inl | 174 | ||||
| -rw-r--r-- | src/kernel/NeKit/KernelPanic.h | 69 | ||||
| -rw-r--r-- | src/kernel/NeKit/Macros.h | 151 | ||||
| -rw-r--r-- | src/kernel/NeKit/MutableArray.h | 203 | ||||
| -rw-r--r-- | src/kernel/NeKit/NeKit.h | 20 | ||||
| -rw-r--r-- | src/kernel/NeKit/New.h | 20 | ||||
| -rw-r--r-- | src/kernel/NeKit/OwnPtr.h | 67 | ||||
| -rw-r--r-- | src/kernel/NeKit/PageMgr.h | 76 | ||||
| -rw-r--r-- | src/kernel/NeKit/Pair.h | 51 | ||||
| -rw-r--r-- | src/kernel/NeKit/Pmm.h | 39 | ||||
| -rw-r--r-- | src/kernel/NeKit/Ref.h | 77 | ||||
| -rw-r--r-- | src/kernel/NeKit/Stream.h | 45 | ||||
| -rw-r--r-- | src/kernel/NeKit/TOML.h | 15 | ||||
| -rw-r--r-- | src/kernel/NeKit/Utils.h | 62 | ||||
| -rw-r--r-- | src/kernel/NeKit/Variant.h | 71 |
25 files changed, 1839 insertions, 0 deletions
diff --git a/src/kernel/NeKit/Array.h b/src/kernel/NeKit/Array.h new file mode 100644 index 00000000..5b8371db --- /dev/null +++ b/src/kernel/NeKit/Array.h @@ -0,0 +1,46 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <KernelKit/DebugOutput.h> +#include <NeKit/Defines.h> +#include <NeKit/ErrorOr.h> + +namespace Kernel { +template <typename T, SizeT N> +class Array final { + public: + explicit Array() = default; + ~Array() = default; + + Array& operator=(const Array&) = default; + Array(const Array&) = default; + + T& operator[](SizeT at) { return fArray[at]; } + + Boolean Empty() { return this->Count() > 0; } + + SizeT Capacity() { return N; } + + SizeT Count() { + const static SizeT kArrCnt = N; + return kArrCnt; // avoid constexpr error. + } + + const T* CData() { return fArray; } + + operator bool() { return !Empty(); } + + private: + T fArray[N]; +}; + +template <typename ValueType> +auto make_list(ValueType val) { + return Array<ValueType, ARRAY_SIZE(val)>{val}; +} +} // namespace Kernel diff --git a/src/kernel/NeKit/ArrayList.h b/src/kernel/NeKit/ArrayList.h new file mode 100644 index 00000000..54613b67 --- /dev/null +++ b/src/kernel/NeKit/ArrayList.h @@ -0,0 +1,44 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> + +namespace Kernel { +template <typename T> +class ArrayList final { + public: + explicit ArrayList(T* list, SizeT length) : fList(reinterpret_cast<T>(list)), fLen(length) {} + + ~ArrayList() = default; + + ArrayList& operator=(const ArrayList&) = default; + ArrayList(const ArrayList&) = default; + + T* Data() { return fList; } + + const T* CData() { return fList; } + + T& operator[](SizeT index) const { + MUST_PASS(index < this->Count()); + return fList[index]; + } + + operator bool() { return fList; } + + SizeT Count() const { return fLen; } + + private: + T* fList{nullptr}; + SizeT fLen{0}; +}; + +template <typename ValueType> +ArrayList<ValueType> make_list(ValueType val) { + return ArrayList<ValueType>{val}; +} +} // namespace Kernel diff --git a/src/kernel/NeKit/Atom.h b/src/kernel/NeKit/Atom.h new file mode 100644 index 00000000..0f8eefbc --- /dev/null +++ b/src/kernel/NeKit/Atom.h @@ -0,0 +1,33 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ +#pragma once + +#include <NeKit/Defines.h> + +namespace Kernel { +template <typename T> +class Atom final { + public: + explicit Atom() = default; + ~Atom() = default; + + public: + Atom& operator=(const Atom&) = delete; + Atom(const Atom&) = delete; + + public: + T operator[](Size bit) { return (fArrayOfAtoms & (1 << bit)); } + + void operator|(Size bit) { fArrayOfAtoms |= (1 << bit); } + + friend Boolean operator==(Atom<T>& atomic, const T& idx) { return atomic[idx] == idx; } + + friend Boolean operator!=(Atom<T>& atomic, const T& idx) { return atomic[idx] == idx; } + + private: + T fArrayOfAtoms; +}; +} // namespace Kernel diff --git a/src/kernel/NeKit/Crc32.h b/src/kernel/NeKit/Crc32.h new file mode 100644 index 00000000..3c6a904f --- /dev/null +++ b/src/kernel/NeKit/Crc32.h @@ -0,0 +1,20 @@ +/* + * ======================================================== + * + * NeKernel + * Date Added: 13/02/2023 + * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + * + * ======================================================== + */ + +#ifndef NEKIT_CRC32_H +#define NEKIT_CRC32_H + +#include <NeKit/Defines.h> + +namespace Kernel { +UInt32 ke_calculate_crc32(const VoidPtr crc, Int32 len) noexcept; +} // namespace Kernel + +#endif // !NEKIT_CRC32_H diff --git a/src/kernel/NeKit/CxxAbi.h b/src/kernel/NeKit/CxxAbi.h new file mode 100644 index 00000000..7b13d6b3 --- /dev/null +++ b/src/kernel/NeKit/CxxAbi.h @@ -0,0 +1,26 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ +#pragma once + +#include <NeKit/Defines.h> + +#ifndef __NECTI__ + +#define kAtExitMacDestructors (128) + +struct atexit_func_entry_t { + void (*destructor_func)(); + void* obj_ptr; + void* dso_handle; +}; + +typedef Kernel::UInt32 uarch_t; + +namespace cxxabiv1 { +typedef Kernel::SizeT* __guard; +} + +#endif // !__NECTI__ diff --git a/src/kernel/NeKit/Defines.h b/src/kernel/NeKit/Defines.h new file mode 100644 index 00000000..1a6a2cf6 --- /dev/null +++ b/src/kernel/NeKit/Defines.h @@ -0,0 +1,179 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Macros.h> + +#define NEKIT_VERSION_STR "0.0.1" +#define NEKIT_VERSION_BCD 0x0001 + +#ifndef __cplusplus +#error !!! Kernel compiles only with a C++ compiler. !!! +#endif + +#if __cplusplus <= 201703L +#define char8_t char +#endif + +#ifdef __has_feature +#if !__has_feature(cxx_nullptr) +#if !__has_nullptr +#error !!! You must at least have nullptr featured on your C++ compiler. !!! +#endif +#endif +#endif + +/// @brief The **Kernel** namespace. +namespace Kernel { +using voidPtr = void*; +using VoidPtr = void*; +using nullPtr = decltype(nullptr); +using NullPtr = decltype(nullptr); + +using Int = int; +using Int32 = __INT32_TYPE__; +using UShort = __UINT16_TYPE__; +using UInt16 = __UINT16_TYPE__; +using Short = short; +using Int16 = __INT16_TYPE__; +using UInt = __UINT32_TYPE__; +using UInt32 = __UINT32_TYPE__; +using Long = __INT64_TYPE__; +using Int64 = __INT64_TYPE__; +using ULong = __UINT64_TYPE__; +using UInt64 = __UINT64_TYPE__; +using Boolean = bool; +using Bool = bool; +using Char = char; +using Int8 = __INT8_TYPE__; +using Char8 = char8_t; +using UChar = __UINT8_TYPE__; +using UInt8 = __UINT8_TYPE__; + +using SSize = long; +using SSizeT = long; +using Size = __SIZE_TYPE__; +using SizeT = __SIZE_TYPE__; +using IntPtr = __INTPTR_TYPE__; +using UIntPtr = __UINTPTR_TYPE__; +using IntFast = __INT_FAST32_TYPE__; +using IntFast64 = __INT_FAST64_TYPE__; +using PtrDiff = __PTRDIFF_TYPE__; + +using SInt16 = Int16; +using SInt32 = Int32; +using SInt64 = Int64; + +typedef UIntPtr* Ptr64; +typedef UInt32* Ptr32; +typedef UInt8* Ptr8; + +using Utf8Char = char8_t; +using Utf16Char = char16_t; +using WideChar = wchar_t; +using Utf32Char = char32_t; + +using LongDouble = long double; +using Double = double; +using Float = float; + +typedef UInt32 PhysicalAddressKind; +typedef UIntPtr VirtualAddressKind; + +using Void = void; +using Any = void*; + +using Lba = UInt64; + +using Char16 = char16_t; + +enum class Endian : UInt8 { kEndianInvalid, kEndianBig, kEndianLittle, kEndianMixed, kEndianCount }; + +/// @brief Forward object. +/// @tparam Args the object type. +/// @param arg the object. +/// @return object's rvalue +template <typename Args> +inline Args&& forward(Args& arg) { + return static_cast<Args&&>(arg); +} + +/// @brief Move object. +/// @tparam Args the object type. +/// @param arg the object. +/// @return object's rvalue +template <typename Args> +inline Args&& move(Args&& arg) { + return static_cast<Args&&>(arg); +} + +/// @brief Encoding interface, used as a proxy to convert T to Char* +/// Used to cast A to B or B to A. +class ICodec { + public: + explicit ICodec() = default; + virtual ~ICodec() = default; + + ICodec& operator=(const ICodec&) = default; + ICodec(const ICodec&) = default; + + public: + /// @brief Convert type to bytes. + /// @tparam T the type. + /// @param type (a1) the data. + /// @return a1 as Char* + template <typename T> + const Char* AsBytes(T type) noexcept { + NE_UNUSED(type); + return nullptr; + } + + /// @brief Construct from type to class. + /// @tparam T the type to convert. + /// @param type (a1) the data. + /// @return a1 as Char* + template <typename OutputClass, typename FactoryClass> + OutputClass* Construct(Char* type) noexcept { + FactoryClass class_fac; + return class_fac.template From<OutputClass>(type); + } + + /// @brief Convert T class to Y class. + /// @tparam T the class type of type. + /// @tparam Y the result class. + /// @param type the class to cast. + /// @return the class as Y. + template <typename T, typename Y> + Y As(T type) noexcept { + if (type.template IsSerializable()) { + return reinterpret_cast<Char*>(type); + } + + return type.template As<Y>(); + } +}; + +/// \brief Scheduler interface, represents a scheduler object. +/// @note This is used to schedule tasks, such as threads, drivers, user threads, etc. +class ISchedulable { + public: + explicit ISchedulable() = default; + virtual ~ISchedulable() = default; + + ISchedulable& operator=(const ISchedulable&) = default; + ISchedulable(const ISchedulable&) = default; + + /// @brief Is this object only accepting user tasks? + virtual Bool IsUser() { return NO; } + + /// @brief Is this object only accepting kernel tasks? + virtual Bool IsKernel() { return NO; } + + /// @brief Is this object offloading to another CPU? + virtual Bool HasMP() { return NO; } +}; +} // namespace Kernel diff --git a/src/kernel/NeKit/ErrorOr.h b/src/kernel/NeKit/ErrorOr.h new file mode 100644 index 00000000..d930fe17 --- /dev/null +++ b/src/kernel/NeKit/ErrorOr.h @@ -0,0 +1,62 @@ +/* + * ======================================================== + * + * NeKernel + * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + * + * ======================================================== + */ + +#pragma once + +#include <NeKit/Defines.h> +#include <NeKit/Ref.h> + +namespace Kernel { +using ErrorT = Int32; + +/// ================================================================================ +/// @brief ErrorOr class for error handling. +/// ================================================================================ +template <typename T> +class ErrorOr final { + public: + explicit ErrorOr() = default; + ~ErrorOr() = default; + + public: + explicit ErrorOr(ErrorT err) : mRef((T*) RTL_ALLOCA(sizeof(T))), mId(err) {} + + explicit ErrorOr(nullPtr) {} + + explicit ErrorOr(T* Class) : mRef(Class) {} + + explicit ErrorOr(T Class) : mRef(Class) {} + + ErrorOr& operator=(const ErrorOr&) = default; + ErrorOr(const ErrorOr&) = default; + + ErrorOr& operator=(const Ref<T>& refErr) { + mRef = refErr; + return *this; + } + + const T& Value() { return mRef.TryLeak(); } + + Ref<T>& Leak() { return mRef; } + + ErrorT Error() { return mId; } + + /// @note DO NOT MAKE THIS EXPLICIT! IT WILL BREAK THE COMPILATION. + operator bool() { return mRef; } + + BOOL HasError() { return this->mId < 0; } + + private: + Ref<T> mRef; + ErrorT mId{0}; +}; + +using ErrorOrAny = ErrorOr<voidPtr>; + +} // namespace Kernel diff --git a/src/kernel/NeKit/Function.h b/src/kernel/NeKit/Function.h new file mode 100644 index 00000000..70242bc3 --- /dev/null +++ b/src/kernel/NeKit/Function.h @@ -0,0 +1,51 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> +#include <NeKit/ErrorOr.h> + +namespace Kernel { +/// ================================================================================ +/// @brief Function wrapper class. +/// ================================================================================ +template <typename T, typename... Args> +class Function final { + public: + Function() = default; + + public: + explicit Function(T (*Fn)(Args... args)) : fFn(Fn) {} + + ~Function() = default; + + Function& operator=(const Function&) = default; + Function(const Function&) = default; + + template <typename... XArgs> + T operator()(Args&&... args) { + return fFn(args...); + } + + template <typename... XArgs> + T Call(Args&&... args) { + return fFn(args...); + } + + operator bool() { return fFn; } + + bool operator!() { return !fFn; } + + private: + T(*fFn) + (Args... args){nullptr}; +}; + +template <typename T, typename... Args> +using FunctionOr = ErrorOr<Function<T, Args...>>; +} // namespace Kernel + diff --git a/src/kernel/NeKit/Json.h b/src/kernel/NeKit/Json.h new file mode 100644 index 00000000..1e804354 --- /dev/null +++ b/src/kernel/NeKit/Json.h @@ -0,0 +1,146 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +/// @brief Kernel JSON API. + +#include <CompilerKit/CompilerKit.h> +#include <NeKit/Defines.h> +#include <NeKit/KString.h> +#include <NeKit/Stream.h> +#include <NeKit/Utils.h> + +#define kNeJsonMaxLen (8196) +#define kNeJsonLen (256) +#define kNeJsonNullArr "[]" +#define kNeJsonNullObj "{}" +#define kNeJsonNullKey "null" +#define kNeJsonNullValue kNeJsonNullKey + +namespace Kernel { +/// ================================================================================ +/// @brief JSON object representation. +/// ================================================================================ +template <typename CharKind = Char> +class JsonObject final { + public: + explicit JsonObject() { + KBasicString<CharKind> key = KString(kNeJsonMaxLen); + key += kNeJsonNullValue; + + this->AsKey() = key; + this->AsValue() = key; + } + + explicit JsonObject(SizeT lhsLen, SizeT rhsLen) : fKey(lhsLen), fValue(rhsLen) { + + KBasicString<CharKind> key = KString(lhsLen); + this->AsKey() = key; + + KBasicString<CharKind> value = KString(rhsLen); + this->AsValue() = value; + } + + ~JsonObject() = default; + + NE_COPY_DEFAULT(JsonObject) + NE_MOVE_DEFAULT(JsonObject) + + Bool& IsUndefined() { return fUndefined; } + + private: + Bool fUndefined; // is this instance undefined? + KBasicString<CharKind> fKey; + KBasicString<CharKind> fValue; + + public: + /// @brief returns the key of the json + /// @return the key as string view. + KBasicString<CharKind>& AsKey() { return fKey; } + + /// @brief returns the value of the json. + /// @return the key as string view. + KBasicString<CharKind>& AsValue() { return fValue; } + + STATIC JsonObject<CharKind> kNull; +}; + +/// ================================================================================ +/// @brief JsonObject stream reader helper for ASCII. +/// ================================================================================ +struct AsciiJsonStreamReader final { + STATIC JsonObject<Char> In(const Char* full_array) { + auto start_val = '{'; + auto end_val = '}'; + Boolean probe_value = false; + + if (full_array[0] != start_val) { + if (full_array[0] != '[') return JsonObject<Char>{0, 0}; + + start_val = '['; + end_val = ']'; + + probe_value = true; + } + + SizeT len = rt_string_len(full_array); + + SizeT key_len = 0; + SizeT value_len = 0; + + JsonObject<Char> type(kNeJsonMaxLen, kNeJsonMaxLen); + + for (SizeT i = 1; i < len; ++i) { + if (full_array[i] == '\r' || full_array[i] == '\n') continue; + + if (probe_value) { + if (full_array[i] == end_val || full_array[i] == ',') { + probe_value = false; + + ++value_len; + } else { + if (full_array[i] == '\'') { + type.AsValue().Data()[value_len] = 0; + break; + } + + type.AsValue().Data()[value_len] = full_array[i]; + + ++value_len; + } + } else { + if (start_val == '[') continue; + + if (full_array[i] == ':') { + type.AsKey().Data()[key_len] = 0; + ++key_len; + + ++i; + + while (full_array[i] == ' ' || full_array[i] == '\t') ++i; + + probe_value = true; + } else { + type.AsKey().Data()[key_len] = full_array[i]; + + ++key_len; + } + } + } + + type.AsValue().Data()[value_len] = 0; + + return type; + } +}; + +/// ================================================================================ +/// @brief AsciiJsonStream type definition. +/// ================================================================================ +using AsciiJsonStream = Stream<AsciiJsonStreamReader, JsonObject<Char>>; +} // namespace Kernel diff --git a/src/kernel/NeKit/KString.h b/src/kernel/NeKit/KString.h new file mode 100644 index 00000000..fa83fed4 --- /dev/null +++ b/src/kernel/NeKit/KString.h @@ -0,0 +1,92 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <CompilerKit/CompilerKit.h> +#include <NeKit/Defines.h> +#include <NeKit/ErrorOr.h> +#include <NeKit/KernelPanic.h> +#include <NeKit/Utils.h> + +namespace Kernel { +inline auto kMinimumStringSize = 8196; + +/// @brief Kernel string class, not dynamic. +template <typename CharKind = Char> +class KBasicString final { + public: + explicit KBasicString() { + fDataSz = kMinimumStringSize; + + fData = new CharKind[fDataSz]; + MUST_PASS(fData); + + rt_set_memory(fData, 0, fDataSz); + } + + explicit KBasicString(SizeT Sz) : fDataSz(Sz) { + MUST_PASS(Sz > 1); + + fData = new CharKind[Sz]; + MUST_PASS(fData); + + rt_set_memory(fData, 0, Sz); + } + + ~KBasicString() { + if (fData) { + delete[] fData; + fData = nullptr; + } + } + + NE_COPY_DEFAULT(KBasicString) + + CharKind* Data(); + const CharKind* CData() const; + Size Length() const; + + bool operator==(const CharKind* rhs) const; + bool operator!=(const CharKind* rhs) const; + + bool operator==(const KBasicString<CharKind>& rhs) const; + bool operator!=(const KBasicString<CharKind>& rhs) const; + + KBasicString<CharKind>& operator+=(const CharKind* rhs); + KBasicString<CharKind>& operator+=(const KBasicString<CharKind>& rhs); + + operator const char*() { return fData; } + + operator bool() { return fData; } + + bool operator!() { return fData; } + + private: + CharKind* fData{nullptr}; + Size fDataSz{0}; + Size fCur{0}; + + friend class KStringBuilder; +}; + +using KString = KBasicString<>; +using KStringOr = ErrorOr<KString>; + +class KStringBuilder final { + public: + template <typename CharKind = Char> + static ErrorOr<KBasicString<CharKind>> Construct(const CharKind* data); + template <typename CharKind = Char> + static const CharKind* FromBool(const CharKind* fmt, bool n); + template <typename CharKind = Char> + static const CharKind* Format(const CharKind* fmt, const CharKind* from); + template <typename CharKind = Char> + static bool Equals(const CharKind* lhs, const CharKind* rhs); +}; +} // namespace Kernel + +#include <NeKit/KString.inl> diff --git a/src/kernel/NeKit/KString.inl b/src/kernel/NeKit/KString.inl new file mode 100644 index 00000000..3a73e90f --- /dev/null +++ b/src/kernel/NeKit/KString.inl @@ -0,0 +1,174 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +/// @file KBasicString.inl +/// @brief Kernel String manipulation file. + +namespace Kernel { +template <typename CharKind> +inline void ort_string_append(CharKind* lhs, const CharKind* rhs, Int32 cur) { + SizeT sz_rhs = oe_string_len<CharKind>(rhs); + SizeT rhs_i = 0; + + for (; rhs_i < sz_rhs; ++rhs_i) { + lhs[rhs_i + cur] = rhs[rhs_i]; + } +} + +template <typename CharKind> +inline CharKind* KBasicString<CharKind>::Data() { + return this->fData; +} + +template <typename CharKind> +inline const CharKind* KBasicString<CharKind>::CData() const { + return const_cast<const CharKind*>(this->fData); +} + +template <typename CharKind> +inline SizeT KBasicString<CharKind>::Length() const { + return this->fDataSz; +} + +template <typename CharKind> +inline bool KBasicString<CharKind>::operator==(const KBasicString<CharKind>& rhs) const { + if (rhs.Length() != this->Length()) return false; + + for (Size index = 0; index < this->Length(); ++index) { + if (rhs.fData[index] != this->fData[index]) return false; + } + + return true; +} + +template <typename CharKind> +inline bool KBasicString<CharKind>::operator==(const CharKind* rhs) const { + if (oe_string_len<CharKind>(rhs) != this->Length()) return false; + + for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) { + if (rhs[index] != this->fData[index]) return false; + } + + return true; +} + +template <typename CharKind> +inline bool KBasicString<CharKind>::operator!=(const KBasicString<CharKind>& rhs) const { + if (rhs.Length() != this->Length()) return false; + + for (Size index = 0; index < rhs.Length(); ++index) { + if (rhs.fData[index] == this->fData[index]) return false; + } + + return true; +} + +template <typename CharKind> +inline bool KBasicString<CharKind>::operator!=(const CharKind* rhs) const { + if (oe_string_len<CharKind>(rhs) != this->Length()) return false; + + for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) { + if (rhs[index] == this->fData[index]) return false; + } + + return true; +} + +template <typename CharKind> +inline KBasicString<CharKind>& KBasicString<CharKind>::operator+=( + const KBasicString<CharKind>& rhs) { + if (oe_string_len<CharKind>(rhs.fData) > this->Length()) return *this; + + ort_string_append(this->fData, const_cast<CharKind*>(rhs.fData), this->fCur); + this->fCur += oe_string_len<CharKind>(const_cast<CharKind*>(rhs.fData)); + + return *this; +} + +template <typename CharKind> +inline KBasicString<CharKind>& KBasicString<CharKind>::operator+=(const CharKind* rhs) { + ort_string_append(this->fData, const_cast<CharKind*>(rhs), this->fCur); + this->fCur += oe_string_len<CharKind>(const_cast<CharKind*>(rhs)); + + return *this; +} + +template <typename CharKind> +inline ErrorOr<KBasicString<CharKind>> KStringBuilder::Construct(const CharKind* data) { + if (!data || *data == 0) return ErrorOr<KBasicString<CharKind>>(nullptr); + + KBasicString<CharKind>* view = new KBasicString<CharKind>(oe_string_len<CharKind>(data)); + (*view) += data; + + return ErrorOr<KBasicString<CharKind>>(*view); +} +template <typename CharKind> +inline const CharKind* KStringBuilder::FromBool(const CharKind* fmt, bool i) { + if (!fmt) return ("?"); + + const CharKind* boolean_expr = i ? "YES" : "NO"; + CharKind* ret = + (CharKind*) RTL_ALLOCA(oe_string_len<CharKind>(boolean_expr) + oe_string_len<CharKind>(fmt)); + + if (!ret) return ("?"); + + const auto fmt_len = oe_string_len<CharKind>(fmt); + const auto res_len = oe_string_len<CharKind>(boolean_expr); + + for (Size idx = 0; idx < fmt_len; ++idx) { + if (fmt[idx] == '%') { + SizeT result_cnt = idx; + + for (auto y_idx = idx; y_idx < res_len; ++y_idx) { + ret[result_cnt] = boolean_expr[y_idx]; + ++result_cnt; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; +} +template <typename CharKind> +inline bool KStringBuilder::Equals(const CharKind* lhs, const CharKind* rhs) { + if (oe_string_len<CharKind>(rhs) != oe_string_len<CharKind>(lhs)) return false; + + for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) { + if (rhs[index] != lhs[index]) return false; + } + + return true; +} +template <typename CharKind> +inline const CharKind* KStringBuilder::Format(const CharKind* fmt, const CharKind* fmt2) { + if (!fmt || !fmt2) return ("?"); + + CharKind* ret = (CharKind*) RTL_ALLOCA( + sizeof(char) * (oe_string_len<CharKind>(fmt2) + oe_string_len<CharKind>(fmt))); + + if (!ret) return ("?"); + + const auto len = oe_string_len<CharKind>(fmt); + + for (Size idx = 0; idx < len; ++idx) { + if (fmt[idx] == '%' && idx < oe_string_len<CharKind>(fmt) && fmt[idx] == 's') { + Size result_cnt = idx; + + for (Size y_idx = 0; y_idx < oe_string_len<CharKind>(fmt2); ++y_idx) { + ret[result_cnt] = fmt2[y_idx]; + ++result_cnt; + } + } + + ret[idx] = fmt[idx]; + } + + return ret; +} +} // namespace Kernel diff --git a/src/kernel/NeKit/KernelPanic.h b/src/kernel/NeKit/KernelPanic.h new file mode 100644 index 00000000..f716e6de --- /dev/null +++ b/src/kernel/NeKit/KernelPanic.h @@ -0,0 +1,69 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> + +namespace Kernel { +void ke_runtime_check(bool expr, const Char* file, const Char* line); +} + +#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG) + +#ifdef TRY +#undef TRY +#endif + +#define TRY(X) \ + { \ + auto fn = X; \ + if ((fn()) == NO) { \ + MUST_PASS(NO); \ + } \ + } + +#ifdef __MUST_PASS +#undef __MUST_PASS +#endif + +#define __MUST_PASS(EXPR, FILE, LINE) Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE)) + +#ifdef __DEBUG__ +#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__) +#define assert(EXPR) MUST_PASS(EXPR) +#else +#define MUST_PASS(EXPR) (Kernel::Void)(EXPR) +#define assert(EXPR) (Kernel::Void)(EXPR) +#endif + +enum RUNTIME_CHECK { + RUNTIME_CHECK_FAILED = 1111, + RUNTIME_CHECK_POINTER, + RUNTIME_CHECK_EXPRESSION, + RUNTIME_CHECK_FILE, + RUNTIME_CHECK_IPC, + RUNTIME_CHECK_TLS, + RUNTIME_CHECK_HANDSHAKE, + RUNTIME_CHECK_ACPI, + RUNTIME_CHECK_INVALID_PRIVILEGE, + RUNTIME_CHECK_PROCESS, + RUNTIME_CHECK_BAD_BEHAVIOR, + RUNTIME_CHECK_BOOTSTRAP, + RUNTIME_CHECK_UNEXCPECTED, + RUNTIME_CHECK_FILESYSTEM, + RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, + RUNTIME_CHECK_PAGE, + RUNTIME_CHECK_INVALID, + RUNTIME_CHECK_COUNT, +}; + +typedef enum RUNTIME_CHECK RTL_RUNTIME_CHECK; + +namespace Kernel { +void ke_panic(const Int32& id, const Char* message = nullptr); +} // namespace Kernel diff --git a/src/kernel/NeKit/Macros.h b/src/kernel/NeKit/Macros.h new file mode 100644 index 00000000..5949b414 --- /dev/null +++ b/src/kernel/NeKit/Macros.h @@ -0,0 +1,151 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +/***********************************************************************************/ +/// @file NeKit/Macros.h +/// @brief Core Types and Macros. +/***********************************************************************************/ + +#ifndef KIB +#define KIB(X) (Kernel::UInt64)((X) / 1024) +#endif + +#ifndef kib_cast +#define kib_cast(X) (Kernel::UInt64)((X) *1024) +#endif + +#ifndef MIB +#define MIB(X) (Kernel::UInt64)((Kernel::UInt64) KIB(X) / 1024) +#endif + +#ifndef mib_cast +#define mib_cast(X) (Kernel::UInt64)((Kernel::UInt64) kib_cast(X) * 1024) +#endif + +#ifndef GIB +#define GIB(X) (Kernel::UInt64)((Kernel::UInt64) MIB(X) / 1024) +#endif + +#ifndef gib_cast +#define gib_cast(X) (Kernel::UInt64)((Kernel::UInt64) mib_cast(X) * 1024) +#endif + +#ifndef TIB +#define TIB(X) (Kernel::UInt64)((Kernel::UInt64) GIB(X) / 1024) +#endif + +#ifndef tib_cast +#define tib_cast(X) ((Kernel::UInt64) gib_cast(X) * 1024) +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) \ + (((sizeof(a) / sizeof(*(a))) / (static_cast<Kernel::Size>(!(sizeof(a) % sizeof(*(a))))))) +#endif + +#define DEPRECATED ATTRIBUTE(deprecated) + +#ifndef ALIGN +#define ALIGN(X) __attribute__((aligned(X))) +#endif // #ifndef ALIGN + +#ifndef ATTRIBUTE +#define ATTRIBUTE(...) __attribute__((__VA_ARGS__)) +#endif // #ifndef ATTRIBUTE + +#ifndef __NE_VER__ +#define __NE_VER__ (2024) +#endif // !__NE_VER__ + +#ifndef EXTERN +#define EXTERN extern +#endif + +#ifndef EXTERN_C +#define EXTERN_C extern "C" +#endif + +#ifndef MAKE_ENUM +#define MAKE_ENUM(NAME) enum NAME { +#endif + +#ifndef END_ENUM +#define END_ENUM() \ + } \ + ; +#endif + +#ifndef MAKE_STRING_ENUM +#define MAKE_STRING_ENUM(NAME) namespace NAME { +#endif + +#ifndef ENUM_STRING +#define ENUM_STRING(NAME, VAL) inline constexpr const char* e##NAME = VAL +#endif + +#ifndef END_STRING_ENUM +#define END_STRING_ENUM() } +#endif + +#ifndef RTL_ALLOCA +#define RTL_ALLOCA(sz) __builtin_alloca(sz) +#endif // #ifndef RTL_ALLOCA + +#ifndef CANT_REACH +#define CANT_REACH() __builtin_unreachable() +#endif + +#define kInvalidAddress 0xFBFBFBFBFBFBFBFB +#define kBadAddress 0x0000000000000000 +#define kMaxAddr 0xFFFFFFFFFFFFFFFF +#define kPathLen 0x100 + +#define PACKED ATTRIBUTE(packed) +#define NO_EXEC ATTRIBUTE(noexec) + +#define EXTERN extern +#define STATIC static + +#define CONST const + +#define STRINGIFY(X) #X +#define NE_UNUSED(X) ((Kernel::Void) X) + +#ifndef RGB +#define RGB(R, G, B) ((Kernel::UInt32)((0xFF << 24) | ((R) << 16) | ((G) << 8) | (B))) +#endif // !RGB + +#ifdef __NE_AMD64__ +#define DBG_TRAP() asm volatile("int $3") +#else +#define DBG_TRAP() ((Kernel::Void) 0) +#endif + +#define LIKELY(ARG) ((ARG) ? MUST_PASS(NO) : ((Kernel::Void) 0)) +#define UNLIKELY(ARG) LIKELY(!(ARG)) + +#define RTL_ENDIAN(address, value) \ + (((reinterpret_cast<Kernel::Char*>(address)[0]) == (value)) ? (Kernel::Endian::kEndianBig) \ + : (Kernel::Endian::kEndianLittle)) + +#define Yes true +#define No false + +#define YES true +#define NO false + +#define TRUE true +#define FALSE false + +#define BOOL Kernel::Boolean + +#ifdef RTL_INIT_OBJECT +#undef RTL_INIT_OBJECT +#endif // ifdef RTL_INIT_OBJECT + +#define RTL_INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/src/kernel/NeKit/MutableArray.h b/src/kernel/NeKit/MutableArray.h new file mode 100644 index 00000000..e1138b3b --- /dev/null +++ b/src/kernel/NeKit/MutableArray.h @@ -0,0 +1,203 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ +#pragma once + +#include <CompilerKit/CompilerKit.h> +#include <NeKit/Array.h> +#include <NeKit/Defines.h> + +#define RTL_TRY_FIND_NODE(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) { \ + if (NAME->fIndex == Index) return NAME->fVal; \ + NAME = NAME->fNext; \ + } + +#define RTL_TRY_FIND_NODE2(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) { \ + if (NAME->fIndex == Index) return Ref<T>{NAME->fVal}; \ + NAME = NAME->fNext; \ + } + +#define RTL_TRY_REMOVE_NODE(NODE) \ + if (NODE && NODE->fIndex == Index) { \ + NODE->fUsed = false; \ + NODE->fIndex = 0; \ + \ + return true; \ + } + +// FIXME: this is a shitty algorithm, because it is memory heavy. +// Remove and occurences of that, and remove that class. +namespace Kernel { +template <typename T> +class MutableArray; + +template <typename T, T _PlaceHolderValue> +class NullableMutableArray; + +template <typename T> +class MutableLinkedList { + public: + T fVal; + SizeT fIndex{0}; + Boolean fUsed{false}; + + MutableLinkedList* fPrev{nullptr}; + MutableLinkedList* fNext{nullptr}; +}; + +template <typename T, T _PlaceHolderValue> +class NullableMutableArray { + public: + // explicit this. + explicit NullableMutableArray() : fFirstNode(new MutableLinkedList<T>()) {} + + /* + * We free all the nodes allocated by the array + * and store the next one inside "NextIt" + */ + + virtual ~NullableMutableArray() { + auto* It = fFirstNode; + MutableLinkedList<T>* NextIt = nullptr; + + while (It) { + NextIt = It->fNext; + delete It; + + It = NextIt; + } + } + + NullableMutableArray& operator=(const NullableMutableArray&) = default; + NullableMutableArray(const NullableMutableArray&) = default; + + operator bool() { return Count() > 1; } + + public: + T operator[](SizeT Index) const { + RTL_TRY_FIND_NODE(first, fFirstNode); + RTL_TRY_FIND_NODE(last, fLastNode); + + return _PlaceHolderValue; + } + + SizeT Count() const { return fNodeCount; } + + public: + Boolean Remove(SizeT Index) { + RTL_TRY_REMOVE_NODE(fFirstNode); + RTL_TRY_REMOVE_NODE(fLastNode); + + return false; + } + + Boolean Add(const T val) { + auto* iterationNode = fFirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) { + if (!iterationNode->fUsed) { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList<T>* fLastNode{nullptr}; + MutableLinkedList<T>* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; + + private: + // don't remove that + friend MutableArray<T>; +}; + +template <typename T> +class MutableArray : public NullableMutableArray<voidPtr, nullptr> { + public: + // explicit this. + explicit MutableArray() = default; + virtual ~MutableArray() = default; + + NE_COPY_DEFAULT(MutableArray) + + public: + Boolean Add(const T val) { + auto* iterationNode = fFirstNode; + + if (!iterationNode) { + fFirstNode = new MutableLinkedList<T>(); + iterationNode = fFirstNode; + } + + MUST_PASS(iterationNode); + + while (iterationNode) { + if (!iterationNode->fUsed) { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + public: + Ref<T> operator[](SizeT Index) const { + RTL_TRY_FIND_NODE2(first, fFirstNode); + RTL_TRY_FIND_NODE2(last, fLastNode); + + return {}; + } + + SizeT Count() const { return fNodeCount; } + + bool Contains(T& value) noexcept { + MutableLinkedList<T>* first = fFirstNode; + + while (first) { + if (first->fVal == value && first->fUsed) return true; + + first = first->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList<T>* fLastNode{nullptr}; + MutableLinkedList<T>* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; +}; +} // namespace Kernel diff --git a/src/kernel/NeKit/NeKit.h b/src/kernel/NeKit/NeKit.h new file mode 100644 index 00000000..4b1e64ca --- /dev/null +++ b/src/kernel/NeKit/NeKit.h @@ -0,0 +1,20 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Array.h> +#include <NeKit/ArrayList.h> +#include <NeKit/ErrorOr.h> +#include <NeKit/Json.h> +#include <NeKit/KernelPanic.h> +#include <NeKit/MutableArray.h> +#include <NeKit/New.h> +#include <NeKit/OwnPtr.h> +#include <NeKit/Ref.h> +#include <NeKit/Stream.h> +#include <NeKit/Utils.h> diff --git a/src/kernel/NeKit/New.h b/src/kernel/NeKit/New.h new file mode 100644 index 00000000..36830129 --- /dev/null +++ b/src/kernel/NeKit/New.h @@ -0,0 +1,20 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <KernelKit/HeapMgr.h> + +/// @note compatible with tk too. +typedef __SIZE_TYPE__ size_t; + +void* operator new(size_t); +void* operator new[](size_t); + +void operator delete(void*) noexcept; +void operator delete(void*, unsigned long); +void operator delete[](void*) noexcept; diff --git a/src/kernel/NeKit/OwnPtr.h b/src/kernel/NeKit/OwnPtr.h new file mode 100644 index 00000000..c8ceb1a2 --- /dev/null +++ b/src/kernel/NeKit/OwnPtr.h @@ -0,0 +1,67 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> +#include <NeKit/KernelPanic.h> +#include <NeKit/Ref.h> + +namespace Kernel { +template <typename T> +class OwnPtr; + +template <typename T> +class NonNullRefPtr; + +template <typename T> +class OwnPtr final { + public: + OwnPtr() {} + ~OwnPtr() { this->Delete(); } + + OwnPtr& operator=(const OwnPtr&) = default; + OwnPtr(const OwnPtr&) = default; + + public: + template <typename... Args> + bool New(Args&&... arg) { + if (fCls) { + return false; + } + + fCls = new T(arg...); + return fCls; + } + + void Delete() { + if (fCls) delete fCls; + + fCls = nullptr; + } + + T* operator->() const { return fCls; } + + T* Raw() { return fCls; } + + Ref<T> AsRef() { return Ref<T>(fCls); } + + operator bool() { return fCls; } + bool operator!() { return !fCls; } + + private: + T* fCls; +}; + +template <typename T, typename... Args> +inline OwnPtr<T> mm_make_own_ptr(Args... args) { + OwnPtr<T> ret; + ret.template New<Args...>(forward(args)...); + + return ret; +} +} // namespace Kernel diff --git a/src/kernel/NeKit/PageMgr.h b/src/kernel/NeKit/PageMgr.h new file mode 100644 index 00000000..6cdd5a5c --- /dev/null +++ b/src/kernel/NeKit/PageMgr.h @@ -0,0 +1,76 @@ +// a way to create and find our pages. +// I'm thinking about a separate way of getting a paged area. + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> +#include <NeKit/Ref.h> + +namespace Kernel { +class PageMgr; + +class PTEWrapper final { + public: + explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false, + UIntPtr Address = 0); + + ~PTEWrapper(); + + PTEWrapper& operator=(const PTEWrapper&) = default; + PTEWrapper(const PTEWrapper&) = default; + + public: + UIntPtr VirtualAddress(); + + Void NoExecute(const bool enable = false); + Bool NoExecute(); + + operator bool() { return fVirtAddr; } + + bool Reclaim(); + bool Shareable(); + bool Present(); + bool Access(); + + private: + Boolean fRw; + Boolean fUser; + Boolean fExecDisable; + UIntPtr fVirtAddr; + Boolean fCache; + Boolean fShareable; + Boolean fWt; + Boolean fPresent; + Boolean fAccessed; + + private: + friend class PageMgr; + friend class Pmm; +}; + +struct PageMgr final { + public: + PageMgr() = default; + ~PageMgr() = default; + + PageMgr& operator=(const PageMgr&) = default; + PageMgr(const PageMgr&) = default; + + public: + PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad); + bool Free(Ref<PTEWrapper>& wrapper); + + private: + void FlushTLB(); + + private: + friend PTEWrapper; + friend class Pmm; +}; +} // namespace Kernel diff --git a/src/kernel/NeKit/Pair.h b/src/kernel/NeKit/Pair.h new file mode 100644 index 00000000..c8914ec6 --- /dev/null +++ b/src/kernel/NeKit/Pair.h @@ -0,0 +1,51 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <CompilerKit/CompilerKit.h> +#include <NeKit/Defines.h> +#include <NeKit/ErrorOr.h> + +namespace Kernel { +template <typename T1, typename T2> +class Pair; + +class PairBuilder; + +template <typename T1, typename T2> +class Pair final { + T1 fFirst{nullptr}; + T2 fSecond{nullptr}; + + friend PairBuilder; + + public: + explicit Pair() = default; + ~Pair() = default; + + NE_COPY_DEFAULT(Pair) + + T1& First() { return fFirst; } + T2& Second() { return fSecond; } + + const T1& First() const { return *fFirst; } + const T2& Second() const { return *fSecond; } + + private: + Pair(T1 first, T2 second) : fFirst(first), fSecond(second) {} +}; + +class PairBuilder final { + template <typename T1, typename T2> + STATIC Pair<T1, T2> Construct(T1 first, T2 second) { + return Pair(first, second); + } +}; + +template <typename T1, typename T2> +using PairOr = ErrorOr<Pair<T1, T2>>; +} // namespace Kernel diff --git a/src/kernel/NeKit/Pmm.h b/src/kernel/NeKit/Pmm.h new file mode 100644 index 00000000..8c117a67 --- /dev/null +++ b/src/kernel/NeKit/Pmm.h @@ -0,0 +1,39 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/PageMgr.h> +#include <NeKit/Ref.h> + +namespace Kernel { +class Pmm; +class PTEWrapper; + +class Pmm final { + public: + explicit Pmm(); + ~Pmm(); + + Pmm& operator=(const Pmm&) = delete; + Pmm(const Pmm&) = default; + + Ref<PTEWrapper> RequestPage(Boolean user = false, Boolean readWrite = false); + Boolean FreePage(Ref<PTEWrapper> refPage); + + Boolean ToggleRw(Ref<PTEWrapper> refPage, Boolean enable = true); + Boolean TogglePresent(Ref<PTEWrapper> refPage, Boolean enable = true); + Boolean ToggleUser(Ref<PTEWrapper> refPage, Boolean enable = true); + Boolean ToggleShare(Ref<PTEWrapper> refPage, Boolean enable = true); + + /// @brief Get the page manager of this. + Ref<PageMgr>& Leak() { return fPageMgr; } + + private: + Ref<PageMgr> fPageMgr; +}; +} // namespace Kernel diff --git a/src/kernel/NeKit/Ref.h b/src/kernel/NeKit/Ref.h new file mode 100644 index 00000000..dac701e0 --- /dev/null +++ b/src/kernel/NeKit/Ref.h @@ -0,0 +1,77 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#ifndef _NEKIT_REF_H_ +#define _NEKIT_REF_H_ + +#include <CompilerKit/CompilerKit.h> +#include <KernelKit/HeapMgr.h> +#include <NeKit/Defines.h> +#include <NeKit/KernelPanic.h> + +namespace Kernel { +/// =========================================================== /// +/// @brief Reference wrapper class. /// +/// =========================================================== /// +template <typename T> +class Ref final { + public: + explicit Ref() = default; + ~Ref() = default; + + public: + Ref(T* cls) : fClass(*cls) {} + Ref(T cls) : fClass(cls) {} + + Ref& operator=(T ref) { + fClass = ref; + return *this; + } + + NE_COPY_DEFAULT(Ref) + + public: + T operator->() const { return fClass; } + + T& Leak() noexcept { return fClass; } + + T& TryLeak() noexcept { return fClass; } + + T operator*() { return fClass; } + + operator bool() noexcept { return true; } + + private: + T fClass; +}; + +template <typename T> +class NonNullRef final { + public: + NonNullRef() = delete; + NonNullRef(nullPtr) = delete; + + NonNullRef(T* ref) : fRef(ref) { MUST_PASS(ref); } + NonNullRef(Ref<T> ref) : fRef(ref) { MUST_PASS(ref); } + + Ref<T>& operator->() { + MUST_PASS(fRef); + return fRef; + } + + NonNullRef& operator=(const NonNullRef<T>& ref) = delete; + NonNullRef(const NonNullRef<T>& ref) = default; + + private: + Ref<T> fRef{}; +}; + +using RefAny = Ref<Any>; +using NonNullRefAny = NonNullRef<Any>; +} // namespace Kernel + +#endif // ifndef _NEKIT_REF_H_ diff --git a/src/kernel/NeKit/Stream.h b/src/kernel/NeKit/Stream.h new file mode 100644 index 00000000..1a53e7f0 --- /dev/null +++ b/src/kernel/NeKit/Stream.h @@ -0,0 +1,45 @@ + +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> +#include <NeKit/Ref.h> + +namespace Kernel { +template <typename StreamTrait, typename Kind> +class Stream final { + public: + explicit Stream(Ref<Stream> ref) : fStream(ref) {} + + ~Stream() = default; + + Stream& operator=(const Stream&) = default; + Stream(const Stream&) = default; + + template <typename Data> + friend Stream<StreamTrait, Kind>& operator>>(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf) { + Ks.fKind = Ks.fStream->In(Buf); + return *Ks; + } + + template <typename Data> + friend Stream<StreamTrait, Kind>& operator<<(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf) { + Ks.fKind = Buf; + Ks.fStream->Out(Buf.Leak()); + return *Ks; + } + + Ref<StreamTrait>& AsStreamTrait() { return fStream; } + + Ref<Kind>& AsType() { return fKind; } + + private: + Ref<StreamTrait> fStream; + Ref<Kind> fKind; +}; +} // namespace Kernel diff --git a/src/kernel/NeKit/TOML.h b/src/kernel/NeKit/TOML.h new file mode 100644 index 00000000..dee273ad --- /dev/null +++ b/src/kernel/NeKit/TOML.h @@ -0,0 +1,15 @@ +/* ======================================== + + Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +namespace Kernel { +class TOMLObject final { + public: + explicit TOMLObject() = delete; + ~TOMLObject() = default; +}; +} // namespace Kernel
\ No newline at end of file diff --git a/src/kernel/NeKit/Utils.h b/src/kernel/NeKit/Utils.h new file mode 100644 index 00000000..caabd2af --- /dev/null +++ b/src/kernel/NeKit/Utils.h @@ -0,0 +1,62 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> + +namespace Kernel { +/// =========================================================== /// +/// @brief ASCII API +/// =========================================================== /// + +Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len); +Int rt_move_memory(const voidPtr src, voidPtr dst, Size len); +voidPtr rt_set_memory(voidPtr dst, UInt32 val, Size len); +void rt_zero_memory(voidPtr pointer, Size len); +Int rt_string_cmp(const Char* src, const Char* cmp, Size len); +const Char* rt_alloc_string(const Char* text); +Size rt_string_len(const Char* str); +Size rt_string_len(const Char* str, SizeT _len); +Boolean rt_to_string(Char* str_out, UInt64 base, Int32 limit); +Boolean rt_is_newln(Int chr); +Boolean rt_is_space(Int chr); +Int32 rt_is_alnum(Int character); +Int rt_to_uppercase(Int c); +Int rt_to_lower(Int c); +voidPtr rt_string_in_string(const Char* in, const Char* needle); +char* rt_string_has_char(Char* str, Char chr); + +/// =========================================================== /// +/// @brief Safe memory functions API +/// =========================================================== /// + +Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size); +voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size); + +/// =========================================================== /// +/// @brief UNICODE API +/// =========================================================== /// + +Int urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size len); +Void urt_set_memory(const voidPtr src, UInt32 dst, Size len); +Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len); +Size urt_string_len(const Utf8Char* str); + +/// =========================================================== /// +/// @brief OpenEncoding API +/// =========================================================== /// + +template <typename CharType = Char> +inline SizeT oe_string_len(const CharType* str) { + if (!str) return 0; + + SizeT len{0}; + + while (str[len] != 0) ++len; + return len; +} +} // namespace Kernel diff --git a/src/kernel/NeKit/Variant.h b/src/kernel/NeKit/Variant.h new file mode 100644 index 00000000..7bcd0dff --- /dev/null +++ b/src/kernel/NeKit/Variant.h @@ -0,0 +1,71 @@ +/* ======================================== + + Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. + +======================================== */ + +#pragma once + +#include <NeKit/Defines.h> +#include <NeKit/Json.h> +#include <NeKit/TOML.h> +#include <NeKit/KString.h> +#include <SwapKit/DiskSwap.h> + +namespace Kernel { +class Variant final { + public: + enum class VariantKind { + kInvalid = 0, + kString = 200, + kBlob, + kNull, + kJson, + kTOML, + kSwap, + }; + + public: + explicit Variant() = delete; + + public: + NE_COPY_DEFAULT(Variant) + + ~Variant() = default; + + public: + template <typename CharKind> + explicit Variant(KBasicString<CharKind>* stringView) + : fPtr((VoidPtr) stringView), fKind(VariantKind::kString) {} + + explicit Variant(JsonObject<>* json) : fPtr((VoidPtr) json), fKind(VariantKind::kJson) {} + + explicit Variant(TOMLObject* toml) : fPtr((VoidPtr) toml), fKind(VariantKind::kTOML) {} + + explicit Variant(nullPtr ptr) : fPtr(ptr), fKind(VariantKind::kNull) {} + + explicit Variant(SWAP_DISK_HEADER* ptr) : fPtr(ptr), fKind(VariantKind::kSwap) {} + + explicit Variant(VoidPtr ptr) : fPtr(ptr), fKind(VariantKind::kBlob) {} + + public: + const Char* ToString(); + + /// ======================================================================== + /// @brief Returns the underlying pointer. + /// @return the underlying pointer. + /// ======================================================================== + VoidPtr Leak(); + + template <typename T> + T* As() noexcept { + return reinterpret_cast<T*>(fPtr); + } + + VariantKind& Kind(); + + private: + VoidPtr fPtr{nullptr}; + VariantKind fKind{VariantKind::kNull}; +}; +} // namespace Kernel |
