X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fstlplus%2Fsubsystems%2Fini_manager.cpp;fp=src%2Fstlplus%2Fsubsystems%2Fini_manager.cpp;h=0000000000000000000000000000000000000000;hb=5846afb00833cc72fe72422ca896d2387c712cb4;hp=41f5b6934bd4106b3431e5fc7ff26be051df88ab;hpb=a97500609dc3c1b11f9786d32bc458eb00de4c36;p=chaz%2Fyoink diff --git a/src/stlplus/subsystems/ini_manager.cpp b/src/stlplus/subsystems/ini_manager.cpp deleted file mode 100644 index 41f5b69..0000000 --- a/src/stlplus/subsystems/ini_manager.cpp +++ /dev/null @@ -1,1243 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// - -// Author: Andy Rushton -// Copyright: (c) Southampton University 1999-2004 -// (c) Andy Rushton 2004-2009 -// License: BSD License, see ../docs/license.html - -//////////////////////////////////////////////////////////////////////////////// -#include "ini_manager.hpp" -#include "file_system.hpp" -#include -#include -#include -#include -#include -//////////////////////////////////////////////////////////////////////////////// - -namespace stlplus -{ - - //////////////////////////////////////////////////////////////////////////////// - // local utilities - - static std::string trim(const std::string& val) - { - std::string result = val; - while (!result.empty() && isspace(result[0])) - result.erase(result.begin()); - while (!result.empty() && isspace(result[result.size()-1])) - result.erase(result.end()-1); - return result; - } - - //////////////////////////////////////////////////////////////////////////////// - // internal data structure for storing a single entry (i.e. line) from an ini file - // lines are categorised as blanks, comments or variables - // TODO - do I need an error category? - //////////////////////////////////////////////////////////////////////////////// - - class ini_entry - { - public: - enum kind_t {BLANK, COMMENT, VARIABLE}; - friend std::string to_string(kind_t kind) - { - switch(kind) - { - case BLANK: return "BLANK"; - case COMMENT: return "COMMENT"; - case VARIABLE: return "VARIABLE"; - } - return "<*unknown kind*>"; - } - - private: - unsigned m_line; - kind_t m_kind; - std::string m_text; - std::string m_name; - std::string m_value; - - public: - ini_entry(unsigned line) : m_line(line), m_kind(BLANK) {} - ini_entry(unsigned line, const std::string& comment) : m_line(line), m_kind(COMMENT), m_text("; " + comment) {} - ini_entry(unsigned line, const std::string& name, const std::string& value) : m_line(line), m_kind(VARIABLE), m_text(name + " = " + value), m_name(name), m_value(value) {} - ~ini_entry(void) {} - - unsigned line(void) const {return m_line;} - kind_t kind(void) const {return m_kind;} - bool blank(void) const {return m_kind == BLANK;} - bool comment(void) const {return m_kind == COMMENT;} - bool variable(void) const {return m_kind == VARIABLE;} - - const std::string& text(void) const {return m_text;} - const std::string& variable_name(void) const {return m_name;} - const std::string& variable_value(void) const {return m_value;} - - bool print(std::ostream& str) const - { - str << " " << m_line << ":" << to_string(m_kind) << ": " << m_text << std::endl; - return !str.fail(); - } - }; - - //////////////////////////////////////////////////////////////////////////////// - // internal data structure representing an ini file section containing all the - // entries for that section from a single ini file - //////////////////////////////////////////////////////////////////////////////// - - class ini_section - { - private: - friend class ini_file; - std::string m_title; - std::list m_entries; - - public: - ini_section(const std::string& title) : - m_title(title) - { - } - - ~ini_section(void) - { - } - - const std::string& title(void) const - { - return m_title; - } - - bool empty(void) const - { - // a section is empty if it contains no variables - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable()) - return false; - } - return true; - } - - void clear(void) - { - m_entries.clear(); - } - - bool variable_exists(const std::string variable) const - { - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable() && i->variable_name() == variable) - return true; - } - return false; - } - - unsigned variables_size(void) const - { - unsigned result = 0; - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - if (i->variable()) - result++; - return result; - } - - std::string variable_name(unsigned offset) const - { - unsigned j = 0; - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable()) - { - if (j == offset) - return i->variable_name(); - j++; - } - } - return std::string(); - } - - std::vector variable_names(void) const - { - std::vector result; - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - if (i->variable()) - result.push_back(i->variable_name()); - return result; - } - - std::string variable_value(unsigned offset) const - { - unsigned j = 0; - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable()) - { - if (j == offset) - return i->variable_value(); - j++; - } - } - return std::string(); - } - - std::string variable_value(const std::string variable) const - { - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable() && i->variable_name() == variable) - return i->variable_value(); - } - return std::string(); - } - - unsigned variable_line(const std::string variable) const - { - for (std::list::const_iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable() && i->variable_name() == variable) - return i->line(); - } - return 0; - } - - bool add_variable(unsigned line, const std::string& variable, const std::string& value) - { - erase_variable(variable); - m_entries.push_back(ini_entry(line ? line : m_entries.size(), variable, value)); - return true; - } - - bool add_comment(unsigned line, const std::string& comment) - { - m_entries.push_back(ini_entry(line ? line : m_entries.size(), comment)); - return true; - } - - bool add_blank(unsigned line) - { - m_entries.push_back(ini_entry(line ? line : m_entries.size())); - return true; - } - - bool erase_variable(const std::string& variable) - { - for (std::list::iterator i = m_entries.begin(); i != m_entries.end(); i++) - { - if (i->variable() && i->variable_name() == variable) - { - m_entries.erase(i); - return true; - } - } - return false; - } - - bool print(std::ostream& str) const - { - str << " [" << m_title << "]" << std::endl; - for (std::list::const_iterator entry = m_entries.begin(); entry != m_entries.end(); entry++) - entry->print(str); - return !str.fail(); - } - }; - - //////////////////////////////////////////////////////////////////////////////// - // internal data structure representing a single ini file - //////////////////////////////////////////////////////////////////////////////// - - class ini_file - { - private: - friend class ini_section; - std::string m_filename; - bool m_changed; - bool m_writable; - std::list m_sections; - - std::list::const_iterator find_section(const std::string& section) const - { - for (std::list::const_iterator i = m_sections.begin(); i != m_sections.end(); i++) - { - if (i->title() == section) - return i; - } - return m_sections.end(); - } - - std::list::iterator find_section(const std::string& section) - { - for (std::list::iterator i = m_sections.begin(); i != m_sections.end(); i++) - { - if (i->title() == section) - return i; - } - return m_sections.end(); - } - - public: - - ini_file(void) : m_changed(false), m_writable(false) - { - } - - ini_file(const std::string& filename) : m_changed(false), m_writable(false) - { - read_file(filename); - } - - ~ini_file(void) - { - if (writable()) - save_file(); - } - - bool initialised(void) const - { - return !m_filename.empty(); - } - - bool writable(void) const - { - return m_writable; - } - - bool read_file(const std::string& filename) - { - m_filename = filename; - m_changed = false; - // file may not yet exist - possible to create an Ini file using this class - // so it is writable if the file exists and is writable or if the folder is writable - m_writable = file_writable(m_filename); - if (!file_exists(m_filename)) - return true; - // create a dummy top section to hold file comments - std::list::iterator section = m_sections.insert(m_sections.end(), ini_section("")); - std::ifstream source(m_filename.c_str()); - unsigned line_number = 0; - std::string line; - while(std::getline(source,line)) - { - line_number++; - unsigned i = 0; - while(i < line.size() && isspace(line[i])) - i++; - if (i < line.size() && line[i] == '[') - { - // found a section title - // skip the [ - i++; - // get the text up to the end ] or the end of the line - std::string title; - while (i < line.size() && line[i] != ']') - title += line[i++]; - // create a new section and make it the current section - section = m_sections.insert(m_sections.end(), ini_section(title)); - } - else if (i < line.size() && line[i] == ';') - { - // found a comment - // skip the ; because that is not part of the comment - i++; - // add the rest of the line as a comment to the current section - section->add_comment(line_number, line.substr(i, line.size()-1)); - } - else if (i == line.size()) - { - // found a blank line - section->add_blank(line_number); - } - else - { - // found a *possible* variable - now scan forwards for the = operator - std::string name; - while (i < line.size() && line[i] != '=') - name += line[i++]; - // skip the = sign - // TODO - detect a missing = sign here and convert to an error - if (i < line.size()) - i++; - // trim trailing whitespace off the name - name = trim(name); - // now get the value, minus any leading whitespace - std::string value; - while(i < line.size() && isspace(line[i])) - i++; - while (i < line.size()) - value += line[i++]; - // trim trailing whitespace off the value - value = trim(value); - // and finally add the name/value pair to the data structure - section->add_variable(line_number, name, value); - } - } - return true; - } - - bool save_file(void) - { - if (!initialised()) return false; - if (!m_changed) return true; - if (!m_writable) return false; - std::ofstream output(m_filename.c_str()); - for (std::list::iterator section = m_sections.begin(); section != m_sections.end(); section++) - { - if (!(section->title().empty())) - output << "[" << section->title() << "]" << std::endl; - for (std::list::iterator entry = section->m_entries.begin(); entry != section->m_entries.end(); entry++) - output << entry->text() << std::endl; - } - m_changed = false; - return true; - } - - std::string filename(void) const - { - return m_filename; - } - - bool empty(void) const - { - // file is empty if it has either no sections or an empty header section - if (m_sections.empty()) return true; - if ((m_sections.begin() == --m_sections.end()) && m_sections.begin()->empty()) return true; - return false; - } - - bool section_exists(const std::string& title) const - { - return find_section(title) != m_sections.end(); - } - - bool add_section(const std::string& section) - { - if (!m_writable) return false; - m_sections.push_back(ini_section(section)); - m_changed = true; - return true; - } - - bool empty_section(const std::string& section) - { - std::list::iterator found = find_section(section); - if (found == m_sections.end()) return false; - return found->empty(); - } - - bool erase_section(const std::string& section) - { - if (!m_writable) return false; - std::list::iterator found = find_section(section); - if (found == m_sections.end()) return false; - m_sections.erase(found); - m_changed = true; - return true; - } - - bool clear_section(const std::string& section) - { - if (!m_writable) return false; - std::list::iterator found = find_section(section); - if (found == m_sections.end()) return false; - found->clear(); - m_changed = true; - return true; - } - - unsigned sections_size(void) const - { - return m_sections.size(); - } - - const std::string& section_name(unsigned i) const - { - std::list::const_iterator result = m_sections.begin(); - for (unsigned j = 1; j <= i; j++) - result++; - return result->title(); - } - - std::vector section_names(void) const - { - std::vector result; - for (unsigned j = 0; j < sections_size(); j++) - result.push_back(section_name(j)); - return result; - } - - bool variable_exists(const std::string& section, const std::string variable) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return false; - return found->variable_exists(variable); - } - - std::vector variable_names(const std::string& section) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return std::vector(); - return found->variable_names(); - } - - unsigned variables_size(const std::string& section) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return 0; - return found->variables_size(); - } - - unsigned variable_line(const std::string& section, const std::string variable) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return 0; - return found->variable_line(variable); - } - - std::string variable_name(const std::string& section, unsigned i) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return std::string(); - return found->variable_name(i); - } - - std::string variable_value(const std::string& section, unsigned i) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return std::string(); - return found->variable_value(i); - } - - std::string variable_value(const std::string& section, const std::string variable) const - { - std::list::const_iterator found = find_section(section); - if (found == m_sections.end()) return std::string(); - return found->variable_value(variable); - } - - bool add_variable(const std::string& section, const std::string& variable, const std::string& value) - { - if (!m_writable) return false; - std::list::iterator found = find_section(section); - if (found == m_sections.end()) found = m_sections.insert(m_sections.end(),ini_section(section)); - if (found->add_variable(0,variable,value)) - m_changed = true; - return true; - } - - bool add_comment(const std::string& section, const std::string& comment) - { - if (!m_writable) return false; - std::list::iterator found = find_section(section); - if (found == m_sections.end()) found = m_sections.insert(m_sections.end(),ini_section(section)); - if (found->add_comment(0,comment)) - m_changed = true; - return true; - } - - bool add_blank(const std::string& section) - { - if (!m_writable) return false; - std::list::iterator found = find_section(section); - if (found == m_sections.end()) found = m_sections.insert(m_sections.end(),ini_section(section)); - if (found->add_blank(0)) - m_changed = true; - return true; - } - - bool erase_variable(const std::string& section, const std::string& variable) - { - if (!m_writable) return false; - std::list::iterator found = find_section(section); - if (found == m_sections.end()) return false; - if (found->erase_variable(variable)) - { - m_changed = true; - return true; - } - return false; - } - - bool print(std::ostream& str) const - { - str << "file: " << m_filename << std::endl; - for (std::list::const_iterator section = m_sections.begin(); section != m_sections.end(); section++) - section->print(str); - return !str.fail(); - } - }; - - //////////////////////////////////////////////////////////////////////////////// - // body data structure contains all the data and is pointed-to by exported data structure - - class ini_manager_body - { - private: - std::vector m_files; - unsigned m_count; - - ini_manager_body(const ini_manager_body&); - ini_manager_body& operator= (const ini_manager_body&); - - public: - - ini_manager_body(void) : m_count(1) - { - } - - ~ini_manager_body(void) - { - save(); - } - - void increment(void) - { - ++m_count; - } - - bool decrement(void) - { - --m_count; - return m_count == 0; - } - - ////////////////////////////////////////////////////////////////////////////// - // file management - - // add files starting with the most local file (e.g. the current project) which has depth 0 - // and working back to the most global (e.g. the installation settings) which has a depth of size()-1 - // This does nothing if the file has already been loaded - it is not permitted to manage the same file twice. - // Returns true if the file loaded okay or was already loaded (it is counted as successful if the file did - // not exist, only read errors cause a failure) - bool add_file(const std::string& filename) - { - // if this file has been loaded, don't load it again - // this is not an error - for (unsigned i = 0; i < m_files.size(); i++) - { - if (filespec_to_path(filename) == filespec_to_path(m_files[i].filename())) - return true; - } - // add a new file to the back of the list and then load it - // I do it in two steps rather than passing the filename to the constructor in order to return the load status - m_files.push_back(ini_file()); - return m_files.back().read_file(filename); - } - - // as above, returns false if *none* of the files were added - // filenames[0] is the local file, and so on - bool add_files(const std::vector& filenames) - { - bool result = true; - for (unsigned i = 0; i < filenames.size(); i++) - result &= add_file(filenames[i]); - return result; - } - - // saves modified ini files - returns true if all modified files were written successfully - bool save(void) - { - bool result = true; - for (unsigned i = 0; i < m_files.size(); i++) - result &= m_files[i].save_file(); - return result; - } - - // get the number of files being managed - unsigned size(void) const - { - return m_files.size(); - } - - // get the ini filename associated with a depth - std::string filename(unsigned depth) const - { - return m_files[depth].filename(); - } - - // test whether a file in the ini manager is writable - bool writable(unsigned depth) const - { - return m_files[depth].writable(); - } - - // test whether a file is empty - // An ini file is considered empty if it has no named sections and the header is empty or missing - bool empty(unsigned depth) const - { - return m_files[depth].empty(); - } - - // erase the ini file from the ini manager and from the disk - bool erase(unsigned depth) - { - std::string file = filename(depth); - remove(depth); - return file_delete(file); - } - - // remove the file from the ini manager but do not erase it from the disk - bool remove(unsigned depth) - { - if (m_files[depth].writable()) - m_files[depth].save_file(); - m_files.erase(m_files.begin() + depth); - return true; - } - - ////////////////////////////////////////////////////////////////////////////// - // section management - - // returns the union of all section names in all of the ini files - std::vector section_names(void) const - { - std::vector result; - for (unsigned i = 0; i < m_files.size(); i++) - { - std::vector file_result = section_names(i); - for (unsigned j = 0; j < file_result.size(); j++) - { - if (std::find(result.begin(), result.end(), file_result[j]) == result.end()) - result.push_back(file_result[j]); - } - } - return result; - } - - // returns the section names in one of the ini files - std::vector section_names(unsigned depth) const - { - return m_files[depth].section_names(); - } - - // tests whether a section is found in any of the ini files - bool section_exists(const std::string& title) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (m_files[i].section_exists(title)) - return true; - } - return false; - } - - // tests whether the section is found in the specific ini file - bool section_exists(const std::string& title, unsigned depth) const - { - return m_files[depth].section_exists(title); - } - - // adds a section to the specified ini file - does nothing if it is already present - bool add_section(const std::string& section, unsigned depth) - { - return m_files[depth].add_section(section); - } - - // test whether a section is empty - bool empty_section(const std::string& section, unsigned depth) - { - return m_files[depth].empty_section(section); - } - - // removes a section from the specified ini file if it exists there but cannot remove it from any other file - bool erase_section(const std::string& section, unsigned depth) - { - return m_files[depth].erase_section(section); - } - - // removes all the contents of a section from the specified ini file but keeps the empty section - bool clear_section(const std::string& section, unsigned depth) - { - return m_files[depth].clear_section(section); - } - - ////////////////////////////////////////////////////////////////////////////// - // variable management - - // test whether a variable exists in any of the ini files - bool variable_exists(const std::string& section, const std::string variable) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (variable_exists(section, variable, i)) - return true; - } - return false; - } - - // test whether a variable exists in specified ini file - bool variable_exists(const std::string& section, const std::string variable, unsigned depth) const - { - return m_files[depth].variable_exists(section, variable); - } - - // get the union of all variables declared in all ini files - std::vector variable_names(const std::string& section) const - { - std::vector result; - for (unsigned i = 0; i < m_files.size(); i++) - { - std::vector file_result = variable_names(section, i); - for (unsigned j = 0; j < file_result.size(); j++) - { - if (std::find(result.begin(), result.end(), file_result[j]) == result.end()) - result.push_back(file_result[j]); - } - } - return result; - } - - // get the set of all varaibale names from one file - std::vector variable_names(const std::string& section, unsigned depth) const - { - return m_files[depth].variable_names(section); - } - - // get the depth of the first ini file to define a variable - // returns 0 if defined in the local ini file, etc. Returns (unsigned)-1 if the variable doesn't exist - unsigned variable_depth(const std::string& section, const std::string variable) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (variable_exists(section, variable, i)) - return i; - } - return (unsigned)-1; - } - - // get the filename that first defines the variable - std::string variable_filename(const std::string& section, const std::string variable) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (variable_exists(section, variable, i)) - return filename(i); - } - return std::string(); - } - - unsigned variable_linenumber(const std::string& section, const std::string variable) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (variable_exists(section, variable, i)) - return m_files[i].variable_line(section,variable); - } - return 0; - } - - // get the value of a variable as a single unprocessed string - // if the variable does not exist the string will be empty, but beware that - // you also get an empty string if a variable exists but has no value - // you can differentiate between the two cases by using variable_exists_all above - std::string variable_value(const std::string& section, const std::string variable) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (variable_exists(section, variable, i)) - return variable_value(section, variable, i); - } - return std::string(); - } - - // get the value from the specified file - std::string variable_value(const std::string& section, const std::string variable, unsigned depth) const - { - return m_files[depth].variable_value(section, variable); - } - - // get the value of a variable as a processed string - // processing splits the value at commas and furthermore supports quoted - // strings (so that values can contain commas for example) - // quoted strings are dequoted before they are added to the result - // the result is a vector of dequoted strings, one per value in the comma-separated list - std::vector variable_values(const std::string& section, const std::string variable) const - { - for (unsigned i = 0; i < m_files.size(); i++) - { - if (variable_exists(section, variable, i)) - return variable_values(section, variable, i); - } - return std::vector(); - } - - // get the processed variable from the specified file - std::vector variable_values(const std::string& section, const std::string variable, unsigned depth) const - { - // get the unprocessed value and then do the processing into processed separate values - std::string value = variable_value(section, variable, depth); - std::vector result; - if (!value.empty()) - { - result.push_back(std::string()); - unsigned i = 0; - // loop which is repeated for each element in the comma-separated list - while(i < value.size()) - { - // skip leading whitespace - while (i < value.size() && isspace(value[i])) i++; - // get the value - this means all text up to the next comma or end of line - // also allow escaped characters - while (i < value.size()) - { - if (value[i] == ',') break; - if (value[i] == '\\') - { - // found an escaped character - de-escape it by only getting the next character - // beware of an escape character at the end of the line which just gets ignored - i++; - if (i < value.size()) result.back() += value[i++]; - } - else if (value[i] == '"') - { - // get a quoted substring - // first skip the opening quote - i++; - // keep getting characters until a close-quote, but allow the quote character to be escaped by itself - while (i < value.size()) - { - if (value[i] == '"') - { - // found a quote skip it - i++; - // now establish whether its an escaped quote - // if it is, keep it, but de-escape it by only getting the next character - // it it isn't, break out and continue processing the value as a non-quoted string - if (i < value.size() && value[i] != '"') break; - if (i < value.size()) result.back() += value[i++]; - } - else - { - // non-quote and non-escape so just get the character - result.back() += value[i++]; - } - } - } - else - { - // non-escape so just get the character - result.back() += value[i++]; - } - } - // trim trailing whitespace off the value - while (!result.back().empty() && isspace(result.back()[result.back().size()-1])) result.back().erase(result.back().size()-1,1); - // now check for whether there is a comma or end of line - if (i <= value.size() && value[i] == ',') - { - // skip the comma and add a new string to the result ready for the next iteration - i++; - result.push_back(std::string()); - } - else - { - // end of line found so break out - break; - } - } - } - return result; - } - - // add a variable to the specified file - bool add_variable(const std::string& section, const std::string& variable, const std::string& value, unsigned depth) - { - return m_files[depth].add_variable(section, variable, value); - } - - // add a variable as a processed string - // processing means that the values in the string vector are converted into a comma-separated list - // values containing reserved characters are automatically quoted - so you should not even try to quote them yourself - bool add_variable(const std::string& section, const std::string& variable, const std::vector& values, unsigned depth) - { - // convert the values vector into a comma-separated string with each value escaped so that special characters do not confuse the reader - // the characters escaped are: '\', ',', '"' - std::string value; - for (unsigned v = 0; v < values.size(); v++) - { - const std::string& element = values[v]; - // add the comma between values === add a comma before all but the first value - if (v > 0) value += ','; - for (unsigned i = 0; i < element.size(); i++) - { - // add a character at a time, escaping special characters - if (element[i] == '"' || element[i] == ',' || element[i] == '\\') - { - // escape the character - value += '\\'; - } - value += element[i]; - } - } - return add_variable(section, variable, value, depth); - } - - // erase a variable from the specified file - // this does not remove the variable from other ini files, so the variable may still exist - // to mask a global variable, set the variable to an empty string instead - bool erase_variable(const std::string& section, const std::string& variable, unsigned depth) - { - return m_files[depth].erase_variable(section, variable); - } - - ////////////////////////////////////////////////////////////////////////////// - // sundry line-entry management - - // add a comment to the specified ini file - bool add_comment(const std::string& section, const std::string& comment, unsigned depth) - { - return m_files[depth].add_comment(section, comment); - } - - // add a blank line to the specified ini file - bool add_blank(const std::string& section, unsigned depth) - { - return m_files[depth].add_blank(section); - } - - bool print(std::ostream& str) const - { - str << "----------------------------------------" << std::endl; - for (unsigned depth = 0; depth < m_files.size(); depth++) - { - m_files[depth].print(str); - str << "----------------------------------------" << std::endl; - } - return !str.fail(); - } - }; - - //////////////////////////////////////////////////////////////////////////////// - // exported data structure representing the set of all ini files and providing - // the access functions exported by the class - //////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////// - // constructors/destructors - - ini_manager::ini_manager(void) : m_body(new ini_manager_body) - { - } - - ini_manager::ini_manager(const std::vector& filenames) : m_body(new ini_manager_body) - { - add_files(filenames); - } - - ini_manager::ini_manager(const ini_manager& manager) : m_body(0) - { - m_body = manager.m_body; - m_body->increment(); - } - - ini_manager& ini_manager::operator= (const ini_manager& manager) - { - if (m_body == manager.m_body) return *this; - if (m_body->decrement()) - delete m_body; - m_body = manager.m_body; - m_body->increment(); - return *this; - } - - ini_manager::~ini_manager(void) - { - if (m_body->decrement()) - delete m_body; - } - - //////////////////////////////////////////////////////////////////////////////// - // file management - - bool ini_manager::add_file(const std::string& filename) - { - return m_body->add_file(filename); - } - - bool ini_manager::add_files(const std::vector& filenames) - { - return m_body->add_files(filenames); - } - - bool ini_manager::save(void) - { - return m_body->save(); - } - - unsigned ini_manager::size(void) const - { - return m_body->size(); - } - - std::string ini_manager::filename(unsigned depth) const - { - return m_body->filename(depth); - } - - bool ini_manager::writable(unsigned depth) const - { - return m_body->writable(depth); - } - - bool ini_manager::empty(unsigned depth) const - { - return m_body->empty(depth); - } - - bool ini_manager::erase(unsigned depth) - { - return m_body->erase(depth); - } - - bool ini_manager::remove(unsigned depth) - { - return m_body->remove(depth); - } - - //////////////////////////////////////////////////////////////////////////////// - // section management - - std::vector ini_manager::section_names(void) const - { - return m_body->section_names(); - } - - std::vector ini_manager::section_names(unsigned depth) const - { - return m_body->section_names(depth); - } - - bool ini_manager::section_exists(const std::string& section) const - { - return m_body->section_exists(section); - } - - bool ini_manager::section_exists(const std::string& section, unsigned depth) const - { - return m_body->section_exists(section, depth); - } - - bool ini_manager::add_section(const std::string& section, unsigned depth) - { - return m_body->add_section(section, depth); - } - - bool ini_manager::empty_section(const std::string& section, unsigned depth) - { - return m_body->empty_section(section, depth); - } - - bool ini_manager::erase_section(const std::string& section, unsigned depth) - { - return m_body->erase_section(section, depth); - } - - bool ini_manager::clear_section(const std::string& section, unsigned depth) - { - return m_body->clear_section(section, depth); - } - - //////////////////////////////////////////////////////////////////////////////// - // variable management - - bool ini_manager::variable_exists(const std::string& section, const std::string variable) const - { - return m_body->variable_exists(section, variable); - } - - bool ini_manager::variable_exists(const std::string& section, const std::string variable, unsigned depth) const - { - return m_body->variable_exists(section, variable, depth); - } - - std::vector ini_manager::variable_names(const std::string& section) const - { - return m_body->variable_names(section); - } - - std::vector ini_manager::variable_names(const std::string& section, unsigned depth) const - { - return m_body->variable_names(section, depth); - } - - unsigned ini_manager::variable_depth(const std::string& section, const std::string variable) const - { - return m_body->variable_depth(section, variable); - } - - std::string ini_manager::variable_filename(const std::string& section, const std::string variable) const - { - return m_body->variable_filename(section, variable); - } - - unsigned ini_manager::variable_linenumber(const std::string& section, const std::string variable) const - { - return m_body->variable_linenumber(section, variable); - } - - std::string ini_manager::variable_value(const std::string& section, const std::string variable) const - { - return m_body->variable_value(section, variable); - } - - std::string ini_manager::variable_value(const std::string& section, const std::string variable, unsigned depth) const - { - return m_body->variable_value(section, variable, depth); - } - - std::vector ini_manager::variable_values(const std::string& section, const std::string variable) const - { - return m_body->variable_values(section, variable); - } - - std::vector ini_manager::variable_values(const std::string& section, const std::string variable, unsigned depth) const - { - return m_body->variable_values(section, variable, depth); - } - - bool ini_manager::add_variable(const std::string& section, const std::string& variable, const std::string& value, unsigned depth) - { - return m_body->add_variable(section, variable, value, depth); - } - - bool ini_manager::add_variable(const std::string& section, const std::string& variable, const std::vector& values, unsigned depth) - { - return m_body->add_variable(section, variable, values, depth); - } - - bool ini_manager::erase_variable(const std::string& section, const std::string& variable, unsigned depth) - { - return m_body->erase_variable(section, variable, depth); - } - - - //////////////////////////////////////////////////////////////////////////////// - // sundry entries - - bool ini_manager::add_comment(const std::string& section, const std::string& comment, unsigned depth) - { - return m_body->add_comment(section, comment, depth); - } - - bool ini_manager::add_blank(const std::string& section, unsigned depth) - { - return m_body->add_blank(section, depth); - } - - bool ini_manager::print(std::ostream& str) const - { - return m_body->print(str); - } - - //////////////////////////////////////////////////////////////////////////////// - // diagnostic print - - std::ostream& operator << (std::ostream& str, const ini_manager& manager) - { - manager.print(str); - return str; - } - - //////////////////////////////////////////////////////////////////////////////// - -} // end namespace stlplus