Ice 3.8
C++ API Reference
Loading...
Searching...
No Matches
Properties.h
1// Copyright (c) ZeroC, Inc.
2
3#ifndef ICE_PROPERTIES_H
4#define ICE_PROPERTIES_H
5
6#include "Config.h"
7#include "Ice/BuiltinSequences.h"
8#include "Ice/PropertyDict.h"
9#include "PropertiesF.h"
10#include "StringConverter.h"
11
12#include <mutex>
13#include <set>
14#include <string>
15#include <string_view>
16
17namespace Ice
18{
19 /// Converts an argument vector into a string sequence.
20 /// @param argc The number of arguments in argv.
21 /// @param argv The arguments.
22 /// @return A string sequence containing the arguments.
23 ICE_API StringSeq argsToStringSeq(int argc, const char* const argv[]);
24
25#if defined(_WIN32) || defined(ICE_DOXYGEN)
26 /// @copydoc argsToStringSeq(int, const char* const[])
27 /// @remark Windows only.
28 ICE_API StringSeq argsToStringSeq(int argc, const wchar_t* const argv[]);
29#endif
30
31 /// Updates @p argv to match the contents of @p seq. This function assumes that @p seq contains only elements of
32 /// @p argv. The function shifts the argument vector elements so that the vector matches the contents of the
33 /// sequence.
34 /// @param seq The string sequence returned from a call to #argsToStringSeq.
35 /// @param[in,out] argc The number of arguments, updated to reflect the size of the sequence.
36 /// @param argv The arguments, shifted to match @p seq.
37 ICE_API void stringSeqToArgs(const StringSeq& seq, int& argc, const char* argv[]);
38
39 /// @copydoc stringSeqToArgs(const StringSeq&, int&, const char*[])
40 inline void stringSeqToArgs(const StringSeq& seq, int& argc, char* argv[])
41 {
42 return stringSeqToArgs(seq, argc, const_cast<const char**>(argv));
43 }
44
45#if defined(_WIN32) || defined(ICE_DOXYGEN)
46 /// @copydoc stringSeqToArgs(const StringSeq&, int&, const char*[])
47 /// @remark Windows only.
48 ICE_API void stringSeqToArgs(const StringSeq& seq, int& argc, const wchar_t* argv[]);
49
50 /// @copydoc stringSeqToArgs(const StringSeq&, int&, const char*[])
51 /// @remark Windows only.
52 inline void stringSeqToArgs(const StringSeq& seq, int& argc, wchar_t* argv[])
53 {
54 return stringSeqToArgs(seq, argc, const_cast<const wchar_t**>(argv));
55 }
56#endif
57
58 /// Represents a set of properties used to configure Ice and Ice-based applications. A property is a key/value pair,
59 /// where both the key and the value are strings. By convention, property keys should have the form
60 /// `application-name>[.category[.sub-category]].name`.
61 /// @remark This class is thread-safe: multiple threads can safely read and write the properties.
62 /// @headerfile Ice/Ice.h
63 class ICE_API Properties final
64 {
65 public:
66 /// Constructs an empty property set.
67 Properties() = default;
68
69 /// Constructs a property set, loads the configuration files specified by the `Ice.Config` property or the
70 /// `ICE_CONFIG` environment variable, and then parses Ice properties from @p args.
71 /// @param args The command-line arguments. This constructor parses arguments starting with `--` and one
72 /// of the reserved prefixes (Ice, IceSSL, etc.) as properties and removes these elements from the vector. If
73 /// there is an argument starting with `--Ice.Config`, this constructor loads the specified configuration file.
74 /// When the same property is set in a configuration file and through a command-line argument, the command-line
75 /// setting takes precedence.
76 /// @param defaults Default values for the new Properties object. Settings in configuration files and the
77 /// arguments override these defaults.
78 /// @remarks This constructor loads properties from files specified by the `ICE_CONFIG` environment variable
79 /// when there is no `--Ice.Config` command-line argument.
80 explicit Properties(StringSeq& args, const PropertiesPtr& defaults = nullptr);
81
82 /// Constructs a property set, loads the configuration files specified by the `Ice.Config` property or the
83 /// `ICE_CONFIG` environment variable, and then parses Ice properties from @p args.
84 /// @tparam ArgvT The type of the argument vector, such as char**, const char**, or wchar_t** (on Windows).
85 /// @param[in, out] argc The number of command-line arguments in @p argv. When this constructor
86 /// parses properties from @p argv, it reshuffles the arguments so that the remaining arguments start at the
87 /// beginning of @p argv, and updates @p argc accordingly.
88 /// @param argv The command-line arguments. This constructor parses arguments starting with `--` and one of the
89 /// reserved prefixes (Ice, IceSSL, etc.) as properties. If there is an argument starting with `--Ice.Config`,
90 /// this constructor loads the specified configuration file. When the same property is set in a configuration
91 /// file and through a command-line argument, the command-line setting takes precedence.
92 /// @param defaults Default values for the new Properties object. Settings in configuration files and the
93 /// arguments override these defaults.
94 /// @remarks This constructor loads properties from files specified by the `ICE_CONFIG` environment variable
95 /// when there is no `--Ice.Config` command-line argument.
96 template<typename ArgvT>
97 Properties(int& argc, ArgvT argv, const PropertiesPtr& defaults = nullptr) : Properties{defaults}
98 {
99 StringSeq args = argsToStringSeq(argc, argv);
100 loadArgs(args);
101 stringSeqToArgs(args, argc, argv);
102 }
103
104 /// @private
105 /// Constructs an empty property set with additional reserved prefixes such as "IceBox", "IceStorm", etc.
106 /// @param firstOptInPrefix The first opt-in prefix.
107 /// @param remainingOptInPrefixes The remaining opt-in prefixes.
108 template<typename... T>
109 Properties(std::string firstOptInPrefix, T... remainingOptInPrefixes)
110 : _optInPrefixes{std::move(firstOptInPrefix), std::move(remainingOptInPrefixes)...}
111 {
112 }
113
114 /// @private
115 /// Constructs a property set, loads the configuration files specified by the `Ice.Config` property or the
116 /// `ICE_CONFIG` environment variable, and then parses Ice properties from @p args.
117 /// @tparam ArgvT The type of the argument vector, such as char**, const char**, or wchar_t** (on Windows).
118 /// @param[in, out] argc The number of command-line arguments in @p argv.
119 /// @param argv The command-line arguments. This constructor parses arguments starting with `--` and one of the
120 /// reserved prefixes (Ice, IceSSL, etc.) as properties and moves these arguments to the end of the array. If
121 /// there is an argument starting with `--Ice.Config`, this constructor loads the specified configuration file.
122 /// When the same property is set in a configuration file and through a command-line argument, the command-line
123 /// setting takes precedence.
124 /// @param firstOptInPrefix The first opt-in prefix.
125 /// @param remainingOptInPrefixes The remaining opt-in prefixes.
126 /// @remarks This constructor loads properties from files specified by the `ICE_CONFIG` environment variable
127 /// when there is no `--Ice.Config` command-line argument.
128 template<typename ArgvT, typename... T>
129 Properties(int& argc, ArgvT argv, std::string firstOptInPrefix, T... remainingOptInPrefixes)
130 : Properties{std::move(firstOptInPrefix), std::move(remainingOptInPrefixes)...}
131 {
132 StringSeq args = argsToStringSeq(argc, argv);
133 loadArgs(args);
134 stringSeqToArgs(args, argc, argv);
135 }
136
137 /// Copy constructor.
138 /// @param source The property set to copy.
139 Properties(const Properties& source);
140
141 Properties(Properties&&) = delete;
142 Properties& operator=(const Properties& rhs) = delete;
143 Properties& operator=(Properties&& rhs) = delete;
144
145 /// Gets a property by key.
146 /// @param key The property key.
147 /// @return The property value, or the empty string if the property is not set.
148 /// @see #setProperty
149 std::string getProperty(std::string_view key);
150
151 /// Gets an Ice property by key.
152 /// @param key The property key.
153 /// @return The property value, or the default value for this property if the property is not set.
154 /// @throws PropertyException Thrown when the property is not a known Ice property.
155 /// @see #setProperty
156 std::string getIceProperty(std::string_view key);
157
158 /// Gets a property by key.
159 /// @param key The property key.
160 /// @param value The default value to return if the property is not set.
161 /// @return The property value or the default value if the property is not set.
162 /// @see #setProperty
163 std::string getPropertyWithDefault(std::string_view key, std::string_view value);
164
165 /// Gets a property as an integer.
166 /// @param key The property key.
167 /// @return The property value interpreted as an integer, or 0 if the property is not set.
168 /// @throws PropertyException Thrown when the property value is not a valid integer.
169 /// @see #setProperty
170 int getPropertyAsInt(std::string_view key);
171
172 /// Gets an Ice property as an integer.
173 /// @param key The property key.
174 /// @return The property value interpreted as an integer, or the default value if the property is not set.
175 /// @throws PropertyException Thrown when the property is not a known Ice property or the value is not a valid
176 /// integer.
177 /// @see #setProperty
178 int getIcePropertyAsInt(std::string_view key);
179
180 /// Gets a property as an integer.
181 /// @param key The property key.
182 /// @param value The default value to return if the property does not exist.
183 /// @return The property value interpreted as an integer, or the default value of the property is not set.
184 /// @throws PropertyException Thrown when the property value is not a valid integer.
185 /// @see #setProperty
186 int getPropertyAsIntWithDefault(std::string_view key, int value);
187
188 /// Gets a property as a list of strings. The strings must be separated by whitespace or comma. The strings in
189 /// the list can contain whitespace and commas if they are enclosed in single or double quotes. If quotes are
190 /// mismatched, an empty list is returned. Within single quotes or double quotes, you can escape the quote in
191 /// question with a backslash, e.g. O'Reilly can be written as O'Reilly, "O'Reilly" or 'O\'Reilly'.
192 /// @param key The property key.
193 /// @return The property value interpreted as a list of strings, or an empty list if the property is not set.
194 /// @see #setProperty
195 StringSeq getPropertyAsList(std::string_view key);
196
197 /// Gets an Ice property as a list of strings. The strings must be separated by whitespace or comma. The strings
198 /// in the list can contain whitespace and commas if they are enclosed in single or double quotes. If quotes are
199 /// mismatched, the default list is returned. Within single quotes or double quotes, you can escape the quote
200 /// in question with a backslash, e.g. O'Reilly can be written as O'Reilly, "O'Reilly" or 'O\'Reilly'.
201 /// @param key The property key.
202 /// @return The property value interpreted as list of strings, or the default value if the property is not set.
203 /// @throws PropertyException If the property is not a known Ice property.
204 /// @see #setProperty
205 StringSeq getIcePropertyAsList(std::string_view key);
206
207 /// Gets a property as a list of strings. The strings must be separated by whitespace or comma. The strings in
208 /// the list can contain whitespace and commas if they are enclosed in single or double quotes. If quotes are
209 /// mismatched, the default list is returned. Within single quotes or double quotes, you can escape the quote
210 /// in question with a backslash, e.g. O'Reilly can be written as O'Reilly, "O'Reilly" or 'O\'Reilly'.
211 /// @param key The property key.
212 /// @param value The default value to use if the property is not set.
213 /// @return The property value interpreted as list of strings, or the default value if the property is not set.
214 /// @see #setProperty
215 StringSeq getPropertyAsListWithDefault(std::string_view key, const StringSeq& value);
216
217 /// Gets all properties whose keys begins with @p prefix. If @p prefix is the empty string, then all properties
218 /// are returned.
219 /// @param prefix The prefix to search for (empty string if none).
220 /// @return The matching property set.
221 PropertyDict getPropertiesForPrefix(std::string_view prefix);
222
223 /// Sets a property. To unset a property, set it to the empty string.
224 /// @param key The property key.
225 /// @param value The property value.
226 /// @see #getProperty
227 void setProperty(std::string_view key, std::string_view value);
228
229 /// Gets a sequence of command-line options that is equivalent to this property set. Each element of the
230 /// returned sequence is a command-line option of the form `--key=value`.
231 /// @return The command line options for this property set.
233
234 /// Converts a sequence of command-line options into properties. All options that start with `--prefix.` are
235 /// converted into properties. If the prefix is empty, all options that begin with `--` are converted to
236 /// properties.
237 /// @param prefix The property prefix, or the empty string to convert all options starting with `--`.
238 /// @param options The command-line options.
239 /// @return The command-line options that do not start with the specified prefix, in their original order.
240 StringSeq parseCommandLineOptions(std::string_view prefix, const StringSeq& options);
241
242 /// Converts a sequence of command-line options into properties. All options that start with one of the
243 /// reserved Ice prefixes (`--Ice`, `--IceSSL`, etc.) are converted into properties.
244 /// @param options The command-line options.
245 /// @return The command-line options that do not start with one of the reserved prefixes, in their original
246 /// order.
248
249 /// Loads properties from a file.
250 /// @param file The property file.
251 void load(std::string_view file);
252
253 /// Creates a copy of this property set.
254 /// @return A copy of this property set.
255 PropertiesPtr clone() { return std::make_shared<Properties>(*this); }
256
257 /// Gets the properties that were never read.
258 /// @return A list of unused properties.
259 std::set<std::string> getUnusedProperties();
260
261 /// Parses a sequence of options into a map of key value pairs starting with a prefix. The options are expected
262 /// to be of the form `--key=value`.
263 /// @param prefix The prefix to match.
264 /// @param options The options to parse.
265 /// @return A pair containing a map of matched key value pairs and a sequence of unmatched options.
266 static std::pair<PropertyDict, StringSeq> parseOptions(std::string_view prefix, const StringSeq& options);
267
268 private:
269 static std::optional<std::pair<std::string, std::string>>
270 parseLine(std::string_view, const StringConverterPtr&);
271
272 Properties(const PropertiesPtr& defaults);
273
274 void loadArgs(StringSeq& args);
275 void loadConfig();
276
277 struct PropertyValue
278 {
279 PropertyValue() : used(false) {}
280
281 PropertyValue(std::string v, bool u) : value(std::move(v)), used(u) {}
282
283 std::string value;
284 bool used;
285 };
286
287 std::map<std::string, PropertyValue, std::less<>> _propertySet;
288 // List of "opt-in" property prefixes to allow in the property set. Setting a property for a property prefix
289 // that is opt-in (eg. IceGrid, IceStorm, Glacier2, etc.) but not in this list is considered an error.
290 std::vector<std::string> _optInPrefixes;
291 mutable std::mutex _mutex;
292 };
293
294 /// Creates a new shared Properties object.
295 /// @param args The arguments to forward to `make_shared<Properties>`.
296 /// @return A new property set.
297 /// @remarks This function is provided for backwards compatibility. New code should call
298 /// `std::make_shared<Properties>` directly.
299 template<class... T> inline PropertiesPtr createProperties(T&&... args)
300 {
301 return std::make_shared<Properties>(std::forward<T>(args)...);
302 }
303}
304
305#endif
std::string getPropertyWithDefault(std::string_view key, std::string_view value)
Gets a property by key.
StringSeq parseIceCommandLineOptions(const StringSeq &options)
Converts a sequence of command-line options into properties.
std::set< std::string > getUnusedProperties()
Gets the properties that were never read.
StringSeq getPropertyAsListWithDefault(std::string_view key, const StringSeq &value)
Gets a property as a list of strings.
std::string getProperty(std::string_view key)
Gets a property by key.
void load(std::string_view file)
Loads properties from a file.
Properties(StringSeq &args, const PropertiesPtr &defaults=nullptr)
Constructs a property set, loads the configuration files specified by the Ice.Config property or the ...
void setProperty(std::string_view key, std::string_view value)
Sets a property.
int getPropertyAsIntWithDefault(std::string_view key, int value)
Gets a property as an integer.
PropertyDict getPropertiesForPrefix(std::string_view prefix)
Gets all properties whose keys begins with prefix.
StringSeq getPropertyAsList(std::string_view key)
Gets a property as a list of strings.
std::string getIceProperty(std::string_view key)
Gets an Ice property by key.
int getIcePropertyAsInt(std::string_view key)
Gets an Ice property as an integer.
Properties(int &argc, ArgvT argv, const PropertiesPtr &defaults=nullptr)
Constructs a property set, loads the configuration files specified by the Ice.Config property or the ...
Definition Properties.h:97
StringSeq parseCommandLineOptions(std::string_view prefix, const StringSeq &options)
Converts a sequence of command-line options into properties.
PropertiesPtr clone()
Creates a copy of this property set.
Definition Properties.h:255
StringSeq getCommandLineOptions()
Gets a sequence of command-line options that is equivalent to this property set.
StringSeq getIcePropertyAsList(std::string_view key)
Gets an Ice property as a list of strings.
int getPropertyAsInt(std::string_view key)
Gets a property as an integer.
Properties(const Properties &source)
Copy constructor.
Properties()=default
Constructs an empty property set.
static std::pair< PropertyDict, StringSeq > parseOptions(std::string_view prefix, const StringSeq &options)
Parses a sequence of options into a map of key value pairs starting with a prefix.
Represents a set of properties used to configure Ice and Ice-based applications.
Definition Properties.h:64
std::shared_ptr< Properties > PropertiesPtr
A shared pointer to a Properties.
Definition PropertiesF.h:13
std::shared_ptr< StringConverter > StringConverterPtr
A shared pointer to a StringConverter.
StringSeq argsToStringSeq(int argc, const char *const argv[])
Converts an argument vector into a string sequence.
std::vector< std::string > StringSeq
A sequence of strings.
void stringSeqToArgs(const StringSeq &seq, int &argc, const char *argv[])
Updates argv to match the contents of seq.
std::map< std::string, std::string, std::less<> > PropertyDict
A simple collection of properties, represented as a dictionary of key/value pairs.
PropertiesPtr createProperties(T &&... args)
Creates a new shared Properties object.
Definition Properties.h:299
The Ice RPC framework.
Definition SampleEvent.h:59