1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker #pragma once
17*4d7e907cSAndroid Build Coastguard Worker
18*4d7e907cSAndroid Build Coastguard Worker #include <hidl/HidlSupport.h>
19*4d7e907cSAndroid Build Coastguard Worker
20*4d7e907cSAndroid Build Coastguard Worker #include <type_traits>
21*4d7e907cSAndroid Build Coastguard Worker #include <variant>
22*4d7e907cSAndroid Build Coastguard Worker
23*4d7e907cSAndroid Build Coastguard Worker namespace android::hardware::radio::compat {
24*4d7e907cSAndroid Build Coastguard Worker
25*4d7e907cSAndroid Build Coastguard Worker /**
26*4d7e907cSAndroid Build Coastguard Worker * Converts hidl_vec<T> HIDL list to std::vector<T> AIDL list.
27*4d7e907cSAndroid Build Coastguard Worker *
28*4d7e907cSAndroid Build Coastguard Worker * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
29*4d7e907cSAndroid Build Coastguard Worker *
30*4d7e907cSAndroid Build Coastguard Worker * \param inp vector to convert
31*4d7e907cSAndroid Build Coastguard Worker */
32*4d7e907cSAndroid Build Coastguard Worker template <typename T>
toAidl(const hidl_vec<T> & inp)33*4d7e907cSAndroid Build Coastguard Worker auto toAidl(const hidl_vec<T>& inp) {
34*4d7e907cSAndroid Build Coastguard Worker std::vector<decltype(toAidl(T{}))> out(inp.size());
35*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < inp.size(); i++) {
36*4d7e907cSAndroid Build Coastguard Worker out[i] = toAidl(inp[i]);
37*4d7e907cSAndroid Build Coastguard Worker }
38*4d7e907cSAndroid Build Coastguard Worker return out;
39*4d7e907cSAndroid Build Coastguard Worker }
40*4d7e907cSAndroid Build Coastguard Worker
41*4d7e907cSAndroid Build Coastguard Worker /**
42*4d7e907cSAndroid Build Coastguard Worker * Converts std::vector<T> AIDL list to hidl_vec<T> HIDL list.
43*4d7e907cSAndroid Build Coastguard Worker *
44*4d7e907cSAndroid Build Coastguard Worker * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
45*4d7e907cSAndroid Build Coastguard Worker *
46*4d7e907cSAndroid Build Coastguard Worker * \param inp vector to convert
47*4d7e907cSAndroid Build Coastguard Worker */
48*4d7e907cSAndroid Build Coastguard Worker template <typename T>
toHidl(const std::vector<T> & inp)49*4d7e907cSAndroid Build Coastguard Worker auto toHidl(const std::vector<T>& inp) {
50*4d7e907cSAndroid Build Coastguard Worker hidl_vec<decltype(toHidl(T{}))> out(inp.size());
51*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < inp.size(); i++) {
52*4d7e907cSAndroid Build Coastguard Worker out[i] = toHidl(inp[i]);
53*4d7e907cSAndroid Build Coastguard Worker }
54*4d7e907cSAndroid Build Coastguard Worker return out;
55*4d7e907cSAndroid Build Coastguard Worker }
56*4d7e907cSAndroid Build Coastguard Worker
57*4d7e907cSAndroid Build Coastguard Worker /**
58*4d7e907cSAndroid Build Coastguard Worker * Converts hidl_array<T> HIDL list to std::vector<T> AIDL list.
59*4d7e907cSAndroid Build Coastguard Worker *
60*4d7e907cSAndroid Build Coastguard Worker * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
61*4d7e907cSAndroid Build Coastguard Worker *
62*4d7e907cSAndroid Build Coastguard Worker * \param inp array to convert
63*4d7e907cSAndroid Build Coastguard Worker */
64*4d7e907cSAndroid Build Coastguard Worker template <typename T, size_t N>
toAidl(const hidl_array<T,N> & inp)65*4d7e907cSAndroid Build Coastguard Worker auto toAidl(const hidl_array<T, N>& inp) {
66*4d7e907cSAndroid Build Coastguard Worker std::vector<decltype(toAidl(T{}))> out(N);
67*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < N; i++) {
68*4d7e907cSAndroid Build Coastguard Worker out[i] = toAidl(inp[i]);
69*4d7e907cSAndroid Build Coastguard Worker }
70*4d7e907cSAndroid Build Coastguard Worker return out;
71*4d7e907cSAndroid Build Coastguard Worker }
72*4d7e907cSAndroid Build Coastguard Worker
73*4d7e907cSAndroid Build Coastguard Worker /**
74*4d7e907cSAndroid Build Coastguard Worker * Converts T=OptionalX HIDL value to std::optional<X> AIDL value.
75*4d7e907cSAndroid Build Coastguard Worker *
76*4d7e907cSAndroid Build Coastguard Worker * To convert values, the template uses toAidl functions for a given type T.value.
77*4d7e907cSAndroid Build Coastguard Worker */
78*4d7e907cSAndroid Build Coastguard Worker template <typename T>
toAidl(const T & opt)79*4d7e907cSAndroid Build Coastguard Worker std::optional<decltype(toAidl(T{}.value()))> toAidl(const T& opt) {
80*4d7e907cSAndroid Build Coastguard Worker if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return std::nullopt;
81*4d7e907cSAndroid Build Coastguard Worker return toAidl(opt.value());
82*4d7e907cSAndroid Build Coastguard Worker }
83*4d7e907cSAndroid Build Coastguard Worker
84*4d7e907cSAndroid Build Coastguard Worker /**
85*4d7e907cSAndroid Build Coastguard Worker * Converts T=OptionalX HIDL value to std::variant<bool, X> AIDL value.
86*4d7e907cSAndroid Build Coastguard Worker *
87*4d7e907cSAndroid Build Coastguard Worker * For some reason, not every OptionalX gets generated into a std::optional<X>.
88*4d7e907cSAndroid Build Coastguard Worker */
89*4d7e907cSAndroid Build Coastguard Worker template <typename T>
toAidlVariant(const T & opt)90*4d7e907cSAndroid Build Coastguard Worker std::variant<bool, decltype(toAidl(T{}.value()))> toAidlVariant(const T& opt) {
91*4d7e907cSAndroid Build Coastguard Worker if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return false;
92*4d7e907cSAndroid Build Coastguard Worker return toAidl(opt.value());
93*4d7e907cSAndroid Build Coastguard Worker }
94*4d7e907cSAndroid Build Coastguard Worker
95*4d7e907cSAndroid Build Coastguard Worker /**
96*4d7e907cSAndroid Build Coastguard Worker * Converts std::optional<X> AIDL value to T=OptionalX HIDL value.
97*4d7e907cSAndroid Build Coastguard Worker *
98*4d7e907cSAndroid Build Coastguard Worker * X is inferred from toAidl(T.value) declaration. Please note that toAidl(T.value) doesn't have to
99*4d7e907cSAndroid Build Coastguard Worker * be implemented if it's not needed for anything else than giving this hint to type system.
100*4d7e907cSAndroid Build Coastguard Worker *
101*4d7e907cSAndroid Build Coastguard Worker * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
102*4d7e907cSAndroid Build Coastguard Worker *
103*4d7e907cSAndroid Build Coastguard Worker * \param opt value to convert
104*4d7e907cSAndroid Build Coastguard Worker */
105*4d7e907cSAndroid Build Coastguard Worker template <typename T>
toHidl(const std::optional<decltype (toAidl (T{}.value ()))> & opt)106*4d7e907cSAndroid Build Coastguard Worker T toHidl(const std::optional<decltype(toAidl(T{}.value()))>& opt) {
107*4d7e907cSAndroid Build Coastguard Worker T hidl;
108*4d7e907cSAndroid Build Coastguard Worker if (opt.has_value()) hidl.value(toHidl(*opt));
109*4d7e907cSAndroid Build Coastguard Worker return hidl;
110*4d7e907cSAndroid Build Coastguard Worker }
111*4d7e907cSAndroid Build Coastguard Worker
112*4d7e907cSAndroid Build Coastguard Worker /**
113*4d7e907cSAndroid Build Coastguard Worker * Converts U AIDL bitfield value to HIDL T bitfield value.
114*4d7e907cSAndroid Build Coastguard Worker *
115*4d7e907cSAndroid Build Coastguard Worker * \param val value to convert
116*4d7e907cSAndroid Build Coastguard Worker */
117*4d7e907cSAndroid Build Coastguard Worker template <typename T, typename U>
toHidlBitfield(U val)118*4d7e907cSAndroid Build Coastguard Worker hidl_bitfield<T> toHidlBitfield(U val) {
119*4d7e907cSAndroid Build Coastguard Worker return static_cast<int>(val);
120*4d7e907cSAndroid Build Coastguard Worker }
121*4d7e907cSAndroid Build Coastguard Worker
122*4d7e907cSAndroid Build Coastguard Worker } // namespace android::hardware::radio::compat
123