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