rtsParser.h 6.38 KB
#include<vector>
#include<fstream>

using namespace std;

//define the parameter data types
#define RTS_ERROR			0
#define RTS_OK				1


#define RTS_STRING			2
#define RTS_DOUBLE			3

struct parameter
{
	//name of the specified parameter
	char* name;
	int ID;
	char* char_value;
	double double_value;
	int type;
	bool set;
};

class rtsParser
{
private:
	vector<parameter> parameters;
	vector<parameter>::iterator p_SearchParams(char* name);
	bool p_SetParameter(char* name, char* value);
	bool p_SetParameter(char* name, double value);

public:
	void AddParameter(char* name, int ID, int type);
	void AddParameter(char* name, int type);
	void OutputParameters();
	void Load(const char* filename);
	int GetDoubleParameter(char* name, double& result);
	int GetStringParameter(char* name, char*& result);
};

vector<parameter>::iterator rtsParser::p_SearchParams(char *name)
{
	//search the parameters vector for a name matching the input parameter

	vector<parameter>::iterator iter;
	
	//run through the vector
	for(iter = parameters.begin(); iter != parameters.end(); iter++)
	{
		//if the name matches the parameter name, return the iterator
		if(strcmp((*iter).name, name) == 0)
			return iter;
	}
	
	return parameters.end();
}

bool rtsParser::p_SetParameter(char *name, char *value)
{
	//sets the character value of a parameter

	//first, find the parameter
	vector<parameter>::iterator iter;
	for(iter = parameters.begin(); iter != parameters.end(); iter++)
	{
		//if the parameter is found
		if(strcmp((*iter).name, name) == 0)
		{
			//if the parameter type is wrong, return false
			if((*iter).type != RTS_STRING)
				return false;
			//otherwise, set the parameter value
			(*iter).char_value = value;
			(*iter).set = true;
			return true;
		}
	}
	//if the parameter was not found, return false
	return false;
}

bool rtsParser::p_SetParameter(char *name, double value)
{
	//sets the character value of a parameter

	//first, find the parameter
	vector<parameter>::iterator iter;
	for(iter = parameters.begin(); iter != parameters.end(); iter++)
	{
		//if the parameter is found
		if(strcmp((*iter).name, name) == 0)
		{
			//if the parameter type is wrong, return false
			if((*iter).type != RTS_DOUBLE)
				return false;
			//otherwise, set the parameter value
			(*iter).double_value = value;
			(*iter).set = true;
			return true;
		}
	}
	//if the parameter was not found, return false
	return false;
}

void rtsParser::Load(const char* filename)
{
	//loads a parameter file and fills the list with the parameter values

	//create an input stream and load the file
	ifstream infile;
	infile.open(filename);

	//create temporary variables to store values
	char param_name[1000];
	vector<parameter>::iterator iter;

	//for each line in the parameter file
	while(!infile.eof())
	{
		//get the parameter name token
		infile.get(param_name, 100, ' ');
		//find the proper parameter in the parameter list
		iter = p_SearchParams(param_name);

		//test to make sure the parameter was found
		if(iter == parameters.end())
		{
			cout<<"Error, could not find parameter: "<<param_name<<endl;
			exit(1);
		}

		//cout<<"infile.get:  "<<param_name<<endl;

		//get the equal sign
		char equals;
		infile>>equals;

		//cout<<"infile>>equals: "<<equals<<endl;
		

		//create space for the string
		char* temp_value_string= new char[500];
		infile.get(temp_value_string, 500);

		//cout<<"temp_value_string: "<<temp_value_string<<endl;

		if((*iter).type == RTS_STRING)
		{
			//remove the quotation marks
			temp_value_string = strchr(temp_value_string, '"');
			if(temp_value_string != NULL)
			{
				temp_value_string++;
				char* end = strrchr(temp_value_string, '"');
				*end = 0;
				
				//set the parameter
				(*iter).char_value = temp_value_string;
				(*iter).set = true;
			}
			else
			{
				cout<<"Error, no quotes in parameter value: "<<(*iter).name<<endl;
			}
		}
		else if((*iter).type == RTS_DOUBLE)
		{
			(*iter).double_value = atof(temp_value_string);
			(*iter).set = true;
		}
		

		

		//get the final line character
		//char temp[2];
		//infile.get(temp, 2);
		//skip to the next line
		infile.getline(param_name, 1000);
		//}

	}

}

int rtsParser::GetDoubleParameter(char* name, double& result)
{
	//find the appropriate parameter
	vector<parameter>::iterator iter = p_SearchParams(name);
	
	//check for errors
	if(iter == parameters.end())
	{
		cout<<"Error finding parameter: "<<name<<endl;
		return RTS_ERROR;
	}
	else if((*iter).type != RTS_DOUBLE)
	{
		cout<<"Invalid data type for parameter: "<<name<<endl;
		return RTS_ERROR;
	}
	else if(!(*iter).set)
	{
		cout<<"Parameter not set during load: "<<name<<endl;
		return RTS_ERROR;
	}

	//return the appropriate value as a reference parameter
	result = (*iter).double_value;
	return RTS_OK;
}

int rtsParser::GetStringParameter(char* name, char*& result)
{
	//find the appropriate parameter
	vector<parameter>::iterator iter = p_SearchParams(name);
	
	//check for errors
	if(iter == parameters.end())
	{
		cout<<"Error finding parameter: "<<name<<endl;
		return RTS_ERROR;
	}
	else if((*iter).type != RTS_STRING)
	{
		cout<<"Invalid data type for parameter: "<<name<<endl;
		return RTS_ERROR;
	}
	else if(!(*iter).set)
	{
		cout<<"Parameter not set during load: "<<name<<endl;
		return RTS_ERROR;
	}

	//return the appropriate value as a reference parameter
	result = (*iter).char_value;
	return RTS_OK;
}

void rtsParser::AddParameter(char *name, int ID, int type)
{
	//this function adds an expected parameter to the parser

	//create a new parameter and store the user-defined variables
	parameter new_param;
	new_param.name = name;
	new_param.ID = ID;
	new_param.type = type;
	new_param.set = false;

	//add the parameter to the parameter list
	parameters.push_back(new_param);
}

void rtsParser::AddParameter(char* name, int type)
{
	AddParameter(name, 0, type);
}

void rtsParser::OutputParameters()
{
	vector<parameter>::iterator iter;
	for(iter = parameters.begin(); iter!= parameters.end(); iter++)
	{
		//test to see if the parameter was set by the file
		if((*iter).set)
		{
			cout<<"name: "<<(*iter).name;
			
			if((*iter).type == RTS_DOUBLE)
				cout<<"  value: "<<(*iter).double_value<<endl;
			else
				cout<<"  value: "<<(*iter).char_value<<endl;
		}
	}
}