/*************************************************************************** * 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(); 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(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(); } int PropertyHandler::attr_exists(char* _attr) { std::map::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) _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::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