/src/resiprocate/rutil/ConfigParse.hxx
Line | Count | Source (jump to first uncovered line) |
1 | | #if !defined(ConfigParse_hxx) |
2 | | #define ConfigParse_hxx |
3 | | |
4 | | #include <map> |
5 | | #include <set> |
6 | | #include <vector> |
7 | | #include "rutil/BaseException.hxx" |
8 | | #include "rutil/HashMap.hxx" |
9 | | #include "rutil/Data.hxx" |
10 | | |
11 | | namespace resip |
12 | | { |
13 | | |
14 | | class ConfigParse |
15 | | { |
16 | | private: |
17 | | class NestedConfigParse; |
18 | | public: |
19 | | class Exception final : public BaseException |
20 | | { |
21 | | public: |
22 | | Exception(const Data& msg, |
23 | | const Data& file, |
24 | | const int line) |
25 | 0 | : BaseException(msg, file, line) {} |
26 | | protected: |
27 | 0 | const char* name() const noexcept override { return "ConfigParse::Exception"; } |
28 | | }; |
29 | | |
30 | | ConfigParse(); |
31 | | virtual ~ConfigParse(); |
32 | | |
33 | | // parses both command line and config file - using config file name from first command line parameter (if present) |
34 | | // skipcount represents the number of command line options to skip before looking for config filename or name value pairs |
35 | | virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename); |
36 | | virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount); |
37 | | virtual void parseCommandLine(int argc, char** argv, int skipCount = 0); |
38 | | virtual void parseConfigFile(const resip::Data& filename); |
39 | | |
40 | | virtual void printHelpText(int argc, char **argv) = 0; |
41 | | |
42 | | void getConfigIndexKeys(const resip::Data& indexName, std::set<resip::Data>& keys) const; |
43 | | |
44 | | bool getConfigValue(const resip::Data& name, resip::Data &value) const; |
45 | | resip::Data getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty=false) const; |
46 | | |
47 | | bool getConfigValue(const resip::Data& name, bool &value) const; |
48 | | bool getConfigBool(const resip::Data& name, bool defaultValue) const; |
49 | | |
50 | | bool getConfigValue(const resip::Data& name, unsigned long &value) const; |
51 | | unsigned long getConfigUnsignedLong(const resip::Data& name, unsigned long defaultValue) const; |
52 | | |
53 | | bool getConfigValue(const resip::Data& name, int &value) const; |
54 | | int getConfigInt(const resip::Data& name, int defaultValue) const; |
55 | | |
56 | | bool getConfigValue(const resip::Data& name, unsigned short &value) const; |
57 | | unsigned short getConfigUnsignedShort(const resip::Data& name, int defaultValue) const; |
58 | | |
59 | | bool getConfigValue(const resip::Data& name, std::vector<resip::Data> &value) const; |
60 | | bool getConfigValue(const resip::Data& name, std::vector<int>& value) const; |
61 | | bool getConfigValue(const resip::Data& name, std::set<resip::Data> &value) const; |
62 | | |
63 | | typedef HashMap<int, NestedConfigParse> NestedConfigMap; |
64 | | NestedConfigMap getConfigNested(const resip::Data& mapsPrefix) const; |
65 | | |
66 | | bool AddBasePathIfRequired(Data& filename) const; |
67 | | |
68 | | void insertConfigValue(const resip::Data& name, const resip::Data& value); |
69 | | |
70 | | protected: |
71 | | template <typename T> |
72 | | bool translateConfigValue(const std::map<T, resip::Data> dict, const resip::Data& name, T& value) const |
73 | | { |
74 | | Data lowerName(name); lowerName.lowercase(); |
75 | | ConfigValuesMap::const_iterator it = mConfigValues.find(lowerName); |
76 | | if(it == mConfigValues.end()) |
77 | | { |
78 | | return false; |
79 | | } |
80 | | const Data& s = it->second; |
81 | | for(const auto kv : dict) { |
82 | | if(isEqualNoCase(s, kv.second)) |
83 | | { |
84 | | value = kv.first; |
85 | | return true; |
86 | | } |
87 | | }; |
88 | | std::cerr << "Invalid value for " << name << ": " << s; |
89 | | exit(-1); |
90 | | }; |
91 | | |
92 | | typedef HashMultiMap<resip::Data, resip::Data> ConfigValuesMap; |
93 | | |
94 | | void insertConfigValue(const Data& source, ConfigValuesMap& configValues, const resip::Data& name, const resip::Data& value); |
95 | | |
96 | | ConfigValuesMap mCmdLineConfigValues; |
97 | | ConfigValuesMap mFileConfigValues; |
98 | | ConfigValuesMap mConfigValues; |
99 | | |
100 | | resip::Data removePath(const resip::Data& fileAndPath) const; |
101 | | |
102 | | // Config filename from command line |
103 | | resip::Data mCmdLineConfigFilename; |
104 | | |
105 | | resip::Data mConfigBasePath; |
106 | | |
107 | | private: |
108 | | friend EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config); |
109 | | }; |
110 | | |
111 | | class ConfigParse::NestedConfigParse : public ConfigParse |
112 | | { |
113 | | public: |
114 | 0 | NestedConfigParse() {}; |
115 | 0 | virtual void printHelpText(int argc, char **argv) {}; |
116 | | }; |
117 | | |
118 | | EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config); |
119 | | |
120 | | } |
121 | | |
122 | | #endif |
123 | | |
124 | | /* ==================================================================== |
125 | | * The Vovida Software License, Version 1.0 |
126 | | * |
127 | | * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
128 | | * Copyright (C) 2013-2023 Daniel Pocock https://danielpocock.com |
129 | | * Copyright (C) 2023 Software Freedom Institute SA https://softwarefreedom.institute |
130 | | * |
131 | | * Redistribution and use in source and binary forms, with or without |
132 | | * modification, are permitted provided that the following conditions |
133 | | * are met: |
134 | | * |
135 | | * 1. Redistributions of source code must retain the above copyright |
136 | | * notice, this list of conditions and the following disclaimer. |
137 | | * |
138 | | * 2. Redistributions in binary form must reproduce the above copyright |
139 | | * notice, this list of conditions and the following disclaimer in |
140 | | * the documentation and/or other materials provided with the |
141 | | * distribution. |
142 | | * |
143 | | * 3. The names "VOCAL", "Vovida Open Communication Application Library", |
144 | | * and "Vovida Open Communication Application Library (VOCAL)" must |
145 | | * not be used to endorse or promote products derived from this |
146 | | * software without prior written permission. For written |
147 | | * permission, please contact vocal@vovida.org. |
148 | | * |
149 | | * 4. Products derived from this software may not be called "VOCAL", nor |
150 | | * may "VOCAL" appear in their name, without prior written |
151 | | * permission of Vovida Networks, Inc. |
152 | | * |
153 | | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
154 | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
155 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
156 | | * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
157 | | * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
158 | | * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
159 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
160 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
161 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
162 | | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
163 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
164 | | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
165 | | * DAMAGE. |
166 | | * |
167 | | * ==================================================================== |
168 | | * |
169 | | * This software consists of voluntary contributions made by Vovida |
170 | | * Networks, Inc. and many individuals on behalf of Vovida Networks, |
171 | | * Inc. For more information on Vovida Networks, Inc., please see |
172 | | * <http://www.vovida.org/>. |
173 | | * |
174 | | */ |