1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
|
/*
* Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
* (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
*
* This file is part of lsp-runtime-lib
* Created on: 18 июн. 2018 г.
*
* lsp-runtime-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* lsp-runtime-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with lsp-runtime-lib. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LSP_PLUG_IN_IO_CHARSET_H_
#define LSP_PLUG_IN_IO_CHARSET_H_
#include <lsp-plug.in/runtime/version.h>
#include <lsp-plug.in/common/types.h>
#include <lsp-plug.in/stdlib/string.h>
#if defined(PLATFORM_WINDOWS)
#include <winnls.h>
#else
#include <iconv.h>
#include <locale.h>
#endif /* PLATFORM_WINDOWS */
#define LSP_UTF32_EOF lsp_utf32_t(-1)
namespace lsp
{
#if defined(PLATFORM_WINDOWS)
ssize_t get_codepage(LCID locale, bool ansi = true);
ssize_t codepage_from_name(const char *charset);
/**
* This is a MultiByteToWideChar wrapping function that handles additional cases
* for non-MBCS encodings
*
* @param cp code page
* @param src source buffer
* @param nsrc number of bytes available in source buffer (will be updated on exit)
* @param dst destination buffer (can be NULL for just estimating the length)
* @param ndst number of characters in destination buffer (will be updated on exit,
* can be NULL or point to zero value for just estimating the length)
* @return number of UTF-16 characters written to destination buffer or negative error code
*/
ssize_t multibyte_to_widechar(size_t cp, LPCCH src, size_t *nsrc, LPWSTR dst, size_t *ndst);
/**
* This is a WideCharToMultiByte wrapping function that handles additional cases
* for non-MBCS encodings
*
* @param cp code page
* @param src source wide string to perform encoding
* @param nsrc number of characters available in source wide string (will be updated on exit)
* @param dst target string to perform encoding (can be NULL for just estimating the length)
* @param ndst number of bytes in destination buffer (will be updated on exit,
* can be NULL or point to zero value for just estimating the length)
* @return number of bytes written to destination buffer or negative error code
*/
ssize_t widechar_to_multibyte(size_t cp, LPCWCH src, size_t *nsrc, LPSTR dst, size_t *ndst);
#else
iconv_t init_iconv_to_wchar_t(const char *charset);
iconv_t init_iconv_from_wchar_t(const char *charset);
#endif /* PLATFORM_WINDOWS */
/**
* Read UTF-16 codepoint from the NULL-terminated UTF-16 string, replace invalid
* code sequence by 0xfffd code point
* @param str pointer to the NULL-terminated UTF-16 string
* @return code point
*/
lsp_utf32_t read_utf16le_codepoint(const lsp_utf16_t **str);
lsp_utf32_t read_utf16be_codepoint(const lsp_utf16_t **str);
inline lsp_utf32_t read_utf16_codepoint(const lsp_utf16_t **str) { return __IF_LEBE(read_utf16le_codepoint, read_utf16be_codepoint)(str); };
/**
* Read UTF-16 codepoint from the NULL-terminated UTF-16 string in streaming mode,
* replace invalid code sequence by 0xfffd code point
* @param str pointer to the pointer to the NULL-terminated UTF-16 string
* @param nsrc counter containing number of unread array elements
* @param force process data as there will be no future data on the input
* @return parsed code point or LSP_UTF32_EOF as end of sequence
*/
lsp_utf32_t read_utf16le_streaming(const lsp_utf16_t **str, size_t *nsrc, bool force);
lsp_utf32_t read_utf16be_streaming(const lsp_utf16_t **str, size_t *nsrc, bool force);
inline lsp_utf32_t read_utf16_streaming(const lsp_utf16_t **str, size_t *nsrc, bool force) { return __IF_LEBE(read_utf16le_streaming, read_utf16be_streaming)(str, nsrc, force); }
/**
* Read UTF-16 codepoint from the NULL-terminated UTF-8 string, replace invalid
* code sequence by 0xfffd code point
* @param str pointer to the NULL-terminated UTF-8 string
* @return code point
*/
lsp_utf32_t read_utf8_codepoint(const char **str);
/**
* Read UTF-8 codepoint from the NULL-terminated UTF-8 string in streaming mode,
* replace invalid code sequence by 0xfffd code point
* @param str pointer to the pointer to the NULL-terminated UTF-8 string
* @param nsrc counter containing number of unread array elements
* @param force process data as there will be no future data on the input
* @return parsed code point or LSP_UTF32_EOF as end of sequence
*/
lsp_utf32_t read_utf8_streaming(const char **str, size_t *nsrc, bool force);
/**
* Write UTF-8 code point to buffer, buffer should be of enough size
* @param str pointer to target buffer
* @param cp code point to write
*/
void write_utf8_codepoint(char **str, lsp_utf32_t cp);
/**
* Write UTF-16 code point to buffer, buffer should be of enough size
* @param str pointer to target buffer
* @param cp code point to write
*/
void write_utf16le_codepoint(lsp_utf16_t **str, lsp_utf32_t cp);
void write_utf16be_codepoint(lsp_utf16_t **str, lsp_utf32_t cp);
inline void write_utf16_codepoint(lsp_utf16_t **str, lsp_utf32_t cp) { return __IF_LEBE(write_utf16le_codepoint, write_utf16be_codepoint)(str, cp); }
/**
* Encode NULL-terminated UTF-8 string to NULL-terminated UTF-16 string
* @param str string to encode
* @return pointer to allocated UTF-16 string that should be free()'d after use
*/
lsp_utf16_t *utf8_to_utf16le(const char *str);
lsp_utf16_t *utf8_to_utf16be(const char *str);
inline lsp_utf16_t *utf8_to_utf16(const char *str) { return __IF_LEBE(utf8_to_utf16le, utf8_to_utf16be)(str); }
/**
* Encode sequence of UTF-8 characters into sequence of UTF-16 characters
* @param dst target buffer to store characters
* @param ndst number of elements available in target buffer
* @param src source buffer to read characters
* @param nsrc number of elements available in source buffer
* @param force force flag that treats the input block as last in the character sequence
* @return number of processed code points
*/
size_t utf8_to_utf16le(lsp_utf16_t *dst, size_t *ndst, const char *src, size_t *nsrc, bool force);
size_t utf8_to_utf16be(lsp_utf16_t *dst, size_t *ndst, const char *src, size_t *nsrc, bool force);
inline size_t utf8_to_utf16(lsp_utf16_t *dst, size_t *ndst, const char *src, size_t *nsrc, bool force) { return __IF_LEBE(utf8_to_utf16le, utf8_to_utf16be)(dst, ndst, src, nsrc, force); }
/**
* Encode NULL-terminated UTF-8 string to NULL-terminated UTF-32 string
* @param str string to encode
* @return pointer to allocated UTF-32 string that should be free()'d after use
*/
lsp_utf32_t *utf8_to_utf32le(const char *str);
lsp_utf32_t *utf8_to_utf32be(const char *str);
inline lsp_utf32_t *utf8_to_utf32(const char *str) { return __IF_LEBE(utf8_to_utf32le, utf8_to_utf32be)(str); };
/**
* Encode sequence of UTF-8 characters into sequence of UTF-32 characters
* @param dst target buffer to store characters
* @param ndst number of elements available in target buffer
* @param src source buffer to read characters
* @param nsrc number of elements available in source buffer
* @param force force flag that treats the input block as last in the character sequence
* @return number of processed code points
*/
size_t utf8_to_utf32le(lsp_utf32_t *dst, size_t *ndst, const char *src, size_t *nsrc, bool force);
size_t utf8_to_utf32be(lsp_utf32_t *dst, size_t *ndst, const char *src, size_t *nsrc, bool force);
inline size_t utf8_to_utf32(lsp_utf32_t *dst, size_t *ndst, const char *src, size_t *nsrc, bool force) { return __IF_LEBE(utf8_to_utf32le, utf8_to_utf32be)(dst, ndst, src, nsrc, force); };
/**
* Encode NULL-terminated UTF-16 string to NULL-terminated UTF-8 string
* @param str string to encode
* @return pointer to allocated UTF-8 string that should be free()'d after use
*/
char *utf16le_to_utf8(const lsp_utf16_t *str);
char *utf16be_to_utf8(const lsp_utf16_t *str);
inline char *utf16_to_utf8(const lsp_utf16_t *str) { return __IF_LEBE(utf16le_to_utf8, utf16be_to_utf8)(str); };
/**
* Encode sequence of UTF-16 characters into sequence of UTF-16 characters
* @param dst target buffer to store characters
* @param ndst number of elements available in target buffer
* @param src source buffer to read characters
* @param nsrc number of elements available in source buffer
* @param force force flag that treats the input block as last in the character sequence
* @return number of processed code points
*/
size_t utf16le_to_utf8(char *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force);
size_t utf16be_to_utf8(char *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force);
inline size_t utf16_to_utf8(char *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf16le_to_utf8, utf16be_to_utf8)(dst, ndst, src, nsrc, force); };
/**
* Encode NULL-terminated UTF-16 string to NULL-terminated UTF-32 string
* @param str string to encode
* @return pointer to allocated UTF-32 string that should be free()'d after use
*/
lsp_utf32_t *utf16le_to_utf32le(const lsp_utf16_t *str);
lsp_utf32_t *utf16le_to_utf32be(const lsp_utf16_t *str);
lsp_utf32_t *utf16be_to_utf32le(const lsp_utf16_t *str);
lsp_utf32_t *utf16be_to_utf32be(const lsp_utf16_t *str);
inline lsp_utf32_t *utf16le_to_utf32(const lsp_utf16_t *str) { return __IF_LEBE(utf16le_to_utf32le, utf16le_to_utf32be)(str); }
inline lsp_utf32_t *utf16be_to_utf32(const lsp_utf16_t *str) { return __IF_LEBE(utf16be_to_utf32le, utf16be_to_utf32be)(str); }
inline lsp_utf32_t *utf16_to_utf32le(const lsp_utf16_t *str) { return __IF_LEBE(utf16le_to_utf32le, utf16be_to_utf32le)(str); }
inline lsp_utf32_t *utf16_to_utf32be(const lsp_utf16_t *str) { return __IF_LEBE(utf16le_to_utf32be, utf16be_to_utf32be)(str); }
inline lsp_utf32_t *utf16_to_utf32(const lsp_utf16_t *str) { return __IF_LEBE(utf16le_to_utf32le, utf16be_to_utf32be)(str); }
/**
* Encode sequence of UTF-16 characters into sequence of UTF-32 characters
* @param dst target buffer to store characters
* @param ndst number of elements available in target buffer
* @param src source buffer to read characters
* @param nsrc number of elements available in source buffer
* @param force force flag that treats the input block as last in the character sequence
* @return number of processed code points
*/
size_t utf16le_to_utf32le(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force);
size_t utf16le_to_utf32be(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force);
size_t utf16be_to_utf32le(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force);
size_t utf16be_to_utf32be(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force);
inline size_t utf16le_to_utf32(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf16le_to_utf32le, utf16le_to_utf32be)(dst, ndst, src, nsrc, force); }
inline size_t utf16be_to_utf32(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf16be_to_utf32le, utf16be_to_utf32be)(dst, ndst, src, nsrc, force); }
inline size_t utf16_to_utf32le(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf16le_to_utf32le, utf16be_to_utf32le)(dst, ndst, src, nsrc, force); }
inline size_t utf16_to_utf32be(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf16le_to_utf32be, utf16be_to_utf32be)(dst, ndst, src, nsrc, force); }
inline size_t utf16_to_utf32(lsp_utf32_t *dst, size_t *ndst, const lsp_utf16_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf16le_to_utf32le, utf16be_to_utf32be)(dst, ndst, src, nsrc, force); }
/**
* Encode NULL-terminated UTF-32 string to NULL-terminated UTF-8 string
* @param str string to encode
* @return pointer to allocated UTF-16 string that should be free()'d after use
*/
char *utf32le_to_utf8(const lsp_utf32_t *str);
char *utf32be_to_utf8(const lsp_utf32_t *str);
inline char *utf32_to_utf8(const lsp_utf32_t *str) { return __IF_LEBE(utf32le_to_utf8, utf32be_to_utf8)(str); };
/**
* Encode sequence of UTF-8 characters into sequence of UTF-16 characters
* @param dst target buffer to store characters
* @param ndst number of elements available in target buffer
* @param src source buffer to read characters
* @param nsrc number of elements available in source buffer
* @param force force flag that treats the input block as last in the character sequence
* @return number of processed code points
*/
size_t utf32le_to_utf8(char *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force);
size_t utf32be_to_utf8(char *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force);
inline size_t utf32_to_utf8(char *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf32le_to_utf8, utf32be_to_utf8)(dst, ndst, src, nsrc, force); }
/**
* Encode NULL-terminated UTF-32 string to NULL-terminated UTF-16 string
* @param str string to encode
* @return pointer to allocated UTF-16 string that should be free()'d after use
*/
lsp_utf16_t *utf32le_to_utf16le(const lsp_utf32_t *str);
lsp_utf16_t *utf32le_to_utf16be(const lsp_utf32_t *str);
lsp_utf16_t *utf32be_to_utf16le(const lsp_utf32_t *str);
lsp_utf16_t *utf32be_to_utf16be(const lsp_utf32_t *str);
inline lsp_utf16_t *utf32le_to_utf16(const lsp_utf32_t *str) { return __IF_LEBE(utf32le_to_utf16le, utf32le_to_utf16be)(str); }
inline lsp_utf16_t *utf32be_to_utf16(const lsp_utf32_t *str) { return __IF_LEBE(utf32be_to_utf16le, utf32be_to_utf16be)(str); }
inline lsp_utf16_t *utf32_to_utf16le(const lsp_utf32_t *str) { return __IF_LEBE(utf32le_to_utf16le, utf32be_to_utf16le)(str); }
inline lsp_utf16_t *utf32_to_utf16be(const lsp_utf32_t *str) { return __IF_LEBE(utf32le_to_utf16be, utf32be_to_utf16be)(str); }
inline lsp_utf16_t *utf32_to_utf16(const lsp_utf32_t *str) { return __IF_LEBE(utf32le_to_utf16le, utf32be_to_utf16be)(str); }
/**
* Encode sequence of UTF-8 characters into sequence of UTF-16 characters
* @param dst target buffer to store characters
* @param ndst number of elements available in target buffer
* @param src source buffer to read characters
* @param nsrc number of elements available in source buffer
* @param force force flag that treats the input block as last in the character sequence
* @return number of processed code points
*/
size_t utf32le_to_utf16le(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force);
size_t utf32le_to_utf16be(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force);
size_t utf32be_to_utf16le(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force);
size_t utf32be_to_utf16be(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force);
inline size_t utf32_to_utf16le(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf32le_to_utf16le, utf32be_to_utf16le)(dst, ndst, src, nsrc, force); }
inline size_t utf32_to_utf16be(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf32le_to_utf16be, utf32be_to_utf16be)(dst, ndst, src, nsrc, force); }
inline size_t utf32le_to_utf16(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf32le_to_utf16le, utf32le_to_utf16be)(dst, ndst, src, nsrc, force); }
inline size_t utf32be_to_utf16(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf32be_to_utf16le, utf32be_to_utf16be)(dst, ndst, src, nsrc, force); }
inline size_t utf32_to_utf16(lsp_utf16_t *dst, size_t *ndst, const lsp_utf32_t *src, size_t *nsrc, bool force) { return __IF_LEBE(utf32le_to_utf16le, utf32be_to_utf16be)(dst, ndst, src, nsrc, force); }
/**
* Compare two character sequences.
* @param s1 character sequence 1
* @param s2 character sequence 2
* @param count number of characters to compare, you must be sure that both sequences have at least count characters
* @return comparison result
*/
#ifdef ARCH_LE
inline int wchar_cmp(const lsp_wchar_t *s1, const lsp_wchar_t *s2, size_t count) { return ::memcmp(s1, s2, count * sizeof(lsp_wchar_t)); }
#else
int wchar_cmp(const lsp_wchar_t *s1, const lsp_wchar_t *s2, size_t count);
#endif
int wchar_casecmp(const lsp_wchar_t *s1, const lsp_wchar_t *s2, size_t count);
}
#endif /* LSP_PLUG_IN_IO_CHARSET_H_ */
|