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