diff --git a/Include/auROXTL/AU_MACROS.hpp b/Include/auROXTL/AU_MACROS.hpp index cb6d71c..3fd26e1 100644 --- a/Include/auROXTL/AU_MACROS.hpp +++ b/Include/auROXTL/AU_MACROS.hpp @@ -215,6 +215,25 @@ // yay, more confusion over what "inline" actually means #define AU_OPTIMIZED static auline + +#if defined(AURORA_FORCE_SPACE_OPTIMIZATION) + // explicit: use global symbol linkage vs one per language translation unit + #define AU_STATIC_OR_OPTIMIZE_SPACE inline +#elif defined(AURORA_IS_MODERNNT_DERIVED) + // assume desktop with massive instruction caches and execution pipelines + #define AU_STATIC_OR_OPTIMIZE_SPACE static +#elif defined(AURORA_IS_LINUX_DERIVED) && defined(AURORA_ARCH_X64) + // assume desktop with massive instruction caches and execution pipelines + #define AU_STATIC_OR_OPTIMIZE_SPACE static +#elif defined(AURORA_IS_LINUX_DERIVED) + // assume embedded with limited ROM + #define AU_STATIC_OR_OPTIMIZE_SPACE inline +#else + // dont know, dont care + #define AU_STATIC_OR_OPTIMIZE_SPACE static +#endif + + // ps: // we wont add __attribute__((optimize(...)) macros // most compilers treat them as file level options; no per function attributes override this. diff --git a/Include/auROXTL/Strings/auLinerParserAndSplitter.hpp b/Include/auROXTL/Strings/auLinerParserAndSplitter.hpp new file mode 100644 index 0000000..efb0a91 --- /dev/null +++ b/Include/auROXTL/Strings/auLinerParserAndSplitter.hpp @@ -0,0 +1,66 @@ +/*** + Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: auLinerParserAndSplitter.hpp + Date: 2024-12-26 + File: LineParser.hpp + Date: 2021-6-9 + Author: Reece + Note: one of the original APIs from Aurora::Parse +***/ +#pragma once + +/** + * @brief Splits lines from @param in + * @param in Buffer to parse + * @param lineCallback a tempated callable () operator (AuFunction, traditional callback function, binding, etc) + * @param bReturnRemaining Assuming POSIX-like boomer logic, every text command sequence must be terminated with a line return. + * The lack of \n implies incomplete data. bReturnRemaining = true will return this incomplete data, otherwise, + * lineCallback(...) is called for each line on the assumed fully buffered blob - including the final line. + * @return + */ +template +AU_STATIC_OR_OPTIMIZE_SPACE +AuROString AuSplitNewlines(const AuROString &in, + const Callable &lineCallback, + bool bReturnRemaining = false); + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints + */ +AU_STATIC_OR_OPTIMIZE_SPACE +bool AuTrySplitString(AuListOfHeap &ret, + const AuROString &in, + AuUInt16 uCharacters); + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints + */ +AU_STATIC_OR_OPTIMIZE_SPACE +bool AuTrySplitString(AuList &ret, + const AuROString &in, + AuUInt16 uCharacters); + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints + */ +AU_STATIC_OR_OPTIMIZE_SPACE +AuList AuSplitString(const AuROString &in, + AuUInt16 uCharacters); + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints while joining the components using the specified @param delimiter into a reserved string buffer + */ +AU_STATIC_OR_OPTIMIZE_SPACE +bool AuTrySplitStringWithDelimiter(AuString &ret, + const AuROString &in, + const AuROString &delimiter, + AuUInt16 uCharacters); + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints while joining the components using the specified @param delimiter into a reserved string buffer + */ +AU_STATIC_OR_OPTIMIZE_SPACE +AuString AuSplitStringWithDelimiter(const AuROString &in, + const AuROString &delimiter, + AuUInt16 uCharacters); \ No newline at end of file diff --git a/Include/auROXTL/Strings/auLinerParserAndSplitter.ipp b/Include/auROXTL/Strings/auLinerParserAndSplitter.ipp new file mode 100644 index 0000000..1e57851 --- /dev/null +++ b/Include/auROXTL/Strings/auLinerParserAndSplitter.ipp @@ -0,0 +1,200 @@ +/*** + Copyright (C) 2021-2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: auLinerParserAndSplitter.ipp + Date: 2024-12-26 + File: LineParser.hpp + Date: 2021-6-9 + Author: Reece + Note: one of the original APIs from Aurora::Parse +***/ +#pragma once + +/** + * @brief Splits lines from @param in + * @param in Buffer to parse + * @param lineCallback a tempated callable () operator (AuFunction, traditional callback function, binding, etc) + * @param bReturnRemaining Assuming POSIX-like boomer logic, every text command sequence must be terminated with a line return. + * The lack of \n implies incomplete data. bReturnRemaining = true will return this incomplete data, otherwise, + * lineCallback(...) is called for each line on the assumed fully buffered blob - including the final line. + * @return + */ +template +AU_STATIC_OR_OPTIMIZE_SPACE +AuROString AuSplitNewlines(const AuROString &in, + const Callable &lineCallback, + bool bReturnRemaining) +{ + AuMach index = 0, startIdx = 0; + + while ((index = in.Find("\n", startIdx)) != AuString::npos) + { + auto line = in.Substr(startIdx, index - startIdx); + startIdx = index + 1; + + if (line[line.Size() - 1] == '\r') + { + line = line.RemoveSuffix(1); + } + + lineCallback(line); + + if (startIdx >= in.Size()) + { + break; + } + } + + if (bReturnRemaining) + { + return in.Substr(startIdx); + } + else + { + lineCallback(in.Substr(startIdx)); + return {}; + } +} + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints + */ +AU_STATIC_OR_OPTIMIZE_SPACE +bool AuTrySplitString(AuListOfHeap &ret, + const AuROString &in, + AuUInt16 uCharacters) +{ + for (AuUInt i = 0u; i < in.Size(); ) + { + AuUInt start, end, len; + + start = i; + end = AuMin(AuUInt(in.size()), AuUInt(i + uCharacters)); + if (end - 1) + { + auto uLastCodepointIndex = AuCodepointsFindPreviousValidByteOffsetFromByteOffset(in, end); + auto uLastByteOffset = AuCodepointsNextLength(in.Substr(uLastCodepointIndex)); + end = uLastCodepointIndex + uLastByteOffset; + } + len = end - start; + i += len; + + if (!AuTryInsert(ret, in.Substr(start, len))) + { + return false; + } + } + + return true; +} + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints + */ +AU_STATIC_OR_OPTIMIZE_SPACE +bool AuTrySplitString(AuList &ret, + const AuROString &in, + AuUInt16 uCharacters) +{ + for (AuUInt i = 0u; i < in.Size(); ) + { + AuUInt start, end, len; + + start = i; + end = AuMin(AuUInt(in.size()), AuUInt(i + uCharacters)); + if (end - 1) + { + auto uLastCodepointIndex = AuCodepointsFindPreviousValidByteOffsetFromByteOffset(in, end); + auto uLastByteOffset = AuCodepointsNextLength(in.Substr(uLastCodepointIndex)); + end = uLastCodepointIndex + uLastByteOffset; + } + len = end - start; + i += len; + + if (!AuTryInsert(ret, in.Substr(start, len))) + { + return false; + } + } + + return true; +} + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints + */ +AU_STATIC_OR_OPTIMIZE_SPACE +AuList AuSplitString(const AuROString &in, + AuUInt16 uCharacters) +{ + AuList ret; + + if (AuTrySplitString(ret, in, uCharacters)) + { + return ret; + } + else + { + AU_THROW_CONST_STRING("Couldn't split string. OOM?"); + } +} + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints while joining the components using the specified @param delimiter into a reserved string buffer + */ +AU_STATIC_OR_OPTIMIZE_SPACE +bool AuTrySplitStringWithDelimiter(AuString &ret, + const AuROString &in, + const AuROString &delimiter, + AuUInt16 uCharacters) +{ + if (!AuTryReserve(ret, in.Size() + (in.Size() / uCharacters * delimiter.size()))) + { + return false; + } + + for (AuUInt i = 0u; i < in.Size(); ) + { + AuUInt start, end, len; + + if (i != 0) + { + ret.insert(ret.size(), delimiter); + } + + start = i; + end = AuMin(AuUInt(in.Size()), AuUInt(i + uCharacters)); + if (end - 1) + { + auto uLastCodepointIndex = AuCodepointsFindPreviousValidByteOffsetFromByteOffset(in, end); + auto uLastByteOffset = AuCodepointsNextLength(in.Substr(uLastCodepointIndex)); + end = uLastCodepointIndex + uLastByteOffset; + } + len = end - start; + i += len; + + ret.insert(ret.size(), in.Substr(start, len)); + } + + return true; +} + +/** + * @brief Splits @param in after @param uCharacters UTF8 codepoints while joining the components using the specified @param delimiter into a reserved string buffer + */ +AU_STATIC_OR_OPTIMIZE_SPACE +AuString AuSplitStringWithDelimiter(const AuROString &in, + const AuROString &delimiter, + AuUInt16 uCharacters) +{ + AuString ret; + + if (AuTrySplitStringWithDelimiter(ret, in, delimiter, uCharacters)) + { + return ret; + } + else + { + AU_THROW_CONST_STRING("Couldn't split string. OOM?"); + } +} \ No newline at end of file diff --git a/Include/auROXTLTypes.hpp b/Include/auROXTLTypes.hpp index 41d90be..641affc 100644 --- a/Include/auROXTLTypes.hpp +++ b/Include/auROXTLTypes.hpp @@ -178,6 +178,7 @@ namespace __audetail #include #include #include +#include namespace Aurora { diff --git a/Include/auROXTLUtils.hpp b/Include/auROXTLUtils.hpp index 39fb48d..873cbb8 100644 --- a/Include/auROXTLUtils.hpp +++ b/Include/auROXTLUtils.hpp @@ -82,6 +82,8 @@ namespace __audetail #include #include +#include + struct IAuNullDelegate { virtual void OnCall() = 0;