Properties.cpp
Go to the documentation of this file.
1 /*
2  * Properties.cpp
3  *
4  * Copyright 2002, Log4cpp Project. All rights reserved.
5  *
6  * See the COPYING file for the terms of usage and distribution.
7  */
8 
9 #include "Properties.hh"
10 #include <cstdlib>
11 #include "StringUtil.hh"
12 
13 namespace log4cpp {
14 
16  }
17 
19  }
20 
21  void Properties::load(std::istream& in) {
22  clear();
23 
24  std::string fullLine, command;
25  std::string leftSide, rightSide;
26  char line[256];
27  std::string::size_type length;
28  bool partiallyRead(false); // fix for bug#137, for strings longer than 256 chars
29 
30  while (in) {
31  if (in.getline(line, 256) || !in.bad()) {
32  // either string is read fully or only partially (logical but not read/write error)
33  if (partiallyRead)
34  fullLine.append(line);
35  else
36  fullLine = line;
37  partiallyRead = (in.fail() && !in.bad());
38  if (partiallyRead && !in.eof()) {
39  in.clear(in.rdstate() & ~std::ios::failbit);
40  continue; // to get full line
41  }
42  } else {
43  break;
44  }
45  /* if the line contains a # then it is a comment
46  if we find it anywhere other than the beginning, then we assume
47  there is a command on that line, and it we don't find it at all
48  we assume there is a command on the line (we test for valid
49  command later) if neither is true, we continue with the next line
50  */
51  length = fullLine.find('#');
52  if (length == std::string::npos) {
53  command = fullLine;
54  } else if (length > 0) {
55  command = fullLine.substr(0, length);
56  } else {
57  continue;
58  }
59 
60  // check the command and handle it
61  length = command.find('=');
62  if (length != std::string::npos) {
63  leftSide = StringUtil::trim(command.substr(0, length));
64  rightSide = StringUtil::trim(command.substr(length + 1, command.size() - length));
65  _substituteVariables(rightSide);
66  } else {
67  continue;
68  }
69 
70  /* handle the command by determining what object the left side
71  refers to and setting the value given on the right
72  ASSUMPTIONS:
73  1. first object given on left side is "log4j" or "log4cpp"
74  2. all class names on right side are ignored because we
75  probably cannot resolve them anyway.
76  */
77 
78  // strip off the "log4j" or "log4cpp"
79  length = leftSide.find('.');
80  if (leftSide.substr(0, length) == "log4j" ||
81  leftSide.substr(0, length) == "log4cpp")
82  leftSide = leftSide.substr(length + 1);
83 
84  // add to the map of properties
85  insert(value_type(leftSide, rightSide));
86  }
87  }
88 
89  void Properties::save(std::ostream& out) {
90  for(const_iterator i = begin(); i != end(); ++i) {
91  out << (*i).first << "=" << (*i).second << std::endl;
92  }
93  }
94 
95  int Properties::getInt(const std::string& property, int defaultValue) {
96  const_iterator key = find(property);
97  return (key == end()) ? defaultValue : std::atoi((*key).second.c_str());
98  }
99 
100  bool Properties::getBool(const std::string& property, bool defaultValue) {
101  const_iterator key = find(property);
102  return (key == end()) ? defaultValue : ((*key).second == "true");
103  }
104 
105  std::string Properties::getString(const std::string& property,
106  const char* defaultValue) {
107  const_iterator key = find(property);
108  return (key == end()) ? std::string(defaultValue) : (*key).second;
109  }
110 
111  void Properties::_substituteVariables(std::string& value) {
112  std::string result;
113 
114  std::string::size_type left = 0;
115  std::string::size_type right = value.find("${", left);
116  if (right == std::string::npos) {
117  // bail out early for 99% of cases
118  return;
119  }
120 
121  while(true) {
122  result += value.substr(left, right - left);
123  if (right == std::string::npos) {
124  break;
125  }
126 
127  left = right + 2;
128  right = value.find('}', left);
129  if (right == std::string::npos) {
130  // no close tag, use string literally
131  result += value.substr(left - 2);
132  break;
133  } else {
134  const std::string key = value.substr(left, right - left);
135  if (key == "${") {
136  result += "${";
137  } else {
138  char* value = std::getenv(key.c_str());
139  if (value) {
140  result += value;
141  } else {
142  const_iterator it = find(key);
143  if (it == end()) {
144  // not found assume empty;
145  } else {
146  result += (*it).second;
147  }
148  }
149  }
150  left = right + 1;
151  }
152 
153  right = value.find("${", left);
154  }
155 
156  value = result;
157  }
158 }
virtual void save(std::ostream &out)
Definition: Properties.cpp:89
virtual void _substituteVariables(std::string &value)
Definition: Properties.cpp:111
static std::string trim(const std::string &s)
Definition: StringUtil.cpp:71
LOG4CPP_EXPORT CategoryStream & left(CategoryStream &os)
virtual int getInt(const std::string &property, int defaultValue)
Definition: Properties.cpp:95
virtual void load(std::istream &in)
Definition: Properties.cpp:21
virtual std::string getString(const std::string &property, const char *defaultValue)
Definition: Properties.cpp:105
virtual ~Properties()
Definition: Properties.cpp:18
virtual bool getBool(const std::string &property, bool defaultValue)
Definition: Properties.cpp:100


log4cpp
Author(s): Stephen Roderick, Bastiaan Bakker, Cedric Le Goater, Steve Ostlind, Marcel Harkema, Walter Stroebel, Glenn Scott and Tony Cheung
autogenerated on Sun Jun 23 2019 19:10:00