Improve tstr <=> UTF-16LE conversions
[wimlib] / include / wimlib / encoding.h
1 #ifndef _WIMLIB_ENCODING_H
2 #define _WIMLIB_ENCODING_H
3
4 #include "wimlib/error.h"
5 #include "wimlib/util.h"
6 #include "wimlib/types.h"
7
8 #include <string.h>
9
10 extern void
11 iconv_global_cleanup(void);
12
13 extern void
14 init_upcase(void);
15
16 extern bool wimlib_mbs_is_utf8;
17
18 #define DECLARE_CHAR_CONVERSION_FUNCTIONS(varname1, varname2,           \
19                                           chartype1, chartype2)         \
20                                                                         \
21 extern int                                                              \
22 varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes,         \
23                          chartype2 **out_ret,                           \
24                          size_t *out_nbytes_ret);                       \
25                                                                         \
26 extern int                                                              \
27 varname1##_to_##varname2##_nbytes(const chartype1 *in, size_t in_nbytes,\
28                                   size_t *out_nbytes_ret);              \
29                                                                         \
30 extern int                                                              \
31 varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes,   \
32                                chartype2 *out);
33
34 extern utf16lechar *
35 utf16le_dupz(const utf16lechar *ustr, size_t usize);
36
37 #if !TCHAR_IS_UTF16LE
38 DECLARE_CHAR_CONVERSION_FUNCTIONS(utf16le, tstr, utf16lechar, tchar);
39 DECLARE_CHAR_CONVERSION_FUNCTIONS(tstr, utf16le, tchar, utf16lechar);
40 #else
41
42 static inline int
43 tstr_to_utf16le(const tchar *tstr, size_t tsize,
44                 utf16lechar **ustr_ret, size_t *usize_ret)
45 {
46         utf16lechar *ustr = utf16le_dupz(tstr, tsize);
47         if (!ustr)
48                 return WIMLIB_ERR_NOMEM;
49         *ustr_ret = ustr;
50         *usize_ret = tsize;
51         return 0;
52 }
53
54 #define utf16le_to_tstr tstr_to_utf16le
55
56 #endif
57
58 DECLARE_CHAR_CONVERSION_FUNCTIONS(utf8, tstr, char, tchar);
59 DECLARE_CHAR_CONVERSION_FUNCTIONS(tstr, utf8, tchar, char);
60
61 extern int
62 utf8_to_tstr_simple(const char *utf8str, tchar **out);
63
64 extern int
65 tstr_to_utf8_simple(const tchar *tstr, char **out);
66
67 extern int
68 cmp_utf16le_strings(const utf16lechar *s1, size_t n1,
69                     const utf16lechar *s2, size_t n2,
70                     bool ignore_case);
71
72 /* Convert a string in the platform-dependent encoding to UTF-16LE, but if both
73  * encodings are UTF-16LE, simply re-use the string.  Release with
74  * tstr_put_utf16le() when done.  */
75 static inline int
76 tstr_get_utf16le_and_len(const tchar *tstr,
77                          const utf16lechar **ustr_ret, size_t *usize_ret)
78 {
79         size_t tsize = tstrlen(tstr) * sizeof(tchar);
80 #if TCHAR_IS_UTF16LE
81         /* No conversion or copy needed  */
82         *ustr_ret = tstr;
83         *usize_ret = tsize;
84         return 0;
85 #else
86         return tstr_to_utf16le(tstr, tsize, (utf16lechar **)ustr_ret, usize_ret);
87 #endif
88 }
89
90 /* Convert a string in the platform-dependent encoding to UTF-16LE, but if both
91  * encodings are UTF-16LE, simply re-use the string.  Release with
92  * tstr_put_utf16le() when done.  */
93 static inline int
94 tstr_get_utf16le(const tchar *tstr, const utf16lechar **ustr_ret)
95 {
96 #if TCHAR_IS_UTF16LE
97         /* No conversion or copy needed  */
98         *ustr_ret = tstr;
99         return 0;
100 #else
101         size_t tsize = tstrlen(tstr) * sizeof(tchar);
102         size_t dummy;
103         return tstr_to_utf16le(tstr, tsize, (utf16lechar **)ustr_ret, &dummy);
104 #endif
105 }
106
107 /* Release a string acquired with tstr_get_utf16le() or
108  * tstr_get_utf16le_and_len().  */
109 static inline void
110 tstr_put_utf16le(const utf16lechar *ustr)
111 {
112 #if !TCHAR_IS_UTF16LE
113         FREE((void *)ustr);
114 #endif
115 }
116
117 /* Convert a UTF16-LE string to the platform-dependent encoding, but if both
118  * encodings are UTF-16LE, simply re-use the string.  Release with
119  * utf16le_put_tstr() when done.  */
120 static inline int
121 utf16le_get_tstr(const utf16lechar *ustr, size_t usize,
122                  const tchar **tstr_ret, size_t *tsize_ret)
123 {
124 #if TCHAR_IS_UTF16LE
125         /* No conversion or copy needed  */
126         *tstr_ret = ustr;
127         *tsize_ret = usize;
128         return 0;
129 #else
130         return utf16le_to_tstr(ustr, usize, (tchar **)tstr_ret, tsize_ret);
131 #endif
132 }
133
134 /* Release a string acquired with utf16le_get_tstr().  */
135 static inline void
136 utf16le_put_tstr(const tchar *tstr)
137 {
138 #if !TCHAR_IS_UTF16LE
139         FREE((void *)tstr);
140 #endif
141 }
142
143 #endif /* _WIMLIB_ENCODING_H */