]> pd.if.org Git - pdclib.old/blob - opt/basecodecs/_PDCLIB_ascii.c
e07e2ba217a341c5199d798f3979d6394ea11d49
[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 *restrict   p_outbuf,
14     size_t                   *restrict   p_outsz,
15     const char     *restrict *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 *restrict  p_outbuf,
39     size_t                   *restrict  p_outsz,
40     const char32_t *restrict *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 struct _PDCLIB_charcodec _PDCLIB_ascii_codec = {
63     .__mbstoc32s = asciitoc32,
64     .__c32stombs = c32toascii,
65     .__mb_max    = 1,
66 };
67
68 #endif
69
70 #ifdef TEST
71 #include <_PDCLIB_test.h>
72
73 int main( void )
74 {
75 #ifndef REGTEST
76     // Valid conversion & back
77
78     char32_t c32out[5];
79
80     char32_t *c32ptr = &c32out[0];
81     size_t    c32rem = 5;
82     char     *chrptr = (char*) &abcde[0];
83     size_t    chrrem = 5;
84     mbstate_t mbs = { 0 };
85
86     TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == true);
87     TESTCASE(c32rem == 0);
88     TESTCASE(chrrem == 0);
89     TESTCASE(c32ptr == &c32out[5]);
90     TESTCASE(chrptr == &abcde[5]);
91     TESTCASE(c32out[0] == 'a' && c32out[1] == 'b' && c32out[2] == 'c' && \
92              c32out[3] == 'd' && c32out[4] == 'e');
93
94     char chrout[5];
95     c32ptr = &c32out[0];
96     c32rem = 5;
97     chrptr = &chrout[0];
98     chrrem = 5;
99
100
101     TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == true);
102     TESTCASE(c32rem == 0);
103     TESTCASE(chrrem == 0);
104     TESTCASE(c32ptr == &c32out[5]);
105     TESTCASE(chrptr == &chrout[5]);
106     TESTCASE(memcmp(chrout, abcde, 5) == 0);
107
108     // Invalid conversions
109     char badascii = '\xC0';
110     c32ptr = &c32out[0];
111     c32rem = 5;
112     chrptr = &badascii;
113     chrrem = 1;
114     TESTCASE(asciitoc32(&c32ptr, &c32rem, &chrptr, &chrrem, &mbs) == false);
115     TESTCASE(c32ptr == &c32out[0]);
116     TESTCASE(c32rem == 5);
117     TESTCASE(chrptr == &badascii);
118     TESTCASE(chrrem == 1);
119
120     char32_t baduni = 0xC0;
121     c32ptr = &baduni;
122     c32rem = 1;
123     chrptr = &chrout[0];
124     chrrem = 5;
125     TESTCASE(c32toascii(&chrptr, &chrrem, &c32ptr, &c32rem, &mbs) == false);
126     TESTCASE(c32ptr == &baduni);
127     TESTCASE(c32rem == 1);
128     TESTCASE(chrptr == &chrout[0]);
129     TESTCASE(chrrem == 5);
130 #endif
131     return TEST_RESULTS;
132 }
133
134 #endif
135