/* $Id$ */ /* * Cantus Tag Editor * Copyright © 2002-2004 by Samuel Abels * Copyright © 2007 by Tim Huetz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see **/ #ifdef HAVE_CONFIG_H # include #endif #include //#define _DEBUG_ /****************************************************************************** * Constructor / Destructor. ******************************************************************************/ ConfigFile::ConfigFile(void) { } ConfigFile::~ConfigFile(void) { } /****************************************************************************** * Public. ******************************************************************************/ /* Defines which file to read/write from. */ void ConfigFile::set_filename(std::string newfilename) { filename = newfilename; } /* Check, whether or not the file exists and is read-/writable. * Returns 0 if the file is read/writeable. * -1 if no filename has been set yet or the file does not exist. * -2 if the file is not readable. * -3 if the file is not writeable. */ gint ConfigFile::check(void) { std::ifstream infile(filename.c_str()); if (!infile) return -1; infile.close(); return 0; } /* This function opens the configfile and saves all option/value pairs in the * given map. Returns an errorcode, or 0 on success. */ int ConfigFile::load(void) { #ifdef _DEBUG_ printf("ConfigFile::load(): Called.\n"); #endif char buffer[1025]; content.clear(); #ifdef _DEBUG_ printf("ConfigFile::load(): Opening file %s...\n", filename.c_str()); #endif std::ifstream infile(filename.c_str()); if (!infile) return -1; #ifdef _DEBUG_ printf("ConfigFile::load(): File open.\n"); #endif memset(buffer, 0, 1025); while (infile.getline(buffer, 1024, '\n')) { #ifdef _DEBUG_ printf("ConfigFile::load(): Read line: %s\n", buffer); #endif content.push_back(get_pair(buffer)); } infile.close(); #ifdef _DEBUG_ printf("ConfigFile::load(): Success.\n"); #endif return 0; } /* This function saves the configfile contents from the memory to the * configfile. Returns an errorcode, or 0 on success. */ int ConfigFile::save(void) { #ifdef _DEBUG_ printf("ConfigFile::save(): Called.\n"); #endif if (content.empty()) return 0; #ifdef _DEBUG_ printf("ConfigFile::save(): Opening file %s...\n", filename.c_str()); #endif std::ofstream outfile(filename.c_str()); if (!outfile) return -1; #ifdef _DEBUG_ printf("ConfigFile::save(): File open.\n"); #endif std::list >::iterator iter; iter = content.begin(); while (iter != content.end()) { std::string line = (*iter).first + "=" + (*iter).second; outfile << line << '\n'; iter++; } outfile.close(); #ifdef _DEBUG_ printf("ConfigFile::save(): Success.\n"); #endif return 0; } /* Clear the configfile content (only in the memory). */ void ConfigFile::clear(void) { content.clear(); } /* Appends one key/value pair to the configfile (only in the memory). * Args passed to the method are: The key name, the value type (e.g. * G_TYPE_INT) and the value. * Returns always TRUE. */ bool ConfigFile::append(std::string key, int type, void *value) { std::pair pair; std::stringstream ss; pair.first = key; switch (type) { case G_TYPE_BOOLEAN: ss << (bool)value ? "TRUE" : "FALSE"; break; case G_TYPE_INT: g_assert(value != NULL); ss << *(int*)value; break; case G_TYPE_CHAR: g_assert(value != NULL); ss << "\"" << (const char*)value << "\""; break; default: g_assert_not_reached(); } pair.second = ss.str(); #ifdef _DEBUG_ printf("ConfigFile::append_pair(): %s/%s\n", pair.first.c_str(), pair.second.c_str()); #endif content.push_back(pair); return TRUE; } /* Walks through all lines of the file, passing every option to the slot. * Args passed to the slot are: The key name, the value type (e.g. * G_TYPE_INT) and the value. */ void ConfigFile::foreach_line(SigC::Slot3 slot) { std::list >::iterator iter = content.begin(); while (iter != content.end()) { #ifdef _DEBUG_ std::cout << "ConfigFile::load(): Pair found: " << (*iter).first << "/" << (*iter).second << "\n"; #endif std::pair pair = grab_value((*iter).second); bool ret = slot((*iter).first, pair.first, pair.second); if (pair.first == G_TYPE_CHAR) g_free(pair.second); if (!ret) return; iter++; } } /****************************************************************************** * Protected. ******************************************************************************/ /* Given one line of a file, this function returns the extracted key/value * pair. */ std::pair ConfigFile::get_pair(const gchar *pline) { std::string line = pline; gint keylen = line.find('='); // Find the "=". gint lineend = line.find('\r') ? line.find('\r') : line.find('\n'); gint vallen = lineend - keylen; // Find the value length. std::string key = line.substr(0, keylen); // The key is left-sided, std::string val = line.substr(keylen + 1, vallen); // the value right-sided. return std::pair(key, val); } /* Given one value string, this function extracts the value in the right data * type. */ std::pair ConfigFile::grab_value(std::string value) { std::pair pair; if (value.substr(0, 1) == "\"") { std::string str = value.substr(1, value.length() - 2); #ifdef _DEBUG_ printf("ConfigFile::string2chvalue(): Found string %s\n", str.c_str()); #endif pair.first = G_TYPE_CHAR; pair.second = (void*)strdup(str.c_str()); return pair; } if (strcmp(value.c_str(), "TRUE") == 0) { #ifdef _DEBUG_ printf("ConfigFile::string2chvalue(): Found bool: TRUE\n"); #endif pair.first = G_TYPE_BOOLEAN; pair.second = (void*)TRUE; return pair; } if (strcmp(value.c_str(), "FALSE") == 0) { #ifdef _DEBUG_ printf("ConfigFile::string2chvalue(): Found bool: FALSE\n"); #endif pair.first = G_TYPE_BOOLEAN; pair.second = (void*)FALSE; return pair; } #ifdef _DEBUG_ printf("ConfigFile::string2chvalue(): Found int: %s\n", value.c_str()); #endif pair.first = G_TYPE_BOOLEAN; pair.second = (void*)atoi(value.c_str()); return pair; }