INF1018 - Software Básico - 2010.2

Primeiro Trabalho

Exemplos para teste

Os arquivos tem o mesmo texto, codificado em UTF-8 e UTF-32!

Codificação UTF

Caracteres de um texto são em geral representados em C pelo tipo char, que tipicamente num PC 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 conjuntamente caracteres dos diferentes alfabetos utilizados pelos 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 atualmente é 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 (1114112 valores). 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.

Já no formato UTF-8, os caracteres tem tamanho variável, podendo ocupar de 1 a 4 bytes. Um caracter tem tamanho mínimo de 8 bits; se seu código necessitar de mais espaço para ser representado, o formato UTF-8 utiliza mais bytes para representá-lo. 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+007F        0xxxxxxx
 U+0080  - U+07FF        110xxxxx 10xxxxxx
 U+0800  - U+FFFF        1110xxxx 10xxxxxx 10xxxxxx
 U+10000 - U+10FFFF      11110xxx 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

Objetivo do trabalho:

O trabalho consiste em implementar, na linguagem C, duas funções (utf32to8 e utf8to32) que realizam a transformação entre as representações UTF-32 e UTF-8. A função utf32to8 tem o seguinte protótipo (cabeçalho):
  int utf32to8(FILE *arq_entrada, FILE *arq_saida);
Ela recebe como parâmetros dois arquivos binários abertos: um arquivo de entrada (arq_entrada) e um arquivo (vazio) de saída (arq_saida). A função deve ler o conteúdo do arquivo de entrada, um texto codificado em UTF-32, e gravar no arquivo de saída esse mesmo texto codificado em UTF-8. Retorna 0 em caso de sucesso, e -1 em caso de erro.

A função utf8to32 tem protótipo semelhante:

  int utf8to32(FILE *arq_entrada, FILE *arq_saida);
Ela deve ler o conteúdo do arquivo de entrada, um texto codificado em UTF-8, e gravar no arquivo de saída esse mesmo texto codificado em UTF-32. Retorna 0 em caso de sucesso, e -1 em caso de erro.

No caso do formato UTF-32, os quatro primeiros bytes do arquivo indicam se os valores a seguir estão little-endian ou big-endian. A sequência 0x00 0x00 0xFE 0xFF indica que os caracteres a seguir estão em big-endian. A sequência 0xFF 0xFE 0x00 0x00 indica que os caracteres a seguir estão em little-endian. A saída codificada em UTF-32 deve sempre utilizar a ordenação little-endian. 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 utfconv.c teste.c
Tanto o arquivo utfconv.c como teste.c devem conter a linha:
#include <utfconv.h>
O arquivo utfconv.h deve conter apenas os protótipos (cabeçalhos) das funções utf32to8 e utf8to32.

Entrega

Deve ser entregue um único arquivo, utfconv.c contendo as duas funções acima e outras que tiverem sido desenvolvidas como auxiliares. Esse arquivo * não * deve conter uma função main.

Prazo

O trabalho deve ser entregue no dia 29 de setembro.

Observações