-static int emufs_tipo1_grabar_registro_con_id(EMUFS* efs, void* reg,
- EMUFS_TIPO1_REG_HEADER header)
-{
- EMUFS_FREE fs; /* espacio libre en el bloque */
- EMUFS_BLOCK_ID block_id; /* identificador del 1er bloque */
- char* block; /* buffer del bloque a guardar en disco */
- char name_f[255];
- int err = 0;
-
- strcpy(name_f, efs->nombre);
- strcat(name_f, ".dat");
-
- /* busco lugar para el registro en un bloque existente */
- block_id = emufs_fsc_buscar_lugar(efs, sizeof(EMUFS_TIPO1_REG_HEADER)
- + header.size, &fs);
- /* si no hay bloques con suficiente espacio creo un bloque nuevo */
- if (block_id == EMUFS_NOT_FOUND) {
- /* tamaño máximo ultilizable para datos en un bloque */
- EMUFS_BLOCK_SIZE block_space = efs->tam_bloque - sizeof(EMUFS_TIPO1_REG_HEADER);
- /* identificador del bloque que se guarda */
- EMUFS_BLOCK_ID curr_block_id = EMUFS_NOT_FOUND;
- /* tamaño de la porción de registro que se guarda */
- EMUFS_REG_SIZE chunk_size = 0;
- /* puntero a la poción del registro */
- char* chunk_ptr = reg;
-
- /* crear un nuevo bloque en memoria */
- block = (char*) malloc(efs->tam_bloque);
- if (block == NULL) {
- /* TODO Manejo de errores */
- PERR("No hay memoria");
- return 2; /* EMUFS_ERROR_OUT_OF_MEMORY */
- }
- do {
- memset(block, 0, efs->tam_bloque); /* inicializa bloque */
- chunk_ptr += chunk_size; /* Avanzo para guardar prox chunk */
- header.size -= chunk_size; /* Resto lo que ya guardé */
- chunk_size = MIN(header.size, block_space);
- /* graba porción del registro en bloque */
- emufs_tipo1_escribir_reg_chunk_en_memoria(block, header, chunk_ptr, chunk_size);
- /* graba el bloque en el archivo */
- curr_block_id = emufs_tipo1_grabar_bloque(efs, block, EMUFS_NOT_FOUND, &err);
- if (err) {
- PERR("error al grabar bloque");
- free(block);
- return err;
- }
- /* grabo el nuevo registro en el archivo de espacios libres */
- err = emufs_fsc_agregar(efs, curr_block_id, block_space - chunk_size);
- if (err) {
- PERR("No se pudo agregar fsc");
- free(block);
- return err;
- }
- /* si es el primer id de bloque obtenido, lo guardo para
- * agregarlo después al archivo de índices. */
- if (block_id == EMUFS_NOT_FOUND) {
- block_id = curr_block_id;
- }
- } while (header.size > block_space);
- free(block);
-
- /* Encontró espacio en un bloque existente, graba registro ahí */
- } else {
- /* cargo el bloque en block_id */
- if (!(block = (char*) emufs_tipo1_leer_bloque(efs, block_id, &err))) {
- /* TODO Manejo de errores */
- PERR("no se pudo leer el bloque");
- return err;
- }
- /* graba registro en bloque */
- emufs_tipo1_escribir_reg_en_memoria(block + efs->tam_bloque - fs,
- header, reg);
- /* graba el bloque en el archivo */
- block_id = emufs_tipo1_grabar_bloque(efs, block, block_id, &err);
- if (err) {
- PERR("error al grabar bloque");
- free(block);
- return err;
- }
- free(block);
- /* actualizo el archivo de espacios libres */
- err = emufs_fsc_actualizar(efs, block_id, fs - header.size
- - sizeof(EMUFS_TIPO1_REG_HEADER));
- if (err) {
- PERR("No se pudo actualizar fsc");
- return err;
- }
- }
-
- /* actualizo el indice de bloques y registros */
- err = emufs_idx_agregar(efs, header.id, block_id);
- if (err){
- PERR("No se pudo agregar idx");
- return err;
- }
-
- return err;
-}
-