1 /*
2  * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 #include "Environ.h"
10 
11 #include "Log.h"
12 #include "Path.h"
13 #include "BaseMsg.h"
14 #include "NameException.h"
15 #include "StringTool.h"
16 
17 #include <stdio.h>
18 
19 //-----------------------------------------------------------------
20 /**
21  * Free all remain messages for watchers.
22  */
~Environ()23 Environ::~Environ()
24 {
25     t_watchers::iterator end = m_watchers.end();
26     for (t_watchers::iterator i = m_watchers.begin(); i != end; ++i) {
27         delete i->second;
28     }
29 }
30 //-----------------------------------------------------------------
31 /**
32  * Save params.
33  * @param file where to store params, this file will be overwritten
34  */
35     void
store(const Path & file)36 Environ::store(const Path &file)
37 {
38     FILE *config = fopen(file.getNative().c_str(), "w");
39     if (config) {
40         fputs("-- this file is automatically generated\n", config);
41 
42         t_values::iterator end = m_values.end();
43         for (t_values::iterator i = m_values.begin(); i != end; ++i) {
44             fprintf(config, "setParam(\"%s\", \"%s\")\n",
45                     i->first.c_str(), i->second.c_str());
46         }
47 
48         fclose(config);
49     }
50     else {
51         LOG_WARNING(ExInfo("cannot save config")
52                 .addInfo("file", file.getNative()));
53     }
54 }
55 //-----------------------------------------------------------------
56 /**
57  * Set param.
58  * Notice watchers.
59  * When watcher is not available, it will be removed.
60  *
61  * @param name param name
62  * @param value param value
63  */
64     void
setParam(const std::string & name,const std::string & value)65 Environ::setParam(const std::string &name, const std::string &value)
66 {
67     if (m_values[name] != value) {
68         m_values[name] = value;
69         LOG_DEBUG(ExInfo("setParam")
70                 .addInfo("param", name)
71                 .addInfo("value", value));
72 
73         t_watchers::iterator it = m_watchers.find(name);
74         if (m_watchers.end() != it) {
75             t_watchers::size_type count = m_watchers.count(name);
76             for (t_watchers::size_type i = 0; i < count; ++i) {
77                 t_watchers::iterator cur_it = it++;
78                 try {
79                     cur_it->second->sendClone();
80                 }
81                 catch (NameException &e) {
82                     LOG_WARNING(e.info());
83                     delete cur_it->second;
84                     m_watchers.erase(cur_it);
85                 }
86             }
87         }
88     }
89 }
90 //-----------------------------------------------------------------
91 /**
92  * Store this integer value like string param.
93  * @param name param name
94  * @param value param value
95  */
96     void
setParam(const std::string & name,long value)97 Environ::setParam(const std::string &name, long value)
98 {
99     setParam(name, StringTool::toString(value));
100 }
101 //-----------------------------------------------------------------
102 /**
103  * Return value.
104  * Implicit value is "".
105  *
106  * @param name param name
107  * @param implicit default value = ""
108  * @return value or implicit value
109  */
110     std::string
getParam(const std::string & name,const std::string & implicit) const111 Environ::getParam(const std::string &name,
112                 const std::string &implicit) const
113 {
114     std::string result = implicit;
115 
116     t_values::const_iterator it = m_values.find(name);
117     if (m_values.end() != it) {
118         result = it->second;
119     }
120     return result;
121 }
122 //-----------------------------------------------------------------
123 /**
124  * Returns number value.
125  * Implicit value is zero.
126  *
127  * @param name param name
128  * @param implicit default value = 0
129  * @return number or implicit
130  */
131     int
getAsInt(const std::string & name,int implicit) const132 Environ::getAsInt(const std::string &name,
133                 int implicit) const
134 {
135     std::string value = getParam(name);
136     bool ok;
137     int result = StringTool::readInt(value.c_str(), &ok);
138     if (!ok) {
139         if (value != "") {
140             LOG_WARNING(ExInfo("cannot recognize numeric value")
141                     .addInfo("property", name)
142                     .addInfo("value", value)
143                     .addInfo("default", implicit));
144         }
145         result = implicit;
146     }
147     return result;
148 }
149 //-----------------------------------------------------------------
150 /**
151  * Returns boolean value.
152  * Recognizes 1/0, true/false, on/off, yes/no.
153  *
154  * @param name param name
155  * @param implicit default value = false
156  * @return stored value or implicit value when value is not recognized
157  */
158     bool
getAsBool(const std::string & name,bool implicit) const159 Environ::getAsBool(const std::string &name,
160                 bool implicit) const
161 {
162     bool result = false;
163     std::string value = getParam(name);
164     if (value == "1" || value == "true" || value == "on" || value == "yes") {
165         result = true;
166     }
167     else if (value == "0" || value == "false" || value == "off" ||
168             value == "no")
169     {
170         result = false;
171     }
172     else {
173         if (value != "") {
174             //TODO: don't print this every time
175             LOG_WARNING(ExInfo("cannot recognize boolean value")
176                     .addInfo("property", name)
177                     .addInfo("value", value)
178                     .addInfo("default", implicit)
179                     .addInfo("hint", "use 1/0, true/false, on/off, yes/no"));
180         }
181         result = implicit;
182     }
183     return result;
184 }
185 //-----------------------------------------------------------------
186 /**
187  * Multiple watcher can watch param change.
188  * @param name param name
189  * @param msg message to raise
190  */
191     void
addWatcher(const std::string & name,BaseMsg * msg)192 Environ::addWatcher(const std::string &name, BaseMsg *msg)
193 {
194     m_watchers.insert(std::pair<std::string,BaseMsg*>(name, msg));
195     LOG_DEBUG(ExInfo("add watcher")
196             .addInfo("param", name)
197             .addInfo("msg", msg->toString()));
198 }
199 //-----------------------------------------------------------------
200 /**
201  * Removes all registered watchers for given listener.
202  */
203 void
removeWatchers(const std::string & listenerName)204 Environ::removeWatchers(const std::string &listenerName)
205 {
206     t_watchers::iterator end = m_watchers.end();
207     for (t_watchers::iterator i = m_watchers.begin(); i != end; /*empty*/) {
208         t_watchers::iterator cur = i++;
209         if (cur->second->getListenerName() == listenerName) {
210             delete cur->second;
211             m_watchers.erase(cur);
212         }
213     }
214 }
215 //-----------------------------------------------------------------
216 std::string
toString() const217 Environ::toString() const
218 {
219     ExInfo info("environ");
220     t_values::const_iterator end = m_values.end();
221     for (t_values::const_iterator i = m_values.begin(); i != end; ++i) {
222         info.addInfo(i->first, i->second);
223     }
224     return info.info();
225 }
226 //-----------------------------------------------------------------
227 std::string
getHelpInfo() const228 Environ::getHelpInfo() const
229 {
230     std::string help;
231     t_values::const_iterator end = m_values.end();
232     for (t_values::const_iterator i = m_values.begin(); i != end; ++i) {
233         help += i->first + "='" + i->second + "'\n";
234     }
235     return help;
236 }
237 
238