1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PROFILE_LIST_H
17 #define PROFILE_LIST_H
18 
19 #include <string>
20 #include <vector>
21 
22 #include "base/base_def.h"
23 
24 namespace OHOS {
25 namespace bluetooth {
26 /**
27  * @brief Represents profile list template.
28  *
29  * @since 6
30  */
31 template<typename T>
32 class ProfilesList final {
33 public:
34     /**
35      * @brief A constructor used to create an <b>ProfilesList</b> instance.
36      *
37      * @since 6
38      */
39     ProfilesList() = default;
40     /**
41      * @brief A destructor used to delete the <b>ProfilesList</b> instance.
42      *
43      * @since 6
44      */
~ProfilesList()45     ~ProfilesList()
46     {
47         std::lock_guard<std::mutex> lock(lock_);
48         profiles_.clear();
49     }
50     /**
51      * @brief Get profile.
52      *
53      * @param transport Adapter transport.
54      * @param name Profile name
55      * @return Returns profile by adapter transport and profile name.
56      * @since 6
57      */
Get(const BTTransport transport,const std::string & name)58     T Get(const BTTransport transport, const std::string &name)
59     {
60         std::lock_guard<std::mutex> lock(lock_);
61         return profiles_[transport][name];
62     }
63     /**
64      * @brief Clear profile list.
65      *
66      * @since 6
67      */
Clear()68     void Clear()
69     {
70         std::lock_guard<std::mutex> lock(lock_);
71         profiles_.clear();
72     }
73     /**
74      * @brief Get profiles map by adapter transport.
75      *
76      * @param transport Adapter transport.
77      * @return Returns profiles map by adapter transport.
78      * @since 6
79      */
GetProfiles(const BTTransport transport)80     std::map<std::string, T> *GetProfiles(const BTTransport transport)
81     {
82         std::lock_guard<std::mutex> lock(lock_);
83 
84         auto it = profiles_.find(transport);
85         if (it != profiles_.end()) {  // find
86             return &(profiles_[transport]);
87         } else {
88             return nullptr;
89         }
90     }
91     /**
92      * @brief Set profile value.
93      *
94      * @param transport Adapter transport.
95      * @param name Profile name
96      * @param data Used to set profile value.
97      * @since 6
98      */
SetProfile(const BTTransport transport,const std::string & name,const T & data)99     void SetProfile(const BTTransport transport, const std::string &name, const T &data)
100     {
101         std::lock_guard<std::mutex> lock(lock_);
102 
103         profiles_[transport][name] = data;
104     }
105     /**
106      * @brief Check whether profiles map contains this profile by transport and profile name.
107      *
108      * @param transport Adapter transport.
109      * @param name Profile name
110      * @return Returns <b>true</b> if profiles map contains this profile;
111      *         returns <b>false</b> if profiles map does not contain this profile.
112      * @since 6
113      */
Contains(const BTTransport transport,const std::string & name)114     bool Contains(const BTTransport transport, const std::string &name)
115     {
116         std::lock_guard<std::mutex> lock(lock_);
117 
118         auto its = profiles_.find(transport);
119         if (its != profiles_.end()) {
120             auto it = profiles_[transport].find(name);
121             if (it != profiles_[transport].end()) {
122                 return true;
123             }
124         }
125         return false;
126     }
127     /**
128      * @brief Check whether profiles map contains this profile by profile name.
129      *
130      * @param name Profile name
131      * @return Returns <b>true</b> if profiles map contains this profile;
132      *         returns <b>false</b> if profiles map does not contain this profile.
133      * @since 6
134      */
Contains(const std::string & name)135     bool Contains(const std::string &name)
136     {
137         std::lock_guard<std::mutex> lock(lock_);
138 
139         for (auto &its : profiles_) {
140             auto it = profiles_[its.first].find(name);
141             if (it != profiles_[its.first].end()) {
142                 return true;
143             }
144         }
145         return false;
146     }
147     /**
148      * @brief Find whether profiles map contains this profile by transport and profile name.
149      * Than get this profile pointer.
150      *
151      * @param transport Adapter transport.
152      * @param name Profile name.
153      * @param data Get profile pointer.
154      * @return Returns <b>true</b> if profiles map contains this profile;
155      *         returns <b>false</b> if profiles map does not contain this profile.
156      * @since 6
157      */
Find(const BTTransport transport,const std::string & name,T & data)158     bool Find(const BTTransport transport, const std::string &name, T &data)
159     {
160         std::lock_guard<std::mutex> lock(lock_);
161 
162         auto its = profiles_.find(transport);
163         if (its != profiles_.end()) {
164             auto it = profiles_[transport].find(name);
165             if (it != profiles_[transport].end()) {
166                 data = profiles_[transport][name];
167                 return true;
168             }
169         }
170         return false;
171     }
172     /**
173      * @brief Find whether profiles map contains this profile by profile name.
174      * Than get this profile pointer.
175      *
176      * @param name Profile name
177      * @param data Get profile pointer.
178      * @return Returns <b>true</b> if profiles map contains this profile;
179      *         returns <b>false</b> if profiles map does not contain this profile.
180      * @since 6
181      */
Find(const std::string & name,T & data)182     bool Find(const std::string &name, T &data)
183     {
184         std::lock_guard<std::mutex> lock(lock_);
185 
186         for (auto its = profiles_.begin(); its != profiles_.end(); its++) {
187             auto it = profiles_[its->first].find(name);
188             if (it != profiles_[its->first].end()) {
189                 data = profiles_[its->first][name];
190                 return true;
191             }
192         }
193         return false;
194     }
195     /**
196      * @brief Whether profiles map is empty.
197      *
198      * @param @param transport Adapter transport.
199      * @return Returns <b>true</b> if profiles map is empty;
200      *         returns <b>false</b> if profiles map is not empty.
201      * @since 6
202      */
IsEmpty(const BTTransport transport)203     bool IsEmpty(const BTTransport transport)
204     {
205         std::lock_guard<std::mutex> lock(lock_);
206 
207         auto it = profiles_.find(transport);
208         if (it != profiles_.end()) {  // find
209             return profiles_[transport].empty();
210         } else {
211             return true;
212         }
213     }
214     /**
215      * @brief Get profiles map size.
216      *
217      * @param @param transport Adapter transport.
218      * @return Returns profiles map size
219      * @since 6
220      */
Size(const BTTransport transport)221     int Size(const BTTransport transport)
222     {
223         std::lock_guard<std::mutex> lock(lock_);
224 
225         auto it = profiles_.find(transport);
226         if (it != profiles_.end()) {  // find
227             return profiles_[transport].size();
228         } else {
229             return 0;
230         }
231     }
232 
233 private:
234     std::mutex lock_ = {};
235     std::map<BTTransport, std::map<std::string, T>> profiles_ = {};
236     BT_DISALLOW_COPY_AND_ASSIGN(ProfilesList);
237 };
238 
239 #define FOR_EACH_LIST(it, profileList, transport) for (auto it : *(profileList.GetProfiles(transport)))
240 }  // namespace bluetooth
241 }  // namespace OHOS
242 
243 #endif  // PROFILE_CONFIG_H