#include #include #include #include #include #include #include #include namespace sta { void Printable::printf(const char * fmt, ...) { va_list args; va_start (args, fmt); char temp[1]; int n = vsnprintf(temp, 1, fmt, args); va_start (args, fmt); char str[n]; vsnprintf(str, n, fmt, args); STA_ASSERT(n > 0); println(str); } void Printable::print(char c) { print(&c, 1); } void Printable::print(bool b) { print(b ? "true" : "false"); } void Printable::print(double d) { char buffer[64]; snprintf(buffer, sizeof(buffer), "%f", d); print(buffer); } void Printable::print(uint8_t num, IntegerBase base) { printBase(num, base, "%" PRIu8, sizeof(num)); } void Printable::print(uint16_t num, IntegerBase base) { printBase(num, base, "%" PRIu16, sizeof(num)); } void Printable::print(uint32_t num, IntegerBase base) { printBase(num, base, "%" PRIu32, sizeof(num)); } void Printable::print(const char * str) { print(str, strlen(str)); } void Printable::println() { print("\r\n", 2); } void Printable::println(char c) { print(&c, 1); println(); } void Printable::println(bool b) { print(b); println(); } void Printable::println(double d) { print(d); println(); } void Printable::println(uint8_t num, IntegerBase base) { print(num, base); println(); } void Printable::println(uint16_t num, IntegerBase base) { print(num, base); println(); } void Printable::println(uint32_t num, IntegerBase base) { print(num, base); println(); } void Printable::println(const char * str) { println(str, strlen(str)); } void Printable::println(const char * str, size_t length) { print(str, length); println(); } void Printable::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size) { switch (base) { case IntegerBase::DEC: printDec(num, fmt); break; case IntegerBase::BIN: // Digits in base 2 = size in bytes * 8 printBin(num, size * 8); break; case IntegerBase::HEX: // Digits in base 16 = size in bytes * 2 printHex(num, size * 2); break; default: print(""); } } void Printable::printDec(uintmax_t num, const char * fmt) { char buffer[64]; snprintf(buffer, sizeof(buffer), fmt, static_cast(num)); print(buffer); } void Printable::printBin(uintmax_t value, size_t digits) { // Need 8 digits for every byte char buffer[sizeof(value) * 8]; // Check bounds if (digits > sizeof(buffer)) { print(""); return; } // Nothing to do if (digits == 0) return; for (size_t i = 0; i < digits; ++i) { // Convert bit to '0' or '1' // First digit in buffer is MSB in value, so shift from high to low buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1); } print(buffer, digits); } void Printable::printHex(uintmax_t value, size_t digits) { // Need 2 digits for every byte char buffer[sizeof(value) * 2]; // Check bounds if (digits > sizeof(buffer)) { print(""); return; } // Nothing to do if (digits == 0) return; for (size_t i = 0; i < digits; ++i) { // Convert 4 bits to hex // First digit in buffer is 4 MSBs in value, so shift from high to low uint8_t hex = ((value >> ((digits - 1 - i) * 4)) & 0xF); if (hex > 9) buffer[i] = 'A' + (hex - 10); else buffer[i] = '0' + hex; } print(buffer, digits); } } // namespace sta