1#include "include/pw.h"
2#include "src/types/string/string_internal.h"
3
4
5[[nodiscard]] bool _pw_string_append_c32(PwValuePtr dest, char32_t c)
6{
7 pw_assert(pw_is_string(dest));
8 if (!_pw_expand_string(dest, 1, calc_char_size(c))) {
9 return false;
10 }
11 unsigned append_position;
12 uint8_t* dest_ptr = _pw_string_start_inc_length(dest, 1, &append_position);
13 uint8_t dest_char_size = dest->str_params.char_size;
14 uint8_t* append_ptr = dest_ptr + append_position * dest_char_size;
15
16 _pw_put_char(append_ptr, c, dest_char_size);
17 return true;
18}
19
20[[nodiscard]] bool _pw_string_append_ascii(PwValuePtr dest, char* start_ptr, char* end_ptr)
21{
22 pw_assert(pw_is_string(dest));
23
24 if (!end_ptr) {
25 end_ptr = start_ptr + strlen(start_ptr);
26 }
27 ptrdiff_t src_len = end_ptr - start_ptr;
28 if (src_len <= 0) {
29 return true;
30 }
31 if (src_len >= UINT_MAX) {
32 pw_set_status(PwStatus(PweStringTooLong));
33 return false;
34 }
35 if (!_pw_expand_string(dest, src_len, 1)) {
36 return false;
37 }
38 unsigned append_position = _pw_string_inc_length(dest, src_len);
39 StrPut fn_strput = _pw_strput_variants[dest->str_params.char_size][1];
40 return fn_strput(dest, append_position, (uint8_t*) start_ptr, (uint8_t*) end_ptr);
41}
42
43[[nodiscard]] bool _pw_string_append_utf8(PwValuePtr dest, char8_t* start_ptr, char8_t* end_ptr)
44{
45 pw_assert(pw_is_string(dest));
46
47 uint8_t src_char_size = 1;
48 ptrdiff_t src_len;
49 if (end_ptr) {
50 unsigned n = end_ptr - start_ptr;
51 src_len = utf8_strlen2_buf(start_ptr, &n, &src_char_size);
52 } else {
53 src_len = utf8_strlen3(start_ptr, &src_char_size, &end_ptr);
54 }
55 if (src_len <= 0) {
56 return true;
57 }
58 if (src_len >= UINT_MAX) {
59 pw_set_status(PwStatus(PweStringTooLong));
60 return false;
61 }
62 if (!_pw_expand_string(dest, src_len, src_char_size)) {
63 return false;
64 }
65 unsigned append_position = _pw_string_inc_length(dest, src_len);
66 StrPut fn_strput = _pw_strput_variants[dest->str_params.char_size][0];
67 return fn_strput(dest, append_position, (uint8_t*) start_ptr, (uint8_t*) end_ptr);
68}
69
70[[nodiscard]] bool _pw_string_append_utf32(PwValuePtr dest, char32_t* start_ptr, char32_t* end_ptr)
71{
72 pw_assert(pw_is_string(dest));
73
74 uint8_t src_char_size = 1;
75 if (!end_ptr) {
76 end_ptr = start_ptr + utf32_strlen2(start_ptr, &src_char_size);
77 }
78 ptrdiff_t src_len = end_ptr - start_ptr;
79 if (src_len <= 0) {
80 return true;
81 }
82 if (src_len >= UINT_MAX / 4) {
83 pw_set_status(PwStatus(PweStringTooLong));
84 return false;
85 }
86 if (!_pw_expand_string(dest, src_len, src_char_size)) {
87 return false;
88 }
89 unsigned append_position = _pw_string_inc_length(dest, src_len);
90 StrPut fn_strput = _pw_strput_variants[dest->str_params.char_size][4];
91 return fn_strput(dest, append_position, (uint8_t*) start_ptr, (uint8_t*) end_ptr);
92}
93
94[[nodiscard]] bool _pw_string_append(PwValuePtr dest, PwValuePtr src)
95{
96 pw_assert(pw_is_string(dest));
97 unsigned src_len = pw_strlen(src);
98 unsigned src_char_size = src->str_params.char_size;
99 if (!_pw_expand_string(dest, src_len, src_char_size)) {
100 return false;
101 }
102 unsigned append_position = _pw_string_inc_length(dest, src_len);
103 uint8_t* src_end_ptr;
104 uint8_t* src_start_ptr = _pw_string_start_end(src, &src_end_ptr);
105 StrPut fn_strput = _pw_strput_variants[dest->str_params.char_size][src_char_size];
106 return fn_strput(dest, append_position, (uint8_t*) src_start_ptr, (uint8_t*) src_end_ptr);
107}
108
109[[nodiscard]] bool pw_string_append_substring(PwValuePtr dest, PwValuePtr src, unsigned src_start_pos, unsigned src_end_pos)
110{
111 pw_assert(pw_is_string(dest));
112 unsigned src_len = pw_strlen(src);
113 if (src_end_pos > src_len) {
114 src_end_pos = src_len;
115 }
116 if (src_start_pos >= src_end_pos) {
117 return true;
118 }
119 src_len = src_end_pos - src_start_pos;
120
121 // expand with char_size unchanged because it is unknown for substring of src
122
123 if (!_pw_expand_string(dest, src_len, 1)) {
124 return false;
125 }
126 uint8_t src_char_size = src->str_params.char_size;
127 uint8_t* src_start_ptr = _pw_string_start(src);
128 uint8_t* src_end_ptr = src_start_ptr + src_end_pos * src_char_size;
129 src_start_ptr += src_start_pos * src_char_size;
130
131 unsigned append_position = _pw_string_inc_length(dest, src_len);
132 StrPut fn_strput = _pw_strput_variants[dest->str_params.char_size][src_char_size];
133 return fn_strput(dest, append_position, src_start_ptr, src_end_ptr);
134}