#include <lib/memory.h>

void *memcpy(void *dest, const void *src, size_t n) {
    uint8_t *pdest = (uint8_t *) dest;
    const uint8_t *psrc = (const uint8_t *) src;

    for (size_t i = 0; i < n; i++) {
        pdest[i] = psrc[i];
    }

    return dest;
}

void *memset(void *s, uint8_t c, size_t n) {
    uint8_t *p = (uint8_t *) s;

    for (size_t i = 0; i < n; i++) {
        p[i] = (uint8_t) c;
    }

    return s;
}

void *memset16(void *s, uint16_t c, size_t n) {
    uint16_t *p = (uint16_t *) s;

    for (size_t i = 0; i < n; i++) {
        p[i] = (uint16_t) c;
    }

    return s;
}

void *memset32(void *s, uint32_t c, size_t n) {
    uint32_t *p = (uint32_t *) s;

    for (size_t i = 0; i < n; i++) {
        p[i] = (uint32_t) c;
    }

    return s;
}

void *memset64(void *s, uint64_t c, size_t n) {
    uint64_t *p = (uint64_t *) s;

    for (size_t i = 0; i < n; i++) {
        p[i] = (uint64_t) c;
    }

    return s;
}

void *memmove(void *dest, const void *src, size_t n) {
    uint8_t *pdest = (uint8_t *) dest;
    const uint8_t *psrc = (const uint8_t *) src;

    if (src > dest) {
        for (size_t i = 0; i < n; i++) {
            pdest[i] = psrc[i];
        }
    } else if (src < dest) {
        for (size_t i = n; i > 0; i--) {
            pdest[i-1] = psrc[i-1];
        }
    }

    return dest;
}

int memcmp(const void *s1, const void *s2, size_t n) {
    const uint8_t *p1 = (const uint8_t *) s1;
    const uint8_t *p2 = (const uint8_t *) s2;

    for (size_t i = 0; i < n; i++) {
        if (p1[i] != p2[i]) {
            return p1[i] < p2[i] ? -1 : 1;
        }
    }

    return 0;
}
