]> git.llucax.com Git - z.facultad/75.06/emufs.git/blobdiff - emufs/tipo1.c
hago un pequeño fix para que ande un poco mejor cuando bloque < reg
[z.facultad/75.06/emufs.git] / emufs / tipo1.c
index b10e9097e6c2603570f7338829c1086d5288353d..76ded8bccd94a61b68df89b035a8e53565c8a505 100644 (file)
@@ -184,41 +184,79 @@ void* emufs_tipo1_leer_registro(EMUFS* efs, EMUFS_REG_ID reg_id,
        return registro;
 }
 
        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* 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_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 */
        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) {
 
        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))) {
                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 {
                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) {
                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);
 
                        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)
 }
 
 void* emufs_tipo1_leer_bloque(EMUFS* efs, EMUFS_BLOCK_ID block_id, int *err)
@@ -467,7 +505,28 @@ void emufs_tipo1_compactar(EMUFS* efs)
                        free(reg);
                }
        }
                        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,
 }
 
 EMUFS_BLOCK_ID emufs_tipo1_grabar_bloque(EMUFS *efs, void *block,