You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
4.1 KiB
227 lines
4.1 KiB
#include "src/lib/string.h"
|
|
#include <stdarg.h>
|
|
|
|
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;
|
|
}
|
|
|