Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions fpsdk_common/include/fpsdk_common/logging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,50 @@ void LoggingPrint(const LoggingLevel level, const std::size_t repeat, const char
void LoggingHexdump(const LoggingLevel level, const uint8_t* data, const std::size_t size, const char* prefix,
const char* fmt, ...) PRINTF_ATTR(5);

/**
* @brief Utility to create a std::ostream that prints through the logging system
*
* For example:
*
* @code{cpp}
* auto w = LoggingOstream(LoggingLevel::WARNING);
* *w << "Hello world!" << std::endl; // This should print: Warning: Hello world!
* @endcode
*
* @note Flushing the stream is required for the log message to be printed. Typically, std::endl flushes. Otherwise
* explicitly flush using std::flush when appropriate.
*/
class LoggingOstream
{
public:
/**
* @brief Constructor
*
* @param[in] level The logging level to use
*/
LoggingOstream(const LoggingLevel level);

/**
* @brief Get stream handle
*
* @returns the stream handle
*/
std::ostream& operator*()
{
return str_;
}

private:
//! Helper buffer that prints through logging
struct StrBuf : public std::stringbuf
{
virtual int sync(); //!< Print function implementation
LoggingLevel level_; //!< Logging level
};
StrBuf buf_; //!< Helper buffer
std::ostream str_; //!< Stream handle
};

// Helper macros
#ifndef _DOXYGEN_
# define _FPSDK_LOGGING_LOG(_level_, ...) \
Expand Down
28 changes: 28 additions & 0 deletions fpsdk_common/src/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,34 @@ void LoggingHexdump(
}
}

// ---------------------------------------------------------------------------------------------------------------------

LoggingOstream::LoggingOstream(const LoggingLevel level) : str_{ &buf_ }
{
buf_.level_ = level;
}

int LoggingOstream::StrBuf::sync()
{
// Print each line
const auto s = this->str();
std::size_t offs = 0;
std::size_t pos = 0;
while ((pos = s.find("\n", offs)) != std::string::npos) {
switch (level_) { // clang-format off
case LoggingLevel::FATAL: FATAL( "%s", s.substr(offs, pos).c_str()); break;
case LoggingLevel::ERROR: ERROR( "%s", s.substr(offs, pos).c_str()); break;
case LoggingLevel::WARNING: WARNING("%s", s.substr(offs, pos).c_str()); break;
case LoggingLevel::NOTICE: NOTICE( "%s", s.substr(offs, pos).c_str()); break;
case LoggingLevel::INFO: INFO( "%s", s.substr(offs, pos).c_str()); break;
case LoggingLevel::DEBUG: DEBUG( "%s", s.substr(offs, pos).c_str()); break;
case LoggingLevel::TRACE: TRACE( "%s", s.substr(offs, pos).c_str()); break;
} // clang-format on
offs = pos + 1;
}
return 0;
}

/* ****************************************************************************************************************** */
} // namespace logging
} // namespace common
Expand Down
Loading