libiconv에서 실질적으로 지원하는 함수는 다음의 세가지 이다.
iconv_open()
iconv()
iconv_close()
open() 함수에서 변환될 코드의 명칭을 전달해주면 변환 핸들을 리턴한다. 이 변환 핸들을 이용해서 iconv()함수를 호출해주면 된다.
그런데, 우선적으로 이 원하는 코드의 명칭이 헷갈렸다. UTF8, UTF-8, ISO-10646/UTF-8 등등 어떤걸 써야할지... 뭐 결론은 저건 다 같은 코드를 가리키고 있다. 아무거나 써도 상관없다는 것.
간단하게 확인하려면, 명령행에서 iconv -l을 실행시켜서 어떤 것을 지원하는지 확인하면 되지만.. 라이브러리로 링크할때 이것이 실제로 링크되었는지 불안한 경우가 있다. 특히 크로스 컴파일을 할 때 매우 헷갈릴 수밖에 없다.
간단하게 링크된 libiconv에서 지원하는 코드 셋을 살펴보고 싶다면 다음의 코드를 이용해보자.
int do_print(unsigned int namescount, const char * const * names, void* data)
{
unsigned int i;
(void) data;
for (i = 0; i < namescount; i++)
{
L_DEBUG(names[i]);
}
return 0;
}
/*
* Use this when you want to known what supported.
*/
void Iconv::DebugPrintSupportedCharacterSets()
{
libiconvlist(do_print, NULL);
}
L_DEBUG는 자체적으로 만들어쓰는 로그 매크로이니 신경쓰지 말자. printf로 바꿔써도 무방.
iconvlist 함수가 없다고 링크 오류가 발생할 수 있는데.. 일반적으로 usr/include/iconv.h 가 인클루드 된 것이다. libiconv 소스 패키지에 들어있는 iconv.h에는 저 함수가 선언되어 있다.
인클루드 패스를 조정해주면 된다.
iconv() 함수는 일반적으로 잘 동작하지만... 리턴 값이 정상적으로 리턴되지 않는 경우가 있다고 한다. 그래서 in_left와 out_left를 이용하여 다음과 같은 함수를 구현해보았다.
const TChar * Iconv::convert(TChar * input, TUint32 length)
{
L_TRACE("legnth = %d", length);
if(length > m_bufferSize)
{
expandBuffer(length + m_bufferSize);
}
TChar * p_in_buf = input;
size_t in_left = length;
TChar * p_out_buf = m_buffer;
size_t out_left = m_bufferSize;
iconv(m_handle,(char **)&p_in_buf, &in_left, &p_out_buf, &out_left);
L_DEBUG("in_left = %d, out_left = %d", in_left, out_left);
if(in_left == length)
{
L_DEBUG("FAIL to convert %s -> %s", DtvCodeTypeToStr(m_sourceType), DtvCodeTypeToStr(m_resultType));
m_resultSize = 0;
m_result = NULL;
return m_result;
}
if(in_left == 0)
{
m_resultSize = m_bufferSize - out_left;
m_result = m_buffer;
return m_result;
}
// WARN!! recursive call.
expandBuffer(m_bufferSize); // x2
return convert(input, length);
}
Iconv 클래스의 생성자와 파괴자에서 m_buffer를 정리해주면 된다.
0 개의 댓글:
댓글 쓰기