/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include "common/numbers.h" #include "common/strings.h" #include "common/type_helper.h" #include "hci/enum_helper.h" #include "storage/config_cache.h" #include "storage/mutation_entry.h" #include "storage/serializable.h" namespace bluetooth { namespace storage { // A thin wrapper around ConfigCache and implement more type supports other than std::string // // - all SetX methods accept value as copy and std::move() in encouraged // - all GetX methods return std::optional and std::nullopt if not exist. std::optional<> can be treated as bool class ConfigCacheHelper { public: static ConfigCacheHelper FromConfigCache(ConfigCache& config_cache) { return ConfigCacheHelper(config_cache); } explicit ConfigCacheHelper(ConfigCache& config_cache) : config_cache_(config_cache) {} virtual ~ConfigCacheHelper() = default; virtual void SetBool(const std::string& section, const std::string& property, bool value); virtual std::optional GetBool(const std::string& section, const std::string& property) const; virtual void SetUint64(const std::string& section, const std::string& property, uint64_t value); virtual std::optional GetUint64(const std::string& section, const std::string& property) const; virtual void SetUint32(const std::string& section, const std::string& property, uint32_t value); virtual std::optional GetUint32(const std::string& section, const std::string& property) const; virtual void SetInt64(const std::string& section, const std::string& property, int64_t value); virtual std::optional GetInt64(const std::string& section, const std::string& property) const; virtual void SetInt(const std::string& section, const std::string& property, int value); virtual std::optional GetInt(const std::string& section, const std::string& property) const; virtual void SetBin(const std::string& section, const std::string& property, const std::vector& value); virtual std::optional> GetBin(const std::string& section, const std::string& property) const; template && std::is_integral_v, int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { auto value = GetInt64(section, property); if (!value) { return std::nullopt; } if (!common::IsNumberInNumericLimits(*value)) { return std::nullopt; } return static_cast(*value); } template && std::is_integral_v, int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { auto value = GetUint64(section, property); if (!value) { return std::nullopt; } if (!common::IsNumberInNumericLimits(*value)) { return std::nullopt; } return static_cast(*value); } template , int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { return config_cache_.GetProperty(section, property); } template >, int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { return GetBin(section, property); } template , int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { return GetBool(section, property); } template , T>, int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { auto value = config_cache_.GetProperty(section, property); if (!value) { return std::nullopt; } return T::FromLegacyConfigString(*value); } template , int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { auto value = config_cache_.GetProperty(section, property); if (!value) { return std::nullopt; } return bluetooth::FromLegacyConfigString(*value); } template < typename T, typename std::enable_if< bluetooth::common::is_specialization_of::value && std::is_base_of_v, typename T::value_type>, int>::type = 0> std::optional Get(const std::string& section, const std::string& property) { auto value = config_cache_.GetProperty(section, property); if (!value) { return std::nullopt; } auto values = common::StringSplit(*value, " "); T result; result.reserve(values.size()); for (const auto& str : values) { auto v = T::value_type::FromLegacyConfigString(str); if (!v) { return std::nullopt; } result.push_back(*v); } return result; } private: ConfigCache& config_cache_; }; } // namespace storage } // namespace bluetooth