void log_dump(int level, const char *category, const void *data, size_t size, int flags, void *reserved) { if (!size || (!log_write_callback && (!log_compat_callback || level < log_compat_level))) { return; } static const char hex[] = "0123456789abcdef"; char buf[LOG_MAX_STRING_LENGTH / 2 * 2 + 1]; // Hex data is flushed in chunks buf[sizeof(buf) - 1] = 0; // Compatibility callback expects null-terminated strings size_t offs = 0; for (size_t i = 0; i < size; ++i) { const uint8_t b = ((const uint8_t*)data)[i]; buf[offs++] = hex[b >> 4]; buf[offs++] = hex[b & 0x0f]; if (offs == sizeof(buf) - 1) { if (log_write_callback) { log_write_callback(buf, sizeof(buf) - 1, level, category, 0); } else { log_compat_callback(buf); } offs = 0; } } if (offs) { if (log_write_callback) { log_write_callback(buf, offs, level, category, 0); } else { buf[offs] = 0; log_compat_callback(buf); } } }
void log_message_v(int level, const char *category, LogAttributes *attr, void *reserved, const char *fmt, va_list args) { const log_message_callback_type msg_callback = log_msg_callback; if (!msg_callback && (!log_compat_callback || level < log_compat_level)) { return; } // Set default attributes if (!attr->has_time) { LOG_ATTR_SET(*attr, time, HAL_Timer_Get_Milli_Seconds()); } char buf[LOG_MAX_STRING_LENGTH]; if (msg_callback) { const int n = vsnprintf(buf, sizeof(buf), fmt, args); if (n > (int)sizeof(buf) - 1) { buf[sizeof(buf) - 2] = '~'; } msg_callback(buf, level, category, attr, 0); } else { // Using compatibility callback const char* const levelName = log_level_name(level, 0); int n = 0; if (attr->has_file && attr->has_line && attr->has_function) { n = snprintf(buf, sizeof(buf), "%010u %s:%d, %s: %s", (unsigned)attr->time, attr->file, attr->line, attr->function, levelName); } else { n = snprintf(buf, sizeof(buf), "%010u %s", (unsigned)attr->time, levelName); } if (n > (int)sizeof(buf) - 1) { buf[sizeof(buf) - 2] = '~'; } log_compat_callback(buf); log_compat_callback(": "); n = vsnprintf(buf, sizeof(buf), fmt, args); if (n > (int)sizeof(buf) - 1) { buf[sizeof(buf) - 2] = '~'; } log_compat_callback(buf); log_compat_callback("\r\n"); } }
void log_write(int level, const char *category, const char *data, size_t size, void *reserved) { if (!size) { return; } if (log_write_callback) { log_write_callback(data, size, level, category, 0); } else if (log_compat_callback && level >= log_compat_level) { // Compatibility callback expects null-terminated strings if (!data[size - 1]) { log_compat_callback(data); } else { char buf[LOG_MAX_STRING_LENGTH]; size_t offs = 0; do { const size_t n = std::min(size - offs, sizeof(buf) - 1); memcpy(buf, data + offs, n); buf[n] = 0; log_compat_callback(buf); offs += n; } while (offs < size); } } }
void log_printf_v(int level, const char *category, void *reserved, const char *fmt, va_list args) { if (!log_write_callback && (!log_compat_callback || level < log_compat_level)) { return; } char buf[LOG_MAX_STRING_LENGTH]; int n = vsnprintf(buf, sizeof(buf), fmt, args); if (n > (int)sizeof(buf) - 1) { buf[sizeof(buf) - 2] = '~'; n = sizeof(buf) - 1; } if (log_write_callback) { log_write_callback(buf, n, level, category, 0); } else { log_compat_callback(buf); // Compatibility callback } }