]> pd.if.org Git - pdclib/blob - opt/basecodecs/_PDCLIB_ascii.c
a705a7a75b43da5b18e429b681601b0ad7d144dc
[pdclib] / opt / basecodecs / _PDCLIB_ascii.c
1 /* ASCII codec
2
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6
7 #include <stdbool.h>
8 #ifndef REGTEST
9 #include <uchar.h>
10
11 static bool asciitoc32(
12     char32_t       **restrict   p_outbuf,
13     size_t          *restrict   p_outsz,
14     const char     **restrict   p_inbuf,
15     size_t          *restrict   p_insz,
16     mbstate_t       *restrict   p_ps
17 )
18 {
19     while(*p_outsz && *p_insz) {
20         unsigned char c = **p_inbuf;
21         if(c > 127)
22             return false;
23         
24         if(p_outbuf) {
25             **p_outbuf = c;
26             (*p_outbuf)++; 
27         }
28
29         (*p_inbuf)++;
30         (*p_insz)--; 
31         (*p_outsz)--;
32     }
33     return true;
34 }
35
36 static bool c32toascii(
37     char           **restrict  p_outbuf,
38     size_t          *restrict  p_outsz,
39     const char32_t **restrict  p_inbuf,
40     size_t          *restrict  p_insz,
41     mbstate_t       *restrict  p_ps
42 )
43 {
44     while(*p_outsz && *p_insz) {
45         char32_t c = **p_inbuf;
46         if(c > 127)
47             return false;
48
49         if(p_outbuf) {
50             **p_outbuf = c;
51             (*p_outbuf)++; 
52         }
53
54         (*p_inbuf)++;
55         (*p_insz)--; 
56         (*p_outsz)--;        
57     }
58     return true;
59 }
60
61 _PDCLIB_charcodec _PDCLIB_ascii_codec = {
62     .__mbstoc32s = asciitoc32,
63     .__c32stombs = c32toascii,
64 };
65
66 #endif
67
68 #ifdef TEST
69 #include <_PDCLIB_test.h>
70
71 int main( void )
72 {
73 #ifndef REGTEST
74     // Valid conversion & back
75
76     char32_t c32out[5];
77
78     char32_t *c32ptr = &c32out[0];
79     size_t    c32rem = 5;
80     char     *chrptr = (char*) &abcde[0];
81     size_t    chrrem = 5;
82     mbstate_t mbs = { 0 };
83
84     TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
85     TESTCASE(c32rem == 0);
86     TESTCASE(chrrem == 0);
87     TESTCASE(c32ptr == &c32out[5]);
88     TESTCASE(chrptr == &abcde[5]);
89     TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
90              c32out[3] == 'd' && c32out[4] == 'e');
91
92     char chrout[5];
93     c32ptr = &c32out[0];
94     c32rem = 5;
95     chrptr = &chrout[0];
96     chrrem = 5;
97
98
99     TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
100     TESTCASE(c32rem == 0);
101     TESTCASE(chrrem == 0);
102     TESTCASE(c32ptr == &c32out[5]);
103     TESTCASE(chrptr == &chrout[5]);
104     TESTCASE(memcmp(chrout, abcde, 5) == 0);
105
106     // Invalid conversions
107     char badascii = '\xC0';
108     c32ptr = &c32out[0];
109     c32rem = 5;
110     chrptr = &badascii;
111     chrrem = 1;
112     TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
113     TESTCASE(c32ptr == &c32out[0]);
114     TESTCASE(c32rem == 5);
115     TESTCASE(chrptr == &badascii);
116     TESTCASE(chrrem == 1);
117
118     char32_t baduni = 0xC0;
119     c32ptr = &baduni;
120     c32rem = 1;
121     chrptr = &chrout[0];
122     chrrem = 5;
123     TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
124     TESTCASE(c32ptr == &baduni);
125     TESTCASE(c32rem == 1);
126     TESTCASE(chrptr == &chrout[0]);
127     TESTCASE(chrrem == 5);
128 #endif
129     return TEST_RESULTS;
130 }
131
132 #endif
133