#include "src/lib/string.h" #include uint8_t bytes_equal(const char *l, const char *r, uint64_t count) { while (count--) { if (*l++ != *r++) { return 0; } } return 1; } uint8_t string_empty(const char *s) { return *s == '\0'; } uint64_t string_length(const char *s) { const char *e = s; while (*e) { e++; } return (uint64_t)(e - s); } uint8_t string_equal(const char *l, const char *r) { while (*l && *r) { if (*l != *r) { return 0; } l++; r++; } return *l == *r; } uint64_t string_split(char *string, char separator, uint64_t max, char **result) { uint64_t count = 1; *result = string; while (*string && count < max) { if (*string == separator) { *string = '\0'; result++; *result = string + 1; count++; } string++; } return count; } uint64_t string_byte_to_hex(uint8_t value, uint64_t max, char *result) { if (max == 0) { return 0; } if (max == 1) { result[0] = '\0'; return 0; } if (max == 2) { result[0] = '0'; result[1] = '\0'; return 1; } char tmp[3] = "00"; uint8_t i = 0; while (value) { uint8_t nibble = value & 0xF; tmp[i++] = nibble < 10 ? '0' + nibble : 'a' + nibble - 10; value >>= 4; } result[0] = '0'; result[1] = 'x'; i = 2; while (i < 4 && i < max - 1) { result[i] = tmp[3 - i]; i++; } result[i] = '\0'; return i; } uint64_t string_uint_to_decimal(uint64_t value, uint64_t max, char *result) { if (max == 0) { return 0; } char tmp[20]; uint8_t len = 0; if (value == 0) { tmp[len++] = '0'; } else { while (value && len < 20) { tmp[len++] = '0' + (value % 10); value /= 10; } } uint8_t i = 0; while (i < len && i < max - 1) { result[i] = tmp[len - 1 - i]; i++; } result[i] = '\0'; return i; } uint64_t string_int_to_decimal(int64_t value, uint64_t max, char *result) { if (max == 0) { return 0; } if (value >= 0) { return string_uint_to_decimal((uint64_t)value, max, result); } result[0] = '-'; return 1 + string_uint_to_decimal((uint64_t)(-value), max - 1, result + 1); } uint64_t string_uint_to_hex(uint64_t value, uint64_t max, char *result) { if (max == 0) { return 0; } if (max == 1) { result[0] = '\0'; return 0; } if (max == 2) { result[0] = '0'; result[1] = '\0'; return 1; } char tmp[17] = "0000000000000000"; uint8_t i = 0; while (value) { uint8_t nibble = value & 0xF; tmp[i++] = nibble < 10 ? '0' + nibble : 'A' + nibble - 10; value >>= 4; } result[0] = '0'; result[1] = 'x'; i = 2; while (i < 18 && i < max - 1) { result[i] = tmp[17 - i]; i++; } result[i] = '\0'; return i; } uint64_t string_format(const char *format, uint64_t max, char *output, ...) { va_list args; va_start(args, output); uint64_t limit = max - 1; uint64_t fi = 0, ri = 0; while (format[fi] && ri < limit) { if (format[fi] != '%') { output[ri++] = format[fi++]; } else { switch (format[fi + 1]) { case 'c': output[ri++] = (char)va_arg(args, int); fi += 2; break; case 'd': string_int_to_decimal(va_arg(args, int64_t), limit - ri, output + ri); while (output[ri]) { ri++; } fi += 2; break; case 'u': string_uint_to_decimal(va_arg(args, uint64_t), limit - ri, output + ri); while (output[ri]) { ri++; } fi += 2; break; case 'x': string_uint_to_hex(va_arg(args, uint64_t), limit - ri, output + ri); while (output[ri]) { ri++; } fi += 2; break; case 's': { char *s = va_arg(args, char *); while (*s && ri < limit) { output[ri++] = *s; s++; } fi += 2; break; } case '%': { output[ri++] = '%'; fi += 2; break; } default: output[ri++] = format[fi++]; output[ri++] = format[fi++]; break; } } } output[ri] = '\0'; va_end(args); return ri; }