static void emufs_tipo1_escribir_reg_chunk_en_memoria(char* dst,
EMUFS_TIPO1_REG_HEADER header, char* reg, EMUFS_REG_SIZE reg_size);
+/** Lee el bloque \param num_bloque y lo almacena en \c ptr. */
+static void* emufs_tipo1_leer_bloque(EMUFS*, EMUFS_BLOCK_ID, int*);
+
+/** Graba el bloque apuntado por \c ptr en el archivo. */
+static EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS*, void*, EMUFS_BLOCK_ID,
+ int*);
+
/*------------------ Funciones públicas ----------------------*/
int emufs_tipo1_inicializar(EMUFS* efs)
{
+ /* como mínimo el tamaño de bloque debe ser 2 veces el tamaño de la cabecera
+ * (una relación 1/2 entre datos e info de control ya es lo suficientemente
+ * mala */
+ if (efs->tam_bloque < (sizeof(EMUFS_TIPO1_REG_HEADER) * 2)) {
+ PERR("bloque demasiado chico");
+ return 1000; /* EMUFS_ERROR_BLOCK_SIZE_TOO_SMALL */
+ }
/* Asigna punteros a funciones. */
efs->leer_bloque = emufs_tipo1_leer_bloque;
efs->grabar_registro = emufs_tipo1_grabar_registro;
efs->borrar_registro = emufs_tipo1_borrar_registro;
efs->leer_registro = emufs_tipo1_leer_registro;
efs->leer_registro_raw = emufs_tipo1_leer_registro_raw;
- return 0;
+ efs->leer_estadisticas = emufs_tipo1_leer_estadisticas;
+ return 0; /* EMUFS_OK */
}
void* emufs_tipo1_leer_registro(EMUFS* efs, EMUFS_REG_ID reg_id,
do {
/* Copio la cabecera del registro actual. */
memcpy(&curr_reg_header, block + offset, sizeof(EMUFS_TIPO1_REG_HEADER));
- offset += sizeof(EMUFS_TIPO1_REG_HEADER);
if (curr_reg_header.id == reg_id) {
/* identificador del bloque actual */
EMUFS_BLOCK_ID curr_block_id = block_id;
return err;
}
- /* TODO desplazar a izquierda registros */
+ /* desplazo registros a izquierda */
+ { /* offset del fin del registro a borrar */
+ EMUFS_BLOCK_SIZE offset_reg_end = offset
+ + sizeof(EMUFS_TIPO1_REG_HEADER) + curr_reg_header.size;
+ /* si es necesario desplazar */
+ if (offset < offset_reg_end) {
+ /* muevo la porción de bloque a izquierda */
+ memcpy(block + offset, block + offset_reg_end,
+ efs->tam_bloque - offset_reg_end);
+ }
+ }
+ /* guardo el bloque en disco */
+ emufs_tipo1_grabar_bloque(efs, block, curr_block_id, &err);
+ if (err) {
+ /* TODO Manejo de errores */
+ PERR("no se pudo grabar bloque en disco");
+ free(block);
+ return err;
+ }
+
+ break; /* salgo del loop, ya hice todo lo que tenía que hacer */
}
/* desplazo el offset */
- offset += curr_reg_header.size;
+ offset += sizeof(EMUFS_TIPO1_REG_HEADER) + curr_reg_header.size;
/* esto no debería ser nunca false porque sé positivamente que el */
} while (offset < efs->tam_bloque); /* registro está en el bloque */
return 0; /* EMUFS_OK */
}
-/** Graba un bloque en el archivo. */
+EMUFS_Estadisticas emufs_tipo1_leer_estadisticas(EMUFS* efs)
+{
+ EMUFS_Estadisticas stats;
+ memset(&stats, 0, sizeof(EMUFS_Estadisticas));
+
+ /* obtengo tamaño de archivo en bytes */
+ {
+ FILE* file;
+ char name_f[255];
+
+ strcpy(name_f,efs->nombre);
+ strcat(name_f,".dat");
+ if ((file = fopen(name_f, "ab")) == NULL) {
+ /* TODO Manejo de errores */
+ PERR("Error al abrir archivo");
+ /* *err = 4; / * EMUFS_ERROR_CANT_OPEN_FILE */
+ return stats;
+ }
+ stats.tam_archivo_bytes = ftell(file);
+ fclose(file);
+ }
+
+ /* obtengo cantidad de bloques */
+ stats.cant_bloques = /* tamaño del archivo sin la cabecera */
+ (stats.tam_archivo_bytes - sizeof(EMUFS_Tipo) - sizeof(EMUFS_BLOCK_SIZE))
+ / efs->tam_bloque; /* dividido el tamaño de un bloque */
+
+ /* obtengo la cantidad de registros en el archivo */
+ {
+ EMUFS_REG_ID *tmp = emufs_idx_get(efs, &stats.tam_archivo);
+ if (tmp) free(tmp); /* libera memoria innecesaria */
+ }
+
+ /* obtengo total de información de control que guarda el archivo */
+ stats.info_control =
+ /* cabecera del archivo */
+ sizeof(EMUFS_Tipo) + sizeof(EMUFS_BLOCK_SIZE)
+ /* cabeceras de registros */
+ + stats.tam_archivo * sizeof(EMUFS_TIPO1_REG_HEADER);
+
+ /* obtengo las estadísticas del archivo de espacio libre por bloque */
+ stats.total_fs = emufs_fsc_get_total_fs(efs);
+ stats.media_fs = emufs_fsc_get_media_fs(efs);
+ emufs_fsc_get_max_min_fs(efs, &stats.min_fs, &stats.max_fs);
+
+ return stats;
+}
+
EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,
EMUFS_BLOCK_ID block_id, int* err)
{