Properties.cpp
Go to the documentation of this file.
00001 /*
00002  * Properties.cpp
00003  *
00004  * Copyright 2002, Log4cpp Project. All rights reserved.
00005  *
00006  * See the COPYING file for the terms of usage and distribution.
00007  */
00008 
00009 #include "Properties.hh"
00010 #include <cstdlib>
00011 #include "StringUtil.hh"
00012 
00013 namespace log4cpp {
00014     
00015     Properties::Properties() {
00016     }
00017 
00018     Properties::~Properties() {
00019     }
00020 
00021     void Properties::load(std::istream& in) {
00022         clear();
00023 
00024         std::string fullLine, command;
00025         std::string leftSide, rightSide;
00026         char line[256];
00027         std::string::size_type length;
00028 
00029         while (in.getline(line, 256)) {
00030             fullLine = line;
00031 
00032             /* if the line contains a # then it is a comment
00033                if we find it anywhere other than the beginning, then we assume 
00034                there is a command on that line, and it we don't find it at all
00035                we assume there is a command on the line (we test for valid 
00036                command later) if neither is true, we continue with the next line
00037             */
00038             length = fullLine.find('#');
00039             if (length == std::string::npos) {
00040                 command = fullLine;
00041             } else if (length > 0) {
00042                 command = fullLine.substr(0, length);
00043             } else {
00044                 continue;
00045             }
00046 
00047             // check the command and handle it
00048             length = command.find('=');
00049             if (length != std::string::npos) {
00050                 leftSide = StringUtil::trim(command.substr(0, length));
00051                 rightSide = StringUtil::trim(command.substr(length + 1, command.size() - length));
00052                 _substituteVariables(rightSide);
00053             } else {
00054                 continue;
00055             }
00056 
00057             /* handle the command by determining what object the left side
00058                refers to and setting the value given on the right
00059                ASSUMPTIONS:  
00060                1. first object given  on left side is "log4j" or "log4cpp"
00061                2. all class names on right side are ignored because we
00062                probably cannot resolve them anyway.
00063             */
00064 
00065             // strip off the "log4j" or "log4cpp"
00066             length = leftSide.find('.');
00067             if (leftSide.substr(0, length) == "log4j" ||
00068                 leftSide.substr(0, length) == "log4cpp")
00069                 leftSide = leftSide.substr(length + 1);
00070 
00071             // add to the map of properties
00072             insert(value_type(leftSide, rightSide));
00073         }
00074     }
00075 
00076     void Properties::save(std::ostream& out) {
00077         for(const_iterator i = begin(); i != end(); ++i) {
00078             out << (*i).first << "=" << (*i).second << std::endl;
00079         }
00080     }
00081     
00082     int Properties::getInt(const std::string& property, int defaultValue) {
00083         const_iterator key = find(property);
00084         return (key == end()) ? defaultValue : std::atoi((*key).second.c_str());
00085     }
00086 
00087     bool Properties::getBool(const std::string& property, bool defaultValue) {
00088         const_iterator key = find(property);
00089         return (key == end()) ? defaultValue : ((*key).second == "true");
00090     }
00091 
00092     std::string Properties::getString(const std::string& property, 
00093                                       const char* defaultValue) {
00094         const_iterator key = find(property);
00095         return (key == end()) ? std::string(defaultValue) : (*key).second;
00096     }
00097 
00098     void Properties::_substituteVariables(std::string& value) {
00099         std::string result;
00100 
00101         std::string::size_type left = 0;
00102         std::string::size_type right = value.find("${", left);
00103         if (right == std::string::npos) {
00104             // bail out early for 99% of cases
00105             return;
00106         }
00107 
00108         while(true) {
00109             result += value.substr(left, right - left);
00110             if (right == std::string::npos) {
00111                 break;
00112             }
00113 
00114             left = right + 2;
00115             right = value.find('}', left);
00116             if (right == std::string::npos) {
00117                 // no close tag, use string literally
00118                 result += value.substr(left - 2);
00119                 break;
00120             } else {
00121                 const std::string key = value.substr(left, right - left);
00122                 if (key == "${") {
00123                     result += "${";
00124                 } else {
00125                     char* value = std::getenv(key.c_str());
00126                     if (value) {
00127                         result += value;
00128                     } else {
00129                         const_iterator it = find(key);
00130                         if (it == end()) {
00131                             // not found assume empty;
00132                         } else {
00133                             result += (*it).second;
00134                         }
00135                     }
00136                 }
00137                 left = right + 1;
00138             }
00139 
00140             right = value.find("${", left);
00141         }
00142 
00143         value = result;
00144     }
00145 }


log4cpp
Author(s): Stephen Roderick
autogenerated on Mon Oct 6 2014 03:13:14