property.cpp 6.03 KB
/***************************************************************************
 *   Universidade Federal da Paraíba                                       *
 *   Copyright (C) 2013 by Laboratório de Aplicações de Vídeo Digital      *
 *                                                                         *
 *   Centro de Informática - UFPB - Campus I                               *
 *   João Pessoa - PB - Brasil                                             *
 *                                                                         *
 *   Author: Leonardo de Araújo Domingues (leonardo.araujo@lavid.ufpb.br)  *
 *   Date: Mon Jun 1 19:29:50 BRT 2015                                    *
 *                                                                         *
 **************************************************************************/

#include "property.h"

 	
PropertyHandler::PropertyHandler(char* _filename, PropertyHandler::HandlerMode _handler_mode)
{
	if ( check_file_extension(_filename) == -1 )
		throw new RuntimeException("Format file not is supported");
	
	filename = (std::string) _filename;
	handler_mode = _handler_mode;
	
	switch (handler_mode)
	{
		case READ: 
			if ( load_properties() <= 0 )
				throw new RuntimeException("Cannot to load properties of the file");
			break;
		case WRITE:
				init_write_mode();
			break;
		default: 
			printf("Handler mode not supported");
			exit(1);
	}
		
}


PropertyHandler::~PropertyHandler() 
{
	if (handler_mode == WRITE)
		update_properties();

 	if (buff_reader_p) delete buff_reader_p;
	if (file_io_p) delete file_io_p;
	if (file_p) delete file_p;
	if (map_ppty_p) delete map_ppty_p;

}


int PropertyHandler::load_properties()
{
	std::string buff_str;
	int buff_index = 0;

	file_p = new File(filename);
	try {
		file_io_p = new FileIO(file_p->getPath(), FileIO::MODE_READ);
	}
	catch(IOException &ex) {
		printf("[ERROR] %s\n", ex.getMessage().c_str());
		exit(1);
	}
	
	buff_reader_p = new BufferedReader(file_io_p);
	map_ppty_p = new std::map<std::string, std::string>();
	
	try {
		buff_str = buff_reader_p->readLine();

		while (buff_str.size() > 0)
		{	
			buff_index++;
			format_line_str(&buff_str);
	
			map_ppty_p->insert(map_ppty_p->begin(), 
				(std::pair<std::string, std::string>(get_key(buff_str), get_value(buff_str))));
	
			/* get next line (key, value) */
			buff_str = buff_reader_p->readLine();
		}

	} catch (EOFException &ex) {
		printf("[ERROR] %s\n", ex.getMessage().c_str());
	}

	return buff_index;

}


void PropertyHandler::init_write_mode()
{
	/* init map structure to manipulate the properties in WRITE mode */
	map_ppty_p = new std::map<std::string, std::string>();
}


int PropertyHandler::attr_exists(char* _attr)
{
	std::map<std::string, std::string>::iterator it;
	if ( (it = map_ppty_p->find((const char*) _attr)) != map_ppty_p->end() )
		return 1;
	return 0;
}

const char* PropertyHandler::get_attibute_value(char* _attr)
{
	if (attr_exists(_attr))
	{
		return (map_ppty_p->find((const char*) _attr)->second).c_str();
	}
	return _attr;
}


void PropertyHandler::set_attribute_value(char* _attr_p, char* _value_p)
{
	if (handler_mode == PropertyHandler::READ)
		throw new RuntimeException("Cannot set properties in the READ mode");

	if (attr_exists(_attr_p))
		throw new RuntimeException("This attribute already exists");

	map_ppty_p->insert(map_ppty_p->begin(),
				(std::pair<std::string, std::string>((std::string) _attr_p, (std::string) _value_p)));
}


void PropertyHandler::update_properties()
{
	FILE* file_output_p;
	file_output_p = fopen (filename.c_str(), "w");
	if (file_output_p == NULL)
		throw new IOException("Cannot open file to write properties");
	fseek(file_output_p, 0, SEEK_SET);

	std::string str_properties;
	
	std::map<std::string, std::string>::iterator it;
	for (it = map_ppty_p->begin(); it != map_ppty_p->end(); it++)		
		if ( write_properties_on_file(it->first, it->second, file_output_p) == 0 )
			throw new IOException("Error to write properties in the file");

	fclose (file_output_p);
}


int PropertyHandler::write_properties_on_file(std::string _key, std::string _value, FILE* _file_output)
{	
	std::string str_properties = _key;
	str_properties.append("=");
	str_properties.append(_value);
	
	int count_bytes = 0;
	
	count_bytes += fputs((char*) str_properties.c_str(), _file_output);
	count_bytes += fputs("\n", _file_output);
		
	return count_bytes;
}

//TODO
int PropertyHandler::remove_attribute(char* _attr_p)
{
	
	if (attr_exists(_attr_p)) {

		if ( map_ppty_p->erase((const char*) _attr_p) != 1 )
			throw new RuntimeException("Cannot remove attribute of the map structure");
		
		/* if delete the attribute corretly, update the map of the properties */
		update_properties();
		return 1;
	}	
	return 0;
}


#define CONF_FILE_EXTENSION ".conf"
/**
	Verify if the file extension is valid.
*/
int PropertyHandler::check_file_extension(char* _filename)
{
	return ((std::string) _filename).find(CONF_FILE_EXTENSION);
}

#undef CONF_FILE_EXTENSION /* .conf */


#define CHAR_TO_REMOVE " \t"
/**
	Remove all whitespaces in the text line.
*/
void PropertyHandler::format_line_str(std::string* _line_str)
{
	int index = -1;
	std::string chars_rm_str = (std::string) CHAR_TO_REMOVE;
	for (int i = 0; i < chars_rm_str.size(); i++)
	{
		while ( (index = (int) _line_str->find(chars_rm_str[i]) ) != std::string::npos)
		{
			_line_str->replace(index, 1, ""); // remove whitespaces (" ") replacing your position by ""
		}
	}
}
#undef CHAR_TO_REMOVE

#define TOKEN_ATTR "="
std::string PropertyHandler::get_key(std::string _ppty_line)
{
	int target_pos = -1;
	target_pos = _ppty_line.find(TOKEN_ATTR);
	
	if (target_pos < 1) /* minimum lenght of a key (k=value) */
	 	throw new RuntimeException("Bad format sentence");
	
	return (std::string) _ppty_line.substr(0, target_pos);
}
 	

std::string PropertyHandler::get_value(std::string _ppty_line)
{
	int target_pos = -1;
	target_pos = _ppty_line.find(TOKEN_ATTR);
	
	if (target_pos < 1) /* minimum lenght of a key (k=value) */
	 	throw new RuntimeException("Bad format sentence");
	
	return (std::string) _ppty_line.substr(target_pos+1, _ppty_line.size());
}
#undef TOKEN_ATTR