INF1018 - Software Básico - 2010.1

Primeiro Trabalho

Gravação compactada

O objetivo desse trabalho é escrever uma função gravacompactado que escreva um array de structs em um arquivo binário de forma compacta, isto é, sem padding, e uma função dump para visualizar o resultado gerado.

A função gravacompactado deve receber como argumentos o tamanho (número de elementos) do array de structs a ser escrito em arquivo, o array de structs propriamente dito, uma descrição dos structs que compõem o array (descrição dos campos), um valor indicando se os valores básicos contidos nesses campos devem ser armazenados no arquivo em little endian ou big endian, e um arquivo aberto, seguindo o protótipo a seguir:

int gravacompactado ( void* valores, int tamanho, char campos[], int little, FILE *arquivo); 

O array campos armazena valores inteiros representando, na ordem, os tipos de cada campo dos structs a serem armazenados no arquivo de acordo com o código a seguir:

char		1
short int       2
int     	3
fim     	0

Como exemplo, dada a declaração:

struct s {
  short s1;
  int i1;
  char c1;
  int i2;
  short s2;
  char c2;
};
struct s exemplo[10];
se o array S for passado para gravacompactado, o argumento campos deveria ter o valor {2,3,1,3,2,1,0}.

O formato do arquivo de saída deve ser o seguinte.

Em seguida, aparecem os bytes com os dados do array de structs. Não devem ser escritos no arquivo os bytes relativos a padding.

Voltando ao caso do array exemplo, o início do arquivo ficaria assim:

| 1101 1011 | /* supondo little endian */
| 1100 100l | /* +12 bits contendo a descrição dos 6 campos */
| 0000 1010 | /* há 10 structs neste arquivo */
| xxxx xxxx | /* aqui começam os dados desses 10 structs */
| ....      |

Nesse exemplo, na memória de um IA-32 executando Linux, cada struct ocuparia 20 bytes. Ao ser armazenado em arquivo por gravacompactado, esse mesmo struct ocuparia 14 bytes.

A função dump permite a visualização de um arquivo gerado pela gravacompactado. Seu protótipo é simplesmente:

void dump (FILE *arquivo); 
A saída dessa função deve ser a seguinte (não é necessário considerar erros na entrada): Como exemplo, para o mesmo arquivo discutido acima, a saída de dump seria:
little
2 short
3 int
1 char
3 int
2 short
1 char
10
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx 
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx 
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx 
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx 
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx
xx xx xx xx xx xx
xx xx xx xx xx xx xx xx 
xx xx xx xx xx xx
(onde os "xx" correspondem aos valores dos campos dos structs)

Entrega

Deve ser entregue um único arquivo, compacta.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.

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 compacta.c teste.c

Tanto o arquivo compacta.c como teste.c devem conter a linha:

#include <gravacompactado.h>
e o arquivo gravacompactado.h usado deve conter apenas os protótipos (cabeçalhos) das funções gravacompactado e dump.

Prazo

O trabalho deve ser entregue no dia 3/5.

Observações