INF1018 - Software Básico - 2012.1

Primeiro Trabalho

Transformação entre as representações UTF-8 e UTF-32

O objetivo deste trabalho é implementar, na linguagem C, duas funções (utf32_8 e utf8_32), que realizam a transformação entre as representações UNICODE UTF-32 e UTF-8.

Leia com atenção o enunciado do trabalho e as instruções para a entrega. Em caso de dúvidas, não invente. Pergunte!


Codificação UTF

Caracteres de um texto são em geral representados em C pelo tipo char, que tipicamente tem o tamanho de 1 byte e pode armazenar apenas 256 (28) valores diferentes. Enquanto a codificação ASCII utiliza apenas inteiros de 0 a 127, uma outra codificação, chamada ISO Latin1, usa a faixa de valores 128-255 para caracteres acentuados e alguns símbolos. Porém isto não é suficiente para armazenar caracteres dos alfabetos utilizados pelos diversos idiomas falados atualmente (inglês, português, chinês, árabe, hebraico, etc.). Para lidar com essa questão foi criada a codificação UNICODE, que é capaz de representar caracteres de todos os idiomas conhecidos, além de símbolos e outros tipos de caracteres.

Cada caracter em UNICODE tem um código na faixa de 0 a 0x10FFFF, o que permite a utilização de 1114112 valores diferentes como códigos de caracteres. Na notação adotada pelo padrão UNICODE, U+xxxx identifica o código com valor hexadecimal xxxx. Por exemplo, o código U+00A9 (o código do símbolo ©) corresponde ao valor hexadecimal 0x00A9.

Existem algumas formas diferentes de codificação de caracteres UNICODE. Para este trabalho, as codificações de interesse são a UTF-32 e a UTF-8.

A codificação UTF-32 é simplesmente a representação numérica do código do caracter, usando um inteiro de 4 bytes. Essa codificação é suficiente para representar todos os códigos previstos no UNICODE, não sendo necessária maior elaboração.

No formato UTF-8, os caracteres tem códigos de tamanho variável, podendo ocupar de 1 a 4 bytes. O código de um caracter tem tamanho mínimo de um byte (8 bits); se seu código necessitar de mais espaço para ser representado, o formato UTF-8 utiliza mais bytes. Uma característica importante é que a codificação UTF-8 é compatível com o padrão ASCII, ou seja, os 128 caracteres associados aos códigos de 0 a 0x7F em ASCII tem a mesma representação em UTF-8.

A tabela a seguir indica para cada faixa de valores de códigos UNICODE o número de bytes necessários para representá-los e a codificação usada para essa faixa.

Código UNICODE Representação UTF-8
U+0000 - U+007F0xxxxxxx
U+0080 - U+07FF110xxxxx 10xxxxxx
U+0800 - U+FFFF1110xxxx 10xxxxxx 10xxxxxx
U+10000 - U+10FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Note que:

Exemplos:

  1. O símbolo © tem código UNICODE U+00A9.

    Em binário A9 é 1010 1001. Usando a codificação de 2 bytes para a faixa U+0080 - U+07FF temos:

    11000010 10101001 = 0xC2 0xA9

  2. O símbolo ≠ tem código UNICODE U+2260.

    Em binário 2260 é 0010 0010 0110 0000. Usando a codificação de 3 bytes para a faixa U+0800 - U+FFFF temos:

    11100010 10001001 10100000 = 0xE2 0x89 0xA0




Funções de transformação

Conversão UTF-8 para UTF-32:

A função utf8_32 deve ler o conteúdo de um arquivo de entrada (um texto codificado em UTF-8) e gravar em um arquivo de saída esse mesmo texto, codificado em UTF-32. No arquivo com formato UTF-32, os quatro primeiros bytes indicam se os valores inteiros após esses quatro bytes estão little-endian ou big-endian. A sequência 0x00 0x00 0xFE 0xFF indica que os inteiros que representam códigos de caracteres estão em big-endian. A sequência 0xFF 0xFE 0x00 0x00 indica que os inteiros que representam códigos de caracteres estão em little-endian.

O protótipo (cabeçalho) da função utf8_32 é o seguinte:

  int utf8_32(FILE *arq_entrada, FILE *arq_saida, int ordem);
Os dois primeiros parâmetros da função são dois arquivos binários abertos: o arquivo de entrada (arq_entrada) e o arquivo de saída (arq_saida). O terceiro parâmetro especifica a ordenação do arquivo de saída: O valor de retorno da função utf8_32 é 0, em caso de sucesso e -1, em caso de erro. Dois tipos de erros podem ocorrer: Nos dois casos, após emitir a mensagem de erro, a função deve retornar.

Conversão UTF-32 para UTF-8:

A função utf32_8 deve ler o conteúdo de um arquivo de entrada (um texto codificado em UTF-32) e gravar em um arquivo de saída esse mesmo texto, codificado em UTF-8. O protótipo da função é o seguinte:
  int utf32_8(FILE *arq_entrada, FILE *arq_saida);
Os parâmetros da função são dois arquivos binários abertos: o arquivo de entrada (arq_entrada) e o arquivo de saída (arq_saida). Note que, neste caso, a própria função descobre a ordenação do arquivo de entrada (UTF-32), inspecionando os primeiros quatro bytes do seu conteúdo.

Assim como na função anterior, o valor de retorno é 0, em caso de sucesso e -1, em caso de erro. Da mesma forma, os procedimentos para os casos de erro são:



Implementação e Execução

Você deve criar um arquivo fonte chamado utft.c contendo as duas funções descritas acima, e funções auxiliares, se for o caso. Esse arquivo não deve conter uma função main. Para testar seu programa, crie um outro arquivo, teste.c, contendo a função main. Crie seu programa executável teste com a linha:
  gcc -Wall -o teste utft.c teste.c
Tanto o arquivo utft.c como teste.c devem conter a linha:
#include "utft.h"
O arquivo utft.h deve conter apenas os protótipos (cabeçalhos) das funções utf32_8 e utf8_32.


Exemplos para teste

Para testar suas funções você pode usar os arquivos abaixo:

Entrega

Os trabalhos deverão ser enviados por email para o professor da turma, com subject/assunto "Trabalho 1 - Software Basico". Indique claramente os integrantes do grupo no corpo do e-mail e anexe os seguintes arquivos:

  1. o arquivo utft.c
  2. um arquivo texto contendo um pequeno relatório explicando o que está funcionando e também (muito importante!) o que não está funcionando. Se seu programa tem bugs, você saber disso é um atenuante...
Coloque no início do arquivo fonte, como comentário, os nomes dos integrantes do grupo, na seguinte forma:
    /* Nome_do_Aluno1 Matricula1 Turma*/
    /* Nome_do_Aluno2 Matricula2 Turma*/
Coloque também no relatório os nomes dos integrantes do grupo.


Prazo

O trabalho deve ser enviado por email ao professor da turma até a meia-noite do dia 23 de abril.



Observações: