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}