1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef sw_Configurator_hpp
16 #define sw_Configurator_hpp
17
18 #include <optional>
19 #include <sstream>
20 #include <string>
21 #include <unordered_map>
22
23 namespace sw {
24
25 class Configurator
26 {
27 public:
28 // Construct a Configurator given a configuration file.
29 explicit Configurator(const std::string &filePath);
30
31 // Construct a Configurator given an in-memory stream.
32 explicit Configurator(std::istream &str);
33
34 void writeFile(const std::string &filePath, const std::string &title = "Configuration File");
35
36 template<typename T>
37 int getInteger(const std::string §ionName, const std::string &keyName, T defaultValue = 0) const;
38 bool getBoolean(const std::string §ionName, const std::string &keyName, bool defaultValue = false) const;
39 double getFloat(const std::string §ionName, const std::string &keyName, double defaultValue = 0.0) const;
40
41 std::string getValue(const std::string §ionName, const std::string &keyName, const std::string &defaultValue = "") const;
42 void addValue(const std::string §ionName, const std::string &keyName, const std::string &value);
43
44 private:
45 bool readConfiguration(std::istream &str);
46
47 std::optional<std::string> getValueIfExists(const std::string §ionName, const std::string &keyName) const;
48
49 struct Section
50 {
51 std::unordered_map<std::string, std::string> keyValuePairs;
52 };
53 std::unordered_map<std::string, Section> sections;
54 };
55
56 template<typename T>
getInteger(const std::string & sectionName,const std::string & keyName,T defaultValue) const57 int Configurator::getInteger(const std::string §ionName, const std::string &keyName, T defaultValue) const
58 {
59 static_assert(std::is_integral_v<T>, "getInteger must be used with integral types");
60
61 auto strValue = getValueIfExists(sectionName, keyName);
62 if(!strValue)
63 return defaultValue;
64
65 std::stringstream ss{ *strValue };
66 if(strValue->find("0x") != std::string::npos)
67 ss >> std::hex;
68
69 T val = 0;
70 ss >> val;
71 return val;
72 }
73
74 } // namespace sw
75
76 #endif // sw_Configurator_hpp
77