return emufs_crear_archivo_auxiliar(efs->nombre, EMUFS_DID_EXT);
}
-EMUFS_REG_ID emufs_did_get_last(EMUFS *efs)
+EMUFS_REG_ID emufs_did_get_last(EMUFS *efs, int* err)
{
FILE *f_did;
EMUFS_REG_ID n_regid;
EMUFS_OFFSET n_offset;
char name_f_did[255];
+ long pos;
strcpy(name_f_did, efs->nombre);
strcat(name_f_did, EMUFS_DID_EXT);
- if ( (f_did = fopen(name_f_did,"r")) == NULL) return -1; /*ERROR*/
- fseek(f_did, 0, SEEK_END);
+ if ((f_did = fopen(name_f_did, "rb")) == NULL) {
+ PERR("No se puede abrir archivo");
+ *err = 4; /* EMUFS_ERROR_CANT_OPEN_FILE */
+ return EMUFS_NOT_FOUND;
+ }
+ if (fseek(f_did, 0l, SEEK_END)) {
+ PERR("No se pudo hacer fseek()");
+ fclose(f_did);
+ *err = 8; /* EMUFS_ERROR_SEEK_FILE */
+ return EMUFS_NOT_FOUND;
+ }
- if (ftell(f_did) > 0){
+ if ((pos = ftell(f_did)) > 0){
/* si el archivo no esta vacio es porque hay un nro disponible*/
- fseek(f_did, -sizeof(EMUFS_REG_ID),SEEK_END);
+ if (fseek(f_did, -sizeof(EMUFS_REG_ID), SEEK_END)) {
+ PERR("No se pudo hacer fseek()");
+ fclose(f_did);
+ *err = 8; /* EMUFS_ERROR_SEEK_FILE */
+ return EMUFS_NOT_FOUND;
+ }
/* leo el ultimo numero */
- fread(&n_regid,sizeof(EMUFS_REG_ID),1,f_did);
+ if (fread(&n_regid, sizeof(EMUFS_REG_ID), 1, f_did) != 1) {
+ fclose(f_did);
+ PERR("Error al leer did");
+ *err = 3; /* EMUFS_ERROR_FILE_READ */
+ return NULL;
+ }
/* voy al final */
- fseek(f_did, 0, SEEK_END);
- /* mido el tamaño del archivo*/
- n_offset = ftell(f_did);
+ if (fseek(f_did, 0l, SEEK_END)) {
+ PERR("No se pudo hacer fseek()");
+ fclose(f_did);
+ *err = 8; /* EMUFS_ERROR_SEEK_FILE */
+ return EMUFS_NOT_FOUND;
+ }
+ /* mido el tamaño del archivo */
+ if ((n_offset = ftell(f_did)) == -1) {
+ PERR("No se pudo hacer ftell()");
+ fclose(f_did);
+ *err = 9; /* EMUFS_ERROR_TELL_FILE */
+ return EMUFS_NOT_FOUND;
+ }
fclose(f_did);
- /*lo trunco */
- truncate(name_f_did, n_offset - sizeof(EMUFS_REG_ID));
- } else {
+ /* lo trunco */
+ if (truncate(name_f_did, n_offset - sizeof(EMUFS_REG_ID))) {
+ PERR("No se pudo truncar el archivo did");
+ *err = 10; /* EMUFS_ERROR_TRUNCATE_FILE */
+ return EMUFS_NOT_FOUND;
+ }
+ } else if (!pos) {
fclose(f_did);
/* si el archivo esta vacio */
n_regid = EMUFS_NOT_FOUND;
+ } else {
+ PERR("No se pudo hacer ftell()");
+ fclose(f_did);
+ *err = 9; /* EMUFS_ERROR_TELL_FILE */
+ return EMUFS_NOT_FOUND;
}
return n_regid;
}
/* Agrega un registro al archivo de ID's Libres (pila) */
int emufs_did_agregar(EMUFS *, EMUFS_REG_ID);
/* Devuelve el ID Libre, liberado mas recientemente (pila) */
-EMUFS_REG_ID emufs_did_get_last(EMUFS *);
+EMUFS_REG_ID emufs_did_get_last(EMUFS*, int*);
#endif /* _EMUFS_DID_H */
#include <stdlib.h>
#include <stdio.h>
+#ifdef DEBUG
+ /** Imprime un mensaje de debug por pantalla. */
+ #define PERR(msg) fprintf(stderr, "%s:%d> %s.\n",__FILE__, __LINE__, msg);
+#else
+ #define PERR(msg) ;
+#endif /* DEBUG */
+
/** Tipo de archivo. */
typedef enum {
T1, /**< Archivo de bloque parametrizado y registro variable. */
*/
#include "idx.h"
+#include "did.h"
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
}
/* Devuelve el mayor id de registro utilizado so far en el archivo de datos, revisando el indice. */
-EMUFS_REG_ID emufs_idx_buscar_mayor_id(EMUFS *emu)
+EMUFS_REG_ID emufs_idx_buscar_mayor_id_libre(EMUFS* emu, int* err)
{
EMUFS_REG_ID max = 0;
- FILE *f_idx;
+ FILE* f_idx;
EMUFS_IDX reg;
char name_f_idx[255]; /* TODO usar malloc para no limitar el tamaño de nombre de archivo */
- char found = 0;
+ int found = 0;
- strcpy(name_f_idx,emu->nombre);
+ strcpy(name_f_idx, emu->nombre);
strcat(name_f_idx, EMUFS_IDX_EXT);
- if ( (f_idx = fopen(name_f_idx,"r")) == NULL) return -1; /*ERROR*/
- while ( !feof(f_idx) ){
+ if ((f_idx = fopen(name_f_idx, "rb")) == NULL) {
+ PERR("No se puede abrir archivo");
+ *err = 4; /* EMUFS_ERROR_CANT_OPEN_FILE */
+ return EMUFS_NOT_FOUND;
+ }
+ while (!feof(f_idx)) {
/* Me aseguro de leer la cantidad de bytes correcta */
- if (fread(®,sizeof(EMUFS_IDX),1,f_idx) != 1) continue;
+ if (fread(®, sizeof(EMUFS_IDX), 1, f_idx) != 1) {
+ PERR("Error al leer registros de idx");
+ *err = 3; /* EMUFS_ERROR_FILE_READ */
+ return EMUFS_NOT_FOUND;
+ }
if (reg.n_idreg >= max) {
max = reg.n_idreg;
found = 1;
}
}
fclose(f_idx);
-
- if (!found)
- return (0);
- else
- return(max+1);
+
+ if (b_found) {
+ return ++max;
+ } else {
+ return 0;
+ }
}
/* busca el registro ID en el archivo ".idx" y devuelve el nro de bloque en el que se encuentra */
free(buffer);
return 0;
}
+
+EMUFS_REG_ID emufs_idx_get_new_id(EMUFS* efs, int* err)
+{
+ EMUFS_REG_ID id;
+
+ id = emufs_did_get_last(efs, err);
+ if (id == EMUFS_NOT_FOUND) {
+ if (*err) {
+ PERR("error al obtener ultimo id");
+ return id;
+ }
+ id = emufs_idx_buscar_mayor_id_libre(efs, err);
+ if (*err) {
+ PERR("error al obtener id mayor");
+ return id;
+ }
+ }
+ return id;
+}
+
} EMUFS_IDX;
FILE* emufs_idx_abrir(EMUFS*, const char*);
+
int emufs_idx_crear(EMUFS*);
-EMUFS_REG_ID emufs_idx_buscar_mayor_id(EMUFS *);
-EMUFS_BLOCK_ID emufs_idx_buscar_registro(EMUFS *, EMUFS_REG_ID);
-int emufs_idx_agregar(EMUFS *, EMUFS_BLOCK_ID, EMUFS_REG_ID);
-int emufs_idx_borrar(EMUFS *emu, EMUFS_REG_ID);
+
+EMUFS_REG_ID emufs_idx_buscar_mayor_id_libre(EMUFS*, int*);
+
+EMUFS_BLOCK_ID emufs_idx_buscar_registro(EMUFS*, EMUFS_REG_ID);
+
+int emufs_idx_agregar(EMUFS*, EMUFS_BLOCK_ID, EMUFS_REG_ID);
+
+int emufs_idx_borrar(EMUFS*, EMUFS_REG_ID);
+
+EMUFS_REG_ID emufs_idx_get_new_id(EMUFS*, int*);
#endif /* _EMUFS_IDX_H */
#include <string.h>
#include <unistd.h>
-#define PERR(msg) printf("%s:%d> %s.\n",__FILE__, __LINE__, msg);
-
/*------------------ Funciones privadas ----------------------*/
int emufs_tipo1_header_jump(FILE*);
return EMUFS_NOT_FOUND;
}
/* graba el registro al principio del bloque */
- reg_id = emufs_tipo1_get_id(efs);
+ reg_id = emufs_idx_get_new_id(efs, err);
/* graba registro en bloque */
emufs_tipo1_escribir_reg_en_memoria(block, reg_id, reg_size, reg);
/* graba el bloque en el archivo */
}
/* inserta el registro en el bloque */
/* tengo que buscar un ID válido para el nuevo registro */
- reg_id = emufs_tipo1_get_id(efs);
+ reg_id = emufs_idx_get_new_id(efs, err);
/* graba registro en bloque */
emufs_tipo1_escribir_reg_en_memoria(block + efs->tam_bloque - fs,
reg_id, reg_size, reg);
return block_id;
}
-/*Busco en el archivo de Id`s un Id valido para un nuevo registro*/
-EMUFS_REG_ID emufs_tipo1_get_id(EMUFS *emu)
-{
- return -1; /* FIXME Error */
-}
-
/*borra un registro de un bloque y acomoda los registros que quedan*/
int emufs_tipo1_buscar_registro(EMUFS *emu, EMUFS_REG_ID id_reg)
{
/** Graba el bloque apuntado por \param ptr en el archivo */
EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS*, void*, EMUFS_BLOCK_ID, int*);
-EMUFS_REG_ID emufs_tipo1_get_id(EMUFS*);
-
int emufs_tipo1_buscar_registro(EMUFS*, EMUFS_REG_ID);
int emufs_tipo1_borrar_registro(EMUFS*, EMUFS_REG_ID, EMUFS_REG_SIZE);
int main(int argc, char* argv[]) {
EMUFS* efs;
+
if (argc < 2) {
printf("Faltan argumentos! %s [nombre]\n", argv[0]);
return 1;
return 1;
}
return 0;
- */
efs = emufs_abrir(argv[1]);
if (!efs) {
return 1;
}
+ if (!efs->leer_registro(efs, 0, registro1) == -1) {
+ printf("No se pudo leer el registro 1.\n");
+ return 1;
+ }
+ registro1[4] = '\0';
+ printf("Registro 1: %s\n", registro1);
+
/*
if (efs->leer_registro(efs, 1, registro2, 5) == -1) {
printf("No se pudo leer el registro 2.\n");
printf("Registro 2: %s\n", registro2);
*/
- emufs_destruir(efs);
+ /*emufs_destruir(efs);*/
return 0;
}
if (n_WrtOffset == -1) {
/* Obtengo un ID libre para el registro y luego grabo a disco */
- n_IdReg = emufs_tipo2_get_id(efs);
+ n_IdReg = emufs_idx_get_new_id(efs, err);
fseek(f_data, 0, SEEK_END);
n_RegOffset = ftell(f_data);
return (0);
}
-/**********************************************************************/
-/* EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *efs) */
-/* Objetivo: Devuelve un Id apropiado y disponible para un nuevo reg */
-/* Parametros: EMUFS *emu // Struct con handlers + info del openfile. */
-/**********************************************************************/
-EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *efs)
-{
- EMUFS_REG_ID n_RegId;
-
- /* Si no se hallo un id libre, entonces debo usar el maximo + 1 */
- if ( (n_RegId = emufs_did_get_last(efs)) == -1 )
- n_RegId = emufs_idx_buscar_mayor_id(efs);
-
- return n_RegId;
-}
EMUFS_REG_ID emufs_tipo2_grabar_registro(EMUFS *, void *, EMUFS_REG_SIZE, int*);
int emufs_tipo2_borrar_registro(EMUFS*, EMUFS_REG_ID);
-EMUFS_REG_ID emufs_tipo2_get_id(EMUFS *);
int emufs_tipo2_get_regsize(EMUFS *efs, EMUFS_OFFSET n_RegPos,EMUFS_REG_SIZE *n_RegSize);
int emufs_tipo2_dummyfill(EMUFS *efs, EMUFS_OFFSET n_RegPos,EMUFS_REG_SIZE n_Amount);
bloque = (char*)malloc(emu->tam_bloque);
/* grabar el registro al principio del bloque */
/*tengo que buscar un ID valido para el nuevo registro*/
- ID_aux = emufs_tipo3_get_id(emu);
+ ID_aux = emufs_idx_get_new_id(emu, err);
/*grabo el id en el bloque*/
memcpy(bloque,&ID_aux,sizeof(EMUFS_REG_ID));
/*grabo el registro en el bloque*/
/*El error puede haberse producido porque la funcion leer_bloque devolvio -1, el cual es un bloque invalido*/
/*insertar el registro en el bloque*/
/*tengo que buscar un ID valido para el nuevo registro*/
- ID_aux = emufs_tipo3_get_id(emu);
+ ID_aux = emufs_idx_get_new_id(emu, err);
/*grabo el id en el bloque*/
memcpy(bloque+emu->tam_bloque-fs,&ID_aux,sizeof(EMUFS_REG_ID));
/*grabo el registro en el bloque*/
return ID_aux;
}
-/*Busco en el archivo de Id`s un Id valido para un nuevo registro*/
-EMUFS_REG_ID emufs_tipo3_get_id(EMUFS *emu)
-{
- EMUFS_REG_ID id;
-
- if ( (id = emufs_did_get_last(emu)) == EMUFS_NOT_FOUND )
- id = emufs_idx_buscar_mayor_id(emu);
- return id;
-}
-
/*Graba un bloque en el archivo*/
int emufs_tipo3_grabar_bloque(EMUFS *emu, void *ptr, EMUFS_BLOCK_ID num)
{
int emufs_tipo3_borrar_registro(EMUFS *emu, EMUFS_REG_ID id_reg);
-EMUFS_REG_ID emufs_tipo3_get_id(EMUFS *emu);
-
int emufs_tipo3_buscar_registro(EMUFS *emu, EMUFS_REG_ID id_reg);
#endif /* _EMUFS_TIPO3_H_ */
{
EMUFS *fp;
EMUFS_REG_ID n1, n2, n3, n4, n5, n6, n7, n8;
- EMUFS_REG_SIZE size;
+ EMUFS_REG_SIZE reg_size;
char a[100];
char b[100];
char c[100];
fp->borrar_registro(fp, n3);
printf("borre el registro de id = %lu\n",n3);
- b_ptr = fp->leer_registro(fp, n2, &size, &err);
+ b_ptr = fp->leer_registro(fp, n2, ®_size, &err);
printf("Recuperado : %s\n", b_ptr);