1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <string>
19 #include <type_traits>
20 
21 #include "common/strings.h"
22 #include "common/type_helper.h"
23 #include "storage/serializable.h"
24 
25 namespace bluetooth {
26 namespace storage {
27 
28 class MutationEntry {
29 public:
30   enum EntryType { SET, REMOVE_PROPERTY, REMOVE_SECTION };
31 
32   enum PropertyType { NORMAL, MEMORY_ONLY };
33 
34   template <typename T, typename std::enable_if<std::is_integral_v<T>, int>::type = 0>
Set(PropertyType property_type,std::string section_param,std::string property_param,T value_param)35   static MutationEntry Set(PropertyType property_type, std::string section_param,
36                            std::string property_param, T value_param) {
37     return MutationEntry::Set(property_type, std::move(section_param), std::move(property_param),
38                               std::to_string(value_param));
39   }
40 
41   template <typename T, typename std::enable_if<std::is_enum_v<T>, int>::type = 0>
Set(PropertyType property_type,std::string section_param,std::string property_param,T value_param)42   static MutationEntry Set(PropertyType property_type, std::string section_param,
43                            std::string property_param, T value_param) {
44     using EnumUnderlyingType = typename std::underlying_type_t<T>;
45     return MutationEntry::Set<EnumUnderlyingType>(property_type, std::move(section_param),
46                                                   std::move(property_param),
47                                                   static_cast<EnumUnderlyingType>(value_param));
48   }
49 
50   template <typename T, typename std::enable_if<std::is_same_v<T, bool>, int>::type = 0>
Set(PropertyType property_type,std::string section_param,std::string property_param,T value_param)51   static MutationEntry Set(PropertyType property_type, std::string section_param,
52                            std::string property_param, T value_param) {
53     return MutationEntry::Set(property_type, std::move(section_param), std::move(property_param),
54                               common::ToString(value_param));
55   }
56 
57   template <typename T, typename std::enable_if<std::is_same_v<T, std::string>, int>::type = 0>
Set(PropertyType property_type,std::string section_param,std::string property_param,T value_param)58   static MutationEntry Set(PropertyType property_type, std::string section_param,
59                            std::string property_param, T value_param) {
60     return MutationEntry::Set(property_type, std::move(section_param), std::move(property_param),
61                               std::move(value_param));
62   }
63 
64   template <typename T,
65             typename std::enable_if<std::is_base_of_v<Serializable<T>, T>, int>::type = 0>
Set(PropertyType property_type,std::string section_param,std::string property_param,const T & value_param)66   static MutationEntry Set(PropertyType property_type, std::string section_param,
67                            std::string property_param, const T& value_param) {
68     return MutationEntry::Set(property_type, std::move(section_param), std::move(property_param),
69                               value_param.ToLegacyConfigString());
70   }
71 
72   template <typename T, typename std::enable_if<
73                                 bluetooth::common::is_specialization_of<T, std::vector>::value &&
74                                         std::is_base_of_v<Serializable<typename T::value_type>,
75                                                           typename T::value_type>,
76                                 int>::type = 0>
Set(PropertyType property_type,std::string section_param,std::string property_param,const T & value_param)77   static MutationEntry Set(PropertyType property_type, std::string section_param,
78                            std::string property_param, const T& value_param) {
79     std::vector<std::string> str_values;
80     str_values.reserve(value_param.size());
81     for (const auto& v : value_param) {
82       str_values.push_back(v.ToLegacyConfigString());
83     }
84     return MutationEntry::Set(property_type, std::move(section_param), std::move(property_param),
85                               common::StringJoin(str_values, " "));
86   }
87 
Set(PropertyType property_type,std::string section_param,std::string property_param,std::string value_param)88   static MutationEntry Set(PropertyType property_type, std::string section_param,
89                            std::string property_param, std::string value_param) {
90     return MutationEntry(EntryType::SET, property_type, std::move(section_param),
91                          std::move(property_param), std::move(value_param));
92   }
93 
Remove(PropertyType property_type,std::string section_param)94   static MutationEntry Remove(PropertyType property_type, std::string section_param) {
95     return MutationEntry(EntryType::REMOVE_SECTION, property_type, std::move(section_param));
96   }
97 
Remove(PropertyType property_type,std::string section_param,std::string property_param)98   static MutationEntry Remove(PropertyType property_type, std::string section_param,
99                               std::string property_param) {
100     return MutationEntry(EntryType::REMOVE_PROPERTY, property_type, std::move(section_param),
101                          std::move(property_param));
102   }
103 
104 private:
105   friend class ConfigCache;
106   friend class Mutation;
107 
108   MutationEntry(EntryType entry_type_param, PropertyType property_type_param,
109                 std::string section_param, std::string property_param = "",
110                 std::string value_param = "");
111 
112   EntryType entry_type;
113   PropertyType property_type;
114   std::string section;
115   std::string property;
116   std::string value;
117 };
118 
119 }  // namespace storage
120 }  // namespace bluetooth
121