blob: d082b186e0ae50445f791700d4dcde3db533ace9 [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>
Patrick Venture189d44e2018-07-09 12:30:59 -07006#include <string>
William A. Kennington III25511a12022-08-04 16:32:28 -07007#include <string_view>
Ratan Guptaed123a32017-06-15 09:07:31 +05308#include <unordered_map>
9#include <vector>
Ratan Guptaed123a32017-06-15 09:07:31 +053010
11namespace phosphor
12{
13namespace network
14{
15namespace config
16{
17
William A. Kennington III150753f2022-08-05 15:20:54 -070018/** @brief Compare in (case insensitive) vs expected (sensitive) */
19bool icaseeq(std::string_view in, std::string_view expected) noexcept;
20/** @brief Turns a systemd bool string into a c++ bool */
21std::optional<bool> parseBool(std::string_view in) noexcept;
22
William A. Kennington IIIa520a392022-08-08 12:17:34 -070023namespace fs = std::filesystem;
24
25fs::path pathForIntfConf(const fs::path& dir, std::string_view intf);
26fs::path pathForIntfDev(const fs::path& dir, std::string_view intf);
27
William A. Kennington III0dd09372022-08-18 14:57:07 -070028template <typename T, typename Check>
29class Checked
30{
31 public:
32 struct unchecked
Patrick Williams89d734b2023-05-10 07:50:25 -050033 {};
William A. Kennington III0dd09372022-08-18 14:57:07 -070034
35 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070036 constexpr Checked(Args&&... args) : t(conCheck(std::forward<Args>(args)...))
Patrick Williams89d734b2023-05-10 07:50:25 -050037 {}
William A. Kennington III0dd09372022-08-18 14:57:07 -070038
39 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070040 constexpr Checked(unchecked, Args&&... args) :
William A. Kennington III0dd09372022-08-18 14:57:07 -070041 t(std::forward<Args>(args)...)
Patrick Williams89d734b2023-05-10 07:50:25 -050042 {}
William A. Kennington III0dd09372022-08-18 14:57:07 -070043
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070044 constexpr const T& get() const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070045 {
46 return t;
47 }
48
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070049 constexpr operator const T&() const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070050 {
51 return t;
52 }
53
William A. Kennington IIIaf77f822023-06-23 02:17:20 -070054 template <typename T2, typename Check2>
55 constexpr bool operator==(const Checked<T2, Check2>& rhs) const noexcept
56 {
57 static_assert(std::is_same_v<Check2, Check>);
58 return t == rhs.t;
59 }
60
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070061 constexpr bool operator==(const auto& rhs) const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070062 {
63 return t == rhs;
64 }
65
66 private:
67 T t;
68
69 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070070 static constexpr T conCheck(Args&&... args)
William A. Kennington III0dd09372022-08-18 14:57:07 -070071 {
72 T t(std::forward<Args>(args)...);
73 Check{}(t);
74 return t;
75 }
76};
77
William A. Kennington III0dd09372022-08-18 14:57:07 -070078struct KeyCheck
79{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070080 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070081};
82struct SectionCheck
83{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070084 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070085};
86struct ValueCheck
87{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070088 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070089};
90
William A. Kennington III25511a12022-08-04 16:32:28 -070091struct string_hash : public std::hash<std::string_view>
92{
93 using is_transparent = void;
William A. Kennington III0dd09372022-08-18 14:57:07 -070094
95 template <typename T>
96 inline size_t operator()(const Checked<std::string, T>& t) const
97 {
98 return static_cast<const std::hash<std::string_view>&>(*this)(t.get());
99 }
100 template <typename T>
101 inline size_t operator()(const T& t) const
102 {
103 return static_cast<const std::hash<std::string_view>&>(*this)(t);
104 }
William A. Kennington III25511a12022-08-04 16:32:28 -0700105};
106
William A. Kennington III0dd09372022-08-18 14:57:07 -0700107using Key = Checked<std::string, KeyCheck>;
108using Section = Checked<std::string, SectionCheck>;
109using Value = Checked<std::string, ValueCheck>;
William A. Kennington III25511a12022-08-04 16:32:28 -0700110using ValueList = std::vector<Value>;
111using KeyValuesMap =
112 std::unordered_map<Key, ValueList, string_hash, std::equal_to<>>;
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700113using KeyValuesMapList = std::vector<KeyValuesMap>;
114using SectionMapInt =
115 std::unordered_map<Section, KeyValuesMapList, string_hash, std::equal_to<>>;
116
117class SectionMap : public SectionMapInt
118{
119 public:
120 const std::string* getLastValueString(std::string_view section,
121 std::string_view key) const noexcept;
122 inline auto getValues(std::string_view section, std::string_view key,
123 auto&& conv) const
124 {
125 std::vector<std::invoke_result_t<decltype(conv), const Value&>> values;
126 auto sit = find(section);
127 if (sit == end())
128 {
129 return values;
130 }
131 for (const auto& secv : sit->second)
132 {
133 auto kit = secv.find(key);
134 if (kit == secv.end())
135 {
136 continue;
137 }
138 for (auto v : kit->second)
139 {
140 values.push_back(conv(v));
141 }
142 }
143 return values;
144 }
145 std::vector<std::string> getValueStrings(std::string_view section,
146 std::string_view key) const;
147};
Ratan Guptac27170a2017-11-22 15:44:42 +0530148
Ratan Guptaed123a32017-06-15 09:07:31 +0530149class Parser
150{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500151 public:
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700152 SectionMap map;
153
Gunnar Mills57d9c502018-09-14 14:42:34 -0500154 Parser() = default;
Ratan Guptaed123a32017-06-15 09:07:31 +0530155
Gunnar Mills57d9c502018-09-14 14:42:34 -0500156 /** @brief Constructor
William A. Kennington III25511a12022-08-04 16:32:28 -0700157 * @param[in] filename - Absolute path of the file which will be parsed.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500158 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700159 Parser(const fs::path& filename);
Ratan Guptaed123a32017-06-15 09:07:31 +0530160
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800161 /** @brief Determine if the loaded file exists */
162 inline bool getFileExists() const noexcept
163 {
164 return fileExists;
165 }
166
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700167 /** @brief Determine if there were warnings parsing the file
168 * @return The number of parsing issues in the file
169 */
170 inline const std::vector<std::string>& getWarnings() const noexcept
171 {
172 return warnings;
173 }
174
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700175 /** @brief Get the filename last parsed successfully
176 * @return file path
177 */
178 inline const fs::path& getFilename() const noexcept
179 {
180 return filename;
181 }
182
Gunnar Mills57d9c502018-09-14 14:42:34 -0500183 /** @brief Set the file name and parse it.
William A. Kennington III25511a12022-08-04 16:32:28 -0700184 * @param[in] filename - Absolute path of the file.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500185 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700186 void setFile(const fs::path& filename);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500187
William A. Kennington III409f1a62022-08-11 15:44:37 -0700188 /** @brief Write the current config to a file */
189 void writeFile() const;
190 void writeFile(const fs::path& filename);
191
Gunnar Mills57d9c502018-09-14 14:42:34 -0500192 private:
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800193 bool fileExists = false;
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700194 fs::path filename;
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700195 std::vector<std::string> warnings;
Ratan Guptaed123a32017-06-15 09:07:31 +0530196};
197
Gunnar Mills57d9c502018-09-14 14:42:34 -0500198} // namespace config
199} // namespace network
200} // namespace phosphor