00001 /** 00002 \file Robots/LoBot/config/LoConfig.H 00003 \brief Robolocust/lobot configuration database. 00004 00005 This file defines a class that reads the Robolocust/lobot config file 00006 (~/.lobotrc by default or as specified by the --config-file option) 00007 and then populates a two-level map of key-value pairs that other parts 00008 of the program can use to query whatever parameters they need. 00009 00010 Robolocust/lobot config files are simplified INI files. See 00011 LoIniFileLexer.l and LoIniFileParser.y for the syntax rules and an 00012 illustrative example of what is allowed. 00013 00014 The first level of the two-level map alluded to above corresponds to 00015 sections in the INI file and the second level is for the key-value 00016 pairs of that section. Thus, the first level maps INI file section 00017 names to maps of key-value pairs. These "inner" maps map key names to 00018 their corresponding values. 00019 */ 00020 00021 // //////////////////////////////////////////////////////////////////// // 00022 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00023 // by the University of Southern California (USC) and the iLab at USC. // 00024 // See http://iLab.usc.edu for information about this project. // 00025 // //////////////////////////////////////////////////////////////////// // 00026 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00027 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00028 // in Visual Environments, and Applications'' by Christof Koch and // 00029 // Laurent Itti, California Institute of Technology, 2001 (patent // 00030 // pending; application number 09/912,225 filed July 23, 2001; see // 00031 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00034 // // 00035 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00036 // redistribute it and/or modify it under the terms of the GNU General // 00037 // Public License as published by the Free Software Foundation; either // 00038 // version 2 of the License, or (at your option) any later version. // 00039 // // 00040 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00041 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00042 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00043 // PURPOSE. See the GNU General Public License for more details. // 00044 // // 00045 // You should have received a copy of the GNU General Public License // 00046 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00047 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00048 // Boston, MA 02111-1307 USA. // 00049 // //////////////////////////////////////////////////////////////////// // 00050 // 00051 // Primary maintainer for this file: mviswana usc edu 00052 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/config/LoConfig.H $ 00053 // $Id: LoConfig.H 13037 2010-03-23 01:00:53Z mviswana $ 00054 // 00055 00056 #ifndef LOBOT_CONFIGURATION_API_DOT_H 00057 #define LOBOT_CONFIGURATION_API_DOT_H 00058 00059 //------------------------------ HEADERS -------------------------------- 00060 00061 // lobot headers 00062 #include "Robots/LoBot/config/LoLexYaccDefs.H" 00063 00064 #include "Robots/LoBot/misc/singleton.hh" 00065 #include "Robots/LoBot/util/LoString.H" 00066 00067 // Standard C++ headers 00068 #include <algorithm> 00069 #include <map> 00070 #include <vector> 00071 #include <string> 00072 00073 //------------------------------ DEFINES -------------------------------- 00074 00075 /// The Robolocust config file is divided into multiple sections with 00076 /// each section consisting of key-value pairs. There is a top-level or 00077 /// global section as well that appears before any other sections in the 00078 /// config file. In actuality, this global section is implemented as a 00079 /// specially named section. 00080 /// 00081 /// In addition to the above-mentioned global section of the config file, 00082 /// we also have an internal section that is not meant to be used 00083 /// directly by users. Rather, it acts as a sort of scratch space via 00084 /// which different Robolocust modules can exchange bits of data without 00085 /// having to explicitly know each other (which greatly simplifies the 00086 /// overall design). 00087 /// 00088 /// This internal section is never defined explicitly in the config file. 00089 /// Instead, Robolocust sets it up internally. 00090 #define LOCD_INTERNAL "__SECRET_INTERNAL_SECTION__" 00091 00092 //----------------------------- NAMESPACE ------------------------------- 00093 00094 namespace lobot { 00095 00096 //------------------------- CLASS DEFINITION ---------------------------- 00097 00098 /** 00099 \class lobot::ConfigDB 00100 \brief Robolocust/lobot configuration database. 00101 00102 This class implements a dictionary of key-value pairs. Both keys and 00103 values are strings. 00104 00105 NOTE: This class does not have any public members. It is not meant to 00106 be used directly clients, which should instead use the API provided by 00107 lobot::Configuration. 00108 */ 00109 class Configuration ; // forward declaration 00110 class ConfigDB : public singleton<ConfigDB> { 00111 /// The Robolocust/lobot config file consists of several sections. 00112 /// Each section has key-value statements in it. The configuration 00113 /// database mirrors this structure with a two-level map, i.e., a map 00114 /// of maps. The top-level map maps section names to the collection of 00115 /// key-value definitions in that section. The key-value maps for a 00116 /// section map key names to their corresponding values. 00117 typedef std::map<std::string, std::string> KeyValuePairs ; 00118 typedef std::map<std::string, KeyValuePairs> ConfigMap ; 00119 00120 ConfigMap m_config_db ; 00121 00122 /// Private constructor because the lobot config database is a 00123 /// singleton object. 00124 ConfigDB() ; 00125 friend class singleton<ConfigDB> ; 00126 00127 /// This method inserts the supplied key-value pair into the specified 00128 /// section of the configuration database. 00129 void insert(const std::string& section, 00130 const std::string& key, const std::string& value) ; 00131 00132 /// This method returns the value corresponding to the specified key 00133 /// from the specified section of the configuration database. If the 00134 /// key is not defined, the default value supplied by the client will 00135 /// be returned. 00136 std::string retrieve(const std::string& section, 00137 const std::string& key, 00138 const std::string& default_value) const ; 00139 00140 /// Clean-up 00141 ~ConfigDB() ; 00142 00143 // The configuration database is not accessed directly by clients. 00144 // Instead they use the API provided by the Configuration class, which 00145 // has full access to this object. 00146 friend class Configuration ; 00147 } ; 00148 00149 //------------------------- CLASS DEFINITION ---------------------------- 00150 00151 /** 00152 \class lobot::Configuration 00153 \brief A more user-friendly API for the ConfigDB. 00154 00155 lobot::ConfigDB is an "internal" class related to the lobot config 00156 system and is not meant to be used directly by other objects in the 00157 lobot system. Instead, client modules should use the API provided by 00158 this class for loading and retrieving configuration settings. 00159 */ 00160 class Configuration { 00161 // prevent instantiation, copy and assignment 00162 Configuration() ; 00163 Configuration(const Configuration&) ; 00164 Configuration& operator=(const Configuration&) ; 00165 00166 public: 00167 /// This method loads the configuration settings from the specified 00168 /// file. 00169 static void load(const std::string& config_file) ; 00170 00171 /// This method inserts the supplied key-value pair into the specified 00172 /// section of the configuration database. 00173 static void set(const std::string& section, 00174 const std::string& key, const std::string& value) ; 00175 00176 /// This method inserts the supplied key-value pair into the 00177 /// unnamed/anonymous global/top-level scope of the configuration 00178 /// database. 00179 static void set_global(const std::string& key, const std::string& value) ; 00180 00181 /// This method inserts the supplied key-value pair into the (secret) 00182 /// internal section of the configuration database. 00183 static void set_internal(const std::string& key, const std::string& value) ; 00184 00185 /// This method retrieves the value corresponding to the specified key 00186 /// from the specified section of the configuration database. If the 00187 /// key is not defined, the default value supplied by the client will 00188 /// be returned. 00189 template<typename T> 00190 static T get(const std::string& section, const std::string& key, 00191 const T& default_value = T()) ; 00192 00193 /// The configuration database simply retains key-value pairs as 00194 /// strings. But some settings can be lists (e.g., the value 00195 /// corresponding to some key may be a list of numbers). This method 00196 /// "breaks up" the value portion of the specified key and section 00197 /// into a list and returns the result via an array of type T. 00198 template<typename T> 00199 static void get(const std::string& section, const std::string& key, 00200 T* target, const T* defaults, unsigned int n) ; 00201 00202 /// This method retrieves the value corresponding to the specified key 00203 /// from the unnamed/anonymous global/top-level scope section of the 00204 /// configuration database. If the key is not defined in the top-level 00205 /// section, the default value supplied by the client will be 00206 /// returned. 00207 template<typename T> 00208 static T get_global(const std::string& key, const T& defval = T()) ; 00209 00210 /// Development and debugging support 00211 static void dump() ; 00212 } ; 00213 00214 /// Retrieve the value corresponding to the specified key from the 00215 /// specified section of the config file and return it as an instance of 00216 /// type T. 00217 template<typename T> 00218 T Configuration::get(const std::string& section, const std::string& key, 00219 const T& default_value) 00220 { 00221 std::string value = ConfigDB::instance().retrieve(section, key, "") ; 00222 if (value == "") //key-value pair not defined in specified sec. of INI file 00223 return default_value ; 00224 return from_string<T>(value) ; 00225 } 00226 00227 /// Partial specialization of above method for retrieving on/off/yes/no 00228 /// flags from the config file. 00229 template<> 00230 bool Configuration::get(const std::string& section, const std::string& key, 00231 const bool& default_value) 00232 { 00233 std::string flag = 00234 downstring(ConfigDB::instance().retrieve(section, key, "")) ; 00235 if (flag == "") // not defined in config file 00236 return default_value ; 00237 if (flag == "f" || flag == "false" || flag == "no" || flag == "off" || 00238 flag == "0" || flag == "disabled") 00239 return false ; 00240 return true ; 00241 } 00242 00243 /// Retrieve the values corresponding to the specified key from the 00244 /// specified section of the config file and return them via an array of 00245 /// type T. 00246 template<typename T> 00247 void Configuration::get(const std::string& section, const std::string& key, 00248 T* target, const T* defaults, unsigned int n) 00249 { 00250 std::copy(defaults, defaults + n, target) ; 00251 std::vector<T> config(string_to_vector<T>(get<std::string>(section, key))) ; 00252 if (config.size() > n) 00253 config.resize(n) ; 00254 std::copy(config.begin(), config.end(), target) ; 00255 } 00256 00257 /// This method retrieves the value corresponding to the specified key 00258 /// from the unnamed/anonymous global/top-level scope section of the 00259 /// configuration database. If the key is not defined in the top-level 00260 /// section, the default value supplied by the client will be returned. 00261 template<typename T> 00262 T Configuration::get_global(const std::string& key, const T& defval) 00263 { 00264 return get<T>(LOCD_TOP_LEVEL, key, defval) ; 00265 } 00266 00267 //----------------------------------------------------------------------- 00268 00269 } // end of namespace encapsulating this file's definitions 00270 00271 #endif 00272 00273 /* So things look consistent in everyone's emacs... */ 00274 /* Local Variables: */ 00275 /* indent-tabs-mode: nil */ 00276 /* End: */