+ if (block_id == EMUFS_NOT_FOUND) {
+ /* TODO Manejo de errores */
+ PERR("Registro no encontrado");
+ *err = EMUFS_NOT_FOUND;
+ return NULL;
+ }
+ if (!(block = (char*) emufs_tipo1_leer_bloque(efs, block_id, err))) {
+ /* TODO Manejo de errores */
+ PERR("no se pudo reservar memoria");
+ *err = 2; /* EMUFS_ERROR_OUT_OF_MEMORY */
+ return NULL;
+ }
+
+ /* Busco secuencialmente en el bloque el registro a leer */
+ offset = 0;
+ do {
+ /* 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 == reg_id) {
+ /* tamaño máximo ultilizable para datos en un bloque */
+ EMUFS_BLOCK_SIZE block_space
+ = efs->tam_bloque - sizeof(EMUFS_TIPO1_REG_HEADER);
+ /* tamaño de la porción de registro que se guarda */
+ EMUFS_REG_SIZE chunk_size = 0;
+ /* puntero a la porción actual del registro */
+ char* chunk_ptr;
+
+ *reg_size = curr_reg_header.size;
+ registro = chunk_ptr = (char*) malloc(*reg_size);
+ if (registro == NULL) {
+ /* TODO Manejo de errores */
+ free(block);
+ PERR("No hay memoria");
+ *err = 2; /* EMUFS_ERROR_OUT_OF_MEMORY */
+ return NULL;
+ }
+ while (1) {
+ chunk_ptr += chunk_size; /* Avanzo para guardar prox chunk */
+ curr_reg_header.size -= chunk_size; /* Resto lo que ya guardé */
+ chunk_size = MIN(curr_reg_header.size, block_space);
+ /* copio porción de registro en el buffer */
+ memcpy(chunk_ptr, block + offset, chunk_size);
+ /* falta leer un bloque */
+ if (curr_reg_header.size > block_space) {
+ free(block);
+ if (!(block = (char*) emufs_tipo1_leer_bloque(efs,
+ ++block_id, err))) {
+ /* TODO Manejo de errores */
+ free(registro);
+ PERR("no se pudo reservar memoria");
+ *err = 2; /* EMUFS_ERROR_OUT_OF_MEMORY */
+ return NULL;
+ }
+ } else { /* se terminó de leer */
+ break;
+ }
+ }
+ break;
+ }
+ /* Desplazo el offset */
+ offset += curr_reg_header.size;
+
+ /* esto no debería ser nunca false porque sé positivamente que el */
+ } while (offset < efs->tam_bloque); /* registro está en el bloque */
+
+ free(block);
+ return registro;
+}
+
+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, block_space; /* offset del bloque leído */
+ EMUFS_TIPO1_REG_HEADER curr_reg_header; /* cabecera del registro a leer */
+ 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 actual. */
+ memcpy(&curr_reg_header, block + offset, sizeof(EMUFS_TIPO1_REG_HEADER));
+ offset += sizeof(EMUFS_TIPO1_REG_HEADER);
+ if (curr_reg_header.id == id) {
+ /* 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);
+
+ return registro;
+}
+
+void* emufs_tipo1_leer_bloque(EMUFS* efs, EMUFS_BLOCK_ID block_id, int *err)
+{
+ FILE* file;
+ char* block; /* bloque leido (en donde está el registro a leer) */
+ char name_f[255];
+
+ strcpy(name_f,efs->nombre);
+ strcat(name_f,".dat");
+
+ if ((file = fopen(name_f, "r")) == NULL) {
+ PERR("No se puede abrir archivo");
+ *err = 4; /* EMUFS_ERROR_CANT_OPEN_FILE */
+ return NULL; /* FIXME ERROR */
+ }
+ emufs_tipo1_header_jump(file); /* salta cabeceras */
+ emufs_tipo1_block_jump(efs, file, block_id); /* salta bloques */
+ /* FIXME: verificar que no se pase de fin de archivo*/