/
ConfigStoreImpl.h
325 lines (266 loc) · 8.58 KB
/
ConfigStoreImpl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
* Distributed under the OpenDDS License.
* See: http://www.opendds.org/license.html
*/
#ifndef OPENDDS_DCPS_CONFIG_STORE_IMPL_H
#define OPENDDS_DCPS_CONFIG_STORE_IMPL_H
#include "InternalTopic.h"
#include "NetworkAddress.h"
#include "SafetyProfileStreams.h"
#include "TimeDuration.h"
#include "dcps_export.h"
#include "debug.h"
#include "dds/DdsDcpsInfrastructureC.h"
#include <ace/Configuration.h>
#include <cstring>
OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
namespace OpenDDS {
namespace DCPS {
const char CONFIG_DEBUG_LOGGING[] = "CONFIG_DEBUG_LOGGING";
const bool CONFIG_DEBUG_LOGGING_default = false;
OpenDDS_Dcps_Export
OPENDDS_VECTOR(String) split(const String& str,
const String& delims,
bool skip_leading,
bool skip_consecutive);
/**
* @class ConfigPair
*
* @brief Key-value pair used for configuration.
*/
class OpenDDS_Dcps_Export ConfigPair {
public:
ConfigPair()
{}
ConfigPair(const String& key,
const String& value)
: key_(canonicalize(key))
, value_(value)
{}
bool operator<(const ConfigPair& other) const
{
return key_ < other.key_;
}
bool operator==(const ConfigPair& other) const
{
return key_ == other.key_ && value_ == other.value_;
}
const String& key() const { return key_; }
const String& value() const { return value_; }
bool key_has_prefix(const String& prefix) const
{
const String p = canonicalize(prefix);
if (p.size() <= key_.size()) {
return std::strncmp(p.data(), key_.data(), p.size()) == 0;
}
return false;
}
static String canonicalize(const String& key);
private:
String key_;
String value_;
};
typedef InternalTopic<ConfigPair> ConfigTopic;
typedef RcHandle<ConfigTopic> ConfigTopic_rch;
typedef InternalDataWriter<ConfigPair> ConfigWriter;
typedef RcHandle<ConfigWriter> ConfigWriter_rch;
typedef InternalDataReaderListener<ConfigPair> ConfigListener;
typedef RcHandle<ConfigListener> ConfigReaderListener_rch;
typedef InternalDataReader<ConfigPair> ConfigReader;
typedef RcHandle<ConfigReader> ConfigReader_rch;
template<typename T>
struct EnumList {
T value;
const char* name;
};
class OpenDDS_Dcps_Export ConfigStoreImpl : public ConfigStore {
public:
enum TimeFormat {
Format_IntegerSeconds,
Format_IntegerMilliseconds,
Format_FractionalSeconds
};
enum NetworkAddressFormat {
Format_No_Port,
Format_Required_Port,
Format_Optional_Port
};
enum NetworkAddressKind {
Kind_ANY,
Kind_IPV4
#ifdef ACE_HAS_IPV6
, Kind_IPV6
#endif
};
ConfigStoreImpl(ConfigTopic_rch config_topic);
~ConfigStoreImpl();
DDS::Boolean has(const char* key);
void set_boolean(const char* key,
DDS::Boolean value);
DDS::Boolean get_boolean(const char* key,
DDS::Boolean value);
void set_int32(const char* key,
DDS::Int32 value);
DDS::Int32 get_int32(const char* key,
DDS::Int32 value);
void set_uint32(const char* key,
DDS::UInt32 value);
DDS::UInt32 get_uint32(const char* key,
DDS::UInt32 value);
void set_float64(const char* key,
DDS::Float64 value);
DDS::Float64 get_float64(const char* key,
DDS::Float64 value);
void set_string(const char* key,
const char* value);
char* get_string(const char* key,
const char* value);
void set_duration(const char* key,
const DDS::Duration_t& value);
DDS::Duration_t get_duration(const char* key,
const DDS::Duration_t& value);
void unset(const char* key);
void set(const char* key,
const String& value);
String get(const char* key,
const String& value,
bool allow_empty = true) const;
typedef OPENDDS_VECTOR(String) StringList;
void set(const char* key,
const StringList& value);
StringList get(const char* key,
const StringList& value) const;
template<typename T>
T get(const char* key,
T value,
const EnumList<T> decoder[])
{
bool found = false;
String value_as_string;
for (size_t idx = 0; decoder[idx].name; ++idx) {
if (decoder[idx].value == value) {
value_as_string = decoder[idx].name;
found = true;
break;
}
}
if (!found && log_level >= LogLevel::Warning) {
ACE_ERROR((LM_WARNING,
"(%P|%t) WARNING: ConfigStoreImpl::get: "
"failed to convert default value to string\n"));
}
const String actual = get(key, value_as_string);
for (size_t idx = 0; decoder[idx].name; ++idx) {
if (decoder[idx].name == actual) {
return decoder[idx].value;
}
}
if (log_level >= LogLevel::Warning) {
ACE_ERROR((LM_WARNING,
"(%P|%t) WARNING: ConfigStoreImpl::get: "
"for %C, failed to encode (%C) to enumerated value, defaulting to (%C)\n",
key, actual.c_str(), value_as_string.c_str()));
}
return value;
}
template<typename T>
void set(const char* key,
T value,
const EnumList<T> decoder[])
{
bool found = false;
String value_as_string;
for (size_t idx = 0; decoder[idx].name; ++idx) {
if (decoder[idx].value == value) {
value_as_string = decoder[idx].name;
found = true;
break;
}
}
if (!found) {
if (log_level >= LogLevel::Warning) {
ACE_ERROR((LM_WARNING,
"(%P|%t) WARNING: ConfigStoreImpl::set: "
"for %C, failed to convert enum value to string\n",
key));
}
return;
}
set(key, value_as_string);
}
template<typename T>
void set(const char* key,
const String& value,
const EnumList<T> decoder[])
{
bool found = false;
// Sanity check.
String value_as_string;
for (size_t idx = 0; decoder[idx].name; ++idx) {
if (value == decoder[idx].name) {
set(key, value);
found = true;
break;
}
}
if (!found && log_level >= LogLevel::Warning) {
ACE_ERROR((LM_WARNING,
"(%P|%t) WARNING: ConfigStoreImpl::set: "
"for %C, %C is not a valid enum value\n",
key, value.c_str()));
}
}
void set(const char* key,
const TimeDuration& value,
TimeFormat format);
TimeDuration get(const char* key,
const TimeDuration& value,
TimeFormat format) const;
void set(const char* key,
const NetworkAddress& value,
NetworkAddressFormat format,
NetworkAddressKind kind);
NetworkAddress get(const char* key,
const NetworkAddress& value,
NetworkAddressFormat format,
NetworkAddressKind kind) const;
void set(const char* key,
const NetworkAddressSet& value,
NetworkAddressFormat format,
NetworkAddressKind kind);
NetworkAddressSet get(const char* key,
const NetworkAddressSet& value,
NetworkAddressFormat format,
NetworkAddressKind kind) const;
// Section names are identified as values starting with '@' and
// having the original text of the last part of the section name.
// This is used to create objects of different types.
StringList get_section_names(const String& prefix) const;
typedef OPENDDS_MAP(String, String) StringMap;
StringMap get_section_values(const String& prefix) const;
/// Remove the section key and all section values.
void unset_section(const String& prefix) const;
static DDS::DataWriterQos datawriter_qos();
static DDS::DataReaderQos datareader_qos();
static bool debug_logging;
private:
ConfigTopic_rch config_topic_;
ConfigWriter_rch config_writer_;
ConfigReader_rch config_reader_;
};
// Takes all samples from reader and returns true if any have the key prefix.
OpenDDS_Dcps_Export bool
take_has_prefix(ConfigReader_rch reader,
const String& prefix);
OpenDDS_Dcps_Export void
process_section(ConfigStoreImpl& config_store,
ConfigReader_rch reader,
ConfigReaderListener_rch listener,
const String& key_prefix,
ACE_Configuration_Heap& config,
const ACE_Configuration_Section_Key& base,
bool allow_overwrite);
} // namespace DCPS
} // namespace OpenDDS
OPENDDS_END_VERSIONED_NAMESPACE_DECL
#endif /* OPENDDS_DCPS_CONFIG_STORE_IMPL_H */