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);
        }
    }
}
Ejemplo n.º 2
0
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
    }
}