Configuration.h
Go to the documentation of this file.
00001 /*
00002  * $Id: Configuration.h 275 2008-03-12 14:43:31Z phbaer $
00003  *
00004  * Copyright 2008 Carpe Noctem, Distributed Systems Group,
00005  * University of Kassel. All right reserved.
00006  *
00007  * The code is licensed under the Carpe Noctem Userfriendly BSD-Based
00008  * License (CNUBBL). Redistribution and use in source and binary forms,
00009  * with or without modification, are permitted provided that the
00010  * conditions of the CNUBBL are met.
00011  *
00012  * You should have received a copy of the CNUBBL along with this
00013  * software. The license is also available on our website:
00014  * http://carpenoctem.das-lab.net/license.txt
00015  */
00016 
00017 #ifndef CASTOR_CONFIGURATION_H
00018 #define CASTOR_CONFIGURATION_H 1
00019 
00020 #include <vector>
00021 #include <string>
00022 #include <iostream>
00023 #include <fstream>
00024 #include <cstdarg>
00025 #include <sstream>
00026 #include <string>
00027 #include <cstdarg>
00028 
00029 #include <boost/algorithm/string.hpp>
00030 #include <boost/lexical_cast.hpp>
00031 #include <boost/shared_ptr.hpp>
00032 #include <boost/any.hpp>
00033 
00034 #include "ConfigException.h"
00035 
00036 #define CONSUME_PARAMS(path) \
00037 boost::shared_ptr<std::vector<std::string> > params(new std::vector<std::string>());\
00038 if (path != NULL) {\
00039         va_list ap;\
00040         va_start(ap, path);\
00041         const char *temp = path;\
00042         do { \
00043                 std::vector<std::string> result; \
00044                 boost::split(result, temp, boost::is_any_of(".")); \
00045                 for (size_t i = 0; i < result.size(); i++) { \
00046                         params->push_back(result[i]); \
00047                 } \
00048         } while ((temp = va_arg(ap, const char *)) != NULL); \
00049         va_end(ap); \
00050 }
00051 
00052 namespace castor {
00053 
00054         class ConfigNode;
00055 
00056         typedef boost::shared_ptr<ConfigNode> ConfigNodePtr;
00057 
00058         class ConfigNode {
00059 
00060                 public:
00061 
00062                         typedef enum {
00063                                 Node = 0,
00064                                 Leaf = 1,
00065                                 Comment = 2,
00066                         } Type;
00067 
00068                 protected:
00069 
00070                         std::string name;
00071                         boost::any value;
00072                         ConfigNode *parent;
00073                         std::vector<ConfigNodePtr> children;
00074                         int depth;
00075                         Type type;
00076 
00077                 public:
00078 
00079                         ConfigNode(std::string name) :
00080                                 name(name), value(), parent(NULL), children(), depth(0), type(Node)
00081                         {
00082                         }
00083 
00084                         ConfigNode(Type type, std::string name) :
00085                                 name(name), value(), parent(NULL), children(), depth(0), type(type)
00086                         {
00087                         }
00088 
00089                         ConfigNode(std::string name, boost::any &value) :
00090                                 name(name), value(value), parent(NULL), children(), depth(0), type(Leaf)
00091                         {
00092                         }
00093 
00094                         ConfigNode(const ConfigNode &other) :
00095                                 name(other.name), value(other.value), parent(other.parent),
00096                                 children(other.children), depth(other.depth), type(other.type)
00097                         {
00098                         }
00099 
00100                         ~ConfigNode() {
00101 //                              std::cout << "deleting " << this->name << std::endl;
00102                         }
00103 
00104                         ConfigNode *create(std::string name) {
00105                                 this->children.push_back(ConfigNodePtr(new ConfigNode(name)));
00106                                 this->children.back()->setParent(this);
00107                                 return this->children.back().get();
00108                         }
00109 
00110                         ConfigNode *create(Type type, std::string name) {
00111                                 this->children.push_back(ConfigNodePtr(new ConfigNode(type, name)));
00112                                 this->children.back()->setParent(this);
00113                                 return this->children.back().get();
00114                         }
00115 
00116                         ConfigNode *create(std::string name, boost::any &value) {
00117                                 this->children.push_back(ConfigNodePtr(new ConfigNode(name, value)));
00118                                 this->children.back()->setParent(this);
00119                                 return this->children.back().get();
00120                         }
00121 
00122                         std::vector<ConfigNodePtr> *getChildren() {
00123                                 return &this->children;
00124                         }
00125 
00126                         ConfigNode *getParent() {
00127                                 return this->parent;
00128                         }
00129 
00130                         void setParent(ConfigNode *parent) {
00131                                 this->parent = parent;
00132                                 this->depth = parent->depth + 1;
00133                         }
00134 
00135                         const boost::any &getValue() const {
00136                                 return this->value;
00137                         }
00138 
00139                         void setValue(boost::any &value) {
00140                                 this->value = value;
00141                         }
00142 
00143                         const std::string &getName() const {
00144                                 return this->name;
00145                         }
00146 
00147                         int getDepth() const {
00148                                 return this->depth;
00149                         }
00150 
00151                         Type getType() const {
00152                                 return this->type;
00153                         }
00154 
00155                         ConfigNode &operator=(const ConfigNode &other) {
00156 
00157                                 this->name = other.name;
00158                                 this->value = other.value;
00159                                 this->parent = other.parent;
00160                                 this->children = other.children;
00161                                 this->depth = other.depth;
00162                                 this->type = other.type;
00163 
00164                                 return *this;
00165                         }
00166         };
00167 
00168         class Configuration {
00169 
00170                 protected:
00171 
00172                         std::string filename;
00173 
00174                         ConfigNodePtr configRoot;
00175 
00176                         void serialize_internal(std::ostringstream *ss, ConfigNode *node);
00177 
00178                         template<typename Target>
00179                                 Target convert(std::string value) {
00180 
00181                                         if (typeid(Target) == typeid(bool)) {
00182 
00183                                                 boost::algorithm::to_lower(value);
00184 
00185                                                 if (("false" == value) || ("no" == value) || ("0" == value)) {
00186                                                         return boost::lexical_cast<Target>(false);
00187                                                 }
00188 
00189                                                 return boost::lexical_cast<Target>(true);
00190                                         }
00191 
00192                                         printf("Value %s\n", value.c_str());
00193 
00194                                         return boost::lexical_cast<Target>(value);
00195                                 }
00196 
00197                         void collect(ConfigNode *node, std::vector<std::string> *params, size_t offset, std::vector<ConfigNode *> *result);
00198                         void collectSections(ConfigNode *node, std::vector<std::string> *params, size_t offset, std::vector<ConfigNode *> *result);
00199                         std::string pathNotFound(std::vector<std::string> *params);
00200 
00201                 public:
00202                         Configuration();
00203                         Configuration(std::string filename);
00204                         Configuration(std::string filename, const std::string content);
00205 
00206                         inline void load(std::string filename) { load(filename, boost::shared_ptr<std::ifstream>(new std::ifstream(filename.c_str(), std::ifstream::in)), false, false); }
00207 
00208                         void load(std::string filename, boost::shared_ptr<std::istream> content, bool create, bool replace);
00209 
00210                         void store();
00211                         void store(std::string filename);
00212 
00213                         std::string serialize();
00214 
00215                         template<typename T>
00216                                 T get(const char *path, ...) {
00217 
00218                                         CONSUME_PARAMS(path);
00219 
00220                                         std::vector<ConfigNode *> nodes;
00221 
00222                                         collect(this->configRoot.get(), params.get(), 0, &nodes);
00223 
00224                                         if (nodes.size() == 0) {
00225                                                 throw ConfigException(pathNotFound(params.get()));
00226                                         }
00227 
00228                                         return convert<T>(boost::any_cast<std::string>(nodes[0]->getValue()));
00229                                 }
00230 
00231                         template<typename T>
00232                                 boost::shared_ptr<std::vector<T> > getAll(const char *path, ...) {
00233         
00234                                         CONSUME_PARAMS(path);
00235                 
00236                                         std::vector<ConfigNode *> nodes;
00237                 
00238                                         collect(this->configRoot.get(), params.get(), 0, &nodes);
00239                 
00240                                         if (nodes.size() == 0) {
00241                                                 throw ConfigException(pathNotFound(params.get()));
00242                                         }
00243                 
00244                                         boost::shared_ptr<std::vector<T> > result(new std::vector<T>());
00245 
00246                                         for (int i = 0; i < nodes.size(); i++) {
00247                                                 result->push_back(convert<T>(boost::any_cast<std::string>(nodes[i]->getValue())));
00248                                         }
00249 
00250                                         return result;
00251 
00252                                 }
00253 
00254                         template<typename T>
00255                                 T tryGet(T d, const char *path, ...) {
00256 
00257                                         CONSUME_PARAMS(path);
00258 
00259                                         std::vector<ConfigNode *> nodes;
00260 
00261                                         collect(this->configRoot.get(), params.get(), 0, &nodes);
00262 
00263                                         if (nodes.size() == 0) {
00264                                                 return d;
00265                                         }
00266 
00267                                         return convert<T>(boost::any_cast<std::string>(nodes[0]->getValue()));
00268                                 }
00269 
00270                         template<typename T>
00271                                 boost::shared_ptr<std::vector<T> > tryGetAll(T d, const char *path, ...) {
00272 
00273                                         CONSUME_PARAMS(path);
00274 
00275                                         std::vector<ConfigNode *> nodes;
00276 
00277                                         collect(this->configRoot.get(), params.get(), 0, &nodes);
00278 
00279                                         boost::shared_ptr<std::vector<T> > result(new std::vector<T>());
00280 
00281                                         if (nodes.size() == 0) {
00282 
00283                                                 result->push_back(d);
00284 
00285                                                 return result;
00286                                         }
00287 
00288                                         for (int i = 0; i < nodes.size(); i++) {
00289                                                 result->push_back(convert<T>(boost::any_cast<std::string>(nodes[i]->getValue())));
00290                                         }
00291 
00292                                         return result;
00293                                 }
00294 
00295                         template<typename T>
00296                                 void set(T value, const char *path, ...) {
00297 
00298                                         CONSUME_PARAMS(path);
00299 
00300                                         std::vector<ConfigNode *> nodes;
00301 
00302                                         collect(this->configRoot.get(), params.get(), 0, &nodes);
00303 
00304                                         for (int i = 0; i < nodes.size(); i++) {
00305                                                 if (nodes[i]->getType() == ConfigNode::Leaf) {
00306                                                         nodes[i]->setValue(value);
00307                                                 }
00308                                         }
00309                                 }
00310 
00311                         boost::shared_ptr<std::vector<std::string> > getSections(const char *path, ...);
00312                         boost::shared_ptr<std::vector<std::string> > getNames(const char *path, ...);
00313 
00314                         boost::shared_ptr<std::vector<std::string> > tryGetSections(std::string d, const char *path, ...);
00315                         boost::shared_ptr<std::vector<std::string> > tryGetNames(std::string d, const char *path, ...);
00316         };
00317 
00318 };
00319 
00320 #endif /* CASTOR_CONFIGURATION_H */
00321 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39