forked from M-Labs/nac3
1
0
Fork 0
nac3/nac3core/irrt/irrt_printer.hpp

82 lines
2.4 KiB
C++

#pragma once
#include "irrt_typedefs.hpp"
// TODO: obviously implementing printf from scratch is bad,
// is there a header only, no-cstdlib library for this?
namespace {
struct Printer {
char* string_base_ptr;
uint32_t max_length;
uint32_t length; // NOTE: this could be incremented past max_length, which indicates
void initialize(char *string_base_ptr, uint32_t max_length) {
this->string_base_ptr = string_base_ptr;
this->max_length = max_length;
this->length = 0;
}
void put_space() {
put_char(' ');
}
void put_char(char ch) {
push_char(ch);
}
void put_string(const char* string) {
// TODO: optimize?
while (*string != '\0') {
push_char(*string);
string++; // Move to next char
}
}
template<typename T>
void put_int(T value) {
// NOTE: Try not to use recursion to print the digits
// value == 0 is a special case
if (value == 0) {
push_char('0');
} else {
// Add a '-' if the value is negative
if (value < 0) {
push_char('-');
value = -value; // Negate then continue to print the digits
}
// TODO: Recursion is a bad idea on embedded systems?
uint32_t num_digits = int_log_floor(value, 10) + 1;
put_int_helper(num_digits, value);
}
}
// TODO: implement put_float() and more would be useful
private:
void push_char(char ch) {
if (length < max_length) {
string_base_ptr[length] = ch;
}
// NOTE: this could increment past max_length,
// to indicate the true length of the message even if it gets cut off
length++;
}
template <typename T>
void put_int_helper(uint32_t num_digits, T value) {
// Print the digits recursively
__builtin_assume(0 <= value);
if (num_digits > 0) {
put_int_helper(num_digits - 1, value / 10);
uint32_t digit = value % 10;
char digit_char = '0' + (char) digit;
put_char(digit_char);
}
}
};
}