blob: 5df8d9890753153516c621c1660be949e5da8280 [file] [log] [blame]
Ratan Guptaed123a32017-06-15 09:07:31 +05301#pragma once
2
Manojkiran Edaa879baa2020-06-13 14:39:08 +05303#include <filesystem>
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -07004#include <functional>
William A. Kennington III150753f2022-08-05 15:20:54 -07005#include <optional>
William A. Kennington III0dd09372022-08-18 14:57:07 -07006#include <ostream>
Patrick Venture189d44e2018-07-09 12:30:59 -07007#include <string>
William A. Kennington III25511a12022-08-04 16:32:28 -07008#include <string_view>
Ratan Guptaed123a32017-06-15 09:07:31 +05309#include <unordered_map>
10#include <vector>
Ratan Guptaed123a32017-06-15 09:07:31 +053011
12namespace phosphor
13{
14namespace network
15{
16namespace config
17{
18
William A. Kennington III150753f2022-08-05 15:20:54 -070019/** @brief Compare in (case insensitive) vs expected (sensitive) */
20bool icaseeq(std::string_view in, std::string_view expected) noexcept;
21/** @brief Turns a systemd bool string into a c++ bool */
22std::optional<bool> parseBool(std::string_view in) noexcept;
23
William A. Kennington IIIa520a392022-08-08 12:17:34 -070024namespace fs = std::filesystem;
25
26fs::path pathForIntfConf(const fs::path& dir, std::string_view intf);
27fs::path pathForIntfDev(const fs::path& dir, std::string_view intf);
28
William A. Kennington III0dd09372022-08-18 14:57:07 -070029template <typename T, typename Check>
30class Checked
31{
32 public:
33 struct unchecked
34 {
35 };
36
37 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070038 constexpr Checked(Args&&... args) : t(conCheck(std::forward<Args>(args)...))
William A. Kennington III0dd09372022-08-18 14:57:07 -070039 {
40 }
41
42 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070043 constexpr Checked(unchecked, Args&&... args) :
William A. Kennington III0dd09372022-08-18 14:57:07 -070044 t(std::forward<Args>(args)...)
45 {
46 }
47
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070048 constexpr const T& get() const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070049 {
50 return t;
51 }
52
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070053 constexpr operator const T&() const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070054 {
55 return t;
56 }
57
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070058 constexpr bool operator==(const auto& rhs) const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070059 {
60 return t == rhs;
61 }
62
63 private:
64 T t;
65
66 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070067 static constexpr T conCheck(Args&&... args)
William A. Kennington III0dd09372022-08-18 14:57:07 -070068 {
69 T t(std::forward<Args>(args)...);
70 Check{}(t);
71 return t;
72 }
73};
74
75template <typename T, typename Check>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070076constexpr bool operator==(const auto& lhs,
77 const Checked<T, Check>& rhs) noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070078{
79 return lhs == rhs.get();
80}
81
82template <typename T, typename Check>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070083inline std::ostream& operator<<(std::ostream& s, const Checked<T, Check>& rhs)
William A. Kennington III0dd09372022-08-18 14:57:07 -070084{
85 return s << rhs.get();
86}
87
88struct KeyCheck
89{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070090 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070091};
92struct SectionCheck
93{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070094 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070095};
96struct ValueCheck
97{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070098 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070099};
100
William A. Kennington III25511a12022-08-04 16:32:28 -0700101struct string_hash : public std::hash<std::string_view>
102{
103 using is_transparent = void;
William A. Kennington III0dd09372022-08-18 14:57:07 -0700104
105 template <typename T>
106 inline size_t operator()(const Checked<std::string, T>& t) const
107 {
108 return static_cast<const std::hash<std::string_view>&>(*this)(t.get());
109 }
110 template <typename T>
111 inline size_t operator()(const T& t) const
112 {
113 return static_cast<const std::hash<std::string_view>&>(*this)(t);
114 }
William A. Kennington III25511a12022-08-04 16:32:28 -0700115};
116
William A. Kennington III0dd09372022-08-18 14:57:07 -0700117using Key = Checked<std::string, KeyCheck>;
118using Section = Checked<std::string, SectionCheck>;
119using Value = Checked<std::string, ValueCheck>;
William A. Kennington III25511a12022-08-04 16:32:28 -0700120using ValueList = std::vector<Value>;
121using KeyValuesMap =
122 std::unordered_map<Key, ValueList, string_hash, std::equal_to<>>;
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700123using KeyValuesMapList = std::vector<KeyValuesMap>;
124using SectionMapInt =
125 std::unordered_map<Section, KeyValuesMapList, string_hash, std::equal_to<>>;
126
127class SectionMap : public SectionMapInt
128{
129 public:
130 const std::string* getLastValueString(std::string_view section,
131 std::string_view key) const noexcept;
132 inline auto getValues(std::string_view section, std::string_view key,
133 auto&& conv) const
134 {
135 std::vector<std::invoke_result_t<decltype(conv), const Value&>> values;
136 auto sit = find(section);
137 if (sit == end())
138 {
139 return values;
140 }
141 for (const auto& secv : sit->second)
142 {
143 auto kit = secv.find(key);
144 if (kit == secv.end())
145 {
146 continue;
147 }
148 for (auto v : kit->second)
149 {
150 values.push_back(conv(v));
151 }
152 }
153 return values;
154 }
155 std::vector<std::string> getValueStrings(std::string_view section,
156 std::string_view key) const;
157};
Ratan Guptac27170a2017-11-22 15:44:42 +0530158
Ratan Guptaed123a32017-06-15 09:07:31 +0530159class Parser
160{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500161 public:
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700162 SectionMap map;
163
Gunnar Mills57d9c502018-09-14 14:42:34 -0500164 Parser() = default;
Ratan Guptaed123a32017-06-15 09:07:31 +0530165
Gunnar Mills57d9c502018-09-14 14:42:34 -0500166 /** @brief Constructor
William A. Kennington III25511a12022-08-04 16:32:28 -0700167 * @param[in] filename - Absolute path of the file which will be parsed.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500168 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700169 Parser(const fs::path& filename);
Ratan Guptaed123a32017-06-15 09:07:31 +0530170
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800171 /** @brief Determine if the loaded file exists */
172 inline bool getFileExists() const noexcept
173 {
174 return fileExists;
175 }
176
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700177 /** @brief Determine if there were warnings parsing the file
178 * @return The number of parsing issues in the file
179 */
180 inline const std::vector<std::string>& getWarnings() const noexcept
181 {
182 return warnings;
183 }
184
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700185 /** @brief Get the filename last parsed successfully
186 * @return file path
187 */
188 inline const fs::path& getFilename() const noexcept
189 {
190 return filename;
191 }
192
Gunnar Mills57d9c502018-09-14 14:42:34 -0500193 /** @brief Set the file name and parse it.
William A. Kennington III25511a12022-08-04 16:32:28 -0700194 * @param[in] filename - Absolute path of the file.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500195 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700196 void setFile(const fs::path& filename);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500197
William A. Kennington III409f1a62022-08-11 15:44:37 -0700198 /** @brief Write the current config to a file */
199 void writeFile() const;
200 void writeFile(const fs::path& filename);
201
Gunnar Mills57d9c502018-09-14 14:42:34 -0500202 private:
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800203 bool fileExists = false;
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700204 fs::path filename;
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700205 std::vector<std::string> warnings;
Ratan Guptaed123a32017-06-15 09:07:31 +0530206};
207
Gunnar Mills57d9c502018-09-14 14:42:34 -0500208} // namespace config
209} // namespace network
210} // namespace phosphor