config_parser: Split up sections
We can't always combine sections together in network files as sections
like
[Address]
Address=::1/128
Peer=fe80::1
[Address]
Address=::2/128
Peer=fe80::2
Require that they are grouped accordingly. Rewrite the storage logic of
the config parser to support this logical organization.
Change-Id: I34ae1523202f8770fe3dcac010fb6226dd28b9ec
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/config_parser.hpp b/src/config_parser.hpp
index 7ff20ba..9b203c2 100644
--- a/src/config_parser.hpp
+++ b/src/config_parser.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <filesystem>
+#include <functional>
#include <optional>
#include <string>
#include <string_view>
@@ -35,8 +36,41 @@
using ValueList = std::vector<Value>;
using KeyValuesMap =
std::unordered_map<Key, ValueList, string_hash, std::equal_to<>>;
-using SectionMap =
- std::unordered_map<Section, KeyValuesMap, string_hash, std::equal_to<>>;
+using KeyValuesMapList = std::vector<KeyValuesMap>;
+using SectionMapInt =
+ std::unordered_map<Section, KeyValuesMapList, string_hash, std::equal_to<>>;
+
+class SectionMap : public SectionMapInt
+{
+ public:
+ const std::string* getLastValueString(std::string_view section,
+ std::string_view key) const noexcept;
+ inline auto getValues(std::string_view section, std::string_view key,
+ auto&& conv) const
+ {
+ std::vector<std::invoke_result_t<decltype(conv), const Value&>> values;
+ auto sit = find(section);
+ if (sit == end())
+ {
+ return values;
+ }
+ for (const auto& secv : sit->second)
+ {
+ auto kit = secv.find(key);
+ if (kit == secv.end())
+ {
+ continue;
+ }
+ for (auto v : kit->second)
+ {
+ values.push_back(conv(v));
+ }
+ }
+ return values;
+ }
+ std::vector<std::string> getValueStrings(std::string_view section,
+ std::string_view key) const;
+};
class Parser
{
@@ -48,13 +82,11 @@
*/
Parser(const fs::path& filename);
- /** @brief Get the values of the given key and section.
- * @param[in] section - section name.
- * @param[in] key - key to look for.
- * @returns The ValueList or nullptr if no key + section exists.
- */
- const ValueList& getValues(std::string_view section,
- std::string_view key) const noexcept;
+ /** @brief Retrieve the map of all values in the file */
+ inline const SectionMap& getMap() const noexcept
+ {
+ return sections;
+ }
/** @brief Determine if there were warnings parsing the file
* @return The number of parsing issues in the file