#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

#include "common.h"
#include "console.h"
#include "io.h"

#if CON_OUT_OF_LINE

void __hot con_putc(char c)
{
    _con_putc(c);
}

void __hot con_puts(const char *str)
{
    _con_puts(str);
}

#endif

void con_vprintf(const char *fmt, va_list ap)
{
    char buf[128];		/* Maximum text size */
    unsigned int len;
    const char *p;

    vsnprintf(buf, sizeof buf, fmt, ap);
    con_puts(buf);
}

void con_printf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    con_vprintf(fmt, ap);
    va_end(ap);
}

void con_hexdump(const void *data, size_t len)
{
    const uint8_t *p = data;

    if (!len)
	return;

    while (1) {
	con_printf("%p", p);
	for (size_t i = 0; i < 16; i++) {
	    if (!(i & 7))
		con_putc(' ');
	    if (i >= len)
		con_puts("   ");
	    else
		con_printf(" %02x", p[i]);
	}
	con_puts("  |");
	for (size_t i = 0; i < 16; i++) {
	    char c;
	    if (i >= len)
		break;
	    c = p[i];
	    if (c < ' ' || c > '~')
		c = '.';
	    con_putc(c);
	}
	con_puts("|\n");

	if (len <= 16)
	    break;

	p += 16;
	len -= 16;
    }
}
