X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fencoding.c;h=d4f4f3993c47fb1b65f97ac75cbee45d41dfce61;hp=822e9f53659ec780d654c4f9168094a2d5b03bcc;hb=a6442deab2424760208a1b03d04e3c26b82c36a4;hpb=f2db311f527e6037c836cf1b14debb841e09b440 diff --git a/src/encoding.c b/src/encoding.c index 822e9f53..d4f4f399 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -21,7 +21,15 @@ * along with wimlib; if not, see http://www.gnu.org/licenses/. */ -#include "wimlib_internal.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "wimlib.h" +#include "wimlib/encoding.h" +#include "wimlib/error.h" +#include "wimlib/list.h" +#include "wimlib/util.h" #include #include @@ -112,7 +120,8 @@ static bool error_message_being_printed = false; #define DEFINE_CHAR_CONVERSION_FUNCTIONS(varname1, longname1, chartype1,\ varname2, longname2, chartype2,\ - earlyreturn, \ + earlyreturn_on_utf8_locale, \ + earlyreturn_expr, \ worst_case_len_expr, \ err_return, \ err_msg, \ @@ -194,7 +203,8 @@ varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes, \ chartype2 *out; \ size_t out_nbytes; \ \ - if (earlyreturn) { \ + if (earlyreturn_on_utf8_locale && wimlib_mbs_is_utf8) { \ + earlyreturn_expr; \ /* Out same as in */ \ out = MALLOC(in_nbytes + sizeof(chartype2)); \ if (!out) \ @@ -217,9 +227,7 @@ varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes, \ \ ret = varname1##_to_##varname2##_buf(in, in_nbytes, out); \ if (ret) { \ - int errno_save = errno; \ FREE(out); \ - errno = errno_save; \ } else { \ *out_ret = out; \ *out_nbytes_ret = out_nbytes; \ @@ -228,35 +236,64 @@ varname1##_to_##varname2(const chartype1 *in, size_t in_nbytes, \ } #if !TCHAR_IS_UTF16LE -DEFINE_CHAR_CONVERSION_FUNCTIONS(tstr, "", tchar, + +/* UNIX */ + +DEFINE_CHAR_CONVERSION_FUNCTIONS(utf8, "UTF-8", tchar, utf16le, "UTF-16LE", utf16lechar, false, - in_nbytes * 4, + , + in_nbytes * 2, + WIMLIB_ERR_INVALID_UTF8_STRING, + ERROR_WITH_ERRNO("Failed to convert UTF-8 string " + "to UTF-16LE string!"), + static) + +DEFINE_CHAR_CONVERSION_FUNCTIONS(utf16le, "UTF-16LE", utf16lechar, + utf8, "UTF-8", tchar, + false, + , + in_nbytes * 2, + WIMLIB_ERR_INVALID_UTF16_STRING, + ERROR_WITH_ERRNO("Failed to convert UTF-16LE string " + "to UTF-8 string!"), + static) + +DEFINE_CHAR_CONVERSION_FUNCTIONS(tstr, "", tchar, + utf16le, "UTF-16LE", utf16lechar, + true, + return utf8_to_utf16le(in, in_nbytes, out_ret, out_nbytes_ret), + in_nbytes * 2, WIMLIB_ERR_INVALID_MULTIBYTE_STRING, ERROR_WITH_ERRNO("Failed to convert multibyte " "string \"%"TS"\" to UTF-16LE string!", in); ERROR("If the data you provided was UTF-8, please make sure " - "the character encoding of your current locale is UTF-8."), + "the character encoding\n" + " of your current locale is UTF-8."), ) DEFINE_CHAR_CONVERSION_FUNCTIONS(utf16le, "UTF-16LE", utf16lechar, tstr, "", tchar, - false, + true, + return utf16le_to_utf8(in, in_nbytes, out_ret, out_nbytes_ret), in_nbytes * 2, WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE, ERROR("Failed to convert UTF-16LE string to " "multibyte string!"); ERROR("This may be because the UTF-16LE string " - "could not be represented in your " - "locale's character encoding."), + "could not be represented\n" + " in your locale's character encoding."), ) #endif /* tchar to UTF-8 and back */ #if TCHAR_IS_UTF16LE + +/* Windows */ DEFINE_CHAR_CONVERSION_FUNCTIONS(tstr, "UTF-16LE", tchar, utf8, "UTF-8", char, false, + , in_nbytes * 2, WIMLIB_ERR_INVALID_UTF16_STRING, ERROR_WITH_ERRNO("Failed to convert UTF-16LE " @@ -266,33 +303,40 @@ DEFINE_CHAR_CONVERSION_FUNCTIONS(tstr, "UTF-16LE", tchar, DEFINE_CHAR_CONVERSION_FUNCTIONS(utf8, "UTF-8", char, tstr, "UTF-16LE", tchar, false, + , in_nbytes * 2, WIMLIB_ERR_INVALID_UTF8_STRING, ERROR_WITH_ERRNO("Failed to convert UTF-8 string " "to UTF-16LE string!"), static) #else + +/* UNIX */ + DEFINE_CHAR_CONVERSION_FUNCTIONS(tstr, "", tchar, utf8, "UTF-8", char, - wimlib_mbs_is_utf8, + true, + , in_nbytes * 4, WIMLIB_ERR_INVALID_MULTIBYTE_STRING, ERROR_WITH_ERRNO("Failed to convert multibyte " "string \"%"TS"\" to UTF-8 string!", in); ERROR("If the data you provided was UTF-8, please make sure " - "the character encoding of your current locale is UTF-8."), + "the character\n" + " encoding of your current locale is UTF-8."), static) DEFINE_CHAR_CONVERSION_FUNCTIONS(utf8, "UTF-8", char, tstr, "", tchar, - wimlib_mbs_is_utf8, + true, + , in_nbytes * 4, WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE, ERROR("Failed to convert UTF-8 string to " "multibyte string!"); ERROR("This may be because the UTF-8 data " - "could not be represented in your " - "locale's character encoding."), + "could not be represented\n" + " in your locale's character encoding."), static) #endif @@ -326,12 +370,14 @@ iconv_cleanup(struct iconv_list_head *head) } void -iconv_global_cleanup() +iconv_global_cleanup(void) { iconv_cleanup(&iconv_utf8_to_tstr); iconv_cleanup(&iconv_tstr_to_utf8); #if !TCHAR_IS_UTF16LE iconv_cleanup(&iconv_utf16le_to_tstr); iconv_cleanup(&iconv_tstr_to_utf16le); + iconv_cleanup(&iconv_utf16le_to_utf8); + iconv_cleanup(&iconv_utf8_to_utf16le); #endif }