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)
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,