26 Rutinas de ficheros y compresi�n



Las siguientes rutinas implementan un sistema de ficheros I/O con buffer r�pido, que soporta la lectura y escritura de ficheros comprimidos usando un algoritmo de buffer de anillo basado en el compresor LZSS de Haruhiko Okumura. Esto no consigue tan buenas compresiones como zip o lha, pero la descompresi�n es muy r�pida y no requiere mucha memoria. Los ficheros comprimidos siempre comienzan con el valor de 32 bits F_PACK_MAGIC, y autodetecta ficheros con el valor F_NOPACK_MAGIC.

char *fix_filename_case(char *path);
Convierte un nombre de fichero a un estado estandarizado. En platadormas DOS, los nombres ser�n todo may�sculas. Devuelve una copia del par�metro de camino.

char *fix_filename_slashes(char *path);
Convierte los separadores de directorios de un nombre de fichero a un car�cter est�ndar. En plataformas DOS, esto es la antibarra. Devuelve una copia del par�metro de camino.

char *fix_filename_path(char *dest, char *path, int size);
Convierte un nombre de fichero parcial en un camino completo, generando hasta el m�ximo n�mero de car�cteres especificados. Devuelve una copia del par�metro dest.

char *replace_filename(char *dest, char *path, char *filename, int size);
Sustituye el camino+nombre de fichero especificados con un nuevo nombre de fichero, generando hasta el m�ximo n�mero de car�cteres especificados. Devuelve una copia del par�metro dest.

char *replace_extension(char *dest, char *filename, char *ext, int size);
Sustituye el nombre de fichero+extensi�n especificados con una nueva extensi�n, generando hasta el m�ximo n�mero de car�cteres especificados. Devuelve una copia del par�metro dest.

char *append_filename(char *dest, char *path, char *filename, int size);
Concatena el nombre de fichero especificado al final del camino especificado, generando hasta el m�ximo n�mero de car�cteres especificados. Devuelve una copia del par�metro dest.

char *get_filename(char *path);
Cuando se le pasa el path espec�fico de un fichero, devuelve un puntero a la porci�n del nombre del fichero. Tanto '\' como '/' son reconocidos como separadores de directorios.

char *get_extension(char *filename);
Cuando se le pasa un nombre de fichero completo (con o sin informaci�n de path) devuelve un puntero a la extensi�n del fichero.

void put_backslash(char *filename);
Si el �ltimo caracter de un nombre no es '\' o '/', esta rutina le a�adir� '\'.

int file_exists(char *filename, int attrib, int *aret);
Chequea la existencia de un fichero de nombre y atributos dados, devolviendo no-cero si el fichero existe. Los atributos pueden contener cualquiera de las constantes FA_* de dir.h. Si aret no es NULL, ser� fijado a los atributos del fichero existente. Si ocurre un error, el c�digo de error de sistema ser� almacenado en errno.

int exists(char *filename);
Versi�n reducida de file_exists(), que chequea la existencia de ficheros normales, los cuales pueden tener los bits de archivo o s�lo lectura activados, pero no son ocultos, directorios, ficheros de sistema, etc.

long file_size(char *filename);
Devuelve el tama�o del fichero en bytes. Si el fichero no existe u ocurre un error, devolver� cero y almacenar� el c�digo de error de sistema en errno.

long file_time(char *filename);
Devuelve el tiempo de modificaci�n de un fichero.

int delete_file(char *filename);
Borra un fichero.

int for_each_file(char *name, int attrib, void (*callback)(), int param);
Encuentra todos los ficheros que se ajusten al nombre (ej: *.exe) y atributos especificados, y ejecuta callback() por cada uno de ellos. A callback() se le pasan tres par�metros, el primero es la cadena que contiene el nombre completo del fichero, el segundo los atributos del fichero, y el tercer par�metro es un entero que es copia de param (puede usar esto para lo que quiera). Si ocurre un error, el c�digo de error ser� almacenado en errno, y callback() puede abortar for_each_file al activar errno. Devuelve el n�mero de llamadas con �xito hechas a callback(). Los atributos de fichero pueden contener cualquiera de los biestables FA_* de dir.h.

void packfile_password(char *password);
Activa el password de encriptaci�n que ser� usado para todas las operaciones de escritura/lectura de ficheros comprimidos. Los ficheros escritos con un password no pueden ser le�dos a no ser que se seleccione el password correcto, por lo que cuidado: si olvida la clave, �nadie podr� recuperar su datos! Pase NULL o una cadena vac�a para volver al modo normal, no encriptado. Si est� usando esta funci�n para evitar que otros accedan a sus ficheros de datos, tenga cuidado de no salvar una copia obvia de su clave en el ejecutable: si hay cadenas como "Soy la clave del fichero de datos", ser�a muy f�cil acceder a sus datos :-)

PACKFILE *pack_fopen(char *filename, char *mode);
Abre un fichero seg�n el modo, que puede contener cualquiera de los siguientes biestables.

En vez de estos biestables, una de las constantes F_READ, FWRITE, F_READ_PACKED, F_WRITE_PACKED o F_WRITE_NOPACK puede ser usada como el par�metro de modo. Si todo funciona, pack_fopen() devuelve un puntero a una estructura de fichero, y con error, devuelve NULL y almacena el c�digo de error en errno. Un intento de leer un fichero normal en modo comprimido activar� errno a EDOM.

Las funciones de ficheros tambi�n entienden varios nombres "m�gicos" que pueden ser usados por varios motivos. Estos nombres son:

Con estos nombres especiales, los contenidos de un objeto de un fichero de datos o de un fichero a�adido pueden ser le�dos de modo id�ntico que un fichero normal, por lo que cualquiera de las funciones de acceso a ficheros de Allegro (ejemplo: load_pcx() y set_config_file()) pueden ser usadas para leerlos. Sin embargo, no podr� escribir en estos ficheros: s�lo pueden ser le�dos. Adem�s, debe tener su fichero de datos descomprimido o con compresi�n por objetos si planea leer objetos individuales (de otra manera, habr� una sobrecarga de b�squeda al ser le�do). Finalmente, tenga en cuenta que los tipos de objetos especiales de Allegro no son los mismos que los de los ficheros que importas los datos. Cuando importe datos como bitmaps o samples en el grabber, �stos son convertidos en un formato espec�fico de Allegro, pero el marcador de sintaxis de ficheros '#' lee los objetos como trozos binarios raw. Esto significa, que si por ejemplo, quiere usar load_pcx para leer una imagen de un fichero de datos, deber�a importarlos como un bloque binario en vez de un objeto BITMAP.

int pack_fclose(PACKFILE *f);
int pack_fseek(PACKFILE *f, int offset);
int pack_feof(PACKFILE *f);
int pack_ferror(PACKFILE *f);
int pack_getc(PACKFILE *f);
int pack_putc(int c, PACKFILE *f);
int pack_igetw(PACKFILE *f);
long pack_igetl(PACKFILE *f);
int pack_iputw(int w, PACKFILE *f);
long pack_iputl(long l, PACKFILE *f);
int pack_mgetw(PACKFILE *f);
long pack_mgetl(PACKFILE *f);
int pack_mputw(int w, PACKFILE *f);
long pack_mputl(long l, PACKFILE *f);
long pack_fread(void *p, long n, PACKFILE *f);
long pack_fwrite(void *p, long n, PACKFILE *f);
char *pack_fgets(char *p, int max, PACKFILE *f);
int pack_fputs(char *p, PACKFILE *f);

Todas estas funcionan como las funciones equivalentes stdio, excepto que pack_fread() y pack_fwrite() toman un s�lo par�metro de tama�o en vez de ese est�pido sistema de tama�o y num_elements, y s�lo puede avanzar en un fichero hacia delante desde la posici�n relativa actual. Las rutinas pack_i* y pack_m leen y escriben valores de 16 y 32 bits usando los sistemas de orden de Intel y Motorola respectivamente. Tome nota que la b�squeda es muy lenta cuando lea ficheros comprimidos, y que deber�a ser evitada a no ser que sepa que el fichero no est� comprimido.

PACKFILE *pack_fopen_chunk(PACKFILE *f, int pack);
Abre sub_chunks en un fichero. Los chunks son primariamente usados por el c�digo de ficheros de datos, pero pueden serle �tiles para sus propias rutinas de ficheros. Un chunk provee una vista l�gica de parte de un fichero, que puede ser comprimido como un ente individual y ser� autom�ticamente insertado y chequea los contadores de tama�o para prevenir la lectura despu�s del final del chunk. Para escribir un chunk en un fichero f, use este c�digo:

      /* Asumo que f es un PACKFILE * que ha sido abierto en modo escritura*/
      f = pack_fopen_chunk(f, pack);
      escribe datos en f
      f = pack_fclose_chunk(f);

Los datos escritos en el chunk ser�n precedidos con dos counts (32 bits, big-endian). Para descomprimir chunks, �stos ser�n ajustados al tama�o de los datos del chunk. Para chunks comprimidos (creados al ajustar el biestable pack), el primer tama�o es el tama�o real del chunk, y el segundo ser� el tama�o negativo de los datos descomprimidos.

Para leer el chunk, use este c�digo:

      /* Asumo que f es un PACKFILE * que ha sido abierto en modo escritura*/
      f = pack_fopen_chunk(f, FALSE);
      lee datos de f
      f = pack_fclose_chunk(f);

Esta secuencia leer� los counts de tama�o creados cuando el chunk fue escrito, y autom�ticamente descomprimir� el contenido del chunk si fue comprimido. El tama�o tambi�n evitar� leer despu�s del final del chunk (Allegro devolver� EOF si intenta esto), y autom�ticamente ignora los chunks no le�dos cuando llamas pack_fclose_chunk().

Los chunks pueden ser anidados unos dentro de otros al hacer llamadas repetidas a pack_fopen_chunk(). Al escribir un fichero, el estado de compresi�n es heredado del fichero padre, por lo que s�lo tiene que activar el biestable pack si el fichero padre no fue comprimido pero quiere comprimir los datos del chunk. Si el fichero padre ya est� abierto en modo comprimido, activar el biestable pack har� que los datos sean comprimidos dos veces: una cuando los datos son escritos en el chunk, y otra cuando el chunk es escrito en el fichero padre.

PACKFILE *pack_fclose_chunk(PACKFILE *f);
Cierra un sub-chunk de un fichero, que previamente ha sido obtenido al llamar pack_fopen_chunk().




Volver al Indice