]> git.llucax.com Git - z.facultad/75.06/emufs.git/blobdiff - emufs/tipo1.c
* Reestructuro para que quede mas claro
[z.facultad/75.06/emufs.git] / emufs / tipo1.c
index 0c3f32dd2b55b1ca075b671e8ff0b4500efb428a..0db0f3a3c85ccbd695d65dcc931d646072c22744 100644 (file)
 #include "idx.h"
 #include "fsc.h"
 #include "did.h"
+#include <unistd.h>
+#include <sys/types.h>
 #include <stdio.h>
+#include <math.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #ifndef MIN
 #      define MIN(x, y) (((x) > (y)) ? (y) : (x))
@@ -62,26 +64,19 @@ static int emufs_tipo1_header_jump(FILE*);
 
 static int emufs_tipo1_block_jump(EMUFS*, FILE*, EMUFS_BLOCK_ID);
 
-static void emufs_tipo1_escribir_reg_en_memoria(char*, EMUFS_TIPO1_REG_HEADER,
-               char*);
-
 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*);
+/** Graba un bloque en el archivo y actualiza .fsc, si se solicita. */
+static EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque_fsc(EMUFS*, void*,
+               EMUFS_BLOCK_ID, EMUFS_FREE, int*);
 
 /** Obtiene el tamaño del archivo. */
 static long emufs_tipo1_get_file_size(EMUFS*, int*);
 
-/** Guarda un registro con un id determinado */
-static int emufs_tipo1_grabar_registro_con_id(EMUFS* efs, void* reg,
-               EMUFS_TIPO1_REG_HEADER header);
-
 /*------------------ Funciones públicas ----------------------*/
 
 int emufs_tipo1_inicializar(EMUFS* efs)
@@ -95,6 +90,7 @@ int emufs_tipo1_inicializar(EMUFS* efs)
        }
        /* Asigna punteros a funciones. */
        efs->leer_bloque       = emufs_tipo1_leer_bloque;
+       efs->leer_bloque_raw   = emufs_tipo1_leer_bloque_raw;
        efs->grabar_registro   = emufs_tipo1_grabar_registro;
        efs->borrar_registro   = emufs_tipo1_borrar_registro;
        efs->leer_registro     = emufs_tipo1_leer_registro;
@@ -184,41 +180,79 @@ 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) + (cant_bloques-1)*2);
+                       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; i<cant_bloques; i++) {
+                               err = 0;
+                               block = (char*)emufs_tipo1_leer_bloque(efs, block_id+i, &err);
+                               /* Solo grabo el header del primer pedazo! */
+                               memcpy(chunk_ptr, "<>", 2);
+                               chunk_ptr += 2;
+                               memcpy(chunk_ptr, block+sizeof(EMUFS_TIPO1_REG_HEADER), efs->tam_bloque-sizeof(EMUFS_TIPO1_REG_HEADER));
+                               chunk_ptr += efs->tam_bloque-sizeof(EMUFS_TIPO1_REG_HEADER);
+                               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)
@@ -256,9 +290,21 @@ void* emufs_tipo1_leer_bloque(EMUFS* efs, EMUFS_BLOCK_ID block_id, int *err)
        return block;
 }
 
-EMUFS_REG_ID emufs_tipo1_grabar_registro(EMUFS* efs, void* reg, EMUFS_REG_SIZE reg_size, int* err)
+EMUFS_REG_ID emufs_tipo1_grabar_registro(EMUFS* efs, void* reg,
+               EMUFS_REG_SIZE reg_size, int* err)
 {
        EMUFS_TIPO1_REG_HEADER header; /* cabecera del registro a leer */
+       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* chunk_ptr = reg; /* puntero a la poción del registro */
+       EMUFS_BLOCK_SIZE block_space /* tamaño máximo para datos en un bloque */
+               = efs->tam_bloque - sizeof(EMUFS_TIPO1_REG_HEADER);
+       /* identificador del bloque que se guarda */
+       EMUFS_BLOCK_ID curr_block_id;
+       /* tamaño de la porción de registro que se guarda */
+       EMUFS_REG_SIZE chunk_size = 0; 
+
        /* obtengo identificador que corresponderá al registro */
        header.id = emufs_idx_get_new_id(efs, err);
        if (*err) {
@@ -266,10 +312,77 @@ EMUFS_REG_ID emufs_tipo1_grabar_registro(EMUFS* efs, void* reg, EMUFS_REG_SIZE r
                return EMUFS_NOT_FOUND;
        }
        header.size = reg_size; /* tamaño del registro */
-       if ((*err = emufs_tipo1_grabar_registro_con_id(efs, reg, header))) {
-               PERR("error al grabar el registro");
+
+       /* busco lugar para el registro en un bloque existente */
+       block_id = emufs_fsc_buscar_n_lugares(efs,
+                       /* cantidad de bloques que necesita el registro */
+                       (EMUFS_BLOCK_SIZE) ceil(header.size / (double) block_space),
+                       /* cabecera + si es un registro multibloque, tomo el bloque */
+                       sizeof(EMUFS_TIPO1_REG_HEADER) + MIN(header.size, block_space),
+                       &fs, err);
+       /* si no hay bloques con suficiente espacio creo un bloque nuevo */
+       if (block_id == EMUFS_NOT_FOUND) {
+               /* crear un nuevo bloque en memoria */
+               block = (char*) malloc(efs->tam_bloque);
+               if (block == NULL) {
+                       /* TODO Manejo de errores */
+                       PERR("No hay memoria");
+                       *err = 2; /* EMUFS_ERROR_OUT_OF_MEMORY */
+                       return EMUFS_NOT_FOUND;
+               }
+               memset(block, 0, efs->tam_bloque); /* inicializa bloque */
+               curr_block_id = EMUFS_NOT_FOUND; /* pongo de bloque actual el final */
+       /* si hay bloques con suficiente espacio, levanto el primero */
+       } 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 EMUFS_NOT_FOUND;
+               }
+               curr_block_id = block_id; /* pongo de bloque actual el primero */
+       }
+
+       do {
+               EMUFS_BLOCK_ID new_block_id; /* identificador del bloque nuevo */
+               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 */ /* destino: fin de bloque */
+               emufs_tipo1_escribir_reg_chunk_en_memoria(block + efs->tam_bloque - fs,
+                               header, chunk_ptr, chunk_size);
+               /* graba el bloque en el archivo */
+               new_block_id = emufs_tipo1_grabar_bloque_fsc(efs, block, curr_block_id,
+                               fs - sizeof(EMUFS_TIPO1_REG_HEADER) - chunk_size, err);
+               if (*err) {
+                       PERR("error al grabar bloque");
+                       free(block);
+                       return EMUFS_NOT_FOUND;
+               }
+               /* 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 = new_block_id;
+               }
+               /* si no estoy por fuera del archivo, incremento el nro. de bloque */
+               if (curr_block_id != EMUFS_NOT_FOUND) {
+                       ++curr_block_id;
+               }
+
+       /* mientras que el chunk no entre en un bloque */
+       } while (header.size > block_space);
+
+       /* libera el bloque */
+       free(block);
+
+       /* 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 EMUFS_NOT_FOUND;
        }
+
        return header.id;
 }
 
@@ -361,8 +474,9 @@ int emufs_tipo1_borrar_registro(EMUFS* efs, EMUFS_REG_ID reg_id)
                                                efs->tam_bloque - offset_reg_end);
                                }
                        }
-                       /* guardo el bloque en disco */
-                       emufs_tipo1_grabar_bloque(efs, block, curr_block_id, &err);
+                       /* guardo el bloque en disco (actualizando espacio libre) */
+                       emufs_tipo1_grabar_bloque_fsc(efs, block, curr_block_id,
+                                       EMUFS_NOT_FOUND, &err);
                        if (err) {
                                /* TODO Manejo de errores */
                                PERR("no se pudo grabar bloque en disco");
@@ -420,6 +534,8 @@ EMUFS_Estadisticas emufs_tipo1_leer_estadisticas(EMUFS* efs)
 
 void emufs_tipo1_compactar(EMUFS* efs)
 {
+       EMUFS_BLOCK_SIZE block_space /* tamaño para datos de un bloque */
+               = efs->tam_bloque - sizeof(EMUFS_TIPO1_REG_HEADER);
        EMUFS_REG_ID total_ids; /* cantidad total de registros en el array */
        /* array con los identificadores de los registros */
        EMUFS_REG_ID* reg_ids = emufs_idx_get(efs, &total_ids);
@@ -427,45 +543,38 @@ void emufs_tipo1_compactar(EMUFS* efs)
 
        /* recorro cada registro válido del archivo */
        for (i = 0; i < total_ids; ++i) {
-               EMUFS_FREE fs; /* espacio libre en el bloque */
                EMUFS_TIPO1_REG_HEADER header; /* cabecera del registro a leer */
+               char* reg; /* buffer para el registro a mover */
                int err = 0; /* para almacenar código de error */
                /* bloque al que pertenece el registro */
                EMUFS_BLOCK_ID block_id = emufs_idx_buscar_registro(efs, reg_ids[i]);
-               /* obtengo un bloque con espacio suficiente para almacenarlo */
-               EMUFS_BLOCK_ID free_block_id = emufs_fsc_buscar_lugar(efs,
-                               sizeof(EMUFS_TIPO1_REG_HEADER) + reg_ids[i], &fs);
 
+               /* obtengo identificador del registro actual */
+               header.id = reg_ids[i];
                /* si el registro está borrado, continúo con el próximo */
                if (block_id == EMUFS_NOT_FOUND) {
                        continue;
                }
-               /* obtengo identificador del registro actual */
-               header.id = reg_ids[i];
-               /* TODO analizar caso de registros multibloque */
-               /* si el bloque obtenido está antes del bloque actual */
-               if (free_block_id < block_id) {
-                       /* leo el registro */
-                       char* reg = (char*) efs->leer_registro(efs, header.id,
-                                       &header.size, &err);
-                       if (err) {
-                               PERR("error al leer registro");
-                               return;
-                       }
-                       /* borro el registro */
-                       if ((err = efs->borrar_registro(efs, header.id))) {
-                               PERR("error al borrar registro");
-                               free(reg);
-                               return;
-                       }
-                       /* lo inserto en la nueva posición */
-                       if ((err = emufs_tipo1_grabar_registro_con_id(efs, reg, header))) {
-                               PERR("error al borrar registro");
-                               free(reg);
-                               return;
-                       }
+               /* leo el registro */
+               reg = (char*) efs->leer_registro(efs, header.id, &header.size, &err);
+               if (err) {
+                       PERR("error al leer registro");
+                       return;
+               }
+               /* borro el registro */
+               if ((err = efs->borrar_registro(efs, header.id))) {
+                       PERR("error al borrar registro");
                        free(reg);
+                       return;
                }
+               /* lo inserto en la nueva posición */
+               emufs_tipo1_grabar_registro(efs, reg, header.size, &err);
+               if (err) {
+                       PERR("error al grabar registro");
+                       free(reg);
+                       return;
+               }
+               free(reg);
        }
        free(reg_ids); /* libero lista de ids */
 
@@ -473,8 +582,7 @@ void emufs_tipo1_compactar(EMUFS* efs)
        {
                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);
+               EMUFS_BLOCK_ID block_id = emufs_fsc_buscar_lugar(efs, block_space, &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 */
@@ -491,23 +599,28 @@ void emufs_tipo1_compactar(EMUFS* efs)
        }
 }
 
-EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,
-               EMUFS_BLOCK_ID block_id, int* err)
+EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque_fsc(EMUFS *efs, void *block,
+               EMUFS_BLOCK_ID block_id, EMUFS_FREE fs, int* err)
 {
        FILE* file;
        char name_f[255];
+       /* obtengo cantidad de bloques */
+       EMUFS_BLOCK_SIZE num_blocks =
+               (emufs_tipo1_get_file_size(efs, err) - emufs_tipo1_header_size())
+               / efs->tam_bloque;
 
+       /* abre archivo */
        strcpy(name_f,efs->nombre);
        strcat(name_f,".dat");
-
        if ((file = fopen(name_f, "r+b")) == NULL) {
                /* TODO Manejo de errores */
                PERR("Error al abrir archivo");
                *err = 4; /* EMUFS_ERROR_CANT_OPEN_FILE */
                return EMUFS_NOT_FOUND;
        }
-       /* Si es NOT_FOUND tengo que agregar un bloque al final del archivo */
-       if (block_id == EMUFS_NOT_FOUND) {
+       /* Si es NOT_FOUND o mayor a la cantidad de bloques presentes,
+        * tengo que agregar un bloque al final del archivo */
+       if ((block_id == EMUFS_NOT_FOUND) || (block_id >= num_blocks)) {
                /* me paro al final del archivo */
                if (fseek(file, 0l, SEEK_END)) {
                        /* TODO Manejo de errores */
@@ -518,6 +631,15 @@ EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,
                }
                /* Obtengo ID del bloque nuevo */
                block_id = (ftell(file) - emufs_tipo1_header_size()) / efs->tam_bloque;
+               /* si me lo solicitan, actualizo el .fsc */
+               if (fs != EMUFS_NOT_FOUND) {
+                       *err = emufs_fsc_agregar(efs, block_id, fs);
+                       if (*err) {
+                               PERR("No se pudo agregar al .fsc");
+                               fclose(file);
+                               return EMUFS_NOT_FOUND;
+                       }
+               }
        /* Si es un ID válido, salto hasta ese bloque. */
        } else {
                /* Salta el header del archivo */
@@ -532,6 +654,15 @@ EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,
                        fclose(file);
                        return EMUFS_NOT_FOUND;
                }
+               /* si me lo solicitan, actualizo el .fsc */
+               if (fs != EMUFS_NOT_FOUND) {
+                       if ((*err = emufs_fsc_actualizar(efs, block_id, fs))) {
+                               /* TODO Manejo de errores */
+                               PERR("no se pudo actualizar .fsc");
+                               fclose(file);
+                               return EMUFS_NOT_FOUND;
+                       }
+               }
        }
        /* Grabo el bloque */
        if (fwrite(block, efs->tam_bloque, 1, file) != 1) {
@@ -545,106 +676,6 @@ EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,
        return block_id;
 }
 
-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;
-}
-
 EMUFS_REG_ID emufs_tipo1_modificar_registro(EMUFS *emu, EMUFS_REG_ID id,
                void *data, EMUFS_REG_SIZE size, int *error)
 {
@@ -675,12 +706,6 @@ int emufs_tipo1_block_jump(EMUFS* efs, FILE* fp, EMUFS_BLOCK_ID block_count)
        return 0; /* EMUFS_OK */
 }
 
-void emufs_tipo1_escribir_reg_en_memoria(char* dst, EMUFS_TIPO1_REG_HEADER header,
-               char* reg)
-{
-       emufs_tipo1_escribir_reg_chunk_en_memoria(dst, header, reg, header.size);
-}
-
 void emufs_tipo1_escribir_reg_chunk_en_memoria(char* dst,
                EMUFS_TIPO1_REG_HEADER header, char* reg, EMUFS_REG_SIZE reg_size)
 {
@@ -711,3 +736,12 @@ long emufs_tipo1_get_file_size(EMUFS* efs, int* err)
        return file_size;
 }
 
+void emufs_tipo1_leer_bloque_raw(EMUFS *efs, EMUFS_BLOCK_ID id, char **actual, char **anterior, char **siguiente, EMUFS_BLOCK_SIZE *size1, EMUFS_BLOCK_SIZE *size2, EMUFS_BLOCK_SIZE *size3)
+{
+       int err;
+       (*actual) = emufs_tipo1_leer_bloque(efs, id, &err);
+       (*anterior) = emufs_tipo1_leer_bloque(efs, id-1, &err);
+       (*siguiente) = emufs_tipo1_leer_bloque(efs, id+1, &err);
+       (*size1) = (*size2) = (*size3) = efs->tam_bloque;
+}
+