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