Skip to content

Commit e1c4239

Browse files
committed
Improve string copy_from and copy_from_unchecked implementations, by making use of caller contracts and language spec (NULL termination and casts).
1 parent aa8d9b8 commit e1c4239

File tree

1 file changed

+22
-39
lines changed

1 file changed

+22
-39
lines changed

core/string/ustring.cpp

+22-39
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,14 @@ void String::copy_from(const char *p_cstr) {
329329

330330
resize(len + 1); // include 0
331331

332+
const char *end = p_cstr + len;
332333
char32_t *dst = ptrw();
333334

334-
for (size_t i = 0; i <= len; i++) {
335-
#if CHAR_MIN == 0
336-
uint8_t c = p_cstr[i];
337-
#else
338-
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
339-
#endif
340-
if (c == 0 && i < len) {
341-
print_unicode_error("NUL character", true);
342-
dst[i] = _replacement_char;
343-
} else {
344-
dst[i] = c;
345-
}
335+
for (; p_cstr < end; ++p_cstr, ++dst) {
336+
// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
337+
*dst = static_cast<uint8_t>(*p_cstr);
346338
}
339+
*dst = 0;
347340
}
348341

349342
void String::copy_from(const char *p_cstr, const int p_clip_to) {
@@ -366,22 +359,14 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) {
366359

367360
resize(len + 1); // include 0
368361

362+
const char *end = p_cstr + len;
369363
char32_t *dst = ptrw();
370364

371-
for (int i = 0; i < len; i++) {
372-
#if CHAR_MIN == 0
373-
uint8_t c = p_cstr[i];
374-
#else
375-
uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]);
376-
#endif
377-
if (c == 0) {
378-
print_unicode_error("NUL character", true);
379-
dst[i] = _replacement_char;
380-
} else {
381-
dst[i] = c;
382-
}
365+
for (; p_cstr < end; ++p_cstr, ++dst) {
366+
// If char is int8_t, a set sign bit will be reinterpreted as 256 - val implicitly.
367+
*dst = static_cast<uint8_t>(*p_cstr);
383368
}
384-
dst[len] = 0;
369+
*dst = 0;
385370
}
386371

387372
void String::copy_from(const wchar_t *p_cstr) {
@@ -469,27 +454,25 @@ void String::copy_from(const char32_t *p_cstr, const int p_clip_to) {
469454
// p_length <= p_char strlen
470455
void String::copy_from_unchecked(const char32_t *p_char, const int p_length) {
471456
resize(p_length + 1);
457+
458+
const char32_t *end = p_char + p_length;
472459
char32_t *dst = ptrw();
473-
dst[p_length] = 0;
474460

475-
for (int i = 0; i < p_length; i++) {
476-
if (p_char[i] == 0) {
477-
print_unicode_error("NUL character", true);
478-
dst[i] = _replacement_char;
479-
continue;
480-
}
481-
if ((p_char[i] & 0xfffff800) == 0xd800) {
482-
print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char[i]));
483-
dst[i] = _replacement_char;
461+
for (; p_char < end; ++p_char, ++dst) {
462+
const char32_t chr = *p_char;
463+
if ((chr & 0xfffff800) == 0xd800) {
464+
print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)chr));
465+
*dst = _replacement_char;
484466
continue;
485467
}
486-
if (p_char[i] > 0x10ffff) {
487-
print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char[i]));
488-
dst[i] = _replacement_char;
468+
if (chr > 0x10ffff) {
469+
print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)chr));
470+
*dst = _replacement_char;
489471
continue;
490472
}
491-
dst[i] = p_char[i];
473+
*dst = chr;
492474
}
475+
*dst = 0;
493476
}
494477

495478
void String::operator=(const char *p_str) {

0 commit comments

Comments
 (0)