fsfw/src/fsfw/serviceinterface/ServiceInterfaceBuffer.cpp

171 lines
4.5 KiB
C++
Raw Normal View History

2022-09-07 17:58:49 +02:00
#include "ServiceInterfaceBuffer.h"
2021-01-03 14:08:40 +01:00
2021-01-03 14:16:52 +01:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
2021-01-03 14:08:40 +01:00
2022-09-07 17:54:04 +02:00
#include <cinttypes>
#include <cstring>
2022-02-02 10:29:30 +01:00
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
#include "fsfw/timemanager/Clock.h"
2021-01-03 13:25:42 +01:00
#if defined(WIN32) && FSFW_COLORED_OUTPUT == 1
#include "Windows.h"
#endif
2018-07-13 15:56:37 +02:00
// to be implemented by bsp
extern "C" void printChar(const char*, bool errStream);
2022-02-02 10:29:30 +01:00
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble,
bool buffered, bool errStream, uint16_t port)
: isActive(true),
logMessage(setMessage),
addCrToPreamble(addCrToPreamble),
buffered(buffered),
errStream(errStream) {
if (buffered) {
// Set pointers if the stream is buffered.
setp(buf, buf + BUF_SIZE);
}
#if FSFW_COLORED_OUTPUT == 1
2022-02-02 10:29:30 +01:00
if (setMessage.find("DEBUG") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_CYAN;
} else if (setMessage.find("INFO") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_GREEN;
} else if (setMessage.find("WARNING") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_MAGENTA;
} else if (setMessage.find("ERROR") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_RED;
} else {
colorPrefix = sif::ANSI_COLOR_RESET;
}
2021-01-03 13:25:42 +01:00
#ifdef WIN32
2022-02-02 10:29:30 +01:00
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwMode = 0;
GetConsoleMode(hOut, &dwMode);
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(hOut, dwMode);
2021-01-03 13:25:42 +01:00
#endif
#endif
2021-01-03 01:39:06 +01:00
2022-02-02 10:29:30 +01:00
preamble.reserve(MAX_PREAMBLE_SIZE);
preamble.resize(MAX_PREAMBLE_SIZE);
}
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
2022-09-08 11:47:40 +02:00
if (not isActive) {
return;
}
2022-02-02 10:29:30 +01:00
char array[BUF_SIZE];
uint32_t length = end - begin;
if (length > sizeof(array)) {
length = sizeof(array);
}
memcpy(array, begin, length);
for (; begin != end; begin++) {
if (errStream) {
printChar(begin, true);
} else {
printChar(begin, false);
}
}
}
int ServiceInterfaceBuffer::overflow(int c) {
2022-02-02 10:29:30 +01:00
if (not buffered and this->isActive) {
if (c != Traits::eof()) {
if (errStream) {
printChar(reinterpret_cast<const char*>(&c), true);
} else {
printChar(reinterpret_cast<const char*>(&c), false);
}
}
return 0;
}
// Handle output
putChars(pbase(), pptr());
if (c != Traits::eof()) {
char c2 = c;
// Handle the one character that didn't fit to buffer
putChars(&c2, &c2 + 1);
}
// This tells that buffer is empty again
setp(buf, buf + BUF_SIZE - 1);
// I'm not sure about this return value!
return 0;
}
int ServiceInterfaceBuffer::sync(void) {
2022-02-02 10:29:30 +01:00
if (not this->isActive and not buffered) {
if (not buffered) {
setp(buf, buf + BUF_SIZE - 1);
}
return 0;
}
if (not buffered) {
return 0;
}
size_t preambleSize = 0;
std::string* preamble = getPreamble(&preambleSize);
// Write logMessage and time
this->putChars(preamble->data(), preamble->data() + preambleSize);
// Handle output
this->putChars(pbase(), pptr());
// This tells that buffer is empty again
setp(buf, buf + BUF_SIZE - 1);
return 0;
}
2022-02-02 10:29:30 +01:00
bool ServiceInterfaceBuffer::isBuffered() const { return buffered; }
2020-05-29 20:31:08 +02:00
2022-02-02 10:29:30 +01:00
std::string* ServiceInterfaceBuffer::getPreamble(size_t* preambleSize) {
Clock::TimeOfDay_t loggerTime;
Clock::getDateAndTime(&loggerTime);
size_t currentSize = 0;
char* parsePosition = &preamble[0];
if (addCrToPreamble) {
preamble[0] = '\r';
currentSize += 1;
parsePosition += 1;
}
#if FSFW_COLORED_OUTPUT == 1
2022-02-02 10:29:30 +01:00
currentSize += sprintf(parsePosition, "%s", colorPrefix.c_str());
parsePosition += colorPrefix.size();
#endif
2022-02-02 10:29:30 +01:00
int32_t charCount =
sprintf(parsePosition, "%s%s | %02" SCNu32 ":%02" SCNu32 ":%02" SCNu32 ".%03" SCNu32 " | ",
this->logMessage.c_str(), sif::ANSI_COLOR_RESET, loggerTime.hour, loggerTime.minute,
loggerTime.second, loggerTime.usecond / 1000);
if (charCount < 0) {
printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n");
return &preamble;
}
if (charCount > MAX_PREAMBLE_SIZE) {
printf(
"ServiceInterfaceBuffer: Char count too large for maximum "
"preamble size");
return &preamble;
}
currentSize += charCount;
if (preambleSize != nullptr) {
*preambleSize = currentSize;
}
return &preamble;
2018-07-13 15:56:37 +02:00
}
2022-02-02 10:29:30 +01:00
bool ServiceInterfaceBuffer::crAdditionEnabled() const { return addCrToPreamble; }
2020-05-29 20:31:08 +02:00
2021-07-24 07:15:24 +02:00
#if FSFW_COLORED_OUTPUT == 1
2021-06-11 14:52:09 +02:00
void ServiceInterfaceBuffer::setAsciiColorPrefix(std::string colorPrefix) {
2022-02-02 10:29:30 +01:00
this->colorPrefix = colorPrefix;
2021-06-11 14:52:09 +02:00
}
2021-07-24 07:15:24 +02:00
#endif
2021-06-11 14:52:09 +02:00
2022-09-07 17:58:49 +02:00
#endif