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