1#include <string.h>
 2
 3#include "include/pw.h"
 4#include "src/types/string/string_internal.h"
 5
 6
 7void _pw_strcopy_n_n(uint8_t* dest_ptr, uint8_t* src_start_ptr, uint8_t* src_end_ptr)
 8{
 9    memcpy(dest_ptr, src_start_ptr, src_end_ptr - src_start_ptr);
10}
11
12#define COPY(DEST_CHAR_TYPE, DEST_CHAR_SIZE, SRC_CHAR_TYPE, SRC_CHAR_SIZE)  \
13    void _pw_strcopy_##DEST_CHAR_SIZE##_##SRC_CHAR_SIZE(uint8_t* dest_ptr, uint8_t* src_start_ptr, uint8_t* src_end_ptr)  \
14    {  \
15        while (src_start_ptr < src_end_ptr) {  \
16            *((DEST_CHAR_TYPE*) dest_ptr) = *((SRC_CHAR_TYPE*) src_start_ptr);  \
17            dest_ptr += DEST_CHAR_SIZE;  \
18            src_start_ptr += SRC_CHAR_SIZE;  \
19        }  \
20    }
21COPY(uint8_t,  1, uint16_t, 2)
22COPY(uint8_t,  1, char32_t, 4)
23COPY(uint16_t, 2, uint8_t,  1)
24COPY(uint16_t, 2, char32_t, 4)
25COPY(char32_t, 4, uint8_t,  1)
26COPY(char32_t, 4, uint16_t, 2)
27
28#define COPY_N_3(DEST_CHAR_TYPE, DEST_CHAR_SIZE)  \
29    void _pw_strcopy_##DEST_CHAR_SIZE##_3(uint8_t* dest_ptr, uint8_t* src_start_ptr, uint8_t* src_end_ptr)  \
30    {  \
31        while (src_start_ptr < src_end_ptr) {  \
32            char32_t c = *src_start_ptr++;  \
33            c |= (*src_start_ptr++) << 8;  \
34            c |= (*src_start_ptr++) << 16;  \
35            *((DEST_CHAR_TYPE*) dest_ptr) = c;  \
36            dest_ptr += DEST_CHAR_SIZE;  \
37        }  \
38    }
39COPY_N_3(uint8_t,  1)
40COPY_N_3(uint16_t, 2)
41COPY_N_3(char32_t, 4)
42
43#define COPY_3_N(SRC_CHAR_TYPE, SRC_CHAR_SIZE)  \
44    void _pw_strcopy_3_##SRC_CHAR_SIZE(uint8_t* dest_ptr, uint8_t* src_start_ptr, uint8_t* src_end_ptr)  \
45    {  \
46        while (src_start_ptr < src_end_ptr) {  \
47            char32_t c = *((SRC_CHAR_TYPE*) src_start_ptr);  \
48            *dest_ptr++ = (uint8_t) c; c >>= 8;  \
49            *dest_ptr++ = (uint8_t) c; c >>= 8;  \
50            *dest_ptr++ = (uint8_t) c;  \
51            src_start_ptr += SRC_CHAR_SIZE;  \
52        }  \
53    }
54COPY_3_N(uint8_t,  1)
55COPY_3_N(uint16_t, 2)
56COPY_3_N(char32_t, 4)
57
58
59StrCopy _pw_strcopy_variants[5][5] = {
60    {
61        nullptr,
62        nullptr,
63        nullptr,
64        nullptr,
65        nullptr
66    },
67    {
68        nullptr,
69        _pw_strcopy_n_n,
70        _pw_strcopy_1_2,
71        _pw_strcopy_1_3,
72        _pw_strcopy_1_4
73    },
74    {
75        nullptr,
76        _pw_strcopy_2_1,
77        _pw_strcopy_n_n,
78        _pw_strcopy_2_3,
79        _pw_strcopy_2_4
80    },
81    {
82        nullptr,
83        _pw_strcopy_3_1,
84        _pw_strcopy_3_2,
85        _pw_strcopy_n_n,
86        _pw_strcopy_3_4
87    },
88    {
89        nullptr,
90        _pw_strcopy_4_1,
91        _pw_strcopy_4_2,
92        _pw_strcopy_4_3,
93        _pw_strcopy_n_n
94    }
95};