mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-02 13:47:56 +02:00
Added more helpers to string, and fixed a bug in replace_from.
This commit is contained in:
parent
ff8790f81d
commit
f9dcd088d0
172
core/string.cpp
172
core/string.cpp
@ -233,10 +233,10 @@ void String::replace_from(const int start_index, const int length, const String
|
|||||||
}
|
}
|
||||||
|
|
||||||
_size -= loffs;
|
_size -= loffs;
|
||||||
}
|
} else {
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
for (int i = 0; i < length; ++i) {
|
_data[i + start_index] = with._data[i];
|
||||||
_data[i + start_index] = with._data[i];
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,6 +255,29 @@ void String::replace(const String &find_str, const String &with) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void String::replace(const String &find_str, const String &with, const int count) {
|
||||||
|
if (empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find_str.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
int start_pos = 0;
|
||||||
|
while ((start_pos = find(find_str, start_pos)) != -1) {
|
||||||
|
replace_from(start_pos, find_str.size(), with);
|
||||||
|
start_pos += with.size();
|
||||||
|
|
||||||
|
++c;
|
||||||
|
|
||||||
|
if (c == count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int String::compare(const String &other) const {
|
int String::compare(const String &other) const {
|
||||||
if (size() < other.size()) {
|
if (size() < other.size()) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -357,6 +380,61 @@ void String::trim_end() {
|
|||||||
_size = last_index;
|
_size = last_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool String::ends_with(const char c) const {
|
||||||
|
if (_size == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _data[_size - 1] == c;
|
||||||
|
}
|
||||||
|
bool String::ends_with(const String &str) const {
|
||||||
|
if (str.size() == 0) {
|
||||||
|
// maybe this should be false?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_size < str.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int diff = _size - str.size();
|
||||||
|
|
||||||
|
for (int i = str.size() - 1; i >= 0; --i) {
|
||||||
|
if (_data[i + diff] != str._data[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::starts_with(const char c) const {
|
||||||
|
if (_size == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _data[0] == c;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool String::starts_with(const String &str) const {
|
||||||
|
if (str.size() == 0) {
|
||||||
|
// maybe this should be false?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_size < str.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < str.size(); ++i) {
|
||||||
|
if (_data[i] != str._data[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int String::get_slice_count(const char splitter) const {
|
int String::get_slice_count(const char splitter) const {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
|
|
||||||
@ -498,7 +576,7 @@ uint16_t String::read_uint16_bytes_at(int &index, bool advance_index) {
|
|||||||
char carr[3];
|
char carr[3];
|
||||||
char *p = carr;
|
char *p = carr;
|
||||||
|
|
||||||
//printf("%u %u\n", static_cast<uint8_t>(p[0]), static_cast<uint8_t>(p[1]));
|
// printf("%u %u\n", static_cast<uint8_t>(p[0]), static_cast<uint8_t>(p[1]));
|
||||||
|
|
||||||
get_substr_nt(p, index, 2);
|
get_substr_nt(p, index, 2);
|
||||||
|
|
||||||
@ -558,7 +636,7 @@ int16_t String::read_int16_bytes_at(int &index, bool advance_index) {
|
|||||||
char carr[3];
|
char carr[3];
|
||||||
char *p = carr;
|
char *p = carr;
|
||||||
|
|
||||||
//printf("%u %u\n", static_cast<uint8_t>(p[0]), static_cast<uint8_t>(p[1]));
|
// printf("%u %u\n", static_cast<uint8_t>(p[0]), static_cast<uint8_t>(p[1]));
|
||||||
|
|
||||||
get_substr_nt(p, index, 2);
|
get_substr_nt(p, index, 2);
|
||||||
|
|
||||||
@ -614,7 +692,7 @@ void String::append_uint16_bytes(const uint16_t val) {
|
|||||||
|
|
||||||
const char *vp = static_cast<const char *>((void *)&val);
|
const char *vp = static_cast<const char *>((void *)&val);
|
||||||
|
|
||||||
//printf("a %u %u\n", static_cast<uint8_t>(vp[0]), static_cast<uint8_t>(vp[1]));
|
// printf("a %u %u\n", static_cast<uint8_t>(vp[0]), static_cast<uint8_t>(vp[1]));
|
||||||
|
|
||||||
memcpy(&_data[_size], vp, 2);
|
memcpy(&_data[_size], vp, 2);
|
||||||
|
|
||||||
@ -656,7 +734,7 @@ void String::append_int16_bytes(const int16_t val) {
|
|||||||
|
|
||||||
const char *vp = static_cast<const char *>((void *)&val);
|
const char *vp = static_cast<const char *>((void *)&val);
|
||||||
|
|
||||||
//printf("a %u %u\n", static_cast<uint8_t>(vp[0]), static_cast<uint8_t>(vp[1]));
|
// printf("a %u %u\n", static_cast<uint8_t>(vp[0]), static_cast<uint8_t>(vp[1]));
|
||||||
|
|
||||||
memcpy(&_data[_size], vp, 2);
|
memcpy(&_data[_size], vp, 2);
|
||||||
|
|
||||||
@ -935,9 +1013,9 @@ String String::bool_str(bool val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::num(double p_num, int p_decimals) {
|
String String::num(double p_num, int p_decimals) {
|
||||||
if (Math::is_nan(p_num)) {
|
if (Math::is_nan(p_num)) {
|
||||||
return "nan";
|
return "nan";
|
||||||
@ -993,7 +1071,7 @@ String String::num(double p_num, int p_decimals) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
buf[255] = 0;
|
buf[255] = 0;
|
||||||
//destroy trailing zeroes
|
// destroy trailing zeroes
|
||||||
{
|
{
|
||||||
bool period = false;
|
bool period = false;
|
||||||
int z = 0;
|
int z = 0;
|
||||||
@ -1024,9 +1102,9 @@ String String::num(double p_num, int p_decimals) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
|
String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
|
||||||
bool sign = p_num < 0;
|
bool sign = p_num < 0;
|
||||||
|
|
||||||
@ -1066,9 +1144,9 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
|
String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
|
||||||
uint64_t n = p_num;
|
uint64_t n = p_num;
|
||||||
|
|
||||||
@ -1098,9 +1176,9 @@ String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::num_real(double p_num, bool p_trailing) {
|
String String::num_real(double p_num, bool p_trailing) {
|
||||||
if (Math::is_nan(p_num)) {
|
if (Math::is_nan(p_num)) {
|
||||||
return "nan";
|
return "nan";
|
||||||
@ -1213,9 +1291,9 @@ String String::num_real(double p_num, bool p_trailing) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::num_scientific(double p_num) {
|
String String::num_scientific(double p_num) {
|
||||||
if (Math::is_nan(p_num)) {
|
if (Math::is_nan(p_num)) {
|
||||||
return "nan";
|
return "nan";
|
||||||
@ -1252,9 +1330,9 @@ String String::num_scientific(double p_num) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::ascii(bool p_allow_extended) const {
|
String String::ascii(bool p_allow_extended) const {
|
||||||
if (!size()) {
|
if (!size()) {
|
||||||
return String();
|
return String();
|
||||||
@ -1270,9 +1348,9 @@ String String::ascii(bool p_allow_extended) const {
|
|||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
String String::utf8(const char *p_utf8, int p_len) {
|
String String::utf8(const char *p_utf8, int p_len) {
|
||||||
String ret;
|
String ret;
|
||||||
ret.parse_utf8(p_utf8, p_len);
|
ret.parse_utf8(p_utf8, p_len);
|
||||||
@ -1280,9 +1358,9 @@ String String::utf8(const char *p_utf8, int p_len) {
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Taken from the Godot Engine (MIT License)
|
// Taken from the Godot Engine (MIT License)
|
||||||
//Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
// Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.
|
||||||
//Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
// Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
|
||||||
bool String::parse_utf8(const char *p_utf8, int p_len) {
|
bool String::parse_utf8(const char *p_utf8, int p_len) {
|
||||||
//#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err));
|
//#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err));
|
||||||
|
|
||||||
@ -1299,7 +1377,7 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
|
|||||||
if (p_len < 0 || p_len >= 3) {
|
if (p_len < 0 || p_len >= 3) {
|
||||||
bool has_bom = uint8_t(p_utf8[0]) == 0xEF && uint8_t(p_utf8[1]) == 0xBB && uint8_t(p_utf8[2]) == 0xBF;
|
bool has_bom = uint8_t(p_utf8[0]) == 0xEF && uint8_t(p_utf8[1]) == 0xBB && uint8_t(p_utf8[2]) == 0xBF;
|
||||||
if (has_bom) {
|
if (has_bom) {
|
||||||
//just skip it
|
// just skip it
|
||||||
if (p_len >= 0) {
|
if (p_len >= 0) {
|
||||||
p_len -= 3;
|
p_len -= 3;
|
||||||
}
|
}
|
||||||
@ -1330,13 +1408,13 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
|
|||||||
skip = 5;
|
skip = 5;
|
||||||
} else {
|
} else {
|
||||||
RLOG_ERR("UNICODE_ERROR: invalid skip\n");
|
RLOG_ERR("UNICODE_ERROR: invalid skip\n");
|
||||||
return true; //invalid utf8
|
return true; // invalid utf8
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip == 1 && (c & 0x1E) == 0) {
|
if (skip == 1 && (c & 0x1E) == 0) {
|
||||||
//printf("overlong rejected\n");
|
// printf("overlong rejected\n");
|
||||||
RLOG_ERR("UNICODE_ERROR: overlong rejected\n");
|
RLOG_ERR("UNICODE_ERROR: overlong rejected\n");
|
||||||
return true; //reject overlong
|
return true; // reject overlong
|
||||||
}
|
}
|
||||||
|
|
||||||
str_size++;
|
str_size++;
|
||||||
@ -1351,7 +1429,7 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
|
|||||||
|
|
||||||
if (skip) {
|
if (skip) {
|
||||||
RLOG_ERR("UNICODE_ERROR: no space left\n");
|
RLOG_ERR("UNICODE_ERROR: no space left\n");
|
||||||
return true; //not enough spac
|
return true; // not enough spac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,18 +1463,18 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
|
|||||||
} else {
|
} else {
|
||||||
RLOG_ERR("UNICODE_ERROR: invalid len\n");
|
RLOG_ERR("UNICODE_ERROR: invalid len\n");
|
||||||
|
|
||||||
return true; //invalid UTF8
|
return true; // invalid UTF8
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > cstr_size) {
|
if (len > cstr_size) {
|
||||||
RLOG_ERR("UNICODE_ERROR: no space left\n");
|
RLOG_ERR("UNICODE_ERROR: no space left\n");
|
||||||
return true; //not enough space
|
return true; // not enough space
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 2 && (*p_utf8 & 0x1E) == 0) {
|
if (len == 2 && (*p_utf8 & 0x1E) == 0) {
|
||||||
//printf("overlong rejected\n");
|
// printf("overlong rejected\n");
|
||||||
RLOG_ERR("UNICODE_ERROR: no space left\n");
|
RLOG_ERR("UNICODE_ERROR: no space left\n");
|
||||||
return true; //reject overlong
|
return true; // reject overlong
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the first character */
|
/* Convert the first character */
|
||||||
@ -1411,19 +1489,19 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
|
|||||||
for (int i = 1; i < len; i++) {
|
for (int i = 1; i < len; i++) {
|
||||||
if ((p_utf8[i] & 0xC0) != 0x80) {
|
if ((p_utf8[i] & 0xC0) != 0x80) {
|
||||||
RLOG_ERR("UNICODE_ERROR: invalid utf8\n");
|
RLOG_ERR("UNICODE_ERROR: invalid utf8\n");
|
||||||
return true; //invalid utf8
|
return true; // invalid utf8
|
||||||
}
|
}
|
||||||
if (unichar == 0 && i == 2 && ((p_utf8[i] & 0x7F) >> (7 - len)) == 0) {
|
if (unichar == 0 && i == 2 && ((p_utf8[i] & 0x7F) >> (7 - len)) == 0) {
|
||||||
RLOG_ERR("UNICODE_ERROR: invalid utf8 overlong\n");
|
RLOG_ERR("UNICODE_ERROR: invalid utf8 overlong\n");
|
||||||
return true; //no overlong
|
return true; // no overlong
|
||||||
}
|
}
|
||||||
unichar = (unichar << 6) | (p_utf8[i] & 0x3F);
|
unichar = (unichar << 6) | (p_utf8[i] & 0x3F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("char %i, len %i\n",unichar,len);
|
// printf("char %i, len %i\n",unichar,len);
|
||||||
if (sizeof(wchar_t) == 2 && unichar > 0xFFFF) {
|
if (sizeof(wchar_t) == 2 && unichar > 0xFFFF) {
|
||||||
unichar = ' '; //too long for windows
|
unichar = ' '; // too long for windows
|
||||||
}
|
}
|
||||||
|
|
||||||
*(dst++) = unichar;
|
*(dst++) = unichar;
|
||||||
@ -1509,7 +1587,7 @@ String String::utf8() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef APPEND_CHAR
|
#undef APPEND_CHAR
|
||||||
*cdst = 0; //trailing zero
|
*cdst = 0; // trailing zero
|
||||||
|
|
||||||
return utf8s;
|
return utf8s;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
|
|
||||||
void replace_from(const int start_index, const int length, const String &with);
|
void replace_from(const int start_index, const int length, const String &with);
|
||||||
void replace(const String &find_str, const String &with);
|
void replace(const String &find_str, const String &with);
|
||||||
|
void replace(const String &find_str, const String &with, const int count);
|
||||||
|
|
||||||
int compare(const String &other) const;
|
int compare(const String &other) const;
|
||||||
|
|
||||||
@ -45,6 +46,12 @@ public:
|
|||||||
void trim_beginning();
|
void trim_beginning();
|
||||||
void trim_end();
|
void trim_end();
|
||||||
|
|
||||||
|
bool ends_with(const char c) const;
|
||||||
|
bool ends_with(const String &str) const;
|
||||||
|
|
||||||
|
bool starts_with(const char c) const;
|
||||||
|
bool starts_with(const String &str) const;
|
||||||
|
|
||||||
int get_slice_count(const char splitter) const;
|
int get_slice_count(const char splitter) const;
|
||||||
int get_slice_count(const String &splitter) const;
|
int get_slice_count(const String &splitter) const;
|
||||||
String get_slice(const char splitter, int index);
|
String get_slice(const char splitter, int index);
|
||||||
|
Loading…
Reference in New Issue
Block a user