From 05508418a793df4d4c8e1116cf15fe7cbcef5d91 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 15 Jan 2021 16:32:25 +0100 Subject: [PATCH] printf support for array printer --- globalfunctions/arrayprinter.cpp | 134 ++++++++++++++++++++----------- globalfunctions/arrayprinter.h | 12 ++- 2 files changed, 95 insertions(+), 51 deletions(-) diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp index b50aeb21..6dc959d7 100644 --- a/globalfunctions/arrayprinter.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -3,64 +3,101 @@ #include void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, - bool printInfo, size_t maxCharPerLine) { + bool printInfo, size_t maxCharPerLine) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - if(printInfo) { - sif::info << "Printing data with size " << size << ": "; - } - sif::info << "["; + if(printInfo) { + sif::info << "Printing data with size " << size << ": "; + } + sif::info << "["; #else - // TODO: Use %zu or %lu depending on whether C99 support is given. - sif::printInfo("Printing data with size %lu: [", static_cast(size)); -#endif - if(type == OutputType::HEX) { - arrayprinter::printHex(data, size, maxCharPerLine); - } - else if (type == OutputType::DEC) { - arrayprinter::printDec(data, size, maxCharPerLine); - } - else if(type == OutputType::BIN) { - arrayprinter::printBin(data, size); - } +#if FSFW_NO_C99_IO == 1 + sif::printInfo("Printing data with size %lu: [", static_cast(size)); +#else + sif::printInfo("Printing data with size %zu: [", size); +#endif /* FSFW_NO_C99_IO == 1 */ +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + if(type == OutputType::HEX) { + arrayprinter::printHex(data, size, maxCharPerLine); + } + else if (type == OutputType::DEC) { + arrayprinter::printDec(data, size, maxCharPerLine); + } + else if(type == OutputType::BIN) { + arrayprinter::printBin(data, size); + } } void arrayprinter::printHex(const uint8_t *data, size_t size, - size_t maxCharPerLine) { + size_t maxCharPerLine) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << std::hex; - for(size_t i = 0; i < size; i++) { - sif::info << "0x" << static_cast(data[i]); - if(i < size - 1){ - sif::info << " , "; - if(i > 0 and i % maxCharPerLine == 0) { - sif::info << std::endl; + sif::info << std::hex; + for(size_t i = 0; i < size; i++) { + sif::info << "0x" << static_cast(data[i]); + if(i < size - 1) { + sif::info << " , "; + if(i > 0 and i % maxCharPerLine == 0) { + sif::info << std::endl; - } - } - } - sif::info << std::dec; - sif::info << "]" << std::endl; + } + } + } + sif::info << std::dec; + sif::info << "]" << std::endl; #else - // how much memory to reserve for printout? + // General format: 0x01, 0x02, 0x03 so it is number of chars times 6 + // plus line break plus small safety margin. + char printBuffer[(size + 1) * 7 + 1]; + size_t currentPos = 0; + for(size_t i = 0; i < size; i++) { + // To avoid buffer overflows. + if(sizeof(printBuffer) - currentPos <= 7) { + break; + } + + currentPos += snprintf(printBuffer + currentPos, 6, "0x%02x", data[i]); + if(i < size - 1) { + currentPos += sprintf(printBuffer + currentPos, ", "); + if(i > 0 and i % maxCharPerLine == 0) { + currentPos += sprintf(printBuffer + currentPos, "\n"); + } + } + } #endif } void arrayprinter::printDec(const uint8_t *data, size_t size, - size_t maxCharPerLine) { + size_t maxCharPerLine) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << std::dec; - for(size_t i = 0; i < size; i++) { - sif::info << static_cast(data[i]); - if(i < size - 1){ - sif::info << " , "; - if(i > 0 and i % maxCharPerLine == 0) { - sif::info << std::endl; - } - } - } - sif::info << "]" << std::endl; + sif::info << std::dec; + for(size_t i = 0; i < size; i++) { + sif::info << static_cast(data[i]); + if(i < size - 1){ + sif::info << " , "; + if(i > 0 and i % maxCharPerLine == 0) { + sif::info << std::endl; + } + } + } + sif::info << "]" << std::endl; #else - // how much memory to reserve for printout? + // General format: 32, 243, -12 so it is number of chars times 5 + // plus line break plus small safety margin. + char printBuffer[(size + 1) * 5 + 1]; + size_t currentPos = 0; + for(size_t i = 0; i < size; i++) { + // To avoid buffer overflows. + if(sizeof(printBuffer) - currentPos <= 5) { + break; + } + + currentPos += snprintf(printBuffer + currentPos, 3, "%d", data[i]); + if(i < size - 1) { + currentPos += sprintf(printBuffer + currentPos, ", "); + if(i > 0 and i % maxCharPerLine == 0) { + currentPos += sprintf(printBuffer + currentPos, "\n"); + } + } + } #endif } @@ -68,11 +105,14 @@ void arrayprinter::printBin(const uint8_t *data, size_t size) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "\n" << std::flush; for(size_t i = 0; i < size; i++) { - sif::info << "Byte " << i + 1 << ": 0b"<< - std::bitset<8>(data[i]) << ",\n" << std::flush; + sif::info << "Byte " << i + 1 << ": 0b" << std::bitset<8>(data[i]) << "," << std::endl; } sif::info << "]" << std::endl; #else - // how much memory to reserve for printout? + sif::printInfo("\n"); + for(size_t i = 0; i < size; i++) { + sif::printInfo("Byte %d: 0b" BYTE_TO_BINARY_PATTERN ",\n", BYTE_TO_BINARY(data[i])); + } + sif::printInfo("]\n"); #endif } diff --git a/globalfunctions/arrayprinter.h b/globalfunctions/arrayprinter.h index e57d8e04..6dfa6ecd 100644 --- a/globalfunctions/arrayprinter.h +++ b/globalfunctions/arrayprinter.h @@ -1,20 +1,24 @@ #ifndef FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ #define FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ + #include #include enum class OutputType { - DEC, - HEX, - BIN + DEC, + HEX, + BIN }; +//! TODO: Write unit tests for this module. namespace arrayprinter { + void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX, - bool printInfo = true, size_t maxCharPerLine = 12); + bool printInfo = true, size_t maxCharPerLine = 12); void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); void printBin(const uint8_t* data, size_t size); + } #endif /* FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ */