X-Git-Url: https://git.llucax.com/z.facultad/75.06/emufs.git/blobdiff_plain/94aef7aeac41c6c2bc364f9ce062cb4851a1ac7a..69c9a330bed7b04915ab1f1e7603150a7c90e0bc:/emufs/tipo1.c diff --git a/emufs/tipo1.c b/emufs/tipo1.c index b10e909..596f69a 100644 --- a/emufs/tipo1.c +++ b/emufs/tipo1.c @@ -184,41 +184,77 @@ void* emufs_tipo1_leer_registro(EMUFS* efs, EMUFS_REG_ID reg_id, return registro; } -/* @todo TODO hacer que soporte registros de más de un bloque */ -void* emufs_tipo1_leer_registro_raw(EMUFS *efs, EMUFS_REG_ID id, - EMUFS_REG_SIZE *size, int *pos) +void* emufs_tipo1_leer_registro_raw(EMUFS *efs, EMUFS_REG_ID id, EMUFS_REG_SIZE *size, int *pos) { + char *chunk_ptr; char* block; /* bloque leido (en donde está el registro a leer) */ + char* registro; /* registro a leer */ EMUFS_BLOCK_ID block_id; /* id del bloque en donde esta el registro a leer */ - EMUFS_BLOCK_SIZE offset; /* offset del bloque leído */ + EMUFS_BLOCK_SIZE offset, block_space; /* offset del bloque leído */ EMUFS_TIPO1_REG_HEADER curr_reg_header; /* cabecera del registro a leer */ - int err; + EMUFS_REG_SIZE cant_bloques; + int err, i; block_id = emufs_idx_buscar_registro(efs, id); if (block_id == EMUFS_NOT_FOUND) { + /* TODO Manejo de errores */ + PERR("Registro no encontrado"); + *pos = 0; + *size = 0; return NULL; } err = 0; if (!(block = (char*) emufs_tipo1_leer_bloque(efs, block_id, &err))) { + /* TODO Manejo de errores */ + PERR("no se pudo reservar memoria"); + *pos = 0; + *size = 0; return NULL; } /* Busco secuencialmente en el bloque el registro a leer */ offset = 0; do { - /* Copio la cabecera del registro. */ + /* 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 == id) { - *pos = offset - sizeof(EMUFS_TIPO1_REG_HEADER); + /* tamaño máximo ultilizable para datos en un bloque */ + *pos = offset-sizeof(EMUFS_TIPO1_REG_HEADER); + block_space = efs->tam_bloque - sizeof(EMUFS_TIPO1_REG_HEADER); + /* tamaño de la porción de registro que se guarda */ + + cant_bloques = curr_reg_header.size / block_space + 1; + *size = cant_bloques*efs->tam_bloque; + registro = chunk_ptr = (char*) malloc(*size - (cant_bloques-1)*sizeof(EMUFS_TIPO1_REG_HEADER)); + if (registro == NULL) { + /* TODO Manejo de errores */ + free(block); + PERR("No hay memoria"); + *pos = 0; + *size = 0; + return NULL; + } + memcpy(registro, block, efs->tam_bloque); + chunk_ptr += efs->tam_bloque; + /* Copio los otros bloques, si los hay */ + free(block); + for(i=1; itam_bloque); + chunk_ptr += efs->tam_bloque; + free(block); + } + /* Todo listo! */ break; } /* Desplazo el offset */ offset += curr_reg_header.size; } while (offset < efs->tam_bloque); - (*size) = efs->tam_bloque; - return block; + return registro; } void* emufs_tipo1_leer_bloque(EMUFS* efs, EMUFS_BLOCK_ID block_id, int *err) @@ -467,7 +503,28 @@ void emufs_tipo1_compactar(EMUFS* efs) free(reg); } } - /* TODO truncar */ + free(reg_ids); /* libero lista de ids */ + + /* truncamos el archivo si hay bloques libres al final */ + { + EMUFS_FREE fs; /* espacio libre en el bloque */ + /* busco si hay algún bloque completo libre */ + EMUFS_BLOCK_ID block_id = emufs_fsc_buscar_lugar(efs, efs->tam_bloque + - sizeof(EMUFS_TIPO1_REG_HEADER), &fs); + /* si hay, el resto del archivo tiene que estar vacío */ + if (block_id != EMUFS_NOT_FOUND) { + long size = emufs_tipo1_header_size() /* cabecera del archivo */ + + block_id * efs->tam_bloque; /* mas los bloques compactos */ + char filename[255]; + + /* trunca archivo de datos */ + strcpy(filename, efs->nombre); + strcat(filename, ".dat"); + truncate(filename, size); + /* trunca archivo de de espacio libre */ + emufs_fsc_truncate(efs, block_id); + } + } } EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,