X-Git-Url: https://git.llucax.com/z.facultad/75.06/emufs.git/blobdiff_plain/46453eaa7a7cbd8a43d9bbebda683814b13a832c..baf79a90e2addd39a342fcb910bbfdb6ee6623cf:/emufs/idx.c

diff --git a/emufs/idx.c b/emufs/idx.c
index 9ae481a..6e33fda 100644
--- a/emufs/idx.c
+++ b/emufs/idx.c
@@ -36,6 +36,9 @@
  */
 
 #include "idx.h"
+#include "did.h"
+#include "error.h"
+#include "common.h"
 #include <stdlib.h>
 #include <strings.h>
 #include <unistd.h>
@@ -49,7 +52,6 @@ FILE* emufs_idx_abrir(EMUFS* efs, const char* mode)
 	filename = (char*) malloc(sizeof(char) * (strlen(efs->nombre)
 				+ strlen(EMUFS_IDX_EXT) + 1));
 	if (filename == NULL) {
-		/* TODO Manejo de errores */
 		return NULL;
 	}
 	strcpy(filename, efs->nombre);
@@ -66,63 +68,71 @@ int emufs_idx_crear(EMUFS *efs)
 }
 
 /* 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) ){
-		/* Me aseguro de leer la cantidad de bytes correcta */
-		if (fread(&reg,sizeof(EMUFS_IDX),1,f_idx) != 1) continue;
-		if (reg.n_idreg >= max) {
-			max = reg.n_idreg;
-			found = 1;
-		}
+	if ((f_idx = fopen(name_f_idx, "rb")) == NULL) {
+		PERR("No se puede abrir archivo");
+		*err = EMUFS_ERROR_CANT_OPEN_FILE;
+		return EMUFS_NOT_FOUND;
+	}
+
+	/* Voy a la ultima entrada */
+	if (fseek(f_idx, -sizeof(EMUFS_IDX), SEEK_END) != 0) {
+		fclose(f_idx);
+		return 0;
+	}
+	
+	if (fread(&reg, sizeof(EMUFS_IDX), 1, f_idx) == 1) {
+		found = 1;
+		max = reg.id_reg;
 	}
 	fclose(f_idx);
 	
-	if (!found)
-		return (0);
-	else
-		return(max+1);
+	if (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 */
-EMUFS_BLOCK_ID emufs_idx_buscar_registro(EMUFS *emu, EMUFS_REG_ID n_IdReg)
+EMUFS_BLOCK_ID emufs_idx_buscar_registro(EMUFS *emu, EMUFS_REG_ID reg_id)
 {
 	FILE* f_idx;
 	EMUFS_IDX reg;
 	char name_f_idx[255];
-	unsigned short int b_Found = 0;
 	
 	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*/
+	if ((f_idx = fopen(name_f_idx, "rb")) == NULL) {
+		PERR("No se puede abrir archivo");
+		/* *err = EMUFS_ERROR_CANT_OPEN_FILE; */
+		return EMUFS_NOT_FOUND;
+	}
 
-	while (!feof(f_idx) && !b_Found){
-		if (fread(&reg,sizeof(EMUFS_IDX),1,f_idx) != 1) continue;
-		if (reg.n_idreg == n_IdReg) b_Found = 1;
+	/* Me muevo a la posicion pedida */
+	if (fseek(f_idx, sizeof(EMUFS_IDX)*reg_id, SEEK_SET) == 0) {
+		if (fread(&reg, sizeof(EMUFS_IDX), 1, f_idx) == 1) {
+			fclose(f_idx);
+			return reg.location;
+		}
 	}
-	
 	fclose(f_idx);
-	
-	/* Sino lo encontre devuelvo uno, otherwise el offset o bloque */
-	if (!b_Found)
-		return(-1);
-	else
-		return(reg.n_location);
+
+	return EMUFS_NOT_FOUND;
 }
 
-/* agrega un registro al final del archivo */
-int emufs_idx_agregar(EMUFS *emu, EMUFS_REG_ID n_idreg, EMUFS_BLOCK_ID n_location)
+int emufs_idx_agregar(EMUFS *emu, EMUFS_REG_ID id_reg, EMUFS_BLOCK_ID location)
 {
 	FILE *f_idx;
 	EMUFS_IDX reg;
@@ -131,69 +141,149 @@ int emufs_idx_agregar(EMUFS *emu, EMUFS_REG_ID n_idreg, EMUFS_BLOCK_ID n_locatio
 	strcpy(name_f_idx,emu->nombre);
 	strcat(name_f_idx, EMUFS_IDX_EXT);
 
-	if ( (f_idx = fopen(name_f_idx,"a+"))==NULL ) return -1;
-		
-    /* Note: Location = Bloque para Tipo 1 y 3, Offset para Tipo 2 */
-    reg.n_idreg = n_idreg;
-		reg.n_location = n_location;
+	if ( (f_idx = fopen(name_f_idx,"r+"))==NULL ) return -1;
+
+	fseek(f_idx, sizeof(EMUFS_IDX)*id_reg, SEEK_SET); 
+	reg.id_reg = id_reg;
+	reg.location = location;
 	fwrite(&reg,sizeof(EMUFS_IDX),1,f_idx); 
 	fclose(f_idx);
+
 	return 0;
 }
 
 /* Borra un registro del indice dada la eliminacion fisica de un reg */
-int emufs_idx_borrar(EMUFS *emu, EMUFS_REG_ID n_IdReg)
+int emufs_idx_borrar(EMUFS *emu, EMUFS_REG_ID idreg)
 {
 	FILE *f_idx;
-	EMUFS_IDX reg, *buffer;
+	EMUFS_IDX reg;
 	char name_f_idx[255];
-	long actual, final, cant, i, tam, a;
 	
 	strcpy(name_f_idx,emu->nombre);
 	strcat(name_f_idx, EMUFS_IDX_EXT);
 
-	if ( (f_idx = fopen(name_f_idx,"a+"))==NULL ) return -1;
-		
+	if ( (f_idx = fopen(name_f_idx,"r+"))==NULL ) return 1;
+
+	if (fseek(f_idx, sizeof(EMUFS_IDX)*idreg, SEEK_SET) == 0) {
+		reg.id_reg = idreg;
+		reg.location = EMUFS_NOT_FOUND;
+		fwrite(&reg, sizeof(EMUFS_IDX), 1, f_idx);
+	}
+	fclose(f_idx);
 	
-	while ( !feof(f_idx) ){
-		/*busco cual tengo que borrar*/
-		if ( fread(&reg, sizeof(EMUFS_IDX), 1, f_idx) != 1 ) continue;
-		if ( reg.n_idreg == n_IdReg )
-			break;
+	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 EMUFS_NOT_FOUND;
+		}
 	}
+
+	return id;	
+}
+
+EMUFS_REG_ID *emufs_idx_get(EMUFS *emu, EMUFS_REG_ID *cant)
+{
+	FILE *f_idx;
+	int count;
+	char name_f_idx[255];
+	EMUFS_REG_ID *tmp;
+	EMUFS_IDX reg;
 	
-	/* me paro en el que tengo que borrar */
-	fseek(f_idx, -sizeof(EMUFS_IDX), SEEK_CUR);	
-	actual = ftell(f_idx); /* Guardo la posicion actual */
-	printf(" actual  = %ld\n",actual);
-	fseek(f_idx, 0, SEEK_END); /* me voy al final */
-	final = ftell(f_idx); /* veo cuando ocupa el archivo */
-	fseek(f_idx, actual, SEEK_SET);/* vuelvo al lugar desde donde quiero justificar */
-	/*calculo cuantos registros tengo que mover */
-	cant = (final-actual)/sizeof(EMUFS_IDX);
-	buffer = (EMUFS_IDX*)malloc((cant)*sizeof(EMUFS_IDX));
-	printf("sizeof buffer = %ld\n",(cant-1)*sizeof(EMUFS_IDX));
-	/*apunto al siguiente del que quiero borrar*/
-	final = actual + sizeof(EMUFS_IDX);
-	/*leo todos los que quedan*/
-	fseek(f_idx,final,SEEK_SET);
-	fread(buffer,sizeof(EMUFS_IDX),cant-1,f_idx) ;
-/*	for( i=0; i<cant-1; i ++)
-		printf("buffer[%ld] = %ld , %ld\n",i,*(buffer+i),*(buffer+2*i));*/
-	/*apunto al lugar donde deben ser guardados*/
-	fseek(f_idx,actual,SEEK_SET);
-	printf(" actual  = %ld\n",actual);
-	/*los guardo*/
-	fwrite(buffer,sizeof(EMUFS_IDX),cant-1,f_idx);
+	strcpy(name_f_idx,emu->nombre);
+	strcat(name_f_idx, EMUFS_IDX_EXT);
+
+	if ( (f_idx = fopen(name_f_idx, "rb"))==NULL){
+		PERR("No se pudo abrir el archvo");
+		(*cant) = EMUFS_NOT_FOUND;
+		return NULL;
+	}
+
+	tmp = NULL;
+	count = 0;
+	while (!feof(f_idx)) {
+		if (fread(&reg, sizeof(EMUFS_IDX), 1, f_idx) != 1) continue;
+		if (reg.location != EMUFS_NOT_FOUND) {
+			count++;
+			tmp = realloc(tmp, count*sizeof(EMUFS_REG_ID));
+			tmp[count-1] = reg.id_reg;
+		}
+	}
+	fclose(f_idx);
+
+	(*cant) = count;
+	return tmp;
+}
+
+/** @todo FIXME borrar cuando se cambie emufs_gui/registros.c que es el unico
+ * que lo usa.
+ * @deprecated Usar emufs_idx_buscar_registro.
+ */
+int emufs_idx_existe_id(EMUFS *emu, int ID)
+{
+	FILE *f_idx;
+	char name_f_idx[255];
+	EMUFS_IDX reg;
 	
+	strcpy(name_f_idx,emu->nombre);
+	strcat(name_f_idx, EMUFS_IDX_EXT);
 
-	fseek (f_idx, -sizeof(EMUFS_IDX),SEEK_END);
-	tam = ftell(f_idx);
+	if ( (f_idx = fopen(name_f_idx, "rb")) == NULL){
+		PERR("No se pudo abrir el archivo");
+		return -1;
+	}
+	
+	if (fseek(f_idx, sizeof(EMUFS_IDX)*ID, SEEK_SET) == 0) {
+		fread(&reg, sizeof(EMUFS_IDX), 1, f_idx);
+		if (reg.location != EMUFS_NOT_FOUND) {
+			fclose(f_idx);
+			return 0;
+		}
+	}
 	fclose(f_idx);
-	if ( truncate(name_f_idx, actual+(cant-1)*sizeof(EMUFS_IDX))!= 0) 
-		printf("no pude truncar\n");
-	else printf("TRUNKE!!!!\n");
+	return -1;/*no existe el id*/
+}
+
+int emufs_idx_actualizar(EMUFS *emu, int ID, EMUFS_BLOCK_ID bloque)
+{
+	FILE *f_idx;
+	char name_f_idx[255];
+	EMUFS_IDX reg;
 	
-	free(buffer);
+	strcpy(name_f_idx,emu->nombre);
+	strcat(name_f_idx, EMUFS_IDX_EXT);
+
+	if ( (f_idx = fopen(name_f_idx, "r+")) == NULL){
+		PERR("No se pudo abrir el archivo");
+		return -1;
+	}
+	fseek(f_idx,0,SEEK_SET);
+	fseek(f_idx,ID*sizeof(EMUFS_IDX),SEEK_SET);
+	fread(&reg,sizeof(EMUFS_IDX),1,f_idx);
+	reg.location = bloque;
+	fseek(f_idx,-sizeof(EMUFS_IDX),SEEK_CUR);
+	fwrite(&reg,sizeof(EMUFS_IDX),1,f_idx);
+	fclose(f_idx);
 	return 0;
 }
+
+long emufs_idx_get_file_size(EMUFS* efs, int* err)
+{
+	char name[255];
+	strcpy(name, efs->nombre);
+	strcat(name, EMUFS_IDX_EXT);
+	return emufs_common_get_file_size(name, err);
+}
+