diff options
author | Samuel Johnson <[email protected]> | 2025-07-01 10:33:05 -0400 |
---|---|---|
committer | Samuel Johnson <[email protected]> | 2025-07-01 10:33:05 -0400 |
commit | 571a656a6bd9b4b9d5c595c578d15ba79bb19ef7 (patch) | |
tree | 46f75b47f4edab4281de14ffa1c4a91a5a84f8f1 /kernel/io/logger/base.ipp | |
parent | 12fd3a91f138bf90520134682e38bf3b0341e660 (diff) |
Diffstat (limited to 'kernel/io/logger/base.ipp')
-rw-r--r-- | kernel/io/logger/base.ipp | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/kernel/io/logger/base.ipp b/kernel/io/logger/base.ipp new file mode 100644 index 0000000..b48a132 --- /dev/null +++ b/kernel/io/logger/base.ipp @@ -0,0 +1,145 @@ +#ifndef HOS_IO_BASE_IMPL +#define HOS_IO_BASE_IMPL + +#include <io/logger/base.h> +#include <utils.h> + +#include <stdarg.h> + +namespace hos::io +{ + template <typename concrete_logger> + logger<concrete_logger>::logger (enum log_level level) + { + this->set_level(level); + } + + template <typename concrete_logger> + void logger<concrete_logger>::set_level (enum log_level level) + { + this->level = level; + } + + template <typename concrete_logger> + void logger<concrete_logger>::write (enum log_level level, const char *message, ...) + { + if (level < this->level) + { + return; + } + + char *bufferptr = this->buffer; + memset(bufferptr, 0, sizeof(this->buffer)); + + const char *logtypes[] = { + "DEBUG: ", + "INFO: ", + "WARN: ", + "ERROR: ", + "FATAL: " + }; + + int len = 0; + switch (level) + { + case log_level::DEBUG: { + len = strlen(logtypes[0]); + + memcpy(bufferptr, logtypes[0], len); + bufferptr += len; + break; + } + case log_level::INFO: { + len = strlen(logtypes[1]); + + memcpy(bufferptr, logtypes[1], len); + bufferptr += len; + break; + } + case log_level::WARN: { + len = strlen(logtypes[2]); + + memcpy(bufferptr, logtypes[2], len); + bufferptr += len; + break; + } + case log_level::ERROR: { + len = strlen(logtypes[3]); + + memcpy(bufferptr, logtypes[3], len); + bufferptr += len; + break; + } + case log_level::FATAL: { + len = strlen(logtypes[4]); + + memcpy(bufferptr, logtypes[4], len); + bufferptr += len; + break; + } + } + + len = strlen(message); + if (bufferptr + len >= this->buffer + 510) { + const char failed[] = "LOGGER: Message longer than display buffer."; + memcpy(bufferptr, failed, strlen(failed)); + static_cast<concrete_logger*>(this)->flush(); + } + + va_list args; + va_start(args, message); + + char temp_buffer[this->buffer + 510 - bufferptr]; + char *tempptr = temp_buffer; + memset(tempptr, 0, sizeof(temp_buffer)); + + char next; + while ((next = *message++) != 0) + { + if (next == '%') + { + next = *message++; + switch (next) + { + case 'c': { + char c = va_arg(args, int); + + if (!((tempptr + 1) - temp_buffer > (long int) sizeof(temp_buffer))) + { + memcpy(tempptr, &c, 1); + tempptr++; + } + + break; + } + case 's': { + char *string = va_arg(args, char *); + + len = strlen(string); + if (!((tempptr + len) - temp_buffer > (long int) sizeof(temp_buffer))) + { + memcpy(tempptr, string, len); + tempptr += len; + } + + break; + } + } + } else { + memcpy(tempptr, &next, 1); + tempptr++; + } + } + + va_end(args); + + len = strlen(temp_buffer); + memcpy(bufferptr, temp_buffer, len); + bufferptr += len; + + memcpy(bufferptr, "\n", 1); + static_cast<concrete_logger*>(this)->flush(); + } +} + +#endif |