1#include "include/pw.h"
 2#include "src/types/string/string_internal.h"
 3
 4[[nodiscard]] bool _pw_string_do_lcut(PwValuePtr str, uint8_t* start_ptr, uint8_t* end_ptr, uint8_t* new_start_ptr)
 5{
 6    if (new_start_ptr == start_ptr) {
 7        return true;
 8    }
 9    if (new_start_ptr == end_ptr) {
10        pw_destroy(str);
11        *str = PwString("");
12        return true;
13    }
14    ptrdiff_t n = end_ptr - new_start_ptr;
15    uint8_t char_size = str->char_size;
16    unsigned new_length = n / char_size;
17    if (new_length == 0) {
18        pw_destroy(str);
19        *str = PwString("");
20        return true;
21    }
22    if (!_pw_string_need_copy_on_write(str)) {
23        // remove chars in-place
24        memmove(start_ptr, new_start_ptr, n);
25        _pw_string_set_length(str, new_length);
26        return true;
27    }
28    // make substring
29    PwValue substr = PW_NULL;
30    if (!_pw_make_empty_string(str->type_id, new_length, char_size, &substr)) {
31        return false;
32    }
33    _pw_string_set_length(&substr, new_length);
34    StrAppend fn_append = _pw_str_append_variants[char_size][char_size];
35    if (!fn_append(&substr, 0, new_start_ptr, end_ptr)) {
36        return false;
37    }
38    if (substr.embedded) {
39        // clean remainder for fast comparison to work
40        unsigned i = char_size * new_length;
41        while (i < sizeof(substr.str_1)) {
42            substr.str_1[i++] = 0;
43        }
44    }
45    pw_move(str, &substr);
46    return true;
47}