Files
korenkonder_AFTMods/src/KKdLib/str_utils.cpp
T
2023-12-19 03:05:29 +03:00

691 lines
16 KiB
C++

/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "str_utils.hpp"
bool str_utils_check_ends_with(const char* str, const char* mask) {
if (!str || !mask)
return false;
size_t mask_len = utf8_length(mask);
size_t len = utf8_length(str);
const char* t = str;
while (t) {
t = strstr(t, mask);
if (t) {
t += mask_len;
if (t == str + len)
return true;
}
}
return false;
}
bool str_utils_check_ends_with(const wchar_t* str, const wchar_t* mask) {
if (!str || !mask)
return false;
size_t mask_len = utf16_length(mask);
size_t len = utf16_length(str);
const wchar_t* t = str;
while (t) {
t = wcsstr(t, mask);
if (t) {
t += mask_len;
if (t == str + len)
return true;
}
}
return false;
}
const char* str_utils_get_next_int32_t(const char* str, int32_t& value, const char split) {
std::string s;
str = str_utils_get_next_string(str, s, split);
sscanf_s(s.c_str(), "%d", &value);
return str;
}
const wchar_t* str_utils_get_next_int32_t(const wchar_t* str, int32_t& value, const wchar_t split) {
std::wstring s;
str = str_utils_get_next_string(str, s, split);
swscanf_s(s.c_str(), L"%d", &value);
return str;
}
const char* str_utils_get_next_float_t(const char* str, float_t& value, const char split) {
std::string s;
str = str_utils_get_next_string(str, s, split);
sscanf_s(s.c_str(), "%f", &value);
return str;
}
const wchar_t* str_utils_get_next_float_t(const wchar_t* str, float_t& value, const wchar_t split) {
std::wstring s;
str = str_utils_get_next_string(str, s, split);
swscanf_s(s.c_str(), L"%f", &value);
return str;
}
const char* str_utils_get_next_string(const char* str, std::string& value, const char split) {
value.clear();
if (!str)
return 0;
const char* t = strchr(str, split);
if (!t) {
value.assign(str);
return 0;
}
value.assign(str, t - str);
t++;
return *t ? t : 0;
}
const wchar_t* str_utils_get_next_string(const wchar_t* str, std::wstring& value, const wchar_t split) {
value.clear();
if (!str)
return 0;
const wchar_t* t = wcschr(str, split);
if (!t) {
value.assign(str);
return 0;
}
value.assign(str, t - str);
t++;
return *t ? t : 0;
}
char* str_utils_split_get_right(const char* str, const char split) {
if (!str)
return 0;
const char* t = strchr(str, split);
if (!t)
return str_utils_copy(str);
t++;
size_t len = utf8_length(t);
char* p = force_malloc<char>(len + 1);
memcpy(p, t, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_get_right(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcschr(str, split);
if (!t)
return str_utils_copy(str);
t++;
size_t len = utf16_length(t);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, t, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_get_left(const char* str, const char split) {
if (!str)
return 0;
const char* t = strchr(str, split);
size_t len = t ? t - str : utf8_length(str);
char* p = force_malloc<char>(len + 1);
memcpy(p, str, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_get_left(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcschr(str, split);
size_t len = t ? t - str : utf16_length(str);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, str, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_get_right_include(const char* str, const char split) {
if (!str)
return 0;
const char* t = strchr(str, split);
if (!t)
return str_utils_copy(str);
size_t len = utf8_length(t);
char* p = force_malloc<char>(len + 1);
memcpy(p, t, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_get_right_include(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcschr(str, split);
if (!t)
return str_utils_copy(str);
size_t len = utf16_length(t);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, t, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_get_left_include(const char* str, const char split) {
if (!str)
return 0;
const char* t = strchr(str, split);
t++;
size_t len = t ? t - str : utf8_length(str);
char* p = force_malloc<char>(len + 1);
memcpy(p, str, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_get_left_include(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcschr(str, split);
t++;
size_t len = t ? t - str : utf16_length(str);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, str, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_right_get_right(const char* str, const char split) {
if (!str)
return 0;
const char* t = strrchr(str, split);
if (!t)
return str_utils_copy(str);
t++;
size_t len = t - str;
char* p = force_malloc<char>(len + 1);
memcpy(p, t, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_right_get_right(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcsrchr(str, split);
if (!t)
return str_utils_copy(str);
t++;
size_t len = t - str;
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, t, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_right_get_left(const char* str, const char split) {
if (!str)
return 0;
const char* t = strrchr(str, split);
size_t len = t ? t - str : utf8_length(str);
char* p = force_malloc<char>(len + 1);
memcpy(p, str, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_right_get_left(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcsrchr(str, split);
size_t len = t ? t - str : utf16_length(str);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, str, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_right_get_right_include(const char* str, const char split) {
if (!str)
return 0;
const char* t = strrchr(str, split);
if (!t)
return str_utils_copy(str);
size_t len = utf8_length(t);
char* p = force_malloc<char>(len + 1);
memcpy(p, t, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_right_get_right_include(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcsrchr(str, split);
if (!t)
return str_utils_copy(str);
size_t len = utf16_length(t);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, t, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_split_right_get_left_include(const char* str, const char split) {
if (!str)
return 0;
const char* t = strrchr(str, split);
if (t)
t++;
size_t len = t ? t - str : utf8_length(str);
char* p = force_malloc<char>(len + 1);
memcpy(p, str, len);
p[len] = 0;
return p;
}
wchar_t* str_utils_split_right_get_left_include(const wchar_t* str, const wchar_t split) {
if (!str)
return 0;
const wchar_t* t = wcsrchr(str, split);
if (t)
t++;
size_t len = t ? t - str : utf16_length(str);
wchar_t* p = force_malloc<wchar_t>(len + 1);
memcpy(p, str, sizeof(wchar_t) * len);
p[len] = 0;
return p;
}
char* str_utils_get_extension(const char* str) {
if (!str)
return 0;
const char* t = strrchr(str, '\\');
return str_utils_split_right_get_right_include(t ? t + 1 : str, '.');
}
wchar_t* str_utils_get_extension(const wchar_t* str) {
if (!str)
return 0;
const wchar_t* t = wcsrchr(str, L'\\');
return str_utils_split_right_get_right_include(t ? t + 1 : str, L'.');
}
char* str_utils_get_without_extension(const char* str) {
if (!str)
return 0;
const char* t = strrchr(str, '\\');
return str_utils_split_right_get_left(t ? t + 1 : str, '.');
}
wchar_t* str_utils_get_without_extension(const wchar_t* str) {
if (!str)
return 0;
const wchar_t* t = wcsrchr(str, L'\\');
return str_utils_split_right_get_left(t ? t + 1 : str, L'.');
}
char* str_utils_add(const char* str0, const char* str1) {
if (str0 && str1) {
size_t str0_len = utf8_length(str0);
size_t str1_len = utf8_length(str1);
char* p = force_malloc<char>(str0_len + str1_len + 1);
memcpy(p, str0, str0_len + 1);
memcpy(p + str0_len, str1, str1_len + 1);
return p;
}
else if (str0)
return str_utils_copy(str0);
else if (str1)
return str_utils_copy(str1);
else
return 0;
}
wchar_t* str_utils_add(const wchar_t* str0, const wchar_t* str1) {
if (str0 && str1) {
size_t str0_len = utf16_length(str0);
size_t str1_len = utf16_length(str1);
wchar_t* p = force_malloc<wchar_t>(str0_len + str1_len + 1);
memcpy(p, str0, sizeof(wchar_t) * (str0_len + 1));
memcpy(p + str0_len, str1, sizeof(wchar_t) * (str1_len + 1));
return p;
}
else if (str0)
return str_utils_copy(str0);
else if (str1)
return str_utils_copy(str1);
else
return 0;
}
char* str_utils_copy(const char* str) {
if (!str)
return 0;
size_t len = utf8_length(str) + 1;
char* p = force_malloc<char>(len);
memcpy(p, str, len);
return p;
}
wchar_t* str_utils_copy(const wchar_t* str) {
if (!str)
return 0;
size_t len = utf16_length(str) + 1;
wchar_t* p = force_malloc<wchar_t>(len);
memcpy(p, str, sizeof(wchar_t) * len);
return p;
}
inline int32_t str_utils_compare_length(const char* str0, size_t str0_len, const char* str1, size_t str1_len) {
if (!str0_len)
return -*str1;
else if (!str1_len)
return *str0;
size_t str0_len_act = str0_len;
const char* i0 = str0;
for (size_t i = str0_len; i; i--)
if (!*i0++) {
str0_len_act = i + 1;
break;
}
size_t str1_len_act = str1_len;
const char* i1 = str1;
for (size_t i = str1_len; i; i--)
if (!*i1++) {
str1_len_act = i + 1;
break;
}
str0_len = str0_len_act;
str1_len = str1_len_act;
int32_t diff = 0;
char c0;
char c1;
do {
c0 = *str0++;
c1 = *str1++;
if (!c0 || !c1)
return c0 - c1;
} while (c0 == c1 && --str0_len && --str1_len);
return c0 - c1;
}
inline int32_t str_utils_compare_length(const wchar_t* str0, size_t str0_len, const wchar_t* str1, size_t str1_len) {
if (!str0_len)
return -*str1;
else if (!str1_len)
return *str0;
size_t str0_len_act = str0_len;
const wchar_t* i0 = str0;
for (size_t i = str0_len; i; i--)
if (!*i0++) {
str0_len_act = i + 1;
break;
}
size_t str1_len_act = str1_len;
const wchar_t* i1 = str1;
for (size_t i = str1_len; i; i--)
if (!*i1++) {
str1_len_act = i + 1;
break;
}
str0_len = str0_len_act;
str1_len = str1_len_act;
int32_t diff = 0;
wchar_t c0;
wchar_t c1;
do {
c0 = *str0++;
c1 = *str1++;
if (!c0 || !c1)
return c0 - c1;
} while (c0 == c1 && --str0_len && --str1_len);
return c0 - c1;
}
size_t str_utils_get_substring_offset(const char* str0, size_t str0_len,
size_t str0_off, const char* str1, size_t str1_len) {
if (!str1_len && str0_off <= str0_len)
return str0_off;
if (str0_off < str0_len && str1_len <= str0_len - str0_off) {
size_t len = str0_len - str1_len - str0_off + 1;
const char* str = &str0[str0_off];
for (; len; ) {
const char* s = (const char*)memchr(str, *str1, len);
if (!s)
break;
if (!str1_len || !memcmp(s, str1, str1_len))
return s - str0;
len += str - (s + 1);
str = s + 1;
}
}
return -1;
}
size_t str_utils_get_substring_offset(const wchar_t* str0, size_t str0_len,
size_t str0_off, const wchar_t* str1, size_t str1_len) {
if (!str1_len && str0_off <= str0_len)
return str0_off;
if (str0_off < str0_len && str1_len <= str0_len - str0_off) {
size_t len = str0_len - str1_len - str0_off + 1;
const wchar_t* str = &str0[str0_off];
for (; len; ) {
const wchar_t* s = wmemchr(str, *str1, len);
if (!s)
break;
if (!str1_len || !memcmp(s, str1, sizeof(wchar_t) * str1_len))
return s - str0;
len += str - (s + 1);
str = s + 1;
}
}
return -1;
}
bool str_utils_text_file_parse(const void* data, size_t size,
char*& buf, char**& lines, size_t& count) {
if (!data || !size)
return false;
const char* d = (const char*)data;
bool del = false;
size_t c;
buf = 0;
lines = 0;
count = 0;
if ((uint8_t)d[0] == 0x00)
return false;
else if (d[0] == 0xFF) {
if (size == 1 || (uint8_t)d[1] != 0xFE || size == 2)
return false;
wchar_t* w_d = (wchar_t*)data + 1;
d = utf16_to_utf8(w_d);
size = utf8_length(d);
del = true;
goto decode_utf8_ansi;
}
else if ((uint8_t)d[0] == 0xFE) {
if (size == 1 || (uint8_t)d[1] != 0xFF || size == 2)
return false;
size /= 2;
wchar_t* w_d = (wchar_t*)data + 1;
w_d = str_utils_copy(w_d);
for (size_t i = 0; i < size; i++)
w_d[i] = (wchar_t)reverse_endianness_uint16_t((uint16_t)w_d[i]);
d = utf16_to_utf8(w_d);
size = utf8_length(d);
del = true;
free_def(w_d);
goto decode_utf8_ansi;
}
else if ((uint8_t)d[0] == 0xEF) {
if (size == 1 || (uint8_t)d[1] != 0xBB || size == 2 || (uint8_t)d[2] != 0xBF || size == 3)
return false;
d += 3;
size -= 3;
goto decode_utf8_ansi;
}
else {
decode_utf8_ansi:
c = 1;
bool lf;
char ch;
const char* t;
lf = false;
t = d;
ch = 0;
size_t buf_len = size;
for (size_t i = 0, l = 0, m = 0; i < size; i++) {
ch = *t++;
if (ch == '\r') {
if (i + 1 < size && *t == '\n') {
i++;
t++;
l++;
}
lf = true;
}
else if (ch == '\n')
lf = true;
if (lf) {
if (!l && c > 1)
buf_len--;
c++;
l = 0;
m = 0;
lf = false;
}
else {
l++;
m++;
}
}
if (ch != '\r' && ch != '\n')
buf_len++;
else
c--;
lf = false;
t = d;
char* temp_buf = force_malloc<char>(buf_len);
char** temp_lines = force_malloc<char*>(c);
char* b = temp_buf;
for (size_t i = 0, j = 0, l = 0, m = 0; j < c; i++) {
ch = *t++;
if (ch == '\r') {
if (i + 1 < size && *t == '\n') {
i++;
t++;
l++;
}
lf = true;
}
else if (ch == '\n')
lf = true;
if (i >= size || lf) {
temp_lines[j] = b;
if (l) {
memcpy(b, d + i - l, m);
b[l] = 0;
b += l + 1;
}
else if (j)
temp_lines[j]--;
else
*b++ = 0;
j++;
if (!lf)
break;
l = 0;
m = 0;
lf = false;
}
else {
l++;
m++;
}
}
buf = temp_buf;
lines = temp_lines;
count = c;
}
if (del) {
void* data = (void*)d;
free_def(data);
}
return true;
}