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.
Las funciones de ficheros tambi�n entienden varios nombres "m�gicos" que pueden ser usados por varios motivos. Estos nombres son:
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().