1 /*
2  * Copyright (C) 2021 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 <hidl/HidlSupport.h>
19 
20 #include <type_traits>
21 #include <variant>
22 
23 namespace android::hardware::radio::compat {
24 
25 /**
26  * Converts hidl_vec<T> HIDL list to std::vector<T> AIDL list.
27  *
28  * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
29  *
30  * \param inp vector to convert
31  */
32 template <typename T>
toAidl(const hidl_vec<T> & inp)33 auto toAidl(const hidl_vec<T>& inp) {
34     std::vector<decltype(toAidl(T{}))> out(inp.size());
35     for (size_t i = 0; i < inp.size(); i++) {
36         out[i] = toAidl(inp[i]);
37     }
38     return out;
39 }
40 
41 /**
42  * Converts std::vector<T> AIDL list to hidl_vec<T> HIDL list.
43  *
44  * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
45  *
46  * \param inp vector to convert
47  */
48 template <typename T>
toHidl(const std::vector<T> & inp)49 auto toHidl(const std::vector<T>& inp) {
50     hidl_vec<decltype(toHidl(T{}))> out(inp.size());
51     for (size_t i = 0; i < inp.size(); i++) {
52         out[i] = toHidl(inp[i]);
53     }
54     return out;
55 }
56 
57 /**
58  * Converts hidl_array<T> HIDL list to std::vector<T> AIDL list.
59  *
60  * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
61  *
62  * \param inp array to convert
63  */
64 template <typename T, size_t N>
toAidl(const hidl_array<T,N> & inp)65 auto toAidl(const hidl_array<T, N>& inp) {
66     std::vector<decltype(toAidl(T{}))> out(N);
67     for (size_t i = 0; i < N; i++) {
68         out[i] = toAidl(inp[i]);
69     }
70     return out;
71 }
72 
73 /**
74  * Converts T=OptionalX HIDL value to std::optional<X> AIDL value.
75  *
76  * To convert values, the template uses toAidl functions for a given type T.value.
77  */
78 template <typename T>
toAidl(const T & opt)79 std::optional<decltype(toAidl(T{}.value()))> toAidl(const T& opt) {
80     if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return std::nullopt;
81     return toAidl(opt.value());
82 }
83 
84 /**
85  * Converts T=OptionalX HIDL value to std::variant<bool, X> AIDL value.
86  *
87  * For some reason, not every OptionalX gets generated into a std::optional<X>.
88  */
89 template <typename T>
toAidlVariant(const T & opt)90 std::variant<bool, decltype(toAidl(T{}.value()))> toAidlVariant(const T& opt) {
91     if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return false;
92     return toAidl(opt.value());
93 }
94 
95 /**
96  * Converts std::optional<X> AIDL value to T=OptionalX HIDL value.
97  *
98  * X is inferred from toAidl(T.value) declaration. Please note that toAidl(T.value) doesn't have to
99  * be implemented if it's not needed for anything else than giving this hint to type system.
100  *
101  * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
102  *
103  * \param opt value to convert
104  */
105 template <typename T>
toHidl(const std::optional<decltype (toAidl (T{}.value ()))> & opt)106 T toHidl(const std::optional<decltype(toAidl(T{}.value()))>& opt) {
107     T hidl;
108     if (opt.has_value()) hidl.value(toHidl(*opt));
109     return hidl;
110 }
111 
112 /**
113  * Converts U AIDL bitfield value to HIDL T bitfield value.
114  *
115  * \param val value to convert
116  */
117 template <typename T, typename U>
toHidlBitfield(U val)118 hidl_bitfield<T> toHidlBitfield(U val) {
119     return static_cast<int>(val);
120 }
121 
122 }  // namespace android::hardware::radio::compat
123