diff --git a/nac3core/irrt/irrt/util.hpp b/nac3core/irrt/irrt/util.hpp index 5306fe17..a1707530 100644 --- a/nac3core/irrt/irrt/util.hpp +++ b/nac3core/irrt/irrt/util.hpp @@ -18,4 +18,84 @@ bool arrays_match(int len, T* as, T* bs) { } return true; } + +namespace cstr_utils { +/** + * @brief Return true if `str` is empty. + */ +bool is_empty(const char* str) { return str[0] == '\0'; } + +/** + * @brief Implementation of `strcmp()` + */ +int8_t compare(const char* a, const char* b) { + uint32_t i = 0; + while (true) { + if (a[i] < b[i]) { + return -1; + } else if (a[i] > b[i]) { + return 1; + } else { + if (a[i] == '\0') { + return 0; + } else { + i++; + } + } + } +} + +/** + * @brief Return true two strings have the same content. + */ +int8_t equal(const char* a, const char* b) { return compare(a, b) == 0; } + +/** + * @brief Implementation of `strlen()`. + */ +uint32_t length(const char* str) { + uint32_t length = 0; + while (*str != '\0') { + length++; + str++; + } + return length; +} + +/** + * @brief Copy a null-terminated string to a buffer with limited size and guaranteed null-termination. + * + * `dst_max_size` must be greater than 0, otherwise this function has undefined behavior. + * + * This function attempts to copy everything from `src` from `dst`, and *always* null-terminates `dst`. + * + * If the size of `dst` is too small, the final byte (`dst[dst_max_size - 1]`) of `dst` will be set to + * the null terminator. + * + * @param src String to copy from. + * @param dst Buffer to copy string to. + * @param dst_max_size + * Number of bytes of this buffer, including the space needed for the null terminator. + * Must be greater than 0. + * @return If `dst` is too small to contain everything in `src`. + */ +bool copy(const char* src, char* dst, uint32_t dst_max_size) { + for (uint32_t i = 0; i < dst_max_size; i++) { + bool is_last = i + 1 == dst_max_size; + if (is_last && src[i] != '\0') { + dst[i] = '\0'; + return false; + } + + if (src[i] == '\0') { + dst[i] = '\0'; + return true; + } + + dst[i] = src[i]; + } + + __builtin_unreachable(); +} +} // namespace cstr_utils } // namespace