ifstream* CovOptimData::read(const char* filename, CovOptimData& cov, std::stack<unsigned int>& format_id, std::stack<unsigned int>& format_version) {

	ifstream* f = CovList::read(filename, cov, format_id, format_version);

	if (format_id.empty() || format_id.top()!=subformat_number || format_version.top()!=FORMAT_VERSION) {
		cov.data->_optim_optimizer_status = (unsigned int) Optimizer::SUCCESS;
		cov.data->_optim_is_extended_space = false;
		cov.data->_optim_uplo = NEG_INFINITY;
		cov.data->_optim_loup = POS_INFINITY;
		cov.data->_optim_loup_point.resize((int) cov.n);
		cov.data->_optim_loup_point = IntervalVector::empty(cov.n);
		cov.data->_optim_time = -1;
		cov.data->_optim_nb_cells = 0;
	}
	else {
		format_id.pop();
		format_version.pop();

		read_vars(*f, cov.n, cov.data->_optim_var_names);

		unsigned int status = read_pos_int(*f);

		switch (status) {
		case 0: cov.data->_optim_optimizer_status = (unsigned int) Optimizer::SUCCESS;           break;
		case 1: cov.data->_optim_optimizer_status = (unsigned int) Optimizer::INFEASIBLE;        break;
		case 2: cov.data->_optim_optimizer_status = (unsigned int) Optimizer::NO_FEASIBLE_FOUND; break;
		case 3: cov.data->_optim_optimizer_status = (unsigned int) Optimizer::UNBOUNDED_OBJ;     break;
		case 4: cov.data->_optim_optimizer_status = (unsigned int) Optimizer::TIME_OUT;     		break;
		case 5: cov.data->_optim_optimizer_status = (unsigned int) Optimizer::UNREACHED_PREC;    break;
		default: ibex_error("[CovOptimData]: invalid optimizer status.");
		}

		cov.data->_optim_is_extended_space = (bool) read_pos_int(*f);
		cov.data->_optim_uplo              = read_double(*f);
		cov.data->_optim_uplo_of_epsboxes  = read_double(*f);
		cov.data->_optim_loup              = read_double(*f);

		unsigned int loup_found   = read_pos_int(*f);
		unsigned int nb_var   = cov.is_extended_space() ? cov.n-1 : cov.n;
		cov.data->_optim_loup_point.resize((int) nb_var);
		// TODO: we assume here that the goal var is n-1
		cov.data->_optim_loup_point 		  = loup_found==1? cov[0].subvector(0,nb_var-1) : IntervalVector::empty(nb_var);

		cov.data->_optim_time              = read_double(*f);
		cov.data->_optim_nb_cells          = read_pos_int(*f);
	}

	return f;
}
/**
 * dev_read_pos_int - read a positive 'int' value from an MTD device sysfs file.
 * @patt: file pattern to read from
 * @dev_num: MTD device number
 * @value: the result is stored here
 *
 * This function returns %0 in case of success and %-1 in case of failure.
 */
static int dev_read_pos_int(const char *patt, int dev_num, int *value)
{
	char file[strlen(patt) + 50];

	sprintf(file, patt, dev_num);
	return read_pos_int(file, value);
}