diff options
author | clyne <clyne@bitgloo.com> | 2021-01-10 09:35:35 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-10 09:35:35 -0500 |
commit | 8fc7548c0330bfbf3860d4c0e8c17e20c37a3439 (patch) | |
tree | e7096bfb21eaa358829d87e4379667fd017ee052 | |
parent | 6a5265be03640928f42e62c936cfb66fd3f0ea3a (diff) |
Validate section tags; add cbegin, cend, and contains
-rw-r--r-- | ini_config.hpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/ini_config.hpp b/ini_config.hpp index b6af299..db30f0f 100644 --- a/ini_config.hpp +++ b/ini_config.hpp @@ -73,6 +73,8 @@ class ini_config return in + 1; } + // Validates INI syntax, returning the count of chars + // needed to store all section names, keys, and values consteval static unsigned int verify_and_size() { unsigned int sizechars = 0; @@ -89,7 +91,10 @@ class ini_config if (*p == '[') { do { ++sizechars; - } while (*++p != ']'); + ++p; + } while (!iseol(*p) && *p != ']'); + if (iseol(*p)) + throw "Bad section tag!"; ++sizechars; // Null terminator continue; } @@ -130,6 +135,7 @@ class ini_config return sizechars; } + // Counts how many key-value pairs are in the text consteval static unsigned int kvpcount() noexcept { unsigned int count = 0; @@ -148,6 +154,7 @@ class ini_config return count; } + // A compact buffer for section names, keys, and values char_type kvp_buffer[verify_and_size() + 1] = {}; consteval void fill_kvp_buffer() noexcept { @@ -209,8 +216,7 @@ public: constexpr const auto& get_next() noexcept { if (*m_pos == '\0') { // At the end - if (m_current.first != nullptr) - m_current.first = nullptr; + m_current.first = nullptr; } else { // Enter new section(s) if necessary while (*m_pos == '[') { @@ -264,6 +270,10 @@ public: } }; + /** + * Constructs the ini_config object, populating the section/key/value + * buffer. + */ consteval ini_config() noexcept #ifdef TCSULLIVAN_INI_CONFIG_CHECK_FORWARD_ITERATOR requires(std::forward_iterator<iterator>) @@ -278,33 +288,42 @@ public: consteval auto size() const noexcept { return kvpcount(); } + constexpr auto begin() const noexcept { return iterator(kvp_buffer); } + constexpr auto cbegin() const noexcept { + return begin(); + } + constexpr auto end() const noexcept { + return iterator(kvp_buffer + sizeof(kvp_buffer) / sizeof(char_type) - 1); + } + constexpr auto cend() const noexcept { + return end(); + } + /** * Returns beginning iterator for the given section. */ constexpr auto begin(const char_type *section) const noexcept { - for (auto it = begin(); it != end(); ++it) { + auto it = begin(); + do { if (it->section != nullptr && stringmatch(it->section, section)) - return it; - } - return end(); - } - constexpr auto end() const noexcept { - return iterator(kvp_buffer + sizeof(kvp_buffer) / sizeof(char_type) - 1); + break; + } while (++it != end()); + return it; } - /** + + /** * Returns end iterator for the given section. */ constexpr auto end(const char_type *section) const noexcept { - for (auto it = begin(); it != end(); ++it) { - if (it->section != nullptr && stringmatch(it->section, section)) { - for (++it; it != end() && stringmatch(it->section, section); ++it); - return it; - } + auto it = begin(section); + while (++it != end()) { + if (!stringmatch(it->section, section)) + break; } - return end(); + return it; } class section_view { @@ -357,6 +376,13 @@ public: constexpr auto operator[](const char_type *key) const noexcept { return get(key); } + + constexpr bool contains(const char_type *key) const noexcept { + return *get(key) != '\0'; + } + constexpr bool contains(const char_type *sec, const char_type *key) const noexcept { + return *get(sec, key) != '\0'; + } }; } // namespace ini_config |