xref: /aosp_15_r20/system/libhidl/base/include/hidl/HidlSupport.h (revision 8222fbe171c3d6fadfe95119c180cf3010c392a8)
1*8222fbe1SAndroid Build Coastguard Worker /*
2*8222fbe1SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*8222fbe1SAndroid Build Coastguard Worker  *
4*8222fbe1SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8222fbe1SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8222fbe1SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8222fbe1SAndroid Build Coastguard Worker  *
8*8222fbe1SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8222fbe1SAndroid Build Coastguard Worker  *
10*8222fbe1SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8222fbe1SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8222fbe1SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8222fbe1SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8222fbe1SAndroid Build Coastguard Worker  * limitations under the License.
15*8222fbe1SAndroid Build Coastguard Worker  */
16*8222fbe1SAndroid Build Coastguard Worker 
17*8222fbe1SAndroid Build Coastguard Worker #ifndef ANDROID_HIDL_SUPPORT_H
18*8222fbe1SAndroid Build Coastguard Worker #define ANDROID_HIDL_SUPPORT_H
19*8222fbe1SAndroid Build Coastguard Worker 
20*8222fbe1SAndroid Build Coastguard Worker #include <algorithm>
21*8222fbe1SAndroid Build Coastguard Worker #include <array>
22*8222fbe1SAndroid Build Coastguard Worker #include <iterator>
23*8222fbe1SAndroid Build Coastguard Worker #include <hidl/HidlInternal.h>
24*8222fbe1SAndroid Build Coastguard Worker #include <map>
25*8222fbe1SAndroid Build Coastguard Worker #include <sstream>
26*8222fbe1SAndroid Build Coastguard Worker #include <stddef.h>
27*8222fbe1SAndroid Build Coastguard Worker #include <tuple>
28*8222fbe1SAndroid Build Coastguard Worker #include <type_traits>
29*8222fbe1SAndroid Build Coastguard Worker #include <vector>
30*8222fbe1SAndroid Build Coastguard Worker 
31*8222fbe1SAndroid Build Coastguard Worker // no requirements on types not used in scatter/gather
32*8222fbe1SAndroid Build Coastguard Worker // no requirements on other libraries
33*8222fbe1SAndroid Build Coastguard Worker #pragma clang diagnostic push
34*8222fbe1SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wpadded"
35*8222fbe1SAndroid Build Coastguard Worker #include <cutils/native_handle.h>
36*8222fbe1SAndroid Build Coastguard Worker #include <hidl/Status.h>
37*8222fbe1SAndroid Build Coastguard Worker #include <utils/Errors.h>
38*8222fbe1SAndroid Build Coastguard Worker #include <utils/RefBase.h>
39*8222fbe1SAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
40*8222fbe1SAndroid Build Coastguard Worker #pragma clang diagnostic pop
41*8222fbe1SAndroid Build Coastguard Worker 
42*8222fbe1SAndroid Build Coastguard Worker namespace android {
43*8222fbe1SAndroid Build Coastguard Worker 
44*8222fbe1SAndroid Build Coastguard Worker // this file is included by all hidl interface, so we must forward declare the
45*8222fbe1SAndroid Build Coastguard Worker // IMemory and IBase types.
46*8222fbe1SAndroid Build Coastguard Worker namespace hidl {
47*8222fbe1SAndroid Build Coastguard Worker namespace memory {
48*8222fbe1SAndroid Build Coastguard Worker namespace V1_0 {
49*8222fbe1SAndroid Build Coastguard Worker 
50*8222fbe1SAndroid Build Coastguard Worker struct IMemory;
51*8222fbe1SAndroid Build Coastguard Worker 
52*8222fbe1SAndroid Build Coastguard Worker }  // namespace V1_0
53*8222fbe1SAndroid Build Coastguard Worker }  // namespace memory
54*8222fbe1SAndroid Build Coastguard Worker }  // namespace hidl
55*8222fbe1SAndroid Build Coastguard Worker 
56*8222fbe1SAndroid Build Coastguard Worker namespace hidl {
57*8222fbe1SAndroid Build Coastguard Worker namespace base {
58*8222fbe1SAndroid Build Coastguard Worker namespace V1_0 {
59*8222fbe1SAndroid Build Coastguard Worker 
60*8222fbe1SAndroid Build Coastguard Worker struct IBase;
61*8222fbe1SAndroid Build Coastguard Worker 
62*8222fbe1SAndroid Build Coastguard Worker }  // namespace V1_0
63*8222fbe1SAndroid Build Coastguard Worker }  // namespace base
64*8222fbe1SAndroid Build Coastguard Worker }  // namespace hidl
65*8222fbe1SAndroid Build Coastguard Worker 
66*8222fbe1SAndroid Build Coastguard Worker namespace hardware {
67*8222fbe1SAndroid Build Coastguard Worker 
68*8222fbe1SAndroid Build Coastguard Worker namespace details {
69*8222fbe1SAndroid Build Coastguard Worker // Return true on userdebug / eng builds and false on user builds.
70*8222fbe1SAndroid Build Coastguard Worker bool debuggable();
71*8222fbe1SAndroid Build Coastguard Worker } //  namespace details
72*8222fbe1SAndroid Build Coastguard Worker 
73*8222fbe1SAndroid Build Coastguard Worker // hidl_death_recipient is a callback interfaced that can be used with
74*8222fbe1SAndroid Build Coastguard Worker // linkToDeath() / unlinkToDeath()
75*8222fbe1SAndroid Build Coastguard Worker struct hidl_death_recipient : public virtual RefBase {
76*8222fbe1SAndroid Build Coastguard Worker     virtual void serviceDied(uint64_t cookie,
77*8222fbe1SAndroid Build Coastguard Worker             const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
78*8222fbe1SAndroid Build Coastguard Worker };
79*8222fbe1SAndroid Build Coastguard Worker 
80*8222fbe1SAndroid Build Coastguard Worker // hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
81*8222fbe1SAndroid Build Coastguard Worker // so that it can safely be transferred between 32-bit and 64-bit processes.
82*8222fbe1SAndroid Build Coastguard Worker // The ownership semantics for this are:
83*8222fbe1SAndroid Build Coastguard Worker // 1) The conversion constructor and assignment operator taking a const native_handle_t*
84*8222fbe1SAndroid Build Coastguard Worker //    do not take ownership of the handle; this is because these operations are usually
85*8222fbe1SAndroid Build Coastguard Worker //    just done for IPC, and cloning by default is a waste of resources. If you want
86*8222fbe1SAndroid Build Coastguard Worker //    a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/);
87*8222fbe1SAndroid Build Coastguard Worker // 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership;
88*8222fbe1SAndroid Build Coastguard Worker //    that is because it's not intuitive that this class encapsulates a native_handle_t
89*8222fbe1SAndroid Build Coastguard Worker //    which needs cloning to be valid; in particular, this allows constructs like this:
90*8222fbe1SAndroid Build Coastguard Worker //    hidl_handle copy;
91*8222fbe1SAndroid Build Coastguard Worker //    foo->someHidlCall([&](auto incoming_handle) {
92*8222fbe1SAndroid Build Coastguard Worker //            copy = incoming_handle;
93*8222fbe1SAndroid Build Coastguard Worker //    });
94*8222fbe1SAndroid Build Coastguard Worker //    // copy and its enclosed file descriptors will remain valid here.
95*8222fbe1SAndroid Build Coastguard Worker // 3) The move constructor does what you would expect; it only owns the handle if the
96*8222fbe1SAndroid Build Coastguard Worker //    original did.
97*8222fbe1SAndroid Build Coastguard Worker struct hidl_handle {
98*8222fbe1SAndroid Build Coastguard Worker     hidl_handle();
99*8222fbe1SAndroid Build Coastguard Worker     ~hidl_handle();
100*8222fbe1SAndroid Build Coastguard Worker 
101*8222fbe1SAndroid Build Coastguard Worker     hidl_handle(const native_handle_t *handle);
102*8222fbe1SAndroid Build Coastguard Worker 
103*8222fbe1SAndroid Build Coastguard Worker     // copy constructor.
104*8222fbe1SAndroid Build Coastguard Worker     hidl_handle(const hidl_handle &other);
105*8222fbe1SAndroid Build Coastguard Worker 
106*8222fbe1SAndroid Build Coastguard Worker     // move constructor.
107*8222fbe1SAndroid Build Coastguard Worker     hidl_handle(hidl_handle &&other) noexcept;
108*8222fbe1SAndroid Build Coastguard Worker 
109*8222fbe1SAndroid Build Coastguard Worker     // assignment operators
110*8222fbe1SAndroid Build Coastguard Worker     hidl_handle &operator=(const hidl_handle &other);
111*8222fbe1SAndroid Build Coastguard Worker 
112*8222fbe1SAndroid Build Coastguard Worker     hidl_handle &operator=(const native_handle_t *native_handle);
113*8222fbe1SAndroid Build Coastguard Worker 
114*8222fbe1SAndroid Build Coastguard Worker     hidl_handle &operator=(hidl_handle &&other) noexcept;
115*8222fbe1SAndroid Build Coastguard Worker 
116*8222fbe1SAndroid Build Coastguard Worker     void setTo(native_handle_t* handle, bool shouldOwn = false);
117*8222fbe1SAndroid Build Coastguard Worker 
118*8222fbe1SAndroid Build Coastguard Worker     const native_handle_t* operator->() const;
119*8222fbe1SAndroid Build Coastguard Worker 
120*8222fbe1SAndroid Build Coastguard Worker     // implicit conversion to const native_handle_t*
121*8222fbe1SAndroid Build Coastguard Worker     operator const native_handle_t *() const;
122*8222fbe1SAndroid Build Coastguard Worker 
123*8222fbe1SAndroid Build Coastguard Worker     // explicit conversion
124*8222fbe1SAndroid Build Coastguard Worker     const native_handle_t *getNativeHandle() const;
125*8222fbe1SAndroid Build Coastguard Worker 
126*8222fbe1SAndroid Build Coastguard Worker     // offsetof(hidl_handle, mHandle) exposed since mHandle is private.
127*8222fbe1SAndroid Build Coastguard Worker     static const size_t kOffsetOfNativeHandle;
128*8222fbe1SAndroid Build Coastguard Worker 
129*8222fbe1SAndroid Build Coastguard Worker private:
130*8222fbe1SAndroid Build Coastguard Worker     void freeHandle();
131*8222fbe1SAndroid Build Coastguard Worker 
132*8222fbe1SAndroid Build Coastguard Worker     details::hidl_pointer<const native_handle_t> mHandle;
133*8222fbe1SAndroid Build Coastguard Worker     bool mOwnsHandle;
134*8222fbe1SAndroid Build Coastguard Worker     uint8_t mPad[7];
135*8222fbe1SAndroid Build Coastguard Worker };
136*8222fbe1SAndroid Build Coastguard Worker 
137*8222fbe1SAndroid Build Coastguard Worker struct hidl_string {
138*8222fbe1SAndroid Build Coastguard Worker     hidl_string();
139*8222fbe1SAndroid Build Coastguard Worker     ~hidl_string();
140*8222fbe1SAndroid Build Coastguard Worker 
141*8222fbe1SAndroid Build Coastguard Worker     // copy constructor.
142*8222fbe1SAndroid Build Coastguard Worker     hidl_string(const hidl_string &);
143*8222fbe1SAndroid Build Coastguard Worker     // copy from a C-style string. nullptr will create an empty string
144*8222fbe1SAndroid Build Coastguard Worker     hidl_string(const char *);
145*8222fbe1SAndroid Build Coastguard Worker     // copy the first length characters from a C-style string.
146*8222fbe1SAndroid Build Coastguard Worker     hidl_string(const char *, size_t length);
147*8222fbe1SAndroid Build Coastguard Worker     // copy from an std::string.
148*8222fbe1SAndroid Build Coastguard Worker     hidl_string(const std::string &);
149*8222fbe1SAndroid Build Coastguard Worker 
150*8222fbe1SAndroid Build Coastguard Worker     // move constructor.
151*8222fbe1SAndroid Build Coastguard Worker     hidl_string(hidl_string &&) noexcept;
152*8222fbe1SAndroid Build Coastguard Worker 
153*8222fbe1SAndroid Build Coastguard Worker     const char *c_str() const;
154*8222fbe1SAndroid Build Coastguard Worker     size_t size() const;
155*8222fbe1SAndroid Build Coastguard Worker     bool empty() const;
156*8222fbe1SAndroid Build Coastguard Worker 
157*8222fbe1SAndroid Build Coastguard Worker     // copy assignment operator.
158*8222fbe1SAndroid Build Coastguard Worker     hidl_string &operator=(const hidl_string &);
159*8222fbe1SAndroid Build Coastguard Worker     // copy from a C-style string.
160*8222fbe1SAndroid Build Coastguard Worker     hidl_string &operator=(const char *s);
161*8222fbe1SAndroid Build Coastguard Worker     // copy from an std::string.
162*8222fbe1SAndroid Build Coastguard Worker     hidl_string &operator=(const std::string &);
163*8222fbe1SAndroid Build Coastguard Worker     // move assignment operator.
164*8222fbe1SAndroid Build Coastguard Worker     hidl_string &operator=(hidl_string &&other) noexcept;
165*8222fbe1SAndroid Build Coastguard Worker     // cast to std::string.
166*8222fbe1SAndroid Build Coastguard Worker     operator std::string() const;
167*8222fbe1SAndroid Build Coastguard Worker 
168*8222fbe1SAndroid Build Coastguard Worker     void clear();
169*8222fbe1SAndroid Build Coastguard Worker 
170*8222fbe1SAndroid Build Coastguard Worker     // Reference an external char array. Ownership is _not_ transferred.
171*8222fbe1SAndroid Build Coastguard Worker     // Caller is responsible for ensuring that underlying memory is valid
172*8222fbe1SAndroid Build Coastguard Worker     // for the lifetime of this hidl_string.
173*8222fbe1SAndroid Build Coastguard Worker     //
174*8222fbe1SAndroid Build Coastguard Worker     // size == strlen(data)
175*8222fbe1SAndroid Build Coastguard Worker     void setToExternal(const char *data, size_t size);
176*8222fbe1SAndroid Build Coastguard Worker 
177*8222fbe1SAndroid Build Coastguard Worker     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
178*8222fbe1SAndroid Build Coastguard Worker     static const size_t kOffsetOfBuffer;
179*8222fbe1SAndroid Build Coastguard Worker 
180*8222fbe1SAndroid Build Coastguard Worker private:
181*8222fbe1SAndroid Build Coastguard Worker     details::hidl_pointer<const char> mBuffer;
182*8222fbe1SAndroid Build Coastguard Worker     uint32_t mSize;  // NOT including the terminating '\0'.
183*8222fbe1SAndroid Build Coastguard Worker     bool mOwnsBuffer; // if true then mBuffer is a mutable char *
184*8222fbe1SAndroid Build Coastguard Worker     uint8_t mPad[3];
185*8222fbe1SAndroid Build Coastguard Worker 
186*8222fbe1SAndroid Build Coastguard Worker     // copy from data with size. Assume that my memory is freed
187*8222fbe1SAndroid Build Coastguard Worker     // (through clear(), for example)
188*8222fbe1SAndroid Build Coastguard Worker     void copyFrom(const char *data, size_t size);
189*8222fbe1SAndroid Build Coastguard Worker     // move from another hidl_string
190*8222fbe1SAndroid Build Coastguard Worker     void moveFrom(hidl_string &&);
191*8222fbe1SAndroid Build Coastguard Worker };
192*8222fbe1SAndroid Build Coastguard Worker 
193*8222fbe1SAndroid Build Coastguard Worker // Use NOLINT to suppress missing parentheses warnings around OP.
194*8222fbe1SAndroid Build Coastguard Worker #define HIDL_STRING_OPERATOR(OP)                                              \
195*8222fbe1SAndroid Build Coastguard Worker     inline bool operator OP(const hidl_string& hs1, const hidl_string& hs2) { \
196*8222fbe1SAndroid Build Coastguard Worker         return strcmp(hs1.c_str(), hs2.c_str()) OP 0; /* NOLINT */            \
197*8222fbe1SAndroid Build Coastguard Worker     }                                                                         \
198*8222fbe1SAndroid Build Coastguard Worker     inline bool operator OP(const hidl_string& hs, const char* s) {           \
199*8222fbe1SAndroid Build Coastguard Worker         return strcmp(hs.c_str(), s) OP 0; /* NOLINT */                       \
200*8222fbe1SAndroid Build Coastguard Worker     }                                                                         \
201*8222fbe1SAndroid Build Coastguard Worker     inline bool operator OP(const char* s, const hidl_string& hs) {           \
202*8222fbe1SAndroid Build Coastguard Worker         return strcmp(s, hs.c_str()) OP 0; /* NOLINT */                       \
203*8222fbe1SAndroid Build Coastguard Worker     }
204*8222fbe1SAndroid Build Coastguard Worker 
205*8222fbe1SAndroid Build Coastguard Worker HIDL_STRING_OPERATOR(==)
206*8222fbe1SAndroid Build Coastguard Worker HIDL_STRING_OPERATOR(!=)
207*8222fbe1SAndroid Build Coastguard Worker HIDL_STRING_OPERATOR(<)
208*8222fbe1SAndroid Build Coastguard Worker HIDL_STRING_OPERATOR(<=)
209*8222fbe1SAndroid Build Coastguard Worker HIDL_STRING_OPERATOR(>)
210*8222fbe1SAndroid Build Coastguard Worker HIDL_STRING_OPERATOR(>=)
211*8222fbe1SAndroid Build Coastguard Worker 
212*8222fbe1SAndroid Build Coastguard Worker #undef HIDL_STRING_OPERATOR
213*8222fbe1SAndroid Build Coastguard Worker 
214*8222fbe1SAndroid Build Coastguard Worker // Send our content to the output stream
215*8222fbe1SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const hidl_string& str);
216*8222fbe1SAndroid Build Coastguard Worker 
217*8222fbe1SAndroid Build Coastguard Worker 
218*8222fbe1SAndroid Build Coastguard Worker // hidl_memory is a structure that can be used to transfer
219*8222fbe1SAndroid Build Coastguard Worker // pieces of shared memory between processes. The assumption
220*8222fbe1SAndroid Build Coastguard Worker // of this object is that the memory remains accessible as
221*8222fbe1SAndroid Build Coastguard Worker // long as the file descriptors in the enclosed mHandle
222*8222fbe1SAndroid Build Coastguard Worker // - as well as all of its cross-process dups() - remain opened.
223*8222fbe1SAndroid Build Coastguard Worker struct hidl_memory {
224*8222fbe1SAndroid Build Coastguard Worker 
hidl_memoryhidl_memory225*8222fbe1SAndroid Build Coastguard Worker     hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
226*8222fbe1SAndroid Build Coastguard Worker     }
227*8222fbe1SAndroid Build Coastguard Worker 
228*8222fbe1SAndroid Build Coastguard Worker     /**
229*8222fbe1SAndroid Build Coastguard Worker      * Creates a hidl_memory object whose handle has the same lifetime
230*8222fbe1SAndroid Build Coastguard Worker      * as the handle moved into it.
231*8222fbe1SAndroid Build Coastguard Worker      */
hidl_memoryhidl_memory232*8222fbe1SAndroid Build Coastguard Worker     hidl_memory(const hidl_string& name, hidl_handle&& handle, size_t size)
233*8222fbe1SAndroid Build Coastguard Worker         : mHandle(std::move(handle)), mSize(size), mName(name) {}
234*8222fbe1SAndroid Build Coastguard Worker 
235*8222fbe1SAndroid Build Coastguard Worker     /**
236*8222fbe1SAndroid Build Coastguard Worker      * Creates a hidl_memory object, but doesn't take ownership of
237*8222fbe1SAndroid Build Coastguard Worker      * the passed in native_handle_t; callers are responsible for
238*8222fbe1SAndroid Build Coastguard Worker      * making sure the handle remains valid while this object is
239*8222fbe1SAndroid Build Coastguard Worker      * used.
240*8222fbe1SAndroid Build Coastguard Worker      */
hidl_memoryhidl_memory241*8222fbe1SAndroid Build Coastguard Worker     hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
242*8222fbe1SAndroid Build Coastguard Worker       :  mHandle(handle),
243*8222fbe1SAndroid Build Coastguard Worker          mSize(size),
244*8222fbe1SAndroid Build Coastguard Worker          mName(name)
245*8222fbe1SAndroid Build Coastguard Worker     {}
246*8222fbe1SAndroid Build Coastguard Worker 
247*8222fbe1SAndroid Build Coastguard Worker     // copy constructor
hidl_memoryhidl_memory248*8222fbe1SAndroid Build Coastguard Worker     hidl_memory(const hidl_memory& other) {
249*8222fbe1SAndroid Build Coastguard Worker         *this = other;
250*8222fbe1SAndroid Build Coastguard Worker     }
251*8222fbe1SAndroid Build Coastguard Worker 
252*8222fbe1SAndroid Build Coastguard Worker     // copy assignment
253*8222fbe1SAndroid Build Coastguard Worker     hidl_memory &operator=(const hidl_memory &other) {
254*8222fbe1SAndroid Build Coastguard Worker         if (this != &other) {
255*8222fbe1SAndroid Build Coastguard Worker             mHandle = other.mHandle;
256*8222fbe1SAndroid Build Coastguard Worker             mSize = other.mSize;
257*8222fbe1SAndroid Build Coastguard Worker             mName = other.mName;
258*8222fbe1SAndroid Build Coastguard Worker         }
259*8222fbe1SAndroid Build Coastguard Worker 
260*8222fbe1SAndroid Build Coastguard Worker         return *this;
261*8222fbe1SAndroid Build Coastguard Worker     }
262*8222fbe1SAndroid Build Coastguard Worker 
263*8222fbe1SAndroid Build Coastguard Worker     // move constructor
hidl_memoryhidl_memory264*8222fbe1SAndroid Build Coastguard Worker     hidl_memory(hidl_memory&& other) noexcept {
265*8222fbe1SAndroid Build Coastguard Worker         *this = std::move(other);
266*8222fbe1SAndroid Build Coastguard Worker     }
267*8222fbe1SAndroid Build Coastguard Worker 
268*8222fbe1SAndroid Build Coastguard Worker     // move assignment
269*8222fbe1SAndroid Build Coastguard Worker     hidl_memory &operator=(hidl_memory &&other) noexcept {
270*8222fbe1SAndroid Build Coastguard Worker         if (this != &other) {
271*8222fbe1SAndroid Build Coastguard Worker             mHandle = std::move(other.mHandle);
272*8222fbe1SAndroid Build Coastguard Worker             mSize = other.mSize;
273*8222fbe1SAndroid Build Coastguard Worker             mName = std::move(other.mName);
274*8222fbe1SAndroid Build Coastguard Worker             other.mSize = 0;
275*8222fbe1SAndroid Build Coastguard Worker         }
276*8222fbe1SAndroid Build Coastguard Worker 
277*8222fbe1SAndroid Build Coastguard Worker         return *this;
278*8222fbe1SAndroid Build Coastguard Worker     }
279*8222fbe1SAndroid Build Coastguard Worker 
280*8222fbe1SAndroid Build Coastguard Worker 
~hidl_memoryhidl_memory281*8222fbe1SAndroid Build Coastguard Worker     ~hidl_memory() {
282*8222fbe1SAndroid Build Coastguard Worker     }
283*8222fbe1SAndroid Build Coastguard Worker 
handlehidl_memory284*8222fbe1SAndroid Build Coastguard Worker     const native_handle_t* handle() const {
285*8222fbe1SAndroid Build Coastguard Worker         return mHandle;
286*8222fbe1SAndroid Build Coastguard Worker     }
287*8222fbe1SAndroid Build Coastguard Worker 
namehidl_memory288*8222fbe1SAndroid Build Coastguard Worker     const hidl_string &name() const {
289*8222fbe1SAndroid Build Coastguard Worker         return mName;
290*8222fbe1SAndroid Build Coastguard Worker     }
291*8222fbe1SAndroid Build Coastguard Worker 
sizehidl_memory292*8222fbe1SAndroid Build Coastguard Worker     uint64_t size() const {
293*8222fbe1SAndroid Build Coastguard Worker         return mSize;
294*8222fbe1SAndroid Build Coastguard Worker     }
295*8222fbe1SAndroid Build Coastguard Worker 
296*8222fbe1SAndroid Build Coastguard Worker     // @return true if it's valid
validhidl_memory297*8222fbe1SAndroid Build Coastguard Worker     inline bool valid() const { return handle() != nullptr; }
298*8222fbe1SAndroid Build Coastguard Worker 
299*8222fbe1SAndroid Build Coastguard Worker     // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
300*8222fbe1SAndroid Build Coastguard Worker     static const size_t kOffsetOfHandle;
301*8222fbe1SAndroid Build Coastguard Worker     // offsetof(hidl_memory, mName) exposed since mHandle is private.
302*8222fbe1SAndroid Build Coastguard Worker     static const size_t kOffsetOfName;
303*8222fbe1SAndroid Build Coastguard Worker 
304*8222fbe1SAndroid Build Coastguard Worker private:
305*8222fbe1SAndroid Build Coastguard Worker     hidl_handle mHandle;
306*8222fbe1SAndroid Build Coastguard Worker     uint64_t mSize;
307*8222fbe1SAndroid Build Coastguard Worker     hidl_string mName;
308*8222fbe1SAndroid Build Coastguard Worker };
309*8222fbe1SAndroid Build Coastguard Worker 
310*8222fbe1SAndroid Build Coastguard Worker // HidlMemory is a wrapper class to support sp<> for hidl_memory. It also
311*8222fbe1SAndroid Build Coastguard Worker // provides factory methods to create an instance from hidl_memory or
312*8222fbe1SAndroid Build Coastguard Worker // from a opened file descriptor. The number of factory methods can be increase
313*8222fbe1SAndroid Build Coastguard Worker // to support other type of hidl_memory without break the ABI.
314*8222fbe1SAndroid Build Coastguard Worker class HidlMemory : public virtual hidl_memory, public virtual ::android::RefBase {
315*8222fbe1SAndroid Build Coastguard Worker public:
316*8222fbe1SAndroid Build Coastguard Worker     static sp<HidlMemory> getInstance(const hidl_memory& mem);
317*8222fbe1SAndroid Build Coastguard Worker 
318*8222fbe1SAndroid Build Coastguard Worker     static sp<HidlMemory> getInstance(hidl_memory&& mem);
319*8222fbe1SAndroid Build Coastguard Worker 
320*8222fbe1SAndroid Build Coastguard Worker     static sp<HidlMemory> getInstance(const hidl_string& name, hidl_handle&& handle, uint64_t size);
321*8222fbe1SAndroid Build Coastguard Worker     // @param fd, shall be opened and points to the resource.
322*8222fbe1SAndroid Build Coastguard Worker     // @note this method takes the ownership of the fd and will close it in
323*8222fbe1SAndroid Build Coastguard Worker     //     destructor
324*8222fbe1SAndroid Build Coastguard Worker     // @return nullptr in failure with the fd closed
325*8222fbe1SAndroid Build Coastguard Worker     static sp<HidlMemory> getInstance(const hidl_string& name, int fd, uint64_t size);
326*8222fbe1SAndroid Build Coastguard Worker 
327*8222fbe1SAndroid Build Coastguard Worker     virtual ~HidlMemory();
328*8222fbe1SAndroid Build Coastguard Worker 
329*8222fbe1SAndroid Build Coastguard Worker protected:
330*8222fbe1SAndroid Build Coastguard Worker     HidlMemory();
331*8222fbe1SAndroid Build Coastguard Worker     HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size);
332*8222fbe1SAndroid Build Coastguard Worker };
333*8222fbe1SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
334*8222fbe1SAndroid Build Coastguard Worker 
335*8222fbe1SAndroid Build Coastguard Worker template<typename T>
336*8222fbe1SAndroid Build Coastguard Worker struct hidl_vec {
337*8222fbe1SAndroid Build Coastguard Worker     using value_type = T;
338*8222fbe1SAndroid Build Coastguard Worker 
hidl_vechidl_vec339*8222fbe1SAndroid Build Coastguard Worker     hidl_vec() : mBuffer(nullptr), mSize(0), mOwnsBuffer(false) {
340*8222fbe1SAndroid Build Coastguard Worker         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
341*8222fbe1SAndroid Build Coastguard Worker 
342*8222fbe1SAndroid Build Coastguard Worker         memset(mPad, 0, sizeof(mPad));
343*8222fbe1SAndroid Build Coastguard Worker     }
344*8222fbe1SAndroid Build Coastguard Worker 
hidl_vechidl_vec345*8222fbe1SAndroid Build Coastguard Worker     hidl_vec(size_t size) : hidl_vec() { resize(size); }
346*8222fbe1SAndroid Build Coastguard Worker 
hidl_vechidl_vec347*8222fbe1SAndroid Build Coastguard Worker     hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
348*8222fbe1SAndroid Build Coastguard Worker         *this = other;
349*8222fbe1SAndroid Build Coastguard Worker     }
350*8222fbe1SAndroid Build Coastguard Worker 
hidl_vechidl_vec351*8222fbe1SAndroid Build Coastguard Worker     hidl_vec(hidl_vec<T> &&other) noexcept : hidl_vec() {
352*8222fbe1SAndroid Build Coastguard Worker         *this = std::move(other);
353*8222fbe1SAndroid Build Coastguard Worker     }
354*8222fbe1SAndroid Build Coastguard Worker 
hidl_vechidl_vec355*8222fbe1SAndroid Build Coastguard Worker     hidl_vec(const std::initializer_list<T> list) : hidl_vec() { *this = list; }
356*8222fbe1SAndroid Build Coastguard Worker 
hidl_vechidl_vec357*8222fbe1SAndroid Build Coastguard Worker     hidl_vec(const std::vector<T> &other) : hidl_vec() {
358*8222fbe1SAndroid Build Coastguard Worker         *this = other;
359*8222fbe1SAndroid Build Coastguard Worker     }
360*8222fbe1SAndroid Build Coastguard Worker 
361*8222fbe1SAndroid Build Coastguard Worker     template <typename InputIterator,
362*8222fbe1SAndroid Build Coastguard Worker               typename = typename std::enable_if<std::is_convertible<
363*8222fbe1SAndroid Build Coastguard Worker                   typename std::iterator_traits<InputIterator>::iterator_category,
364*8222fbe1SAndroid Build Coastguard Worker                   std::input_iterator_tag>::value>::type>
hidl_vechidl_vec365*8222fbe1SAndroid Build Coastguard Worker     hidl_vec(InputIterator first, InputIterator last) : hidl_vec() {
366*8222fbe1SAndroid Build Coastguard Worker         auto size = std::distance(first, last);
367*8222fbe1SAndroid Build Coastguard Worker         if (size > static_cast<int64_t>(UINT32_MAX)) {
368*8222fbe1SAndroid Build Coastguard Worker             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
369*8222fbe1SAndroid Build Coastguard Worker         }
370*8222fbe1SAndroid Build Coastguard Worker         if (size < 0) {
371*8222fbe1SAndroid Build Coastguard Worker             details::logAlwaysFatal("size can't be negative.");
372*8222fbe1SAndroid Build Coastguard Worker         }
373*8222fbe1SAndroid Build Coastguard Worker         mSize = static_cast<uint32_t>(size);
374*8222fbe1SAndroid Build Coastguard Worker         mBuffer = new T[mSize]();
375*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = true;
376*8222fbe1SAndroid Build Coastguard Worker 
377*8222fbe1SAndroid Build Coastguard Worker         size_t idx = 0;
378*8222fbe1SAndroid Build Coastguard Worker         for (; first != last; ++first) {
379*8222fbe1SAndroid Build Coastguard Worker             mBuffer[idx++] = static_cast<T>(*first);
380*8222fbe1SAndroid Build Coastguard Worker         }
381*8222fbe1SAndroid Build Coastguard Worker     }
382*8222fbe1SAndroid Build Coastguard Worker 
~hidl_vechidl_vec383*8222fbe1SAndroid Build Coastguard Worker     ~hidl_vec() {
384*8222fbe1SAndroid Build Coastguard Worker         if (mOwnsBuffer) {
385*8222fbe1SAndroid Build Coastguard Worker             delete[] mBuffer;
386*8222fbe1SAndroid Build Coastguard Worker         }
387*8222fbe1SAndroid Build Coastguard Worker         mBuffer = nullptr;
388*8222fbe1SAndroid Build Coastguard Worker     }
389*8222fbe1SAndroid Build Coastguard Worker 
390*8222fbe1SAndroid Build Coastguard Worker     // Reference an existing array, optionally taking ownership. It is the
391*8222fbe1SAndroid Build Coastguard Worker     // caller's responsibility to ensure that the underlying memory stays
392*8222fbe1SAndroid Build Coastguard Worker     // valid for the lifetime of this hidl_vec.
393*8222fbe1SAndroid Build Coastguard Worker     void setToExternal(T *data, size_t size, bool shouldOwn = false) {
394*8222fbe1SAndroid Build Coastguard Worker         if (mOwnsBuffer) {
395*8222fbe1SAndroid Build Coastguard Worker             delete [] mBuffer;
396*8222fbe1SAndroid Build Coastguard Worker         }
397*8222fbe1SAndroid Build Coastguard Worker         mBuffer = data;
398*8222fbe1SAndroid Build Coastguard Worker         if (size > UINT32_MAX) {
399*8222fbe1SAndroid Build Coastguard Worker             details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
400*8222fbe1SAndroid Build Coastguard Worker         }
401*8222fbe1SAndroid Build Coastguard Worker         mSize = static_cast<uint32_t>(size);
402*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = shouldOwn;
403*8222fbe1SAndroid Build Coastguard Worker     }
404*8222fbe1SAndroid Build Coastguard Worker 
datahidl_vec405*8222fbe1SAndroid Build Coastguard Worker     T *data() {
406*8222fbe1SAndroid Build Coastguard Worker         return mBuffer;
407*8222fbe1SAndroid Build Coastguard Worker     }
408*8222fbe1SAndroid Build Coastguard Worker 
datahidl_vec409*8222fbe1SAndroid Build Coastguard Worker     const T *data() const {
410*8222fbe1SAndroid Build Coastguard Worker         return mBuffer;
411*8222fbe1SAndroid Build Coastguard Worker     }
412*8222fbe1SAndroid Build Coastguard Worker 
releaseDatahidl_vec413*8222fbe1SAndroid Build Coastguard Worker     T *releaseData() {
414*8222fbe1SAndroid Build Coastguard Worker         if (!mOwnsBuffer && mBuffer != nullptr) {
415*8222fbe1SAndroid Build Coastguard Worker             resize(mSize);
416*8222fbe1SAndroid Build Coastguard Worker         }
417*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = false;
418*8222fbe1SAndroid Build Coastguard Worker         return mBuffer;
419*8222fbe1SAndroid Build Coastguard Worker     }
420*8222fbe1SAndroid Build Coastguard Worker 
421*8222fbe1SAndroid Build Coastguard Worker     hidl_vec &operator=(hidl_vec &&other) noexcept {
422*8222fbe1SAndroid Build Coastguard Worker         if (mOwnsBuffer) {
423*8222fbe1SAndroid Build Coastguard Worker             delete[] mBuffer;
424*8222fbe1SAndroid Build Coastguard Worker         }
425*8222fbe1SAndroid Build Coastguard Worker         mBuffer = other.mBuffer;
426*8222fbe1SAndroid Build Coastguard Worker         mSize = other.mSize;
427*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = other.mOwnsBuffer;
428*8222fbe1SAndroid Build Coastguard Worker         other.mOwnsBuffer = false;
429*8222fbe1SAndroid Build Coastguard Worker         return *this;
430*8222fbe1SAndroid Build Coastguard Worker     }
431*8222fbe1SAndroid Build Coastguard Worker 
432*8222fbe1SAndroid Build Coastguard Worker     hidl_vec &operator=(const hidl_vec &other) {
433*8222fbe1SAndroid Build Coastguard Worker         if (this != &other) {
434*8222fbe1SAndroid Build Coastguard Worker             if (mOwnsBuffer) {
435*8222fbe1SAndroid Build Coastguard Worker                 delete[] mBuffer;
436*8222fbe1SAndroid Build Coastguard Worker             }
437*8222fbe1SAndroid Build Coastguard Worker             copyFrom(other, other.mSize);
438*8222fbe1SAndroid Build Coastguard Worker         }
439*8222fbe1SAndroid Build Coastguard Worker 
440*8222fbe1SAndroid Build Coastguard Worker         return *this;
441*8222fbe1SAndroid Build Coastguard Worker     }
442*8222fbe1SAndroid Build Coastguard Worker 
443*8222fbe1SAndroid Build Coastguard Worker     // copy from an std::vector.
444*8222fbe1SAndroid Build Coastguard Worker     hidl_vec &operator=(const std::vector<T> &other) {
445*8222fbe1SAndroid Build Coastguard Worker         if (mOwnsBuffer) {
446*8222fbe1SAndroid Build Coastguard Worker             delete[] mBuffer;
447*8222fbe1SAndroid Build Coastguard Worker         }
448*8222fbe1SAndroid Build Coastguard Worker         copyFrom(other, other.size());
449*8222fbe1SAndroid Build Coastguard Worker         return *this;
450*8222fbe1SAndroid Build Coastguard Worker     }
451*8222fbe1SAndroid Build Coastguard Worker 
452*8222fbe1SAndroid Build Coastguard Worker     hidl_vec& operator=(const std::initializer_list<T> list) {
453*8222fbe1SAndroid Build Coastguard Worker         if (list.size() > UINT32_MAX) {
454*8222fbe1SAndroid Build Coastguard Worker             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
455*8222fbe1SAndroid Build Coastguard Worker         }
456*8222fbe1SAndroid Build Coastguard Worker         if (mOwnsBuffer) {
457*8222fbe1SAndroid Build Coastguard Worker             delete[] mBuffer;
458*8222fbe1SAndroid Build Coastguard Worker         }
459*8222fbe1SAndroid Build Coastguard Worker         mSize = static_cast<uint32_t>(list.size());
460*8222fbe1SAndroid Build Coastguard Worker         mBuffer = new T[mSize]();
461*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = true;
462*8222fbe1SAndroid Build Coastguard Worker 
463*8222fbe1SAndroid Build Coastguard Worker         size_t idx = 0;
464*8222fbe1SAndroid Build Coastguard Worker         for (auto it = list.begin(); it != list.end(); ++it) {
465*8222fbe1SAndroid Build Coastguard Worker             mBuffer[idx++] = *it;
466*8222fbe1SAndroid Build Coastguard Worker         }
467*8222fbe1SAndroid Build Coastguard Worker         return *this;
468*8222fbe1SAndroid Build Coastguard Worker     }
469*8222fbe1SAndroid Build Coastguard Worker 
470*8222fbe1SAndroid Build Coastguard Worker     // cast to an std::vector.
471*8222fbe1SAndroid Build Coastguard Worker     operator std::vector<T>() const {
472*8222fbe1SAndroid Build Coastguard Worker         std::vector<T> v(mSize);
473*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < mSize; ++i) {
474*8222fbe1SAndroid Build Coastguard Worker             v[i] = mBuffer[i];
475*8222fbe1SAndroid Build Coastguard Worker         }
476*8222fbe1SAndroid Build Coastguard Worker         return v;
477*8222fbe1SAndroid Build Coastguard Worker     }
478*8222fbe1SAndroid Build Coastguard Worker 
479*8222fbe1SAndroid Build Coastguard Worker     // equality check, assuming that T::operator== is defined.
480*8222fbe1SAndroid Build Coastguard Worker     bool operator==(const hidl_vec &other) const {
481*8222fbe1SAndroid Build Coastguard Worker         if (mSize != other.size()) {
482*8222fbe1SAndroid Build Coastguard Worker             return false;
483*8222fbe1SAndroid Build Coastguard Worker         }
484*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < mSize; ++i) {
485*8222fbe1SAndroid Build Coastguard Worker             if (!(mBuffer[i] == other.mBuffer[i])) {
486*8222fbe1SAndroid Build Coastguard Worker                 return false;
487*8222fbe1SAndroid Build Coastguard Worker             }
488*8222fbe1SAndroid Build Coastguard Worker         }
489*8222fbe1SAndroid Build Coastguard Worker         return true;
490*8222fbe1SAndroid Build Coastguard Worker     }
491*8222fbe1SAndroid Build Coastguard Worker 
492*8222fbe1SAndroid Build Coastguard Worker     // inequality check, assuming that T::operator== is defined.
493*8222fbe1SAndroid Build Coastguard Worker     inline bool operator!=(const hidl_vec &other) const {
494*8222fbe1SAndroid Build Coastguard Worker         return !((*this) == other);
495*8222fbe1SAndroid Build Coastguard Worker     }
496*8222fbe1SAndroid Build Coastguard Worker 
sizehidl_vec497*8222fbe1SAndroid Build Coastguard Worker     size_t size() const {
498*8222fbe1SAndroid Build Coastguard Worker         return mSize;
499*8222fbe1SAndroid Build Coastguard Worker     }
500*8222fbe1SAndroid Build Coastguard Worker 
501*8222fbe1SAndroid Build Coastguard Worker     T &operator[](size_t index) {
502*8222fbe1SAndroid Build Coastguard Worker         return mBuffer[index];
503*8222fbe1SAndroid Build Coastguard Worker     }
504*8222fbe1SAndroid Build Coastguard Worker 
505*8222fbe1SAndroid Build Coastguard Worker     const T &operator[](size_t index) const {
506*8222fbe1SAndroid Build Coastguard Worker         return mBuffer[index];
507*8222fbe1SAndroid Build Coastguard Worker     }
508*8222fbe1SAndroid Build Coastguard Worker 
509*8222fbe1SAndroid Build Coastguard Worker     // Copies over old elements fitting in new size. Value initializes the rest.
resizehidl_vec510*8222fbe1SAndroid Build Coastguard Worker     void resize(size_t size) {
511*8222fbe1SAndroid Build Coastguard Worker         if (size > UINT32_MAX) {
512*8222fbe1SAndroid Build Coastguard Worker             details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
513*8222fbe1SAndroid Build Coastguard Worker         }
514*8222fbe1SAndroid Build Coastguard Worker         T* newBuffer = new T[size]();
515*8222fbe1SAndroid Build Coastguard Worker 
516*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
517*8222fbe1SAndroid Build Coastguard Worker             newBuffer[i] = std::move(mBuffer[i]);
518*8222fbe1SAndroid Build Coastguard Worker         }
519*8222fbe1SAndroid Build Coastguard Worker 
520*8222fbe1SAndroid Build Coastguard Worker         if (mOwnsBuffer) {
521*8222fbe1SAndroid Build Coastguard Worker             delete[] mBuffer;
522*8222fbe1SAndroid Build Coastguard Worker         }
523*8222fbe1SAndroid Build Coastguard Worker         mBuffer = newBuffer;
524*8222fbe1SAndroid Build Coastguard Worker 
525*8222fbe1SAndroid Build Coastguard Worker         mSize = static_cast<uint32_t>(size);
526*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = true;
527*8222fbe1SAndroid Build Coastguard Worker     }
528*8222fbe1SAndroid Build Coastguard Worker 
529*8222fbe1SAndroid Build Coastguard Worker     // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
530*8222fbe1SAndroid Build Coastguard Worker     static const size_t kOffsetOfBuffer;
531*8222fbe1SAndroid Build Coastguard Worker 
532*8222fbe1SAndroid Build Coastguard Worker private:
533*8222fbe1SAndroid Build Coastguard Worker     // Define std interator interface for walking the array contents
534*8222fbe1SAndroid Build Coastguard Worker     template<bool is_const>
535*8222fbe1SAndroid Build Coastguard Worker     class iter {
536*8222fbe1SAndroid Build Coastguard Worker     public:
537*8222fbe1SAndroid Build Coastguard Worker         using iterator_category = std::random_access_iterator_tag;
538*8222fbe1SAndroid Build Coastguard Worker         using value_type = T;
539*8222fbe1SAndroid Build Coastguard Worker         using difference_type = ptrdiff_t;
540*8222fbe1SAndroid Build Coastguard Worker         using pointer = std::conditional_t<is_const, const T *, T *>;
541*8222fbe1SAndroid Build Coastguard Worker         using reference = std::conditional_t<is_const, const T &, T &>;
iterhidl_vec542*8222fbe1SAndroid Build Coastguard Worker         iter(pointer ptr) : mPtr(ptr) { }
543*8222fbe1SAndroid Build Coastguard Worker         inline iter &operator++()    { mPtr++; return *this; }
544*8222fbe1SAndroid Build Coastguard Worker         inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
545*8222fbe1SAndroid Build Coastguard Worker         inline iter &operator--()    { mPtr--; return *this; }
546*8222fbe1SAndroid Build Coastguard Worker         inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
547*8222fbe1SAndroid Build Coastguard Worker         inline friend iter operator+(difference_type n, const iter &it) { return it.mPtr + n; }
548*8222fbe1SAndroid Build Coastguard Worker         inline iter  operator+(difference_type n) const { return mPtr + n; }
549*8222fbe1SAndroid Build Coastguard Worker         inline iter  operator-(difference_type n) const { return mPtr - n; }
550*8222fbe1SAndroid Build Coastguard Worker         inline difference_type operator-(const iter &other) const { return mPtr - other.mPtr; }
551*8222fbe1SAndroid Build Coastguard Worker         inline iter &operator+=(difference_type n) { mPtr += n; return *this; }
552*8222fbe1SAndroid Build Coastguard Worker         inline iter &operator-=(difference_type n) { mPtr -= n; return *this; }
553*8222fbe1SAndroid Build Coastguard Worker         inline reference operator*() const { return *mPtr; }
554*8222fbe1SAndroid Build Coastguard Worker         inline pointer operator->() const  { return mPtr; }
555*8222fbe1SAndroid Build Coastguard Worker         inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
556*8222fbe1SAndroid Build Coastguard Worker         inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
557*8222fbe1SAndroid Build Coastguard Worker         inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
558*8222fbe1SAndroid Build Coastguard Worker         inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
559*8222fbe1SAndroid Build Coastguard Worker         inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
560*8222fbe1SAndroid Build Coastguard Worker         inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
561*8222fbe1SAndroid Build Coastguard Worker         inline reference operator[](size_t n) const { return mPtr[n]; }
562*8222fbe1SAndroid Build Coastguard Worker     private:
563*8222fbe1SAndroid Build Coastguard Worker         pointer mPtr;
564*8222fbe1SAndroid Build Coastguard Worker     };
565*8222fbe1SAndroid Build Coastguard Worker public:
566*8222fbe1SAndroid Build Coastguard Worker     using iterator       = iter<false /* is_const */>;
567*8222fbe1SAndroid Build Coastguard Worker     using const_iterator = iter<true  /* is_const */>;
568*8222fbe1SAndroid Build Coastguard Worker 
beginhidl_vec569*8222fbe1SAndroid Build Coastguard Worker     iterator begin() { return data(); }
endhidl_vec570*8222fbe1SAndroid Build Coastguard Worker     iterator end() { return data()+mSize; }
beginhidl_vec571*8222fbe1SAndroid Build Coastguard Worker     const_iterator begin() const { return data(); }
endhidl_vec572*8222fbe1SAndroid Build Coastguard Worker     const_iterator end() const { return data()+mSize; }
findhidl_vec573*8222fbe1SAndroid Build Coastguard Worker     iterator find(const T& v) { return std::find(begin(), end(), v); }
findhidl_vec574*8222fbe1SAndroid Build Coastguard Worker     const_iterator find(const T& v) const { return std::find(begin(), end(), v); }
containshidl_vec575*8222fbe1SAndroid Build Coastguard Worker     bool contains(const T& v) const { return find(v) != end(); }
576*8222fbe1SAndroid Build Coastguard Worker 
577*8222fbe1SAndroid Build Coastguard Worker   private:
578*8222fbe1SAndroid Build Coastguard Worker     details::hidl_pointer<T> mBuffer;
579*8222fbe1SAndroid Build Coastguard Worker     uint32_t mSize;
580*8222fbe1SAndroid Build Coastguard Worker     bool mOwnsBuffer;
581*8222fbe1SAndroid Build Coastguard Worker     uint8_t mPad[3];
582*8222fbe1SAndroid Build Coastguard Worker 
583*8222fbe1SAndroid Build Coastguard Worker     // copy from an array-like object, assuming my resources are freed.
584*8222fbe1SAndroid Build Coastguard Worker     template <typename Array>
copyFromhidl_vec585*8222fbe1SAndroid Build Coastguard Worker     void copyFrom(const Array &data, size_t size) {
586*8222fbe1SAndroid Build Coastguard Worker         mSize = static_cast<uint32_t>(size);
587*8222fbe1SAndroid Build Coastguard Worker         mOwnsBuffer = true;
588*8222fbe1SAndroid Build Coastguard Worker         if (mSize > 0) {
589*8222fbe1SAndroid Build Coastguard Worker             mBuffer = new T[size]();
590*8222fbe1SAndroid Build Coastguard Worker             for (size_t i = 0; i < size; ++i) {
591*8222fbe1SAndroid Build Coastguard Worker                 mBuffer[i] = data[i];
592*8222fbe1SAndroid Build Coastguard Worker             }
593*8222fbe1SAndroid Build Coastguard Worker         } else {
594*8222fbe1SAndroid Build Coastguard Worker             mBuffer = nullptr;
595*8222fbe1SAndroid Build Coastguard Worker         }
596*8222fbe1SAndroid Build Coastguard Worker     }
597*8222fbe1SAndroid Build Coastguard Worker };
598*8222fbe1SAndroid Build Coastguard Worker 
599*8222fbe1SAndroid Build Coastguard Worker template <typename T>
600*8222fbe1SAndroid Build Coastguard Worker const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
601*8222fbe1SAndroid Build Coastguard Worker 
602*8222fbe1SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
603*8222fbe1SAndroid Build Coastguard Worker 
604*8222fbe1SAndroid Build Coastguard Worker namespace details {
605*8222fbe1SAndroid Build Coastguard Worker 
606*8222fbe1SAndroid Build Coastguard Worker     template<size_t SIZE1, size_t... SIZES>
607*8222fbe1SAndroid Build Coastguard Worker     struct product {
608*8222fbe1SAndroid Build Coastguard Worker         static constexpr size_t value = SIZE1 * product<SIZES...>::value;
609*8222fbe1SAndroid Build Coastguard Worker     };
610*8222fbe1SAndroid Build Coastguard Worker 
611*8222fbe1SAndroid Build Coastguard Worker     template<size_t SIZE1>
612*8222fbe1SAndroid Build Coastguard Worker     struct product<SIZE1> {
613*8222fbe1SAndroid Build Coastguard Worker         static constexpr size_t value = SIZE1;
614*8222fbe1SAndroid Build Coastguard Worker     };
615*8222fbe1SAndroid Build Coastguard Worker 
616*8222fbe1SAndroid Build Coastguard Worker     template<typename T, size_t SIZE1, size_t... SIZES>
617*8222fbe1SAndroid Build Coastguard Worker     struct std_array {
618*8222fbe1SAndroid Build Coastguard Worker         using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
619*8222fbe1SAndroid Build Coastguard Worker     };
620*8222fbe1SAndroid Build Coastguard Worker 
621*8222fbe1SAndroid Build Coastguard Worker     template<typename T, size_t SIZE1>
622*8222fbe1SAndroid Build Coastguard Worker     struct std_array<T, SIZE1> {
623*8222fbe1SAndroid Build Coastguard Worker         using type = std::array<T, SIZE1>;
624*8222fbe1SAndroid Build Coastguard Worker     };
625*8222fbe1SAndroid Build Coastguard Worker 
626*8222fbe1SAndroid Build Coastguard Worker     template<typename T, size_t SIZE1, size_t... SIZES>
627*8222fbe1SAndroid Build Coastguard Worker     struct accessor {
628*8222fbe1SAndroid Build Coastguard Worker 
629*8222fbe1SAndroid Build Coastguard Worker         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
630*8222fbe1SAndroid Build Coastguard Worker 
631*8222fbe1SAndroid Build Coastguard Worker         explicit accessor(T *base)
632*8222fbe1SAndroid Build Coastguard Worker             : mBase(base) {
633*8222fbe1SAndroid Build Coastguard Worker         }
634*8222fbe1SAndroid Build Coastguard Worker 
635*8222fbe1SAndroid Build Coastguard Worker         accessor<T, SIZES...> operator[](size_t index) {
636*8222fbe1SAndroid Build Coastguard Worker             return accessor<T, SIZES...>(
637*8222fbe1SAndroid Build Coastguard Worker                     &mBase[index * product<SIZES...>::value]);
638*8222fbe1SAndroid Build Coastguard Worker         }
639*8222fbe1SAndroid Build Coastguard Worker 
640*8222fbe1SAndroid Build Coastguard Worker         accessor &operator=(const std_array_type &other) {
641*8222fbe1SAndroid Build Coastguard Worker             for (size_t i = 0; i < SIZE1; ++i) {
642*8222fbe1SAndroid Build Coastguard Worker                 (*this)[i] = other[i];
643*8222fbe1SAndroid Build Coastguard Worker             }
644*8222fbe1SAndroid Build Coastguard Worker             return *this;
645*8222fbe1SAndroid Build Coastguard Worker         }
646*8222fbe1SAndroid Build Coastguard Worker 
647*8222fbe1SAndroid Build Coastguard Worker     private:
648*8222fbe1SAndroid Build Coastguard Worker         T *mBase;
649*8222fbe1SAndroid Build Coastguard Worker     };
650*8222fbe1SAndroid Build Coastguard Worker 
651*8222fbe1SAndroid Build Coastguard Worker     template<typename T, size_t SIZE1>
652*8222fbe1SAndroid Build Coastguard Worker     struct accessor<T, SIZE1> {
653*8222fbe1SAndroid Build Coastguard Worker 
654*8222fbe1SAndroid Build Coastguard Worker         using std_array_type = typename std_array<T, SIZE1>::type;
655*8222fbe1SAndroid Build Coastguard Worker 
656*8222fbe1SAndroid Build Coastguard Worker         explicit accessor(T *base)
657*8222fbe1SAndroid Build Coastguard Worker             : mBase(base) {
658*8222fbe1SAndroid Build Coastguard Worker         }
659*8222fbe1SAndroid Build Coastguard Worker 
660*8222fbe1SAndroid Build Coastguard Worker         T &operator[](size_t index) {
661*8222fbe1SAndroid Build Coastguard Worker             return mBase[index];
662*8222fbe1SAndroid Build Coastguard Worker         }
663*8222fbe1SAndroid Build Coastguard Worker 
664*8222fbe1SAndroid Build Coastguard Worker         accessor &operator=(const std_array_type &other) {
665*8222fbe1SAndroid Build Coastguard Worker             for (size_t i = 0; i < SIZE1; ++i) {
666*8222fbe1SAndroid Build Coastguard Worker                 (*this)[i] = other[i];
667*8222fbe1SAndroid Build Coastguard Worker             }
668*8222fbe1SAndroid Build Coastguard Worker             return *this;
669*8222fbe1SAndroid Build Coastguard Worker         }
670*8222fbe1SAndroid Build Coastguard Worker 
671*8222fbe1SAndroid Build Coastguard Worker     private:
672*8222fbe1SAndroid Build Coastguard Worker         T *mBase;
673*8222fbe1SAndroid Build Coastguard Worker     };
674*8222fbe1SAndroid Build Coastguard Worker 
675*8222fbe1SAndroid Build Coastguard Worker     template<typename T, size_t SIZE1, size_t... SIZES>
676*8222fbe1SAndroid Build Coastguard Worker     struct const_accessor {
677*8222fbe1SAndroid Build Coastguard Worker 
678*8222fbe1SAndroid Build Coastguard Worker         using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
679*8222fbe1SAndroid Build Coastguard Worker 
680*8222fbe1SAndroid Build Coastguard Worker         explicit const_accessor(const T *base)
681*8222fbe1SAndroid Build Coastguard Worker             : mBase(base) {
682*8222fbe1SAndroid Build Coastguard Worker         }
683*8222fbe1SAndroid Build Coastguard Worker 
684*8222fbe1SAndroid Build Coastguard Worker         const_accessor<T, SIZES...> operator[](size_t index) const {
685*8222fbe1SAndroid Build Coastguard Worker             return const_accessor<T, SIZES...>(
686*8222fbe1SAndroid Build Coastguard Worker                     &mBase[index * product<SIZES...>::value]);
687*8222fbe1SAndroid Build Coastguard Worker         }
688*8222fbe1SAndroid Build Coastguard Worker 
689*8222fbe1SAndroid Build Coastguard Worker         operator std_array_type() {
690*8222fbe1SAndroid Build Coastguard Worker             std_array_type array;
691*8222fbe1SAndroid Build Coastguard Worker             for (size_t i = 0; i < SIZE1; ++i) {
692*8222fbe1SAndroid Build Coastguard Worker                 array[i] = (*this)[i];
693*8222fbe1SAndroid Build Coastguard Worker             }
694*8222fbe1SAndroid Build Coastguard Worker             return array;
695*8222fbe1SAndroid Build Coastguard Worker         }
696*8222fbe1SAndroid Build Coastguard Worker 
697*8222fbe1SAndroid Build Coastguard Worker     private:
698*8222fbe1SAndroid Build Coastguard Worker         const T *mBase;
699*8222fbe1SAndroid Build Coastguard Worker     };
700*8222fbe1SAndroid Build Coastguard Worker 
701*8222fbe1SAndroid Build Coastguard Worker     template<typename T, size_t SIZE1>
702*8222fbe1SAndroid Build Coastguard Worker     struct const_accessor<T, SIZE1> {
703*8222fbe1SAndroid Build Coastguard Worker 
704*8222fbe1SAndroid Build Coastguard Worker         using std_array_type = typename std_array<T, SIZE1>::type;
705*8222fbe1SAndroid Build Coastguard Worker 
706*8222fbe1SAndroid Build Coastguard Worker         explicit const_accessor(const T *base)
707*8222fbe1SAndroid Build Coastguard Worker             : mBase(base) {
708*8222fbe1SAndroid Build Coastguard Worker         }
709*8222fbe1SAndroid Build Coastguard Worker 
710*8222fbe1SAndroid Build Coastguard Worker         const T &operator[](size_t index) const {
711*8222fbe1SAndroid Build Coastguard Worker             return mBase[index];
712*8222fbe1SAndroid Build Coastguard Worker         }
713*8222fbe1SAndroid Build Coastguard Worker 
714*8222fbe1SAndroid Build Coastguard Worker         operator std_array_type() {
715*8222fbe1SAndroid Build Coastguard Worker             std_array_type array;
716*8222fbe1SAndroid Build Coastguard Worker             for (size_t i = 0; i < SIZE1; ++i) {
717*8222fbe1SAndroid Build Coastguard Worker                 array[i] = (*this)[i];
718*8222fbe1SAndroid Build Coastguard Worker             }
719*8222fbe1SAndroid Build Coastguard Worker             return array;
720*8222fbe1SAndroid Build Coastguard Worker         }
721*8222fbe1SAndroid Build Coastguard Worker 
722*8222fbe1SAndroid Build Coastguard Worker     private:
723*8222fbe1SAndroid Build Coastguard Worker         const T *mBase;
724*8222fbe1SAndroid Build Coastguard Worker     };
725*8222fbe1SAndroid Build Coastguard Worker 
726*8222fbe1SAndroid Build Coastguard Worker }  // namespace details
727*8222fbe1SAndroid Build Coastguard Worker 
728*8222fbe1SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
729*8222fbe1SAndroid Build Coastguard Worker 
730*8222fbe1SAndroid Build Coastguard Worker // A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
731*8222fbe1SAndroid Build Coastguard Worker template<typename T, size_t SIZE1, size_t... SIZES>
732*8222fbe1SAndroid Build Coastguard Worker struct hidl_array {
733*8222fbe1SAndroid Build Coastguard Worker 
734*8222fbe1SAndroid Build Coastguard Worker     using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
735*8222fbe1SAndroid Build Coastguard Worker 
736*8222fbe1SAndroid Build Coastguard Worker     hidl_array() = default;
737*8222fbe1SAndroid Build Coastguard Worker     hidl_array(const hidl_array&) noexcept = default;
738*8222fbe1SAndroid Build Coastguard Worker     hidl_array(hidl_array&&) noexcept = default;
739*8222fbe1SAndroid Build Coastguard Worker 
740*8222fbe1SAndroid Build Coastguard Worker     // Copies the data from source, using T::operator=(const T &).
741*8222fbe1SAndroid Build Coastguard Worker     hidl_array(const T *source) {
742*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < elementCount(); ++i) {
743*8222fbe1SAndroid Build Coastguard Worker             mBuffer[i] = source[i];
744*8222fbe1SAndroid Build Coastguard Worker         }
745*8222fbe1SAndroid Build Coastguard Worker     }
746*8222fbe1SAndroid Build Coastguard Worker 
747*8222fbe1SAndroid Build Coastguard Worker     // Copies the data from the given std::array, using T::operator=(const T &).
748*8222fbe1SAndroid Build Coastguard Worker     hidl_array(const std_array_type &array) {
749*8222fbe1SAndroid Build Coastguard Worker         details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
750*8222fbe1SAndroid Build Coastguard Worker         modifier = array;
751*8222fbe1SAndroid Build Coastguard Worker     }
752*8222fbe1SAndroid Build Coastguard Worker 
753*8222fbe1SAndroid Build Coastguard Worker     hidl_array& operator=(const hidl_array&) noexcept = default;
754*8222fbe1SAndroid Build Coastguard Worker     hidl_array& operator=(hidl_array&&) noexcept = default;
755*8222fbe1SAndroid Build Coastguard Worker 
756*8222fbe1SAndroid Build Coastguard Worker     T *data() { return mBuffer; }
757*8222fbe1SAndroid Build Coastguard Worker     const T *data() const { return mBuffer; }
758*8222fbe1SAndroid Build Coastguard Worker 
759*8222fbe1SAndroid Build Coastguard Worker     details::accessor<T, SIZES...> operator[](size_t index) {
760*8222fbe1SAndroid Build Coastguard Worker         return details::accessor<T, SIZES...>(
761*8222fbe1SAndroid Build Coastguard Worker                 &mBuffer[index * details::product<SIZES...>::value]);
762*8222fbe1SAndroid Build Coastguard Worker     }
763*8222fbe1SAndroid Build Coastguard Worker 
764*8222fbe1SAndroid Build Coastguard Worker     details::const_accessor<T, SIZES...> operator[](size_t index) const {
765*8222fbe1SAndroid Build Coastguard Worker         return details::const_accessor<T, SIZES...>(
766*8222fbe1SAndroid Build Coastguard Worker                 &mBuffer[index * details::product<SIZES...>::value]);
767*8222fbe1SAndroid Build Coastguard Worker     }
768*8222fbe1SAndroid Build Coastguard Worker 
769*8222fbe1SAndroid Build Coastguard Worker     // equality check, assuming that T::operator== is defined.
770*8222fbe1SAndroid Build Coastguard Worker     bool operator==(const hidl_array &other) const {
771*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < elementCount(); ++i) {
772*8222fbe1SAndroid Build Coastguard Worker             if (!(mBuffer[i] == other.mBuffer[i])) {
773*8222fbe1SAndroid Build Coastguard Worker                 return false;
774*8222fbe1SAndroid Build Coastguard Worker             }
775*8222fbe1SAndroid Build Coastguard Worker         }
776*8222fbe1SAndroid Build Coastguard Worker         return true;
777*8222fbe1SAndroid Build Coastguard Worker     }
778*8222fbe1SAndroid Build Coastguard Worker 
779*8222fbe1SAndroid Build Coastguard Worker     inline bool operator!=(const hidl_array &other) const {
780*8222fbe1SAndroid Build Coastguard Worker         return !((*this) == other);
781*8222fbe1SAndroid Build Coastguard Worker     }
782*8222fbe1SAndroid Build Coastguard Worker 
783*8222fbe1SAndroid Build Coastguard Worker     using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
784*8222fbe1SAndroid Build Coastguard Worker 
785*8222fbe1SAndroid Build Coastguard Worker     static constexpr size_tuple_type size() {
786*8222fbe1SAndroid Build Coastguard Worker         return std::make_tuple(SIZE1, SIZES...);
787*8222fbe1SAndroid Build Coastguard Worker     }
788*8222fbe1SAndroid Build Coastguard Worker 
789*8222fbe1SAndroid Build Coastguard Worker     static constexpr size_t elementCount() {
790*8222fbe1SAndroid Build Coastguard Worker         return details::product<SIZE1, SIZES...>::value;
791*8222fbe1SAndroid Build Coastguard Worker     }
792*8222fbe1SAndroid Build Coastguard Worker 
793*8222fbe1SAndroid Build Coastguard Worker     operator std_array_type() const {
794*8222fbe1SAndroid Build Coastguard Worker         return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
795*8222fbe1SAndroid Build Coastguard Worker     }
796*8222fbe1SAndroid Build Coastguard Worker 
797*8222fbe1SAndroid Build Coastguard Worker private:
798*8222fbe1SAndroid Build Coastguard Worker     T mBuffer[elementCount()];
799*8222fbe1SAndroid Build Coastguard Worker };
800*8222fbe1SAndroid Build Coastguard Worker 
801*8222fbe1SAndroid Build Coastguard Worker // An array of T's. Assumes that T::operator=(const T &) is defined.
802*8222fbe1SAndroid Build Coastguard Worker template<typename T, size_t SIZE1>
803*8222fbe1SAndroid Build Coastguard Worker struct hidl_array<T, SIZE1> {
804*8222fbe1SAndroid Build Coastguard Worker     using value_type = T;
805*8222fbe1SAndroid Build Coastguard Worker     using std_array_type = typename details::std_array<T, SIZE1>::type;
806*8222fbe1SAndroid Build Coastguard Worker 
807*8222fbe1SAndroid Build Coastguard Worker     hidl_array() = default;
808*8222fbe1SAndroid Build Coastguard Worker     hidl_array(const hidl_array&) noexcept = default;
809*8222fbe1SAndroid Build Coastguard Worker     hidl_array(hidl_array&&) noexcept = default;
810*8222fbe1SAndroid Build Coastguard Worker 
811*8222fbe1SAndroid Build Coastguard Worker     // Copies the data from source, using T::operator=(const T &).
812*8222fbe1SAndroid Build Coastguard Worker     hidl_array(const T *source) {
813*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < elementCount(); ++i) {
814*8222fbe1SAndroid Build Coastguard Worker             mBuffer[i] = source[i];
815*8222fbe1SAndroid Build Coastguard Worker         }
816*8222fbe1SAndroid Build Coastguard Worker     }
817*8222fbe1SAndroid Build Coastguard Worker 
818*8222fbe1SAndroid Build Coastguard Worker     // Copies the data from the given std::array, using T::operator=(const T &).
819*8222fbe1SAndroid Build Coastguard Worker     hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
820*8222fbe1SAndroid Build Coastguard Worker 
821*8222fbe1SAndroid Build Coastguard Worker     hidl_array& operator=(const hidl_array&) noexcept = default;
822*8222fbe1SAndroid Build Coastguard Worker     hidl_array& operator=(hidl_array&&) noexcept = default;
823*8222fbe1SAndroid Build Coastguard Worker 
824*8222fbe1SAndroid Build Coastguard Worker     T *data() { return mBuffer; }
825*8222fbe1SAndroid Build Coastguard Worker     const T *data() const { return mBuffer; }
826*8222fbe1SAndroid Build Coastguard Worker 
827*8222fbe1SAndroid Build Coastguard Worker     T &operator[](size_t index) {
828*8222fbe1SAndroid Build Coastguard Worker         return mBuffer[index];
829*8222fbe1SAndroid Build Coastguard Worker     }
830*8222fbe1SAndroid Build Coastguard Worker 
831*8222fbe1SAndroid Build Coastguard Worker     const T &operator[](size_t index) const {
832*8222fbe1SAndroid Build Coastguard Worker         return mBuffer[index];
833*8222fbe1SAndroid Build Coastguard Worker     }
834*8222fbe1SAndroid Build Coastguard Worker 
835*8222fbe1SAndroid Build Coastguard Worker     // equality check, assuming that T::operator== is defined.
836*8222fbe1SAndroid Build Coastguard Worker     bool operator==(const hidl_array &other) const {
837*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < elementCount(); ++i) {
838*8222fbe1SAndroid Build Coastguard Worker             if (!(mBuffer[i] == other.mBuffer[i])) {
839*8222fbe1SAndroid Build Coastguard Worker                 return false;
840*8222fbe1SAndroid Build Coastguard Worker             }
841*8222fbe1SAndroid Build Coastguard Worker         }
842*8222fbe1SAndroid Build Coastguard Worker         return true;
843*8222fbe1SAndroid Build Coastguard Worker     }
844*8222fbe1SAndroid Build Coastguard Worker 
845*8222fbe1SAndroid Build Coastguard Worker     inline bool operator!=(const hidl_array &other) const {
846*8222fbe1SAndroid Build Coastguard Worker         return !((*this) == other);
847*8222fbe1SAndroid Build Coastguard Worker     }
848*8222fbe1SAndroid Build Coastguard Worker 
849*8222fbe1SAndroid Build Coastguard Worker     static constexpr size_t size() { return SIZE1; }
850*8222fbe1SAndroid Build Coastguard Worker     static constexpr size_t elementCount() { return SIZE1; }
851*8222fbe1SAndroid Build Coastguard Worker 
852*8222fbe1SAndroid Build Coastguard Worker     // Copies the data to an std::array, using T::operator=(T).
853*8222fbe1SAndroid Build Coastguard Worker     operator std_array_type() const {
854*8222fbe1SAndroid Build Coastguard Worker         std_array_type array;
855*8222fbe1SAndroid Build Coastguard Worker         for (size_t i = 0; i < SIZE1; ++i) {
856*8222fbe1SAndroid Build Coastguard Worker             array[i] = mBuffer[i];
857*8222fbe1SAndroid Build Coastguard Worker         }
858*8222fbe1SAndroid Build Coastguard Worker         return array;
859*8222fbe1SAndroid Build Coastguard Worker     }
860*8222fbe1SAndroid Build Coastguard Worker 
861*8222fbe1SAndroid Build Coastguard Worker private:
862*8222fbe1SAndroid Build Coastguard Worker     T mBuffer[SIZE1];
863*8222fbe1SAndroid Build Coastguard Worker };
864*8222fbe1SAndroid Build Coastguard Worker 
865*8222fbe1SAndroid Build Coastguard Worker // ----------------------------------------------------------------------
866*8222fbe1SAndroid Build Coastguard Worker // Version functions
867*8222fbe1SAndroid Build Coastguard Worker struct hidl_version {
868*8222fbe1SAndroid Build Coastguard Worker public:
869*8222fbe1SAndroid Build Coastguard Worker     constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {
870*8222fbe1SAndroid Build Coastguard Worker         static_assert(sizeof(*this) == 4, "wrong size");
871*8222fbe1SAndroid Build Coastguard Worker     }
872*8222fbe1SAndroid Build Coastguard Worker 
873*8222fbe1SAndroid Build Coastguard Worker     bool operator==(const hidl_version& other) const {
874*8222fbe1SAndroid Build Coastguard Worker         return (mMajor == other.get_major() && mMinor == other.get_minor());
875*8222fbe1SAndroid Build Coastguard Worker     }
876*8222fbe1SAndroid Build Coastguard Worker 
877*8222fbe1SAndroid Build Coastguard Worker     bool operator!=(const hidl_version& other) const {
878*8222fbe1SAndroid Build Coastguard Worker         return !(*this == other);
879*8222fbe1SAndroid Build Coastguard Worker     }
880*8222fbe1SAndroid Build Coastguard Worker 
881*8222fbe1SAndroid Build Coastguard Worker     bool operator<(const hidl_version& other) const {
882*8222fbe1SAndroid Build Coastguard Worker         return (mMajor < other.get_major() ||
883*8222fbe1SAndroid Build Coastguard Worker                 (mMajor == other.get_major() && mMinor < other.get_minor()));
884*8222fbe1SAndroid Build Coastguard Worker     }
885*8222fbe1SAndroid Build Coastguard Worker 
886*8222fbe1SAndroid Build Coastguard Worker     bool operator>(const hidl_version& other) const {
887*8222fbe1SAndroid Build Coastguard Worker         return other < *this;
888*8222fbe1SAndroid Build Coastguard Worker     }
889*8222fbe1SAndroid Build Coastguard Worker 
890*8222fbe1SAndroid Build Coastguard Worker     bool operator<=(const hidl_version& other) const {
891*8222fbe1SAndroid Build Coastguard Worker         return !(*this > other);
892*8222fbe1SAndroid Build Coastguard Worker     }
893*8222fbe1SAndroid Build Coastguard Worker 
894*8222fbe1SAndroid Build Coastguard Worker     bool operator>=(const hidl_version& other) const {
895*8222fbe1SAndroid Build Coastguard Worker         return !(*this < other);
896*8222fbe1SAndroid Build Coastguard Worker     }
897*8222fbe1SAndroid Build Coastguard Worker 
898*8222fbe1SAndroid Build Coastguard Worker     constexpr uint16_t get_major() const { return mMajor; }
899*8222fbe1SAndroid Build Coastguard Worker     constexpr uint16_t get_minor() const { return mMinor; }
900*8222fbe1SAndroid Build Coastguard Worker 
901*8222fbe1SAndroid Build Coastguard Worker private:
902*8222fbe1SAndroid Build Coastguard Worker     uint16_t mMajor;
903*8222fbe1SAndroid Build Coastguard Worker     uint16_t mMinor;
904*8222fbe1SAndroid Build Coastguard Worker };
905*8222fbe1SAndroid Build Coastguard Worker 
906*8222fbe1SAndroid Build Coastguard Worker inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
907*8222fbe1SAndroid Build Coastguard Worker     return hidl_version(major,minor);
908*8222fbe1SAndroid Build Coastguard Worker }
909*8222fbe1SAndroid Build Coastguard Worker 
910*8222fbe1SAndroid Build Coastguard Worker ///////////////////// toString functions
911*8222fbe1SAndroid Build Coastguard Worker 
912*8222fbe1SAndroid Build Coastguard Worker std::string toString(const void *t);
913*8222fbe1SAndroid Build Coastguard Worker 
914*8222fbe1SAndroid Build Coastguard Worker // toString alias for numeric types
915*8222fbe1SAndroid Build Coastguard Worker template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
916*8222fbe1SAndroid Build Coastguard Worker inline std::string toString(T t) {
917*8222fbe1SAndroid Build Coastguard Worker     return std::to_string(t);
918*8222fbe1SAndroid Build Coastguard Worker }
919*8222fbe1SAndroid Build Coastguard Worker 
920*8222fbe1SAndroid Build Coastguard Worker namespace details {
921*8222fbe1SAndroid Build Coastguard Worker 
922*8222fbe1SAndroid Build Coastguard Worker template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
923*8222fbe1SAndroid Build Coastguard Worker inline std::string toHexString(T t, bool prefix = true) {
924*8222fbe1SAndroid Build Coastguard Worker     std::ostringstream os;
925*8222fbe1SAndroid Build Coastguard Worker     if (prefix) { os << std::showbase; }
926*8222fbe1SAndroid Build Coastguard Worker     os << std::hex << t;
927*8222fbe1SAndroid Build Coastguard Worker     return os.str();
928*8222fbe1SAndroid Build Coastguard Worker }
929*8222fbe1SAndroid Build Coastguard Worker 
930*8222fbe1SAndroid Build Coastguard Worker template<>
931*8222fbe1SAndroid Build Coastguard Worker inline std::string toHexString(uint8_t t, bool prefix) {
932*8222fbe1SAndroid Build Coastguard Worker     return toHexString(static_cast<int32_t>(t), prefix);
933*8222fbe1SAndroid Build Coastguard Worker }
934*8222fbe1SAndroid Build Coastguard Worker 
935*8222fbe1SAndroid Build Coastguard Worker template<>
936*8222fbe1SAndroid Build Coastguard Worker inline std::string toHexString(int8_t t, bool prefix) {
937*8222fbe1SAndroid Build Coastguard Worker     return toHexString(static_cast<int32_t>(t), prefix);
938*8222fbe1SAndroid Build Coastguard Worker }
939*8222fbe1SAndroid Build Coastguard Worker 
940*8222fbe1SAndroid Build Coastguard Worker template<typename Array>
941*8222fbe1SAndroid Build Coastguard Worker std::string arrayToString(const Array &a, size_t size);
942*8222fbe1SAndroid Build Coastguard Worker 
943*8222fbe1SAndroid Build Coastguard Worker template<size_t SIZE1>
944*8222fbe1SAndroid Build Coastguard Worker std::string arraySizeToString() {
945*8222fbe1SAndroid Build Coastguard Worker     return std::string{"["} + toString(SIZE1) + "]";
946*8222fbe1SAndroid Build Coastguard Worker }
947*8222fbe1SAndroid Build Coastguard Worker 
948*8222fbe1SAndroid Build Coastguard Worker template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
949*8222fbe1SAndroid Build Coastguard Worker std::string arraySizeToString() {
950*8222fbe1SAndroid Build Coastguard Worker     return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
951*8222fbe1SAndroid Build Coastguard Worker }
952*8222fbe1SAndroid Build Coastguard Worker 
953*8222fbe1SAndroid Build Coastguard Worker template<typename T, size_t SIZE1>
954*8222fbe1SAndroid Build Coastguard Worker std::string toString(details::const_accessor<T, SIZE1> a) {
955*8222fbe1SAndroid Build Coastguard Worker     return arrayToString(a, SIZE1);
956*8222fbe1SAndroid Build Coastguard Worker }
957*8222fbe1SAndroid Build Coastguard Worker 
958*8222fbe1SAndroid Build Coastguard Worker template<typename Array>
959*8222fbe1SAndroid Build Coastguard Worker std::string arrayToString(const Array &a, size_t size) {
960*8222fbe1SAndroid Build Coastguard Worker     using android::hardware::toString;
961*8222fbe1SAndroid Build Coastguard Worker     std::string os;
962*8222fbe1SAndroid Build Coastguard Worker     os += "{";
963*8222fbe1SAndroid Build Coastguard Worker     for (size_t i = 0; i < size; ++i) {
964*8222fbe1SAndroid Build Coastguard Worker         if (i > 0) {
965*8222fbe1SAndroid Build Coastguard Worker             os += ", ";
966*8222fbe1SAndroid Build Coastguard Worker         }
967*8222fbe1SAndroid Build Coastguard Worker         os += toString(a[i]);
968*8222fbe1SAndroid Build Coastguard Worker     }
969*8222fbe1SAndroid Build Coastguard Worker     os += "}";
970*8222fbe1SAndroid Build Coastguard Worker     return os;
971*8222fbe1SAndroid Build Coastguard Worker }
972*8222fbe1SAndroid Build Coastguard Worker 
973*8222fbe1SAndroid Build Coastguard Worker template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
974*8222fbe1SAndroid Build Coastguard Worker std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
975*8222fbe1SAndroid Build Coastguard Worker     return arrayToString(a, SIZE1);
976*8222fbe1SAndroid Build Coastguard Worker }
977*8222fbe1SAndroid Build Coastguard Worker 
978*8222fbe1SAndroid Build Coastguard Worker }  //namespace details
979*8222fbe1SAndroid Build Coastguard Worker 
980*8222fbe1SAndroid Build Coastguard Worker inline std::string toString(const void *t) {
981*8222fbe1SAndroid Build Coastguard Worker     return details::toHexString(reinterpret_cast<uintptr_t>(t));
982*8222fbe1SAndroid Build Coastguard Worker }
983*8222fbe1SAndroid Build Coastguard Worker 
984*8222fbe1SAndroid Build Coastguard Worker // debug string dump. There will be quotes around the string!
985*8222fbe1SAndroid Build Coastguard Worker inline std::string toString(const hidl_string &hs) {
986*8222fbe1SAndroid Build Coastguard Worker     return std::string{"\""} + hs.c_str() + "\"";
987*8222fbe1SAndroid Build Coastguard Worker }
988*8222fbe1SAndroid Build Coastguard Worker 
989*8222fbe1SAndroid Build Coastguard Worker // debug string dump
990*8222fbe1SAndroid Build Coastguard Worker inline std::string toString(const hidl_handle &hs) {
991*8222fbe1SAndroid Build Coastguard Worker     return toString(hs.getNativeHandle());
992*8222fbe1SAndroid Build Coastguard Worker }
993*8222fbe1SAndroid Build Coastguard Worker 
994*8222fbe1SAndroid Build Coastguard Worker inline std::string toString(const hidl_memory &mem) {
995*8222fbe1SAndroid Build Coastguard Worker     return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
996*8222fbe1SAndroid Build Coastguard Worker               + toString(mem.size())
997*8222fbe1SAndroid Build Coastguard Worker               + ", .handle = " + toString(mem.handle()) + "}";
998*8222fbe1SAndroid Build Coastguard Worker }
999*8222fbe1SAndroid Build Coastguard Worker 
1000*8222fbe1SAndroid Build Coastguard Worker inline std::string toString(const sp<hidl_death_recipient> &dr) {
1001*8222fbe1SAndroid Build Coastguard Worker     return std::string{"death_recipient@"} + toString(dr.get());
1002*8222fbe1SAndroid Build Coastguard Worker }
1003*8222fbe1SAndroid Build Coastguard Worker 
1004*8222fbe1SAndroid Build Coastguard Worker // debug string dump, assuming that toString(T) is defined.
1005*8222fbe1SAndroid Build Coastguard Worker template<typename T>
1006*8222fbe1SAndroid Build Coastguard Worker std::string toString(const hidl_vec<T> &a) {
1007*8222fbe1SAndroid Build Coastguard Worker     std::string os;
1008*8222fbe1SAndroid Build Coastguard Worker     os += "[" + toString(a.size()) + "]";
1009*8222fbe1SAndroid Build Coastguard Worker     os += details::arrayToString(a, a.size());
1010*8222fbe1SAndroid Build Coastguard Worker     return os;
1011*8222fbe1SAndroid Build Coastguard Worker }
1012*8222fbe1SAndroid Build Coastguard Worker 
1013*8222fbe1SAndroid Build Coastguard Worker template<typename T, size_t SIZE1>
1014*8222fbe1SAndroid Build Coastguard Worker std::string toString(const hidl_array<T, SIZE1> &a) {
1015*8222fbe1SAndroid Build Coastguard Worker     return details::arraySizeToString<SIZE1>()
1016*8222fbe1SAndroid Build Coastguard Worker             + details::toString(details::const_accessor<T, SIZE1>(a.data()));
1017*8222fbe1SAndroid Build Coastguard Worker }
1018*8222fbe1SAndroid Build Coastguard Worker 
1019*8222fbe1SAndroid Build Coastguard Worker template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
1020*8222fbe1SAndroid Build Coastguard Worker std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
1021*8222fbe1SAndroid Build Coastguard Worker     return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
1022*8222fbe1SAndroid Build Coastguard Worker             + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
1023*8222fbe1SAndroid Build Coastguard Worker }
1024*8222fbe1SAndroid Build Coastguard Worker 
1025*8222fbe1SAndroid Build Coastguard Worker namespace details {
1026*8222fbe1SAndroid Build Coastguard Worker // Never instantiated. Used as a placeholder for template variables.
1027*8222fbe1SAndroid Build Coastguard Worker template <typename T>
1028*8222fbe1SAndroid Build Coastguard Worker struct hidl_invalid_type;
1029*8222fbe1SAndroid Build Coastguard Worker 
1030*8222fbe1SAndroid Build Coastguard Worker // HIDL generates specializations of this for enums. See hidl_enum_range.
1031*8222fbe1SAndroid Build Coastguard Worker template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1032*8222fbe1SAndroid Build Coastguard Worker constexpr hidl_invalid_type<T> hidl_enum_values;
1033*8222fbe1SAndroid Build Coastguard Worker }  // namespace details
1034*8222fbe1SAndroid Build Coastguard Worker 
1035*8222fbe1SAndroid Build Coastguard Worker /**
1036*8222fbe1SAndroid Build Coastguard Worker  * Every HIDL generated enum supports this function.
1037*8222fbe1SAndroid Build Coastguard Worker  * E.x.: for(const auto v : hidl_enum_range<Enum>) { ... }
1038*8222fbe1SAndroid Build Coastguard Worker  */
1039*8222fbe1SAndroid Build Coastguard Worker template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1040*8222fbe1SAndroid Build Coastguard Worker struct hidl_enum_range {
1041*8222fbe1SAndroid Build Coastguard Worker     // Container-like associated type.
1042*8222fbe1SAndroid Build Coastguard Worker     using value_type = T;
1043*8222fbe1SAndroid Build Coastguard Worker 
1044*8222fbe1SAndroid Build Coastguard Worker     constexpr auto begin() const { return std::begin(details::hidl_enum_values<T>); }
1045*8222fbe1SAndroid Build Coastguard Worker     constexpr auto cbegin() const { return begin(); }
1046*8222fbe1SAndroid Build Coastguard Worker     constexpr auto rbegin() const { return std::rbegin(details::hidl_enum_values<T>); }
1047*8222fbe1SAndroid Build Coastguard Worker     constexpr auto crbegin() const { return rbegin(); }
1048*8222fbe1SAndroid Build Coastguard Worker     constexpr auto end() const { return std::end(details::hidl_enum_values<T>); }
1049*8222fbe1SAndroid Build Coastguard Worker     constexpr auto cend() const { return end(); }
1050*8222fbe1SAndroid Build Coastguard Worker     constexpr auto rend() const { return std::rend(details::hidl_enum_values<T>); }
1051*8222fbe1SAndroid Build Coastguard Worker     constexpr auto crend() const { return rend(); }
1052*8222fbe1SAndroid Build Coastguard Worker };
1053*8222fbe1SAndroid Build Coastguard Worker 
1054*8222fbe1SAndroid Build Coastguard Worker template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
1055*8222fbe1SAndroid Build Coastguard Worker struct hidl_enum_iterator {
1056*8222fbe1SAndroid Build Coastguard Worker     static_assert(!std::is_enum<T>::value,
1057*8222fbe1SAndroid Build Coastguard Worker                   "b/78573628: hidl_enum_iterator was renamed to hidl_enum_range because it is not "
1058*8222fbe1SAndroid Build Coastguard Worker                   "actually an iterator. Please use that type instead.");
1059*8222fbe1SAndroid Build Coastguard Worker };
1060*8222fbe1SAndroid Build Coastguard Worker 
1061*8222fbe1SAndroid Build Coastguard Worker /**
1062*8222fbe1SAndroid Build Coastguard Worker  * Bitfields in HIDL are the underlying type of the enumeration.
1063*8222fbe1SAndroid Build Coastguard Worker  */
1064*8222fbe1SAndroid Build Coastguard Worker template <typename Enum>
1065*8222fbe1SAndroid Build Coastguard Worker using hidl_bitfield = typename std::underlying_type<Enum>::type;
1066*8222fbe1SAndroid Build Coastguard Worker 
1067*8222fbe1SAndroid Build Coastguard Worker }  // namespace hardware
1068*8222fbe1SAndroid Build Coastguard Worker }  // namespace android
1069*8222fbe1SAndroid Build Coastguard Worker 
1070*8222fbe1SAndroid Build Coastguard Worker 
1071*8222fbe1SAndroid Build Coastguard Worker #endif  // ANDROID_HIDL_SUPPORT_H
1072