]> pd.if.org Git - pdclib.old/blob - internals/_PDCLIB_encoding.h
Move lconv definition for default locale inside of struct
[pdclib.old] / internals / _PDCLIB_encoding.h
1 /* Encoding support <_PDCLIB_encoding.h>
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 #ifndef __PDCLIB_ENCODING_H
8 #define __PDCLIB_ENCODING_H __PDCLIB_ENCODING_H
9 #include "_PDCLIB_int.h"
10
11 /* Must be cauued with bufsize >= 1, in != NULL, out != NULL, ps != NULL
12  *
13  * Converts a UTF-16 (char16_t) to a UCS4 (char32_t) value. Returns
14  *   1, 2   : Valid character (converted to UCS-4)
15  *   -1     : Encoding error
16  *   -2     : Partial character (only lead surrogate in buffer)
17  */
18 static inline int _PDCLIB_c16rtoc32(
19             _PDCLIB_char32_t    *_PDCLIB_restrict   out, 
20     const   _PDCLIB_char16_t    *_PDCLIB_restrict   in,
21             _PDCLIB_size_t                          bufsize,
22             _PDCLIB_mbstate_t   *_PDCLIB_restrict   ps  
23 )
24 {
25     if(ps->_Surrogate) {
26         // We already have a lead surrogate
27         if((*in & ~0x3FF) != 0xDC00) {
28             // Encoding error
29             return -1;
30         } else {
31             // Decode and reset state
32             *out = (ps->_Surrogate & 0x3FF) << 10 | (*in & 0x3FF);
33             ps->_Surrogate = 0;
34             return 1;
35         }
36     } if((*in & ~0x3FF) == 0xD800) {
37         // Lead surrogate
38         if(bufsize >= 2) {
39             // Buffer big enough
40             if((in[1] & ~0x3FF) != 0xDC00) {
41                 // Encoding error
42                 return -1;
43             } else {
44                 *out = (in[0] & 0x3FF) << 10 | (in[1] & 0x3FF);
45                 return 2;
46             }
47         } else {
48             // Buffer too small - update state
49             ps->_Surrogate = *in;
50             return -2;
51         }
52     } else {
53         // BMP character
54         *out = *in;
55         return 1;
56     }
57 }
58
59 static inline _PDCLIB_size_t _PDCLIB_c32rtoc16(
60             _PDCLIB_wchar_t     *_PDCLIB_restrict   out,
61     const   _PDCLIB_char32_t    *_PDCLIB_restrict   in,
62             _PDCLIB_size_t                          bufsize,
63             _PDCLIB_mbstate_t   *_PDCLIB_restrict   ps
64 )
65 {
66     if(ps->_Surrogate) {
67         *out = ps->_Surrogate;
68         ps->_Surrogate = 0;
69         return 0;
70     }
71
72     if(*in <= 0xFFFF) {
73         // BMP character
74         *out = *in;
75         return 1;
76     } else {
77         // Supplementary plane character
78         *out = 0xD800 | (*in & 0x3FF);
79         if(bufsize >= 2) {
80             out[1] = 0xDC00 | (*in >> 10);
81             return 2;
82         } else {
83             ps->_Surrogate = 0xDC00 | (*in >> 10);
84             return 1;
85         }
86     }
87 }
88
89 struct _PDCLIB_charcodec {
90     /* Reads at most *_P_insz code units from *_P_inbuf and writes the result 
91      * into *_P_outbuf, writing at most *_P_outsz code units. Updates 
92      * *_P_outbuf, *_P_outsz, *_P_inbuf, *_P_outsz with the resulting state
93      *
94      * If _P_outbuf is NULL, then the input must be processed but no output 
95      * generated. _P_outsz may be processed as normal.
96      *
97      * Returns true if the conversion completed successfully (i.e. one of 
98      * _P_outsize or _P_insize reached zero and no coding errors were 
99      * encountered), else return false.
100      */
101
102     /* UCS-4 variants. Mandatory. */
103
104     _PDCLIB_bool (*__mbstoc32s)(
105         _PDCLIB_char32_t       *_PDCLIB_restrict *_PDCLIB_restrict   _P_outbuf,
106         _PDCLIB_size_t                           *_PDCLIB_restrict   _P_outsz,
107         const char             *_PDCLIB_restrict *_PDCLIB_restrict   _P_inbuf,
108         _PDCLIB_size_t                           *_PDCLIB_restrict   _P_insz,
109         _PDCLIB_mbstate_t                        *_PDCLIB_restrict   _P_ps
110     );
111
112     _PDCLIB_bool (*__c32stombs)(
113         char                   *_PDCLIB_restrict *_PDCLIB_restrict  _P_outbuf,
114         _PDCLIB_size_t                           *_PDCLIB_restrict  _P_outsz,
115         const _PDCLIB_char32_t *_PDCLIB_restrict *_PDCLIB_restrict  _P_inbuf,
116         _PDCLIB_size_t                           *_PDCLIB_restrict  _P_insz,
117         _PDCLIB_mbstate_t                        *_PDCLIB_restrict  _P_ps
118     );
119
120     /* UTF-16 variants; same as above except optional. 
121      *
122      * If not provided, _PDCLib will internally synthesize on top of the UCS-4
123      * variants above, albeit at a performance cost.
124      */
125
126     _PDCLIB_bool (*__mbstoc16s)(
127         _PDCLIB_char16_t       *_PDCLIB_restrict *_PDCLIB_restrict   _P_outbuf,
128         _PDCLIB_size_t                           *_PDCLIB_restrict   _P_outsz,
129         const char             *_PDCLIB_restrict *_PDCLIB_restrict   _P_inbuf,
130         _PDCLIB_size_t                           *_PDCLIB_restrict   _P_insz,
131         _PDCLIB_mbstate_t                        *_PDCLIB_restrict   _P_ps
132     );
133
134     _PDCLIB_bool (*__c16stombs)(
135         char                   *_PDCLIB_restrict *_PDCLIB_restrict  _P_outbuf,
136         _PDCLIB_size_t                           *_PDCLIB_restrict  _P_outsz,
137         const _PDCLIB_char16_t *_PDCLIB_restrict *_PDCLIB_restrict  _P_inbuf,
138         _PDCLIB_size_t                           *_PDCLIB_restrict  _P_insz,
139         _PDCLIB_mbstate_t                        *_PDCLIB_restrict  _P_ps
140     );
141 };
142
143 #endif