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