/** * Copyright (c) 2009-2010 Mika Laitio * * This file and library is covered by the LGPL version 3, read LICENSE for details. * * History: * - Created charencoding_internal.c on: Nov 25, 2009 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define SIZE_CALCULATION_TEMP_BUFFER_SIZE 8 static bool _locale_charset_initialized = false; const char *get_locale_charset_alias() { if (_locale_charset_initialized == false) { setlocale(LC_ALL, ""); _locale_charset_initialized = true; } return nl_langinfo(CODESET); } size_t calculate_target_charset_bytecount(iconv_t conversion_desc, const char *src, size_t bcount_src) { size_t ret_val; size_t err_flg; size_t bcount_trgt; const char *p_src; char *p_trgt; char tmp_buf[SIZE_CALCULATION_TEMP_BUFFER_SIZE]; ret_val = 0; err_flg = 0; // reset conversion descriptor to initial state iconv(conversion_desc, NULL, NULL, NULL, NULL); p_src = src; while (bcount_src > 0) { p_trgt = tmp_buf; bcount_trgt = SIZE_CALCULATION_TEMP_BUFFER_SIZE; err_flg = iconv(conversion_desc, (char **)&p_src, &bcount_src, &p_trgt, &bcount_trgt); if (err_flg == (size_t)(-1)) { if (errno == E2BIG) { // too small tmp_buf error can be skipped err_flg = 0; } else { err_flg = -1; break; } } ret_val = ret_val + SIZE_CALCULATION_TEMP_BUFFER_SIZE - bcount_trgt; } if (err_flg != 0) { ret_val =-1; } printf("size: %d\n", ret_val); return ret_val; } char *str_iconv_encode(iconv_t conversion_desc, const char *src, size_t bcount_src, size_t *p_bcount, int *err_flg) { char *ret_val; char *p_ret_val; const char *p_src; size_t bcount_src_left; size_t bcount_trgt_left; size_t ic_ret_val; ret_val = NULL; *err_flg = 0; *p_bcount = calculate_target_charset_bytecount(conversion_desc, src, bcount_src); if (*p_bcount >= 0) { ret_val = (char *)calloc(1, *p_bcount + 1); if (ret_val != NULL) { // reset conversion descriptor to initial state iconv(conversion_desc, NULL, NULL, NULL, NULL); p_src = src; bcount_src_left = bcount_src; p_ret_val = ret_val; bcount_trgt_left = *p_bcount; while (bcount_src_left > 0) { errno = 0; ic_ret_val = iconv(conversion_desc, (char **)&p_src, &bcount_src_left, &p_ret_val, &bcount_trgt_left); if (ic_ret_val == (size_t)(-1)) { free(ret_val); ret_val = NULL; *err_flg = -1; break; } } } else { *err_flg = -1; } } else { // could not calculate the byte count *err_flg = -1; } if (*err_flg != 0) { *p_bcount = -1; } return ret_val; }