/*
* iconv를 사용하여 문자코드를 변경한다.
* 이 함수에서 반환된 포인터는 반드시 safe_free 되어야
한다.
* 실패했을 경우 NULL을 반환한다.
* 사용 예제 : p2 = iconv_convert(p1, "EUC-KR",
"UTF-8"); safe_free(p1);
*/
#define ICONV_BYTES(n) ((n) * 6 + 1)
char
*iconv_convert(const char *srcp, const char *to, const char *from)
{
iconv_t iconv_value;
size_t iconv_ret, in_bytes, dstp_bytes,
last_bytes;
char *dstp, *clone_dstp;
// iconv 함수를 사용하기 위해서 iconv_open을 호출한다.
if ((iconv_value =
iconv_open(to, from)) == (iconv_t)-1)
{
iconv_error: // Error 처리
Label
iconv_close(iconv_value);
return NULL;
}
else
{
// in_bytes에 원본
문자열 길이를 넣는다.
in_bytes = strlen(srcp);
// 변환된 문자열이 들어갈 공간을 준비한다.
dstp = (char
*)safe_malloc(ICONV_BYTES(in_bytes));
if (dstp ==
NULL)
goto iconv_error;
clone_dstp = dstp;
dstp_bytes = ICONV_BYTES(in_bytes);
do
{
last_bytes = in_bytes;
// 변환 한다.
iconv_ret =
iconv(iconv_value, &srcp, (size_t *)&in_bytes, (char **)&clone_dstp,
(size_t *)&dstp_bytes);
if (iconv_ret <
(size_t)0)
{
// 오류 처리
if(errno == EILSEQ || errno == EINVAL)
{
srcp++; // skip broken
byte
in_bytes--;
}
else
{
goto
iconv_error;
}
}
}
while
(in_bytes > 0 && in_bytes < last_bytes);
iconv_close(iconv_value);
*clone_dstp = '\0';
return dstp;
}
return NULL;
}