1 /*
2  * Copyright (c) 2024 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 API_CORE_PROPERTY_IPROPERTY_HANDLE_UTIL_H
17 #define API_CORE_PROPERTY_IPROPERTY_HANDLE_UTIL_H
18 
19 #include <base/containers/string_view.h>
20 #include <core/property/intf_property_api.h>
21 #include <core/property/intf_property_handle.h>
22 #include <core/property/property.h>
23 #include <core/property/property_types.h>
24 #include <core/property/scoped_handle.h>
25 
CORE_BEGIN_NAMESPACE()26 CORE_BEGIN_NAMESPACE()
27 template<typename T>
28 ScopedHandle<T> MakeScopedHandle(
29     IPropertyHandle& handle, BASE_NS::string_view propertyName, const PropertyTypeDecl& propertyType)
30 {
31     for (const auto& metaData : handle.Owner()->MetaData()) {
32         if (metaData.name == propertyName) {
33             if (metaData.type == propertyType) {
34                 if (auto scoped = ScopedHandle<T>(&handle); scoped) {
35                     scoped.data_ = reinterpret_cast<decltype(scoped.data_)>(
36                         reinterpret_cast<uintptr_t>(scoped.data_) + metaData.offset);
37                     return scoped;
38                 }
39             }
40             break;
41         }
42     }
43     return {};
44 }
45 
46 template<typename T>
MakeScopedHandle(IPropertyHandle & handle,BASE_NS::string_view propertyName)47 ScopedHandle<T> MakeScopedHandle(IPropertyHandle& handle, BASE_NS::string_view propertyName)
48 {
49     using BaseT = BASE_NS::remove_const_t<BASE_NS::remove_reference_t<BASE_NS::remove_extent_t<T>>>;
50     constexpr const auto propertyType = PropertySystem::PropertyTypeDeclFromType<BaseT, BASE_NS::is_array_t<T>>();
51     return MakeScopedHandle<T>(handle, propertyName, propertyType);
52 }
53 
54 template<typename T>
SetPropertyValue(IPropertyHandle & handle,BASE_NS::string_view propertyName,const PropertyTypeDecl & propertyType,T && propertyValue)55 bool SetPropertyValue(
56     IPropertyHandle& handle, BASE_NS::string_view propertyName, const PropertyTypeDecl& propertyType, T&& propertyValue)
57 {
58     using BaseT = BASE_NS::remove_const_t<BASE_NS::remove_reference_t<T>>;
59     if (auto scoped = MakeScopedHandle<BaseT>(handle, propertyName, propertyType); scoped) {
60         *scoped = BASE_NS::forward<T>(propertyValue);
61         return true;
62     }
63     return false;
64 }
65 
66 template<typename T>
SetPropertyValue(IPropertyHandle & handle,BASE_NS::string_view propertyName,T && propertyValue)67 bool SetPropertyValue(IPropertyHandle& handle, BASE_NS::string_view propertyName, T&& propertyValue)
68 {
69     using BaseT = BASE_NS::remove_const_t<BASE_NS::remove_reference_t<BASE_NS::remove_extent_t<T>>>;
70     constexpr const auto propertyType = PropertySystem::PropertyTypeDeclFromType<BaseT, BASE_NS::is_array_t<T>>();
71     return SetPropertyValue(handle, propertyName, propertyType, BASE_NS::forward<T>(propertyValue));
72 }
73 
74 template<typename T>
GetPropertyValue(IPropertyHandle & handle,BASE_NS::string_view propertyName,const PropertyTypeDecl & propertyType)75 T GetPropertyValue(IPropertyHandle& handle, BASE_NS::string_view propertyName, const PropertyTypeDecl& propertyType)
76 {
77     using BaseT = BASE_NS::remove_const_t<BASE_NS::remove_reference_t<T>>;
78     if (auto scoped = MakeScopedHandle<const BaseT>(handle, propertyName, propertyType); scoped) {
79         return *scoped;
80     }
81     return {};
82 }
83 
84 template<typename T>
GetPropertyValue(IPropertyHandle & handle,BASE_NS::string_view propertyName)85 T GetPropertyValue(IPropertyHandle& handle, BASE_NS::string_view propertyName)
86 {
87     constexpr const auto propertyType = PropertySystem::PropertyTypeDeclFromType<T, BASE_NS::is_array_t<T>>();
88     return GetPropertyValue<T>(handle, propertyName, propertyType);
89 }
90 CORE_END_NAMESPACE()
91 #endif // API_CORE_PROPERTY_IPROPERTY_HANDLE_UTIL_H
92