Browse Source

settings: query for specific entry

separate search and value retrieval
test/dev
Maxim Prokhorov 1 month ago
parent
commit
c3ab86bbd7
13 changed files with 141 additions and 61 deletions
  1. +1
    -1
      code/espurna/button.cpp
  2. +1
    -1
      code/espurna/homeassistant.cpp
  3. +1
    -1
      code/espurna/led.cpp
  4. +1
    -1
      code/espurna/mqtt.cpp
  5. +2
    -2
      code/espurna/relay.cpp
  6. +1
    -1
      code/espurna/scheduler.cpp
  7. +1
    -1
      code/espurna/sensors/DigitalSensor.h
  8. +36
    -16
      code/espurna/settings.cpp
  9. +90
    -28
      code/espurna/settings_helpers.h
  10. +2
    -2
      code/espurna/system.cpp
  11. +1
    -1
      code/espurna/telnet.cpp
  12. +1
    -1
      code/espurna/uart.cpp
  13. +3
    -5
      code/espurna/wifi.cpp

+ 1
- 1
code/espurna/button.cpp View File

@ -834,7 +834,7 @@ bool checkSamePrefix(StringView key) {
}
String findValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
button::internal::buttons.size(), IndexedSettings, key);
}


+ 1
- 1
code/espurna/homeassistant.cpp View File

@ -126,7 +126,7 @@ bool checkSamePrefix(espurna::StringView key) {
}
String findValueFrom(espurna::StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}
void setup() {


+ 1
- 1
code/espurna/led.cpp View File

@ -635,7 +635,7 @@ bool checkSamePrefix(StringView key) {
}
String findValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
::espurna::led::internal::leds.size(), IndexedSettings, key);
}


+ 1
- 1
code/espurna/mqtt.cpp View File

@ -411,7 +411,7 @@ bool checkSamePrefix(espurna::StringView key) {
}
String findValueFrom(espurna::StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}
void setup() {


+ 2
- 2
code/espurna/relay.cpp View File

@ -3322,7 +3322,7 @@ bool checkSamePrefix(StringView key) {
}
String findIndexedValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(_relays.size(), IndexedSettings, key);
return espurna::settings::query::findValueFrom(_relays.size(), IndexedSettings, key);
}
bool checkExact(StringView key) {
@ -3336,7 +3336,7 @@ bool checkExact(StringView key) {
}
String findValueFrom(StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}
void setup() {


+ 1
- 1
code/espurna/scheduler.cpp View File

@ -421,7 +421,7 @@ bool checkSamePrefix(StringView key) {
}
String findIndexedValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(count(), IndexedSettings, key);
return espurna::settings::query::findValueFrom(count(), IndexedSettings, key);
}
void setup() {


+ 1
- 1
code/espurna/sensors/DigitalSensor.h View File

@ -194,7 +194,7 @@ bool checkSamePrefix(StringView key) {
}
String findValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
build::SensorsMax, IndexedSettings, key);
}


+ 36
- 16
code/espurna/settings.cpp View File

@ -41,53 +41,73 @@ static kvs_type kv_store(
namespace query {
const Setting* Setting::findFrom(const Setting* begin, const Setting* end, StringView key) {
String Result::value() const {
if (_ptr == nullptr) {
return String();
}
return (_index == IndexMax)
? (*reinterpret_cast<const Setting*>(_ptr)).value()
: (*reinterpret_cast<const IndexedSetting*>(_ptr)).value(_index);
}
Result findFrom(const Setting* begin, const Setting* end, StringView key) {
for (auto it = begin; it != end; ++it) {
if ((*it) == key) {
return it;
return Result(it);
}
}
return end;
return Result(nullptr);
}
String Setting::findValueFrom(const Setting* begin, const Setting* end, StringView key) {
String findValueFrom(const Setting* begin, const Setting* end, StringView key) {
String out;
const auto value = findFrom(begin, end, key);
if (value != end) {
out = (*value).value();
const auto result = findFrom(begin, end, key);
if (result.ok()) {
out = result.value();
}
return out;
}
bool IndexedSetting::findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
const IndexedSetting* findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
const IndexedSetting* out { nullptr };
for (auto it = begin; it != end; ++it) {
if (key.startsWith((*it).prefix())) {
return true;
out = it;
break;
}
}
return false;
return out;
}
String IndexedSetting::findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
String out;
Result findFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
while (iota) {
for (auto it = begin; it != end; ++it) {
const auto expected = Key(
(*it).prefix().toString(), *iota);
if (key == expected.value()) {
out = (*it).value(*iota);
goto output;
return Result(it, *iota);
}
}
++iota;
}
output:
return Result(nullptr);
}
String findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
String out;
const auto result = findFrom(iota, begin, end, key);
if (result.pointer() != end) {
out = result.value();
}
return out;
}


+ 90
- 28
code/espurna/settings_helpers.h View File

@ -347,6 +347,8 @@ private:
// both require a linear iterators as input e.g. most commonly - a static array
// (either a plain [], or an std::array. template should treat both equally)
struct Result;
// single key variant, exact match of the provided string
struct alignas(8) Setting {
using ValueFunc = String(*)();
@ -373,20 +375,6 @@ struct alignas(8) Setting {
return _key == key;
}
static const Setting* findFrom(const Setting* begin, const Setting* end, StringView key);
template <typename T>
static const Setting* findFrom(const T& settings, StringView key) {
return findFrom(std::begin(settings), std::end(settings), key);
}
static String findValueFrom(const Setting* begin, const Setting* end, StringView key);
template <typename T>
static String findValueFrom(const T& settings, StringView key) {
return findValueFrom(std::begin(settings), std::end(settings), key);
}
private:
StringView _key;
ValueFunc _func;
@ -415,30 +403,104 @@ struct alignas(8) IndexedSetting {
return _prefix;
}
static bool findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key);
private:
StringView _prefix;
ValueFunc _func;
};
template <typename T>
static bool findSamePrefix(const T& settings, StringView key) {
return findSamePrefix(std::begin(settings), std::end(settings), key);
}
// generic way to retrieve specific settings entry or report its absence
struct Result {
static constexpr size_t IndexMax = std::numeric_limits<size_t>::max();
static String findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key);
Result(const Result&) = default;
Result& operator=(const Result&) = default;
template <typename T>
static String findValueFrom(Iota iota, const T& settings, StringView key) {
return findValueFrom(iota, std::begin(settings), std::end(settings), key);
Result(Result&&) = default;
Result& operator=(Result&&) = default;
Result() = default;
explicit Result(const Setting* setting) :
_ptr(setting)
{}
Result(const IndexedSetting* setting, size_t index) :
_ptr(setting),
_index(index)
{}
bool ok() const {
return _ptr != nullptr;
}
template <typename T>
static String findValueFrom(size_t size, const T& settings, StringView key) {
return findValueFrom(Iota{size}, settings, key);
explicit operator bool() const {
return ok();
}
String value() const;
const void* pointer() const {
return _ptr;
}
private:
StringView _prefix;
ValueFunc _func;
const void* _ptr { nullptr };
size_t _index { IndexMax };
};
Result findFrom(const Setting* begin, const Setting* end, StringView key);
template <typename T>
inline Result findFrom(const T& settings, StringView key) {
return findFrom(std::begin(settings), std::end(settings), key);
}
String findValueFrom(const Setting* begin, const Setting* end, StringView key);
template <typename T>
inline String findValueFrom(const T& settings, StringView key) {
return findValueFrom(std::begin(settings), std::end(settings), key);
}
Result findFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key);
template <typename T>
inline Result findFrom(Iota iota, const T& settings, StringView key) {
return findFrom(iota, std::begin(settings), std::end(settings), key);
}
template <typename T>
inline Result findFrom(size_t size, const T& settings, StringView key) {
return findFrom(Iota{size}, settings, key);
}
String findValueFrom(Iota iota, const IndexedSetting* begin, const IndexedSetting* end, StringView key);
template <typename T>
inline String findValueFrom(Iota iota, const T& settings, StringView key) {
return findValueFrom(iota, std::begin(settings), std::end(settings), key);
}
template <typename T>
inline String findValueFrom(size_t size, const T& settings, StringView key) {
return findValueFrom(Iota{size}, settings, key);
}
const IndexedSetting* findSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key);
template <typename T>
inline const IndexedSetting* findSamePrefix(const T& settings, StringView key) {
return findSamePrefix(std::begin(settings), std::end(settings), key);
}
inline bool hasSamePrefix(const IndexedSetting* begin, const IndexedSetting* end, StringView key) {
return nullptr != findSamePrefix(begin, end, key);
}
template <typename T>
inline bool hasSamePrefix(const T& settings, StringView key) {
return hasSamePrefix(std::begin(settings), std::end(settings), key);
}
} // namespace query
} // namespace settings


+ 2
- 2
code/espurna/system.cpp View File

@ -599,11 +599,11 @@ static constexpr std::array<espurna::settings::query::Setting, 5> Settings PROGM
}};
bool checkExact(StringView key) {
return espurna::settings::query::Setting::findFrom(Settings, key) != Settings.end();
return espurna::settings::query::findFrom(Settings, key).ok();
}
String findValueFrom(StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}
void setup() {


+ 1
- 1
code/espurna/telnet.cpp View File

@ -131,7 +131,7 @@ bool checkExactPrefix(StringView key) {
}
String findValueFrom(StringView key) {
return espurna::settings::query::Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}
void setup() {


+ 1
- 1
code/espurna/uart.cpp View File

@ -461,7 +461,7 @@ bool checkSamePrefix(StringView key) {
}
String findIndexedValueFrom(StringView key) {
return espurna::settings::query::IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
ports(), IndexedSettings, key);
}


+ 3
- 5
code/espurna/wifi.cpp View File

@ -2264,7 +2264,7 @@ static constexpr std::array<espurna::settings::query::Setting, 11> Settings PROG
// indexed settings for 'sta' connections
bool checkIndexedPrefix(StringView key) {
return espurna::settings::query::IndexedSetting::findSamePrefix(
return espurna::settings::query::hasSamePrefix(
sta::settings::query::Settings, key);
}
@ -2274,15 +2274,13 @@ bool checkExactPrefix(StringView key) {
}
String findIndexedValueFrom(StringView key) {
using espurna::settings::query::IndexedSetting;
return IndexedSetting::findValueFrom(
return espurna::settings::query::findValueFrom(
sta::countNetworks(),
sta::settings::query::Settings, key);
}
String findValueFrom(StringView key) {
using espurna::settings::query::Setting;
return Setting::findValueFrom(Settings, key);
return espurna::settings::query::findValueFrom(Settings, key);
}
void setup() {


Loading…
Cancel
Save