1#include "include/pw.h"
2#include "src/types/string/string_internal.h"
3
4static bool is_space_1(uint8_t* start_ptr, uint8_t* end_ptr)
5{
6 while (start_ptr < end_ptr) {
7 uint8_t c = *start_ptr++;
8 if (!isspace(c)) {
9 return false;
10 }
11 }
12 return true;
13}
14
15#define IS_SPACE(CHAR_TYPE, CHAR_SIZE) \
16 static bool is_space_##CHAR_SIZE(uint8_t* start_ptr, uint8_t* end_ptr) \
17 { \
18 while (start_ptr < end_ptr) { \
19 char32_t c = *(CHAR_TYPE*) start_ptr; \
20 if (!pw_isspace(c)) { \
21 return false; \
22 } \
23 start_ptr += CHAR_SIZE; \
24 } \
25 return true; \
26 }
27IS_SPACE(uint16_t, 2)
28IS_SPACE(char32_t, 4)
29
30static bool is_space_3(uint8_t* start_ptr, uint8_t* end_ptr)
31{
32 while (start_ptr < end_ptr) {
33 char32_t c = *start_ptr++;
34 c |= (*start_ptr++) << 8;
35 c |= (*start_ptr++) << 16;
36 if (!pw_isspace(c)) {
37 return false;
38 }
39 }
40 return true;
41}
42
43typedef bool (*StrIsSpace)(uint8_t* start_ptr, uint8_t* end_ptr);
44
45static StrIsSpace is_space_variants[5] = {
46 nullptr,
47 is_space_1,
48 is_space_2,
49 is_space_3,
50 is_space_4
51};
52
53bool pw_string_isspace(PwValuePtr str)
54{
55 pw_assert_string(str);
56 uint8_t* end_ptr;
57 uint8_t* start_ptr = _pw_string_start_end(str, &end_ptr);
58 if (_pw_unlikely(start_ptr == end_ptr)) {
59 return false;
60 }
61 StrIsSpace fn_is_space = is_space_variants[str->char_size];
62 return fn_is_space(start_ptr, end_ptr);
63}