Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | #include "gate/strings.hpp" | ||
30 | #include "gate/exceptions.hpp" | ||
31 | #include "gate/memalloc.hpp" | ||
32 | |||
33 | namespace gate | ||
34 | { | ||
35 | |||
36 | ✗ | int Char::toLower(int chr) | |
37 | { | ||
38 | ✗ | return gate_char_lowercase(chr); | |
39 | } | ||
40 | ✗ | int Char::toUpper(int chr) | |
41 | { | ||
42 | ✗ | return gate_char_uppercase(chr); | |
43 | } | ||
44 | ✗ | bool_t Char::isDigit(int chr) | |
45 | { | ||
46 | ✗ | return gate_char_is_digit(chr); | |
47 | } | ||
48 | ✗ | bool_t Char::isWhitespace(int chr) | |
49 | { | ||
50 | ✗ | return gate_char_is_whitespace(chr); | |
51 | } | ||
52 | |||
53 | ✗ | size_t Char::readUtf8(char_8_t const* utf8text, size_t length, char_32_t& chr32) | |
54 | { | ||
55 | ✗ | return gate_char_read_utf8(utf8text, length, &chr32); | |
56 | } | ||
57 | ✗ | size_t Char::readUtf16(char_16_t const* utf16text, size_t length, char_32_t& chr32) | |
58 | { | ||
59 | ✗ | return gate_char_read_utf16(utf16text, length, &chr32); | |
60 | } | ||
61 | ✗ | size_t Char::readUtf32(char_32_t const* utf32text, size_t length, char_32_t& chr32) | |
62 | { | ||
63 | ✗ | return gate_char_read_utf32(utf32text, length, &chr32); | |
64 | } | ||
65 | |||
66 | ✗ | size_t Char::writeUtf8(char_32_t chr32, char_8_t* utf8text, size_t length) | |
67 | { | ||
68 | ✗ | return gate_char_write_utf8(chr32, utf8text, length); | |
69 | } | ||
70 | ✗ | size_t Char::writeUtf16(char_32_t chr32, char_16_t* utf16text, size_t length) | |
71 | { | ||
72 | ✗ | return gate_char_write_utf16(chr32, utf16text, length); | |
73 | } | ||
74 | ✗ | size_t Char::writeUtf32(char_32_t chr32, char_32_t* utf32text, size_t length) | |
75 | { | ||
76 | ✗ | return gate_char_write_utf32(chr32, utf32text, length); | |
77 | } | ||
78 | |||
79 | |||
80 | size_t const String::npos = GATE_STR_NPOS; | ||
81 | size_t const String::NPOS = GATE_STR_NPOS; | ||
82 | |||
83 | 1885 | String::String() noexcept | |
84 | { | ||
85 | 1885 | gate_string_create_empty(&this->impl); | |
86 | 1885 | } | |
87 | 477 | String::String(char_8_t const* str) | |
88 | { | ||
89 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 477 times.
|
477 | if (NULL == gate_string_create(&this->impl, str, gate_str_length(str))) |
90 | { | ||
91 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
92 | } | ||
93 | 477 | } | |
94 | 107 | String::String(char_8_t const* str, size_t len) | |
95 | { | ||
96 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 107 times.
|
107 | if (NULL == gate_string_create(&this->impl, str, len)) |
97 | { | ||
98 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
99 | } | ||
100 | 107 | } | |
101 | 390 | String::String(String const& src) noexcept | |
102 | { | ||
103 | 390 | gate_string_duplicate(&this->impl, &src.impl); | |
104 | 390 | } | |
105 | 7 | String::String(gate_string_t const& src) | |
106 | { | ||
107 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
7 | if (NULL == gate_string_clone(&this->impl, &src)) |
108 | { | ||
109 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
110 | } | ||
111 | 7 | } | |
112 | ✗ | String::String(StringBuilder& strbuilder) | |
113 | { | ||
114 | ✗ | gate_string_create_empty(&this->impl); | |
115 | ✗ | String tmp = strbuilder.toString(); | |
116 | ✗ | this->swap(tmp); | |
117 | ✗ | } | |
118 | |||
119 | |||
120 | |||
121 | 8 | String& String::operator=(String const& src) noexcept | |
122 | { | ||
123 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (this != &src) |
124 | { | ||
125 | 16 | String that(src); | |
126 | 8 | this->swap(that); | |
127 | } | ||
128 | 8 | return *this; | |
129 | } | ||
130 | |||
131 | 5734 | String::~String() noexcept | |
132 | { | ||
133 | 2867 | gate_string_release(&this->impl); | |
134 | 2867 | } | |
135 | |||
136 | #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS) | ||
137 | 1 | String::String(String&& src) noexcept | |
138 | { | ||
139 | 1 | gate_string_create_empty(&this->impl); | |
140 | 1 | gate::swapRefs(this->impl, src.impl); | |
141 | 1 | } | |
142 | |||
143 | 234 | String& String::operator=(String&& src) noexcept | |
144 | { | ||
145 | 234 | gate::swapRefs(this->impl, src.impl); | |
146 | 234 | return *this; | |
147 | } | ||
148 | #endif | ||
149 | |||
150 | 364 | String String::createStatic(char_8_t const* str) noexcept | |
151 | { | ||
152 | 364 | String tmp; | |
153 | 364 | gate_string_create_static(&tmp.impl, str); | |
154 | 364 | return tmp; | |
155 | } | ||
156 | 87 | String String::createStatic(char_8_t const* str, size_t len) noexcept | |
157 | { | ||
158 | 87 | String tmp; | |
159 | 87 | gate_string_create_static_len(&tmp.impl, str, len); | |
160 | 87 | return tmp; | |
161 | } | ||
162 | 188 | String String::createFrom(gate_string_t& str) noexcept | |
163 | { | ||
164 | 188 | String ret; | |
165 | 188 | ret.impl = str; | |
166 | 188 | gate_string_create_empty(&str); | |
167 | 188 | return ret; | |
168 | } | ||
169 | ✗ | String createFilled(size_t count, char_8_t content) | |
170 | { | ||
171 | ✗ | StringBuilder builder(count); | |
172 | ✗ | builder.appendChars(count, content); | |
173 | ✗ | return builder.toString(); | |
174 | } | ||
175 | |||
176 | |||
177 | ✗ | String String::createIntNum(int64_t num) | |
178 | { | ||
179 | char buffer[64]; | ||
180 | ✗ | size_t len = gate_str_print_int64(buffer, sizeof(buffer), num); | |
181 | ✗ | return String(buffer, len); | |
182 | } | ||
183 | ✗ | String String::createRealNum(real64_t num, int32_t decimalCount) | |
184 | { | ||
185 | char buffer[64]; | ||
186 | ✗ | size_t len = gate_str_print_real(buffer, sizeof(buffer), num, 0, decimalCount, 0); | |
187 | ✗ | return String(buffer, len); | |
188 | } | ||
189 | |||
190 | 57 | void String::assign(gate_string_t& dst, gate_string_t const& src) | |
191 | { | ||
192 | 57 | gate_string_t tmp = GATE_STRING_INIT_EMPTY; | |
193 |
2/4✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 57 times.
|
57 | if (NULL == gate_string_clone(&tmp, &src)) |
194 | { | ||
195 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
196 | } | ||
197 |
1/2✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
|
57 | gate_string_release(&dst); |
198 | 57 | dst = tmp; | |
199 | 57 | } | |
200 | |||
201 | 5 | void String::assign(gate_string_t& dst, String const& src) | |
202 | { | ||
203 | 5 | String::assign(dst, *src.c_impl()); | |
204 | 5 | } | |
205 | |||
206 | |||
207 | |||
208 | 12 | void String::swap(String& that) noexcept | |
209 | { | ||
210 | 12 | gate::swapRefsNoExcept(this->impl, that.impl); | |
211 | 12 | } | |
212 | 5 | void String::swap(gate_string_t& that) noexcept | |
213 | { | ||
214 | 5 | gate::swapRefsNoExcept(this->impl, that); | |
215 | 5 | } | |
216 | ✗ | void String::swap(gate_string_t& a, gate_string_t& b) noexcept | |
217 | { | ||
218 | ✗ | gate::swapRefsNoExcept(a, b); | |
219 | ✗ | } | |
220 | |||
221 | |||
222 | |||
223 | 1178 | size_t String::size() const noexcept | |
224 | { | ||
225 | 1178 | return gate_string_length(&this->impl); | |
226 | } | ||
227 | 2107 | size_t String::length() const noexcept | |
228 | { | ||
229 | 2107 | return gate_string_length(&this->impl); | |
230 | } | ||
231 | 150 | bool String::empty() const noexcept | |
232 | { | ||
233 | 150 | return this->size() == 0; | |
234 | } | ||
235 | 1119 | char_8_t const* String::c_str() const noexcept | |
236 | { | ||
237 | 1119 | return gate_string_ptr(&this->impl, 0); | |
238 | } | ||
239 | |||
240 | ✗ | char_8_t const& String::at(size_t index) const noexcept | |
241 | { | ||
242 | ✗ | return *gate_string_ptr(&this->impl, index); | |
243 | } | ||
244 | |||
245 | 572 | gate_string_t const* String::c_impl() const noexcept | |
246 | { | ||
247 | 572 | return &this->impl; | |
248 | } | ||
249 | |||
250 | ✗ | String::const_iterator String::cbegin() const noexcept | |
251 | { | ||
252 | ✗ | return gate_string_ptr(&this->impl, 0); | |
253 | } | ||
254 | ✗ | String::const_iterator String::cend() const noexcept | |
255 | { | ||
256 | ✗ | return gate_string_ptr(&this->impl, 0) + gate_string_length(&this->impl); | |
257 | } | ||
258 | |||
259 | ✗ | String::const_iterator String::begin() const noexcept | |
260 | { | ||
261 | ✗ | return this->cbegin(); | |
262 | } | ||
263 | ✗ | String::const_iterator String::end() const noexcept | |
264 | { | ||
265 | ✗ | return this->cend(); | |
266 | } | ||
267 | |||
268 | ✗ | size_t String::positionOf(String const& text, size_t startAt) const noexcept | |
269 | { | ||
270 | ✗ | return gate_string_pos(&this->impl, text.c_impl(), startAt); | |
271 | } | ||
272 | ✗ | size_t String::positionOf(char const& chr, size_t startAt) const noexcept | |
273 | { | ||
274 | ✗ | return gate_string_char_pos(&this->impl, chr, startAt); | |
275 | } | ||
276 | |||
277 | ✗ | size_t String::positionOfLast(String const& text) const noexcept | |
278 | { | ||
279 | ✗ | return gate_string_pos_last(&this->impl, text.c_impl()); | |
280 | } | ||
281 | ✗ | size_t String::positionOfLast(char const& chr) const noexcept | |
282 | { | ||
283 | ✗ | return gate_string_char_pos_last(&this->impl, chr); | |
284 | } | ||
285 | |||
286 | |||
287 | ✗ | size_t String::findFirstOf(String const& text, size_t startAt) const noexcept | |
288 | { | ||
289 | ✗ | return gate_string_find_first_of(&this->impl, text.c_impl(), startAt); | |
290 | } | ||
291 | ✗ | size_t String::findFirstNotOf(String const& text, size_t startAt) const noexcept | |
292 | { | ||
293 | ✗ | return gate_string_find_first_not_of(&this->impl, text.c_impl(), startAt); | |
294 | } | ||
295 | ✗ | size_t String::findLastOf(String const& text) const noexcept | |
296 | { | ||
297 | ✗ | return gate_string_find_last_of(&this->impl, text.c_impl()); | |
298 | } | ||
299 | ✗ | size_t String::findLastNotOf(String const& text) const noexcept | |
300 | { | ||
301 | ✗ | return gate_string_find_last_not_of(&this->impl, text.c_impl()); | |
302 | } | ||
303 | |||
304 | ✗ | String String::substr(size_t offset, size_t len) const | |
305 | { | ||
306 | ✗ | String ret; | |
307 | ✗ | gate_string_substr(&ret.impl, &this->impl, offset, len); | |
308 | ✗ | return ret; | |
309 | } | ||
310 | ✗ | String String::left(size_t len) const | |
311 | { | ||
312 | ✗ | return this->substr(0, len); | |
313 | } | ||
314 | ✗ | String String::right(size_t len) const | |
315 | { | ||
316 | ✗ | size_t sz = this->size(); | |
317 | ✗ | if (len >= sz) | |
318 | { | ||
319 | ✗ | return *this; | |
320 | } | ||
321 | else | ||
322 | { | ||
323 | ✗ | return this->substr(sz - len, len); | |
324 | } | ||
325 | } | ||
326 | ✗ | String String::readLine(String& tail) const | |
327 | { | ||
328 | gate_string_t str_line; | ||
329 | gate_string_t str_tail; | ||
330 | ✗ | if (NULL == gate_string_read_line(&str_line, &this->impl, &str_tail)) | |
331 | { | ||
332 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
333 | } | ||
334 | ✗ | tail = String::duplicate(str_tail); | |
335 | ✗ | gate_string_release(&str_tail); | |
336 | |||
337 | ✗ | String ret = String::duplicate(str_line); | |
338 | ✗ | gate_string_release(&str_line); | |
339 | ✗ | return ret; | |
340 | } | ||
341 | ✗ | String String::readLine() | |
342 | { | ||
343 | ✗ | String tail; | |
344 | ✗ | String ret = this->readLine(tail); | |
345 | ✗ | this->swap(tail); | |
346 | ✗ | return ret; | |
347 | } | ||
348 | ✗ | String String::toLower() const | |
349 | { | ||
350 | ✗ | gate_string_t dst = GATE_STRING_INIT_EMPTY; | |
351 | ✗ | if (NULL == gate_string_to_lower(&dst, &this->impl)) | |
352 | { | ||
353 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
354 | } | ||
355 | ✗ | return String::createFrom(dst); | |
356 | } | ||
357 | ✗ | String String::toUpper() const | |
358 | { | ||
359 | ✗ | gate_string_t dst = GATE_STRING_INIT_EMPTY; | |
360 | ✗ | if (NULL == gate_string_to_upper(&dst, &this->impl)) | |
361 | { | ||
362 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
363 | } | ||
364 | ✗ | return String::createFrom(dst); | |
365 | } | ||
366 | |||
367 | |||
368 | |||
369 | ✗ | String String::ltrim() const | |
370 | { | ||
371 | ✗ | String ret; | |
372 | ✗ | gate_string_ltrim(&ret.impl, &this->impl); | |
373 | ✗ | return ret; | |
374 | } | ||
375 | ✗ | String String::rtrim() const | |
376 | { | ||
377 | ✗ | String ret; | |
378 | ✗ | gate_string_rtrim(&ret.impl, &this->impl); | |
379 | ✗ | return ret; | |
380 | } | ||
381 | ✗ | String String::trim() const | |
382 | { | ||
383 | ✗ | String ret; | |
384 | ✗ | gate_string_trim(&ret.impl, &this->impl); | |
385 | ✗ | return ret; | |
386 | } | ||
387 | |||
388 | 7 | String String::copy(gate_string_t const& src) | |
389 | { | ||
390 | 7 | String ret; | |
391 |
2/4✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
|
7 | if (NULL == gate_string_create_copy(&ret.impl, &src)) |
392 | { | ||
393 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
394 | } | ||
395 | 7 | return ret; | |
396 | } | ||
397 | 11 | String String::clone(gate_string_t const& src) | |
398 | { | ||
399 | 11 | String ret; | |
400 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
|
11 | if (NULL == gate_string_clone(&ret.impl, &src)) |
401 | { | ||
402 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
403 | } | ||
404 | 11 | return ret; | |
405 | |||
406 | } | ||
407 | 335 | String String::duplicate(gate_string_t const& src) noexcept | |
408 | { | ||
409 | 335 | String ret; | |
410 | 335 | gate_string_duplicate(&ret.impl, &src); | |
411 | 335 | return ret; | |
412 | } | ||
413 | |||
414 | |||
415 | ✗ | String String::copy() const | |
416 | { | ||
417 | ✗ | return String::copy(this->impl); | |
418 | } | ||
419 | 10 | String String::clone() const | |
420 | { | ||
421 | 10 | return String::clone(this->impl); | |
422 | } | ||
423 | ✗ | String String::duplicate() const noexcept | |
424 | { | ||
425 | ✗ | return String::duplicate(this->impl); | |
426 | } | ||
427 | |||
428 | |||
429 | |||
430 | 14 | size_t String::copyTo(char_8_t* buffer, size_t capacity) const | |
431 | { | ||
432 |
2/4✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
|
14 | if ((buffer == NULL) || (capacity == 0)) |
433 | { | ||
434 | ✗ | return 0; | |
435 | } | ||
436 | 14 | size_t sz = this->size(); | |
437 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
|
14 | if (capacity <= sz) |
438 | { | ||
439 | ✗ | sz = capacity - 1; | |
440 | } | ||
441 | 14 | gate_mem_copy(buffer, this->impl.str, sz); | |
442 | 14 | buffer[sz] = 0; | |
443 | 14 | return sz; | |
444 | } | ||
445 | |||
446 | |||
447 | 1377 | int String::compare(String const& str) const noexcept | |
448 | { | ||
449 | 1377 | return gate_str_compare(this->impl.str, this->impl.length, str.impl.str, str.impl.length); | |
450 | } | ||
451 | ✗ | int String::compareIC(String const& str) const noexcept | |
452 | { | ||
453 | ✗ | return gate_str_compare_ic(this->impl.str, this->impl.length, str.impl.str, str.impl.length); | |
454 | } | ||
455 | ✗ | bool_t String::startsWith(String const& str) const noexcept | |
456 | { | ||
457 | ✗ | return gate_string_starts_with(&this->impl, &str.impl); | |
458 | } | ||
459 | ✗ | bool_t String::startsWith(char const& chr) const noexcept | |
460 | { | ||
461 | ✗ | return gate_string_starts_with_char(&this->impl, chr); | |
462 | } | ||
463 | ✗ | bool_t String::startsWithIC(String const& str) const noexcept | |
464 | { | ||
465 | ✗ | if (this->impl.length < str.impl.length) | |
466 | { | ||
467 | ✗ | return false; | |
468 | } | ||
469 | else | ||
470 | { | ||
471 | ✗ | return 0 == gate_str_compare_ic(this->impl.str, str.impl.length, str.impl.str, str.impl.length); | |
472 | } | ||
473 | } | ||
474 | ✗ | bool_t String::endsWith(String const& str) const noexcept | |
475 | { | ||
476 | ✗ | return gate_string_ends_with(&this->impl, &str.impl); | |
477 | } | ||
478 | ✗ | bool_t String::endsWith(char const& chr) const noexcept | |
479 | { | ||
480 | ✗ | return gate_string_ends_with_char(&this->impl, chr); | |
481 | } | ||
482 | ✗ | bool_t String::endsWithIC(String const& str) const noexcept | |
483 | { | ||
484 | ✗ | if (this->impl.length < str.impl.length) | |
485 | { | ||
486 | ✗ | return false; | |
487 | } | ||
488 | else | ||
489 | { | ||
490 | ✗ | return 0 == gate_str_compare_ic(&this->impl.str[this->impl.length - str.impl.length], str.impl.length, str.impl.str, str.impl.length); | |
491 | } | ||
492 | } | ||
493 | ✗ | bool_t String::equals(String const& str) const noexcept | |
494 | { | ||
495 | ✗ | return gate_string_equals(&this->impl, &str.impl); | |
496 | } | ||
497 | ✗ | bool_t String::equalsIC(String const& str) const noexcept | |
498 | { | ||
499 | ✗ | return gate_string_equals_ic(&this->impl, &str.impl); | |
500 | } | ||
501 | ✗ | bool_t String::like(String const& pattern) const noexcept | |
502 | { | ||
503 | ✗ | return gate_string_like(&this->impl, &pattern.impl); | |
504 | } | ||
505 | ✗ | bool_t String::likeOneOf(String const& pattern, char_8_t separator) const noexcept | |
506 | { | ||
507 | ✗ | return gate_string_like_one_of(&this->impl, &pattern.impl, separator); | |
508 | } | ||
509 | |||
510 | 2 | size_t String::length(char const* str) noexcept | |
511 | { | ||
512 | 2 | return gate_str_length(str); | |
513 | } | ||
514 | |||
515 | ✗ | int String::compare(char_8_t const* str) const noexcept | |
516 | { | ||
517 | ✗ | return this->compare(String::createStatic(str)); | |
518 | } | ||
519 | ✗ | int String::compareIC(char_8_t const* str) const noexcept | |
520 | { | ||
521 | ✗ | return this->compareIC(String::createStatic(str)); | |
522 | } | ||
523 | ✗ | bool_t String::startsWith(char_8_t const* str) const noexcept | |
524 | { | ||
525 | ✗ | return this->startsWith(String::createStatic(str)); | |
526 | } | ||
527 | ✗ | bool_t String::startsWithIC(char_8_t const* str) const noexcept | |
528 | { | ||
529 | ✗ | return this->startsWithIC(String::createStatic(str)); | |
530 | } | ||
531 | ✗ | bool_t String::endsWith(char_8_t const* str) const noexcept | |
532 | { | ||
533 | ✗ | return this->endsWith(String::createStatic(str)); | |
534 | } | ||
535 | ✗ | bool_t String::endsWithIC(char_8_t const* str) const noexcept | |
536 | { | ||
537 | ✗ | return this->endsWithIC(String::createStatic(str)); | |
538 | } | ||
539 | ✗ | bool_t String::equals(char_8_t const* str) const noexcept | |
540 | { | ||
541 | ✗ | return this->equals(String::createStatic(str)); | |
542 | } | ||
543 | ✗ | bool_t String::equalsIC(char_8_t const* str) const noexcept | |
544 | { | ||
545 | ✗ | return this->equalsIC(String::createStatic(str)); | |
546 | } | ||
547 | |||
548 | ✗ | size_t String::parseNum(uint64_t& num) const noexcept | |
549 | { | ||
550 | ✗ | return gate_str_parse_uint64(this->impl.str, this->impl.length, &num); | |
551 | } | ||
552 | 1 | size_t String::parseNum(int64_t& num) const noexcept | |
553 | { | ||
554 | 1 | return gate_str_parse_int64(this->impl.str, this->impl.length, &num); | |
555 | } | ||
556 | 1 | size_t String::parseNum(real64_t& num) const noexcept | |
557 | { | ||
558 | 1 | return gate_str_parse_real(this->impl.str, this->impl.length, &num); | |
559 | } | ||
560 | ✗ | size_t String::parseNum(real32_t& num) const noexcept | |
561 | { | ||
562 | ✗ | real64_t r64 = 0.0; | |
563 | ✗ | size_t ret = this->parseNum(r64); | |
564 | ✗ | num = static_cast<real32_t>(r64); | |
565 | ✗ | return ret; | |
566 | } | ||
567 | |||
568 | 1 | size_t String::parseHex(uint64_t& num) const noexcept | |
569 | { | ||
570 | 1 | return gate_str_parse_hex_int(this->impl.str, this->impl.length, &num); | |
571 | } | ||
572 | |||
573 | ✗ | String String::parseHex() const noexcept | |
574 | { | ||
575 | ✗ | char const* ptr = this->c_str(); | |
576 | ✗ | size_t len = this->length(); | |
577 | ✗ | StringBuilder builder(len / 2 + 2); | |
578 | ✗ | while (len > 1) | |
579 | { | ||
580 | ✗ | gate_uint8_t b = 0; | |
581 | ✗ | if (!gate_str_parse_hex_byte(ptr, &b)) | |
582 | { | ||
583 | ✗ | break; | |
584 | } | ||
585 | ✗ | builder.appendChars(1, gate_char8_t(b)); | |
586 | ✗ | ptr += 2; | |
587 | ✗ | len -= 2; | |
588 | } | ||
589 | ✗ | return builder.toString(); | |
590 | } | ||
591 | |||
592 | 1 | int64_t String::parseInt() const noexcept | |
593 | { | ||
594 | 1 | int64_t ret = 0; | |
595 | 1 | this->parseNum(ret); | |
596 | 1 | return ret; | |
597 | } | ||
598 | |||
599 | 1 | real64_t String::parseReal() const noexcept | |
600 | { | ||
601 | 1 | real64_t ret = 0.0; | |
602 | 1 | this->parseNum(ret); | |
603 | 1 | return ret; | |
604 | } | ||
605 | |||
606 | ✗ | size_t String::parse(String const& find, size_t startAt, String* ptrHead, String* ptrTail, bool_t separatorAsTail) | |
607 | { | ||
608 | ✗ | gate_string_t head = GATE_STRING_INIT_EMPTY; | |
609 | ✗ | gate_string_t tail = GATE_STRING_INIT_EMPTY; | |
610 | |||
611 | ✗ | size_t ret = gate_string_parse(&this->impl, find.c_impl(), startAt, &head, &tail, separatorAsTail); | |
612 | ✗ | if (ptrHead) | |
613 | { | ||
614 | ✗ | *ptrHead = String::duplicate(head); | |
615 | } | ||
616 | ✗ | if (ptrTail) | |
617 | { | ||
618 | ✗ | *ptrTail = String::duplicate(tail); | |
619 | } | ||
620 | ✗ | gate_string_release(&tail); | |
621 | ✗ | gate_string_release(&head); | |
622 | ✗ | return ret; | |
623 | } | ||
624 | |||
625 | ✗ | String String::toHex(char_8_t const* str, size_t len, bool_t upperCase) | |
626 | { | ||
627 | ✗ | StringBuilder builder(len * 2); | |
628 | ✗ | builder.appendHex(str, len, upperCase); | |
629 | ✗ | return builder.toString(); | |
630 | } | ||
631 | |||
632 | ✗ | String String::toHex() const | |
633 | { | ||
634 | ✗ | return String::toHex(this->c_str(), this->length()); | |
635 | } | ||
636 | |||
637 | |||
638 | |||
639 | 325 | bool_t String::operator==(String const& src) const noexcept | |
640 | { | ||
641 | 325 | return this->compare(src) == 0; | |
642 | } | ||
643 | 1 | bool_t String::operator!=(String const& src) const noexcept | |
644 | { | ||
645 | 1 | return this->compare(src) != 0; | |
646 | } | ||
647 | 1048 | bool_t String::operator< (String const& src) const noexcept | |
648 | { | ||
649 | 1048 | return this->compare(src) < 0; | |
650 | } | ||
651 | 1 | bool_t String::operator> (String const& src) const noexcept | |
652 | { | ||
653 | 1 | return this->compare(src) > 0; | |
654 | } | ||
655 | 1 | bool_t String::operator<=(String const& src) const noexcept | |
656 | { | ||
657 | 1 | return this->compare(src) <= 0; | |
658 | } | ||
659 | 1 | bool_t String::operator>=(String const& src) const noexcept | |
660 | { | ||
661 | 1 | return this->compare(src) >= 0; | |
662 | } | ||
663 | ✗ | bool_t String::operator!() const noexcept | |
664 | { | ||
665 | ✗ | return this->empty(); | |
666 | } | ||
667 | ✗ | gate_string_t const& String::operator*() const noexcept | |
668 | { | ||
669 | ✗ | return this->impl; | |
670 | } | ||
671 | |||
672 | ✗ | char_8_t const& String::operator[](size_t index) const noexcept | |
673 | { | ||
674 | static char_8_t empty_dummy[2] = GATE_INIT_EMPTY; | ||
675 | ✗ | char_8_t const* ptr = gate_string_ptr(&this->impl, index); | |
676 | ✗ | if (ptr) | |
677 | { | ||
678 | ✗ | return *ptr; | |
679 | } | ||
680 | else | ||
681 | { | ||
682 | ✗ | return empty_dummy[0]; | |
683 | } | ||
684 | } | ||
685 | |||
686 | 2 | String operator+(String const& str1, String const& str2) | |
687 | { | ||
688 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | StringBuilder builder(str1.length() + str2.length() + 2); |
689 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | builder << str1 << str2; |
690 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | return builder.toString(); |
691 | } | ||
692 | 1 | String operator+(String const& str1, char const* str2) | |
693 | { | ||
694 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | StringBuilder builder(str1.length() + String::length(str2)); |
695 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | builder << str1 << str2; |
696 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | return builder.toString(); |
697 | } | ||
698 | 1 | String operator+(char const* str1, String const& str2) | |
699 | { | ||
700 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | StringBuilder builder(String::length(str1) + str2.length() + 2); |
701 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | builder << str1 << str2; |
702 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | return builder.toString(); |
703 | } | ||
704 | |||
705 | |||
706 | |||
707 | 151 | StaticString::StaticString(char_8_t const* str) noexcept | |
708 | 151 | : String(String::createStatic(str)) | |
709 | { | ||
710 | 151 | } | |
711 | ✗ | StaticString::StaticString(char_8_t const* str, size_t len) noexcept | |
712 | ✗ | : String(String::createStatic(str, len)) | |
713 | { | ||
714 | ✗ | } | |
715 | ✗ | StaticString::StaticString(StaticString const& src) noexcept | |
716 | ✗ | : String(src) | |
717 | { | ||
718 | ✗ | } | |
719 | ✗ | StaticString& StaticString::operator=(StaticString const& src) noexcept | |
720 | { | ||
721 | ✗ | String::operator=(src); | |
722 | ✗ | return *this; | |
723 | } | ||
724 | 151 | StaticString::~StaticString() noexcept | |
725 | { | ||
726 | 151 | } | |
727 | |||
728 | |||
729 | |||
730 | |||
731 | |||
732 | 8 | StringBuilder::StringBuilder(size_t capacity) | |
733 | { | ||
734 | 8 | gate_strbuilder_create(&this->impl, capacity); | |
735 | 8 | } | |
736 | ✗ | StringBuilder::StringBuilder(char* staticBuffer, size_t capacity, size_t alreadyUsed) | |
737 | { | ||
738 | ✗ | gate_strbuilder_create_static(&this->impl, staticBuffer, capacity, alreadyUsed); | |
739 | ✗ | } | |
740 | |||
741 | 16 | StringBuilder::~StringBuilder() | |
742 | { | ||
743 | 8 | gate_strbuilder_release(&this->impl); | |
744 | 8 | } | |
745 | |||
746 | ✗ | gate_strbuilder_t const* StringBuilder::c_impl() const noexcept | |
747 | { | ||
748 | ✗ | return &this->impl; | |
749 | } | ||
750 | 3 | gate_strbuilder_t* StringBuilder::c_impl() noexcept | |
751 | { | ||
752 | 3 | return &this->impl; | |
753 | } | ||
754 | |||
755 | ✗ | char_8_t const* StringBuilder::ptr(size_t pos) const noexcept | |
756 | { | ||
757 | ✗ | return gate_strbuilder_ptr(&this->impl, pos); | |
758 | } | ||
759 | ✗ | size_t StringBuilder::length() const noexcept | |
760 | { | ||
761 | ✗ | return gate_strbuilder_length(&this->impl); | |
762 | } | ||
763 | |||
764 | ✗ | size_t StringBuilder::resize(size_t sz) | |
765 | { | ||
766 | ✗ | return gate_strbuilder_resize(&this->impl, sz); | |
767 | } | ||
768 | 13 | size_t StringBuilder::append(String const& text) | |
769 | { | ||
770 | 13 | return gate_strbuilder_append_text(&this->impl, text.c_str(), text.length()); | |
771 | } | ||
772 | 1 | size_t StringBuilder::append(char const* ptr, size_t len) | |
773 | { | ||
774 | 1 | return gate_strbuilder_append_text(&this->impl, ptr, len); | |
775 | } | ||
776 | ✗ | size_t StringBuilder::append(char_16_t const* text16, size_t textlen) | |
777 | { | ||
778 | ✗ | return gate_strbuilder_append_text16(&this->impl, text16, textlen); | |
779 | } | ||
780 | ✗ | size_t StringBuilder::append(char_32_t const* text32, size_t textlen) | |
781 | { | ||
782 | ✗ | return gate_strbuilder_append_text32(&this->impl, text32, textlen); | |
783 | } | ||
784 | |||
785 | ✗ | size_t StringBuilder::append(int16_t const& num) | |
786 | { | ||
787 | ✗ | return gate_strbuilder_append_int16(&this->impl, num); | |
788 | } | ||
789 | ✗ | size_t StringBuilder::append(uint16_t const& num) | |
790 | { | ||
791 | ✗ | return gate_strbuilder_append_uint16(&this->impl, num); | |
792 | } | ||
793 | ✗ | size_t StringBuilder::append(int32_t const& num) | |
794 | { | ||
795 | ✗ | return gate_strbuilder_append_int32(&this->impl, num); | |
796 | } | ||
797 | ✗ | size_t StringBuilder::append(uint32_t const& num) | |
798 | { | ||
799 | ✗ | return gate_strbuilder_append_uint32(&this->impl, num); | |
800 | } | ||
801 | ✗ | size_t StringBuilder::append(int64_t const& num) | |
802 | { | ||
803 | ✗ | return gate_strbuilder_append_int64(&this->impl, num); | |
804 | } | ||
805 | 2 | size_t StringBuilder::append(uint64_t const& num) | |
806 | { | ||
807 | 2 | return gate_strbuilder_append_uint64(&this->impl, num); | |
808 | } | ||
809 | ✗ | size_t StringBuilder::append(real64_t const& num, unsigned intlen, unsigned decimallen, unsigned grouplen) | |
810 | { | ||
811 | ✗ | return gate_strbuilder_append_real(&this->impl, num, intlen, decimallen, grouplen); | |
812 | } | ||
813 | ✗ | size_t StringBuilder::appendHex(uint8_t const& num, bool_t upperCase) | |
814 | { | ||
815 | char buffer[8]; | ||
816 | ✗ | size_t buffer_used = gate_str_print_hex_byte(buffer, sizeof(buffer), num, upperCase); | |
817 | ✗ | return this->append(buffer, buffer_used); | |
818 | } | ||
819 | ✗ | size_t StringBuilder::appendHex(uint16_t const& num, bool_t upperCase) | |
820 | { | ||
821 | char buffer[8]; | ||
822 | ✗ | size_t buffer_used = gate_str_print_hex_num(buffer, sizeof(buffer), num, upperCase); | |
823 | ✗ | return this->append(buffer, buffer_used); | |
824 | } | ||
825 | ✗ | size_t StringBuilder::appendHex(uint32_t const& num, bool_t upperCase) | |
826 | { | ||
827 | char buffer[16]; | ||
828 | ✗ | size_t buffer_used = gate_str_print_hex_num(buffer, sizeof(buffer), num, upperCase); | |
829 | ✗ | return this->append(buffer, buffer_used); | |
830 | } | ||
831 | ✗ | size_t StringBuilder::appendHex(uint64_t const& num, bool_t upperCase) | |
832 | { | ||
833 | char buffer[24]; | ||
834 | ✗ | size_t buffer_used = gate_str_print_hex_num(buffer, sizeof(buffer), num, upperCase); | |
835 | ✗ | return this->append(buffer, buffer_used); | |
836 | } | ||
837 | ✗ | size_t StringBuilder::appendHex(char const* txt, size_t len, bool_t upperCase) | |
838 | { | ||
839 | ✗ | size_t ret = 0; | |
840 | ✗ | while (len-- > 0) | |
841 | { | ||
842 | ✗ | ret += this->appendHex(static_cast<uint8_t>(*txt), upperCase); | |
843 | ✗ | ++txt; | |
844 | } | ||
845 | ✗ | return ret; | |
846 | } | ||
847 | |||
848 | |||
849 | ✗ | size_t StringBuilder::appendChars(size_t count, gate_char8_t chr) | |
850 | { | ||
851 | ✗ | return gate_strbuilder_append_chars(&this->impl, count, chr); | |
852 | } | ||
853 | |||
854 | ✗ | size_t StringBuilder::appendNewLine() | |
855 | { | ||
856 | ✗ | return this->append(strings::NewLine); | |
857 | } | ||
858 | ✗ | size_t StringBuilder::discard(size_t charCount) | |
859 | { | ||
860 | ✗ | return gate_strbuilder_discard(&this->impl, charCount); | |
861 | } | ||
862 | ✗ | size_t StringBuilder::discardBack(size_t charCount) | |
863 | { | ||
864 | ✗ | return gate_strbuilder_discard_back(&this->impl, charCount); | |
865 | } | ||
866 | 8 | String StringBuilder::toString() | |
867 | { | ||
868 | gate_string_t tmp; | ||
869 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
|
8 | if (NULL == gate_strbuilder_to_string(&this->impl, &tmp)) |
870 | { | ||
871 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
872 | } | ||
873 | 8 | String ret = String::duplicate(tmp); | |
874 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | gate_string_release(&tmp); |
875 | 16 | return ret; | |
876 | } | ||
877 | ✗ | String StringBuilder::copyString() const | |
878 | { | ||
879 | gate_string_t tmp; | ||
880 | ✗ | if (NULL == gate_strbuilder_copy_to_string(&this->impl, &tmp)) | |
881 | { | ||
882 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
883 | } | ||
884 | ✗ | String ret = String::duplicate(tmp); | |
885 | ✗ | gate_string_release(&tmp); | |
886 | ✗ | return ret; | |
887 | } | ||
888 | |||
889 | ✗ | String StringBuilder::getView() const | |
890 | { | ||
891 | return String::createStatic( | ||
892 | gate_strbuilder_ptr(&this->impl, 0), | ||
893 | gate_strbuilder_length(&this->impl) | ||
894 | ✗ | ); | |
895 | } | ||
896 | |||
897 | |||
898 | 8 | StringBuilder& StringBuilder::operator<<(String const& text) { this->append(text); return *this; } | |
899 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
5 | StringBuilder& StringBuilder::operator<<(char const* text) { this->append(String(text)); return *this; } |
900 | ✗ | StringBuilder& StringBuilder::operator<<(int16_t const& num) { this->append(num); return *this; } | |
901 | ✗ | StringBuilder& StringBuilder::operator<<(uint16_t const& num) { this->append(num); return *this; } | |
902 | ✗ | StringBuilder& StringBuilder::operator<<(int32_t const& num) { this->append(num); return *this; } | |
903 | ✗ | StringBuilder& StringBuilder::operator<<(uint32_t const& num) { this->append(num); return *this; } | |
904 | ✗ | StringBuilder& StringBuilder::operator<<(int64_t const& num) { this->append(num); return *this; } | |
905 | 2 | StringBuilder& StringBuilder::operator<<(uint64_t const& num) { this->append(num); return *this; } | |
906 | ✗ | StringBuilder& StringBuilder::operator<<(real64_t const& num) { this->append(num); return *this; } | |
907 | |||
908 | static char_8_t const empty_dummy = '\0'; | ||
909 | ✗ | char_8_t const& StringBuilder::operator[](size_t index) const | |
910 | { | ||
911 | ✗ | gate_char8_t const* ptr = gate_strbuilder_ptr(&this->impl, index); | |
912 | ✗ | if (ptr) | |
913 | { | ||
914 | ✗ | return empty_dummy; | |
915 | } | ||
916 | else | ||
917 | { | ||
918 | ✗ | return *ptr; | |
919 | } | ||
920 | } | ||
921 | ✗ | char_8_t& StringBuilder::operator[](size_t index) | |
922 | { | ||
923 | ✗ | gate_char8_t const* ptr = gate_strbuilder_ptr(&this->impl, index); | |
924 | ✗ | return *const_cast<gate_char8_t*>(ptr); | |
925 | } | ||
926 | |||
927 | |||
928 | 1 | CstrBuffer::CstrBuffer(char const* ptr, size_t length, bool_t copyNeeded) | |
929 | { | ||
930 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (NULL == gate_cstrbuffer_create(&this->impl, ptr, length, copyNeeded)) |
931 | { | ||
932 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
933 | } | ||
934 | |||
935 | 1 | } | |
936 | 1 | CstrBuffer::CstrBuffer(String const& str, bool_t copyNeeded) | |
937 | { | ||
938 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | if (NULL == gate_cstrbuffer_create_string(&this->impl, str.c_impl(), copyNeeded)) |
939 | { | ||
940 | ✗ | GATEXX_RAISE_ERROR(results::OutOfMemory); | |
941 | } | ||
942 | 1 | } | |
943 | 4 | CstrBuffer::~CstrBuffer() noexcept | |
944 | { | ||
945 | 2 | gate_cstrbuffer_destroy(&this->impl); | |
946 | 2 | } | |
947 | |||
948 | 1 | char const* CstrBuffer::get() const | |
949 | { | ||
950 | 1 | return gate_cstrbuffer_get(&this->impl); | |
951 | } | ||
952 | 1 | size_t CstrBuffer::length() const | |
953 | { | ||
954 | 1 | return gate_cstrbuffer_length(&this->impl); | |
955 | } | ||
956 | |||
957 | |||
958 | namespace strings | ||
959 | { | ||
960 | String const NewLine = String::createStatic(GATE_STR_NEWLINE, GATE_STR_NEWLINE_LENGTH); | ||
961 | String const Cr = String::createStatic(GATE_STR_CR, 1); | ||
962 | String const Lf = String::createStatic(GATE_STR_LF, 1); | ||
963 | String const CrLf = String::createStatic(GATE_STR_CRLF, 2); | ||
964 | String const Empty = String(); | ||
965 | |||
966 | } // end of namespace strings | ||
967 | |||
968 | |||
969 | |||
970 | |||
971 | } // end of namespace gate | ||
972 |