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