Convertendo string multibyte UTF-8 para wchar_t e vice-versa com iconv
Nos ultimos dias eu estive trabalhando em uma forma de suportar caracteres utf-8 no bitsheet. Ontem eu resolvi usar a iconv para fazer este trabalho de conversão de wchar_t para UTF-8 e vice-versa. Resolvi postar aqui a solução que usei.
<Teoria chata>
O tipo wchar_t foi introduzido para que houvesse suporte a wide characters, mas a codificação de uma array de wchar_t (ou wide string) é dependente da locale do sistema (LC_TYPE/LC_ALL/LC_LANG) e do compilador. O padrão C não especifica um tamanho exato para o tipo wchar_t, largando esta tarefa aos compiladores, então o valor deste tipo geralmente varia entre 8 e 32 bits. No caso da implementação do wchar_t do gcc, o tamanho é 32 bits, portanto o mesmo comporta caracteres que consumam até 4bytes (como alguns caracteres Unicode).
UTF-8 (8-bit Unicode Transformation Format) é uma das primeiras codificações que implementam suporte a Unicode characters, ele foi criado por Ken Thompson (o cara que criou a linguagem B e que ja recebeu até premio turing junto com o Denis Ritchie) e Rob Pike (junto com Ken Thompson criou o sistema operacional Plan 9) num restaurante de New Jersey (pode acreditar!) em setembro de 1992. Os caras resolveram fazer isso porque odiaram o suporte a caracteres 16bit do UTF original e do ISO 10646. O formato foi feito para ser compatível com o padrão ASCII e utiliza um numero variado de bytes para representar os caracteres (caracteres ASCII usam 1 caracteres, e letras acentuadas geralmente utilizam 2 caracteres).
Nem todas as implementações do tipo wchar_t comportam todas as possibilidades da codificação UTF-8, o wchar_t do compilador c++ da microsoft é de 16bits e portanto não comporta os casos em que os caracteres utf-8 são maiores que 16bits (É UMA CILADA BINO!). Mas aí existem umas manhas pra resolver este problema.
</Teoria chata>
A biblioteca iconv é uma biblioteca comum em sistemas UNIX, ela faz a conversão entre diferentes codificações de caracteres inclusive de uma codificação como o utf-8 para a codificação interna do wchar_t. Chega de enrolação, la vai o codigo.
(a linguagem é C++)
Referências:
- http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
- http://opengroup.org/onlinepubs/007908799/xsh/wchar.h.html
- http://icu-project.org/docs/papers/unicode_wchar_t.html