17211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen/*
27211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * Copyright (C) 2016 The Android Open Source Project
37211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen *
47211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * Licensed under the Apache License, Version 2.0 (the "License");
57211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * you may not use this file except in compliance with the License.
67211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * You may obtain a copy of the License at
77211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen *
87211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen *      http://www.apache.org/licenses/LICENSE-2.0
97211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen *
107211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * Unless required by applicable law or agreed to in writing, software
117211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * distributed under the License is distributed on an "AS IS" BASIS,
127211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * See the License for the specific language governing permissions and
147211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen * limitations under the License.
157211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen */
167211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
177211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen#ifndef ANDROID_HIDL_SUPPORT_H
187211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen#define ANDROID_HIDL_SUPPORT_H
197211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
20692070a68db8e587dda5a60c52f54133d2c4cc9cIliyan Malchev#include <algorithm>
2144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong#include <array>
22bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph#include <iterator>
234d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen#include <cutils/native_handle.h>
24337c3ae7f5ce6e94d6ccaaa7fb4ac92c4069b2ddSteven Moreland#include <hidl/HidlInternal.h>
25a3c3184067f679b9c62a6493a157aa51abae2defYifan Hong#include <hidl/Status.h>
261e265bb9ebafee77e82651c573d0e2847d6a5e6dYifan Hong#include <map>
27be7a6887b28a1240ba0d944126c3db631342256dYifan Hong#include <sstream>
2864fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong#include <stddef.h>
2900a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber#include <tuple>
3064fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong#include <type_traits>
31692070a68db8e587dda5a60c52f54133d2c4cc9cIliyan Malchev#include <utils/Errors.h>
32692070a68db8e587dda5a60c52f54133d2c4cc9cIliyan Malchev#include <utils/RefBase.h>
33692070a68db8e587dda5a60c52f54133d2c4cc9cIliyan Malchev#include <utils/StrongPointer.h>
347f97f44562b057c3c780c0a05c101b677f9b0f96Yifan Hong#include <vector>
357211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
367211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenennamespace android {
373079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
389b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// this file is included by all hidl interface, so we must forward declare the
399b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// IMemory and IBase types.
403079100878a2595be644d866e67c12a9de620fd5Martijn Coenennamespace hidl {
413079100878a2595be644d866e67c12a9de620fd5Martijn Coenennamespace memory {
423079100878a2595be644d866e67c12a9de620fd5Martijn Coenennamespace V1_0 {
433079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    struct IMemory;
443079100878a2595be644d866e67c12a9de620fd5Martijn Coenen}; // namespace V1_0
453079100878a2595be644d866e67c12a9de620fd5Martijn Coenen}; // namespace manager
463079100878a2595be644d866e67c12a9de620fd5Martijn Coenen}; // namespace hidl
473079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
489b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenennamespace hidl {
499b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenennamespace base {
509b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenennamespace V1_0 {
519b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen    struct IBase;
529b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen}; // namespace V1_0
539b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen}; // namespace base
549b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen}; // namespace hidl
559b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen
567211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenennamespace hardware {
577211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
5824332ef104a44b4bfb28c56ac2aa44584190e337Yifan Hongnamespace details {
5924332ef104a44b4bfb28c56ac2aa44584190e337Yifan Hong// Return true on userdebug / eng builds and false on user builds.
6024332ef104a44b4bfb28c56ac2aa44584190e337Yifan Hongbool debuggable();
6124332ef104a44b4bfb28c56ac2aa44584190e337Yifan Hong} //  namespace details
6224332ef104a44b4bfb28c56ac2aa44584190e337Yifan Hong
639b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// hidl_death_recipient is a callback interfaced that can be used with
649b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen// linkToDeath() / unlinkToDeath()
659b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenenstruct hidl_death_recipient : public virtual RefBase {
669b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen    virtual void serviceDied(uint64_t cookie,
679b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen            const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
689b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen};
699b8f9c38ea8ac1fe1fdf11ea219097885a5f2fa7Martijn Coenen
704d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen// hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
714d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen// so that it can safely be transferred between 32-bit and 64-bit processes.
7204b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen// The ownership semantics for this are:
7304b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen// 1) The conversion constructor and assignment operator taking a const native_handle_t*
7404b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    do not take ownership of the handle; this is because these operations are usually
7504b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    just done for IPC, and cloning by default is a waste of resources. If you want
7604b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/);
7704b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen// 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership;
7804b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    that is because it's not intuitive that this class encapsulates a native_handle_t
7904b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    which needs cloning to be valid; in particular, this allows constructs like this:
8004b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    hidl_handle copy;
8104b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    foo->someHidlCall([&](auto incoming_handle) {
8204b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//            copy = incoming_handle;
8304b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    });
8404b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    // copy and its enclosed file descriptors will remain valid here.
8504b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen// 3) The move constructor does what you would expect; it only owns the handle if the
8604b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen//    original did.
874d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenenstruct hidl_handle {
8804b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_handle();
8904b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    ~hidl_handle();
904d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
9104b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_handle(const native_handle_t *handle);
924d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
9304b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    // copy constructor.
9404b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_handle(const hidl_handle &other);
954d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
964d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen    // move constructor.
97e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_handle(hidl_handle &&other) noexcept;
984d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
996ffdc2a87c22f6941705d7fef1fa260f5be494f0Steven Moreland    // assignment operators
10004b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_handle &operator=(const hidl_handle &other);
1014d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
10204b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_handle &operator=(const native_handle_t *native_handle);
1034d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
104e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_handle &operator=(hidl_handle &&other) noexcept;
10504b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen
10604b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    void setTo(native_handle_t* handle, bool shouldOwn = false);
10704b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen
10804b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    const native_handle_t* operator->() const;
1094d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
1104d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen    // implicit conversion to const native_handle_t*
11104b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    operator const native_handle_t *() const;
11204b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen
1134d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen    // explicit conversion
11404b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    const native_handle_t *getNativeHandle() const;
1154d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenenprivate:
11604b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    void freeHandle();
11704b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen
1186688d60a53e605fe8a3cc663e415a1f938009fcaAndreas Huber    details::hidl_pointer<const native_handle_t> mHandle __attribute__ ((aligned(8)));
1196688d60a53e605fe8a3cc663e415a1f938009fcaAndreas Huber    bool mOwnsHandle __attribute ((aligned(8)));
1204d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen};
1214d1e9cccc1762eaa7613981d8d7953cb47054750Martijn Coenen
1227211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenenstruct hidl_string {
1237211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    hidl_string();
1247211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    ~hidl_string();
1257211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
126602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy constructor.
1277211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    hidl_string(const hidl_string &);
128a21d84f11f066315bd1476368d511286d129cb8aSteven Moreland    // copy from a C-style string. nullptr will create an empty string
129e03c08722dc4602cb501cf54692f1fce2a6f4758Steven Moreland    hidl_string(const char *);
13053120f70b7d429c81fe47718182e829660ed5ef9Steven Moreland    // copy the first length characters from a C-style string.
13153120f70b7d429c81fe47718182e829660ed5ef9Steven Moreland    hidl_string(const char *, size_t length);
132602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy from an std::string.
133602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    hidl_string(const std::string &);
134602b85a846834d466e1f545eace06df87cf94a1eYifan Hong
135602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // move constructor.
136e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_string(hidl_string &&) noexcept;
1377211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
1387211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    const char *c_str() const;
1397211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    size_t size() const;
1407211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    bool empty() const;
1417211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
142602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy assignment operator.
143e03c08722dc4602cb501cf54692f1fce2a6f4758Steven Moreland    hidl_string &operator=(const hidl_string &);
144602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy from a C-style string.
1457211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    hidl_string &operator=(const char *s);
146602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy from an std::string.
147602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    hidl_string &operator=(const std::string &);
148602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // move assignment operator.
149e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_string &operator=(hidl_string &&other) noexcept;
150602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // cast to std::string.
151602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    operator std::string() const;
152e03c08722dc4602cb501cf54692f1fce2a6f4758Steven Moreland
1537211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    void clear();
1547211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
1557211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    // Reference an external char array. Ownership is _not_ transferred.
1567211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    // Caller is responsible for ensuring that underlying memory is valid
1577211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    // for the lifetime of this hidl_string.
1587211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    void setToExternal(const char *data, size_t size);
1597211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
160ebfeb36df865d690264cdf677325f27e8822c46aAndreas Huber    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
161ebfeb36df865d690264cdf677325f27e8822c46aAndreas Huber    static const size_t kOffsetOfBuffer;
162ebfeb36df865d690264cdf677325f27e8822c46aAndreas Huber
1637211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenenprivate:
1644ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen    details::hidl_pointer<const char> mBuffer;
1654ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen    uint32_t mSize;  // NOT including the terminating '\0'.
166602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    bool mOwnsBuffer; // if true then mBuffer is a mutable char *
1677211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
168602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy from data with size. Assume that my memory is freed
169602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // (through clear(), for example)
170602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    void copyFrom(const char *data, size_t size);
171602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // move from another hidl_string
172602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    void moveFrom(hidl_string &&);
1737211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen};
1747211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
175551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland#define HIDL_STRING_OPERATOR(OP)                                               \
176551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland    inline bool operator OP(const hidl_string &hs1, const hidl_string &hs2) {  \
177551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland        return strcmp(hs1.c_str(), hs2.c_str()) OP 0;                          \
178551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland    }                                                                          \
179551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland    inline bool operator OP(const hidl_string &hs, const char *s) {            \
180551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland        return strcmp(hs.c_str(), s) OP 0;                                     \
181551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland    }                                                                          \
182551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland    inline bool operator OP(const char *s, const hidl_string &hs) {            \
183551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland        return strcmp(hs.c_str(), s) OP 0;                                     \
184551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland    }
1855708fb4e117f06f8b867eb623d73fd3e5d969155Yifan Hong
186551396afe50bb40b046e9f16b4501e6df055c88aSteven MorelandHIDL_STRING_OPERATOR(==)
187551396afe50bb40b046e9f16b4501e6df055c88aSteven MorelandHIDL_STRING_OPERATOR(!=)
188551396afe50bb40b046e9f16b4501e6df055c88aSteven MorelandHIDL_STRING_OPERATOR(<)
189551396afe50bb40b046e9f16b4501e6df055c88aSteven MorelandHIDL_STRING_OPERATOR(<=)
190551396afe50bb40b046e9f16b4501e6df055c88aSteven MorelandHIDL_STRING_OPERATOR(>)
191551396afe50bb40b046e9f16b4501e6df055c88aSteven MorelandHIDL_STRING_OPERATOR(>=)
1925708fb4e117f06f8b867eb623d73fd3e5d969155Yifan Hong
193551396afe50bb40b046e9f16b4501e6df055c88aSteven Moreland#undef HIDL_STRING_OPERATOR
1945708fb4e117f06f8b867eb623d73fd3e5d969155Yifan Hong
1950c84ab4192f9b0b03b9840b85fc430afa17f55f1Scott Randolph// Send our content to the output stream
1960c84ab4192f9b0b03b9840b85fc430afa17f55f1Scott Randolphstd::ostream& operator<<(std::ostream& os, const hidl_string& str);
1970c84ab4192f9b0b03b9840b85fc430afa17f55f1Scott Randolph
1980c84ab4192f9b0b03b9840b85fc430afa17f55f1Scott Randolph
1993079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// hidl_memory is a structure that can be used to transfer
2003079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// pieces of shared memory between processes. The assumption
2013079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// of this object is that the memory remains accessible as
2023079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// long as the file descriptors in the enclosed mHandle
2033079100878a2595be644d866e67c12a9de620fd5Martijn Coenen// - as well as all of its cross-process dups() - remain opened.
2043079100878a2595be644d866e67c12a9de620fd5Martijn Coenenstruct hidl_memory {
2053079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
20604b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
2073079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2083079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2093079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    /**
21004b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen     * Creates a hidl_memory object, but doesn't take ownership of
21104b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen     * the passed in native_handle_t; callers are responsible for
21204b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen     * making sure the handle remains valid while this object is
21304b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen     * used.
2143079100878a2595be644d866e67c12a9de620fd5Martijn Coenen     */
21504b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen    hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
21604b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen      :  mHandle(handle),
2173079100878a2595be644d866e67c12a9de620fd5Martijn Coenen         mSize(size),
2183079100878a2595be644d866e67c12a9de620fd5Martijn Coenen         mName(name)
2193079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    {}
2203079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2213079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    // copy constructor
2223079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    hidl_memory(const hidl_memory& other) {
2233079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        *this = other;
2243079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2253079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2263079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    // copy assignment
2273079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    hidl_memory &operator=(const hidl_memory &other) {
2283079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        if (this != &other) {
22904b91c0fa5d2ccfe92816791064c30a25cbef0beMartijn Coenen            mHandle = other.mHandle;
2303079100878a2595be644d866e67c12a9de620fd5Martijn Coenen            mSize = other.mSize;
2313079100878a2595be644d866e67c12a9de620fd5Martijn Coenen            mName = other.mName;
2323079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        }
2333079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2343079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        return *this;
2353079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2363079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2370126889103d84c2078896688017d61d612a12c4fHridya Valsaraju    // move constructor
238e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_memory(hidl_memory&& other) noexcept {
2390126889103d84c2078896688017d61d612a12c4fHridya Valsaraju        *this = std::move(other);
2400126889103d84c2078896688017d61d612a12c4fHridya Valsaraju    }
2410126889103d84c2078896688017d61d612a12c4fHridya Valsaraju
2420126889103d84c2078896688017d61d612a12c4fHridya Valsaraju    // move assignment
243e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_memory &operator=(hidl_memory &&other) noexcept {
2440126889103d84c2078896688017d61d612a12c4fHridya Valsaraju        if (this != &other) {
2450126889103d84c2078896688017d61d612a12c4fHridya Valsaraju            mHandle = std::move(other.mHandle);
2460126889103d84c2078896688017d61d612a12c4fHridya Valsaraju            mSize = other.mSize;
2470126889103d84c2078896688017d61d612a12c4fHridya Valsaraju            mName = std::move(other.mName);
2480126889103d84c2078896688017d61d612a12c4fHridya Valsaraju            other.mSize = 0;
2490126889103d84c2078896688017d61d612a12c4fHridya Valsaraju        }
2500126889103d84c2078896688017d61d612a12c4fHridya Valsaraju
2510126889103d84c2078896688017d61d612a12c4fHridya Valsaraju        return *this;
2520126889103d84c2078896688017d61d612a12c4fHridya Valsaraju    }
2530126889103d84c2078896688017d61d612a12c4fHridya Valsaraju
2543079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2553079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    ~hidl_memory() {
2563079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2573079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2583079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    const native_handle_t* handle() const {
2593079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        return mHandle;
2603079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2613079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2623079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    const hidl_string &name() const {
2633079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        return mName;
2643079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2653079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2666d4acb12519597610322097f86850d9e404d251aHridya Valsaraju    uint64_t size() const {
2673079100878a2595be644d866e67c12a9de620fd5Martijn Coenen        return mSize;
2683079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    }
2693079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
2703079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
2713079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    static const size_t kOffsetOfHandle;
2723079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    // offsetof(hidl_memory, mName) exposed since mHandle is private.
2733079100878a2595be644d866e67c12a9de620fd5Martijn Coenen    static const size_t kOffsetOfName;
2740f3461db91b75d9acd7e0bec8b1e97cbb3bafdf7Jeff Tinker
2753079100878a2595be644d866e67c12a9de620fd5Martijn Coenenprivate:
2766d4acb12519597610322097f86850d9e404d251aHridya Valsaraju    hidl_handle mHandle __attribute__ ((aligned(8)));
2776d4acb12519597610322097f86850d9e404d251aHridya Valsaraju    uint64_t mSize __attribute__ ((aligned(8)));
2786d4acb12519597610322097f86850d9e404d251aHridya Valsaraju    hidl_string mName __attribute__ ((aligned(8)));
2793079100878a2595be644d866e67c12a9de620fd5Martijn Coenen};
2803079100878a2595be644d866e67c12a9de620fd5Martijn Coenen
28120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber////////////////////////////////////////////////////////////////////////////////
28220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
2837211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenentemplate<typename T>
284b7370304cbf33a6ff53ec3955cda0bf18920df48Hridya Valsarajustruct hidl_vec {
2857211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    hidl_vec()
2867211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        : mBuffer(NULL),
2877211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen          mSize(0),
2887211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen          mOwnsBuffer(true) {
2896d4acb12519597610322097f86850d9e404d251aHridya Valsaraju        static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
2907211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
2917211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
292602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
2937211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        *this = other;
2947211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
2957211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
296e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_vec(hidl_vec<T> &&other) noexcept
2979fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland    : mOwnsBuffer(false) {
298d3ddf6221c317e39a540a51f504c55009e7bdddaJanis Danisevskis        *this = std::move(other);
2990ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov    }
3000ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov
301b69926a728aa472be47f51dc5fc374571d7da5a8Steven Moreland    hidl_vec(const std::initializer_list<T> list)
302ca1d1bf76f0e38cbe8d301a761b1c428f83bf853Yifan Hong            : mOwnsBuffer(true) {
303ca1d1bf76f0e38cbe8d301a761b1c428f83bf853Yifan Hong        if (list.size() > UINT32_MAX) {
304b7370304cbf33a6ff53ec3955cda0bf18920df48Hridya Valsaraju            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
305ca1d1bf76f0e38cbe8d301a761b1c428f83bf853Yifan Hong        }
306ca1d1bf76f0e38cbe8d301a761b1c428f83bf853Yifan Hong        mSize = static_cast<uint32_t>(list.size());
3079fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland        mBuffer = new T[mSize];
3089fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland
309b69926a728aa472be47f51dc5fc374571d7da5a8Steven Moreland        size_t idx = 0;
3109fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland        for (auto it = list.begin(); it != list.end(); ++it) {
3119fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland            mBuffer[idx++] = *it;
3129fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland        }
3139fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland    }
3149fbfe475d933ecd29c9c2af7e35e9b13fbdf905dSteven Moreland
315602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    hidl_vec(const std::vector<T> &other) : hidl_vec() {
316602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        *this = other;
317602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    }
318602b85a846834d466e1f545eace06df87cf94a1eYifan Hong
3197211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    ~hidl_vec() {
3207211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        if (mOwnsBuffer) {
3217211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen            delete[] mBuffer;
3227211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        }
3237211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        mBuffer = NULL;
3247211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
3257211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
326e229901631d27c2be50ee6988c2e0f4d1ba9fae5Alexey Polyudov    // Reference an existing array, optionally taking ownership. It is the
3277211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    // caller's responsibility to ensure that the underlying memory stays
3287211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    // valid for the lifetime of this hidl_vec.
329e229901631d27c2be50ee6988c2e0f4d1ba9fae5Alexey Polyudov    void setToExternal(T *data, size_t size, bool shouldOwn = false) {
3307211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        if (mOwnsBuffer) {
3317211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen            delete [] mBuffer;
3327211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        }
3337211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        mBuffer = data;
3344ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        if (size > UINT32_MAX) {
335b7370304cbf33a6ff53ec3955cda0bf18920df48Hridya Valsaraju            details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
3364ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        }
3374ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        mSize = static_cast<uint32_t>(size);
338e229901631d27c2be50ee6988c2e0f4d1ba9fae5Alexey Polyudov        mOwnsBuffer = shouldOwn;
3397211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
3407211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
3416f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov    T *data() {
3426f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov        return mBuffer;
3436f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov    }
3446f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov
3456f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov    const T *data() const {
3466f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov        return mBuffer;
3476f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov    }
3486f0c9a168ea05c0a2ee7efb24fa790e2f216211cAlexey Polyudov
349c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov    T *releaseData() {
350c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov        if (!mOwnsBuffer && mSize > 0) {
351c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov            resize(mSize);
352c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov        }
353c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov        mOwnsBuffer = false;
354c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov        return mBuffer;
355c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov    }
356c98a99c318a79ddebaae690309e98282f08922e1Alexey Polyudov
357e8c36e1e36f26cbf1bb26a86bcf59c1fedbfab56Martijn Coenen    hidl_vec &operator=(hidl_vec &&other) noexcept {
358d3ddf6221c317e39a540a51f504c55009e7bdddaJanis Danisevskis        if (mOwnsBuffer) {
359d3ddf6221c317e39a540a51f504c55009e7bdddaJanis Danisevskis            delete[] mBuffer;
360d3ddf6221c317e39a540a51f504c55009e7bdddaJanis Danisevskis        }
3610ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov        mBuffer = other.mBuffer;
3620ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov        mSize = other.mSize;
3630ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov        mOwnsBuffer = other.mOwnsBuffer;
3640ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov        other.mOwnsBuffer = false;
3650ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov        return *this;
3660ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov    }
3670ebdbe839df139b270cf462a67f00343d9a2fbd6Alexey Polyudov
3687211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    hidl_vec &operator=(const hidl_vec &other) {
3697211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        if (this != &other) {
3707211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen            if (mOwnsBuffer) {
3717211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen                delete[] mBuffer;
3727211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen            }
373602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            copyFrom(other, other.mSize);
3747211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        }
3757211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
3767211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        return *this;
3777211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
3787211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
379602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy from an std::vector.
380602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    hidl_vec &operator=(const std::vector<T> &other) {
381602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        if (mOwnsBuffer) {
382602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            delete[] mBuffer;
383602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        }
384602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        copyFrom(other, other.size());
385602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        return *this;
386602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    }
387602b85a846834d466e1f545eace06df87cf94a1eYifan Hong
388602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // cast to an std::vector.
389602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    operator std::vector<T>() const {
390602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        std::vector<T> v(mSize);
391602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        for (size_t i = 0; i < mSize; ++i) {
392602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            v[i] = mBuffer[i];
393602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        }
394602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        return v;
395602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    }
396602b85a846834d466e1f545eace06df87cf94a1eYifan Hong
3979fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    // equality check, assuming that T::operator== is defined.
3989fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    bool operator==(const hidl_vec &other) const {
3999fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        if (mSize != other.size()) {
4009fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            return false;
4019fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        }
4029fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        for (size_t i = 0; i < mSize; ++i) {
4039fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            if (!(mBuffer[i] == other.mBuffer[i])) {
4049fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong                return false;
4059fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            }
4069fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        }
4079fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        return true;
4089fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    }
4099fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong
4109fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    // inequality check, assuming that T::operator== is defined.
4119fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    inline bool operator!=(const hidl_vec &other) const {
4129fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        return !((*this) == other);
4139fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    }
4149fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong
4157211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    size_t size() const {
4167211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        return mSize;
4177211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
4187211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
4197211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    T &operator[](size_t index) {
4207211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        return mBuffer[index];
4217211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
4227211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
4237211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    const T &operator[](size_t index) const {
4247211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        return mBuffer[index];
4257211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
4267211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
4277211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    void resize(size_t size) {
4284ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        if (size > UINT32_MAX) {
429b7370304cbf33a6ff53ec3955cda0bf18920df48Hridya Valsaraju            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
4304ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        }
4317211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        T *newBuffer = new T[size];
4327211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
4334ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
4347211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen            newBuffer[i] = mBuffer[i];
4357211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        }
4367211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
4377211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        if (mOwnsBuffer) {
4387211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen            delete[] mBuffer;
4397211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        }
4407211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        mBuffer = newBuffer;
4417211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
4424ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen        mSize = static_cast<uint32_t>(size);
4437211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        mOwnsBuffer = true;
4447211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
4457211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
446089ae13d36aab7e29ccf193f541aba3b2a0aaf32Yifan Hong    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
447089ae13d36aab7e29ccf193f541aba3b2a0aaf32Yifan Hong    static const size_t kOffsetOfBuffer;
448bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph
44964fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hongprivate:
450bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    // Define std interator interface for walking the array contents
45164fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong    template<bool is_const>
45264fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong    class iter : public std::iterator<
45364fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong            std::random_access_iterator_tag, /* Category */
45464fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong            T,
45564fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong            ptrdiff_t, /* Distance */
45664fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong            typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
45764fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong            typename std::conditional<is_const, const T &, T &>::type /* Reference */>
458bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    {
45964fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        using traits = std::iterator_traits<iter>;
46064fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        using ptr_type = typename traits::pointer;
46164fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        using ref_type = typename traits::reference;
46264fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        using diff_type = typename traits::difference_type;
463bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    public:
46464fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        iter(ptr_type ptr) : mPtr(ptr) { }
46564fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter &operator++()    { mPtr++; return *this; }
46664fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
46764fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter &operator--()    { mPtr--; return *this; }
46864fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
46964fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
47064fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter  operator+(diff_type n) const { return mPtr + n; }
47164fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter  operator-(diff_type n) const { return mPtr - n; }
47264fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
47364fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
47464fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
47564fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline ref_type operator*() const  { return *mPtr; }
47664fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline ptr_type operator->() const { return mPtr; }
47764fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
47864fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
47964fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
48064fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
48164fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
48264fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
48364fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        inline ref_type operator[](size_t n) const { return mPtr[n]; }
484bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    private:
48564fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong        ptr_type mPtr;
486bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    };
48764fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hongpublic:
48864fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong    using iterator       = iter<false /* is_const */>;
48964fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong    using const_iterator = iter<true  /* is_const */>;
49064fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong
491bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    iterator begin() { return data(); }
492bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph    iterator end() { return data()+mSize; }
49364fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong    const_iterator begin() const { return data(); }
49464fdf4d1bdea86202c7526482d4d329724d33dcbYifan Hong    const_iterator end() const { return data()+mSize; }
495bb840f73dc33c5de153cc6959672cf05c55ae4e6Scott Randolph
4967211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenenprivate:
4974ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen    details::hidl_pointer<T> mBuffer;
4984ca39a01032d2ac2658335bb5e0d5196779d767bMartijn Coenen    uint32_t mSize;
4997211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    bool mOwnsBuffer;
500602b85a846834d466e1f545eace06df87cf94a1eYifan Hong
501602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    // copy from an array-like object, assuming my resources are freed.
502602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    template <typename Array>
503602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    void copyFrom(const Array &data, size_t size) {
5044b48edc21b333247a4b48cb12b82ab413040521aChia-I Wu        mSize = static_cast<uint32_t>(size);
505602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        mOwnsBuffer = true;
506602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        if (mSize > 0) {
507602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            mBuffer = new T[size];
508602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            for (size_t i = 0; i < size; ++i) {
509602b85a846834d466e1f545eace06df87cf94a1eYifan Hong                mBuffer[i] = data[i];
510602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            }
511602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        } else {
512602b85a846834d466e1f545eace06df87cf94a1eYifan Hong            mBuffer = NULL;
513602b85a846834d466e1f545eace06df87cf94a1eYifan Hong        }
514602b85a846834d466e1f545eace06df87cf94a1eYifan Hong    }
5157211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen};
5167211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
517089ae13d36aab7e29ccf193f541aba3b2a0aaf32Yifan Hongtemplate <typename T>
518089ae13d36aab7e29ccf193f541aba3b2a0aaf32Yifan Hongconst size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
519089ae13d36aab7e29ccf193f541aba3b2a0aaf32Yifan Hong
52020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber////////////////////////////////////////////////////////////////////////////////
52120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
52220dce0887813c368ac5b1a3e311cdecad3800163Andreas Hubernamespace details {
52320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
52420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    template<size_t SIZE1, size_t... SIZES>
52520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    struct product {
52620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        static constexpr size_t value = SIZE1 * product<SIZES...>::value;
52720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    };
52820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
52920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    template<size_t SIZE1>
53020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    struct product<SIZE1> {
53120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        static constexpr size_t value = SIZE1;
53220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    };
53320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
53420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    template<typename T, size_t SIZE1, size_t... SIZES>
53544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    struct std_array {
53644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
53744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    };
53844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
53944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    template<typename T, size_t SIZE1>
54044ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    struct std_array<T, SIZE1> {
54144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        using type = std::array<T, SIZE1>;
54244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    };
54344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
54444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    template<typename T, size_t SIZE1, size_t... SIZES>
54520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    struct accessor {
54644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
54744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
54844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
54920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        explicit accessor(T *base)
55020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            : mBase(base) {
55120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
55220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
55320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        accessor<T, SIZES...> operator[](size_t index) {
55420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            return accessor<T, SIZES...>(
55520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber                    &mBase[index * product<SIZES...>::value]);
55620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
55720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
55844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        accessor &operator=(const std_array_type &other) {
55944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            for (size_t i = 0; i < SIZE1; ++i) {
56044ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong                (*this)[i] = other[i];
56144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            }
56244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            return *this;
56344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
56444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
56520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    private:
56620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        T *mBase;
56720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    };
56820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
56920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    template<typename T, size_t SIZE1>
57020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    struct accessor<T, SIZE1> {
57144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
57244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        using std_array_type = typename std_array<T, SIZE1>::type;
57344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
57420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        explicit accessor(T *base)
57520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            : mBase(base) {
57620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
57720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
57820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        T &operator[](size_t index) {
57920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            return mBase[index];
58020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
58120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
58244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        accessor &operator=(const std_array_type &other) {
58344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            for (size_t i = 0; i < SIZE1; ++i) {
58444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong                (*this)[i] = other[i];
58544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            }
58644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            return *this;
58744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
58844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
58920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    private:
59020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        T *mBase;
59120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    };
59220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
59320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    template<typename T, size_t SIZE1, size_t... SIZES>
59420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    struct const_accessor {
59544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
59644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;
59744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
59820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        explicit const_accessor(const T *base)
59920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            : mBase(base) {
60020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
60120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
602be7a6887b28a1240ba0d944126c3db631342256dYifan Hong        const_accessor<T, SIZES...> operator[](size_t index) const {
60320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            return const_accessor<T, SIZES...>(
60420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber                    &mBase[index * product<SIZES...>::value]);
60520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
60620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
60744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        operator std_array_type() {
60844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            std_array_type array;
60944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            for (size_t i = 0; i < SIZE1; ++i) {
61044ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong                array[i] = (*this)[i];
61144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            }
61244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            return array;
61344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
61444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
61520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    private:
61620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        const T *mBase;
61720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    };
61820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
61920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    template<typename T, size_t SIZE1>
62020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    struct const_accessor<T, SIZE1> {
62144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
62244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        using std_array_type = typename std_array<T, SIZE1>::type;
62344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
62420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        explicit const_accessor(const T *base)
62520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            : mBase(base) {
62620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
62720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
62820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        const T &operator[](size_t index) const {
62920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber            return mBase[index];
63020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        }
63120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
63244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        operator std_array_type() {
63344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            std_array_type array;
63444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            for (size_t i = 0; i < SIZE1; ++i) {
63544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong                array[i] = (*this)[i];
63644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            }
63744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            return array;
63844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
63944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
64020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    private:
64120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        const T *mBase;
64220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    };
64320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
64420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber}  // namespace details
64520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
64620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber////////////////////////////////////////////////////////////////////////////////
64720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
64844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong// A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
64920dce0887813c368ac5b1a3e311cdecad3800163Andreas Hubertemplate<typename T, size_t SIZE1, size_t... SIZES>
65020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huberstruct hidl_array {
65144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
65244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
65344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
65420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    hidl_array() = default;
65520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
65644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    // Copies the data from source, using T::operator=(const T &).
65744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    hidl_array(const T *source) {
65844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        for (size_t i = 0; i < elementCount(); ++i) {
65944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            mBuffer[i] = source[i];
66044ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
66144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    }
66244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
66344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    // Copies the data from the given std::array, using T::operator=(const T &).
66444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    hidl_array(const std_array_type &array) {
66544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
66644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        modifier = array;
66744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    }
66844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
66920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    T *data() { return mBuffer; }
67020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    const T *data() const { return mBuffer; }
67120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
67220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    details::accessor<T, SIZES...> operator[](size_t index) {
67320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        return details::accessor<T, SIZES...>(
67420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber                &mBuffer[index * details::product<SIZES...>::value]);
67520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    }
67620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
67720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    details::const_accessor<T, SIZES...> operator[](size_t index) const {
67820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        return details::const_accessor<T, SIZES...>(
67920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber                &mBuffer[index * details::product<SIZES...>::value]);
68020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    }
68120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
6829fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    // equality check, assuming that T::operator== is defined.
6839fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    bool operator==(const hidl_array &other) const {
6849fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        for (size_t i = 0; i < elementCount(); ++i) {
6859fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            if (!(mBuffer[i] == other.mBuffer[i])) {
6869fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong                return false;
6879fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            }
6889fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        }
6899fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        return true;
6909fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    }
6919fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong
6929fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    inline bool operator!=(const hidl_array &other) const {
6939fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        return !((*this) == other);
6949fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    }
6959fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong
69600a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber    using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;
69700a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber
69800a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber    static constexpr size_tuple_type size() {
69900a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber        return std::make_tuple(SIZE1, SIZES...);
70000a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber    }
70100a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber
70244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    static constexpr size_t elementCount() {
70344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        return details::product<SIZE1, SIZES...>::value;
70444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    }
70544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
70644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    operator std_array_type() const {
70744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
70844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    }
70944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
71020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huberprivate:
71144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    T mBuffer[elementCount()];
71220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber};
71320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
71444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong// An array of T's. Assumes that T::operator=(const T &) is defined.
71520dce0887813c368ac5b1a3e311cdecad3800163Andreas Hubertemplate<typename T, size_t SIZE1>
71620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huberstruct hidl_array<T, SIZE1> {
71744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
71844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    using std_array_type = typename details::std_array<T, SIZE1>::type;
71944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
72020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    hidl_array() = default;
72144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
72244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    // Copies the data from source, using T::operator=(const T &).
7233da68488e12ae8d487f43700582b775a4cdb6ec1Sasha Levitskiy    hidl_array(const T *source) {
72444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        for (size_t i = 0; i < elementCount(); ++i) {
72544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            mBuffer[i] = source[i];
72644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
7273da68488e12ae8d487f43700582b775a4cdb6ec1Sasha Levitskiy    }
72820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
72944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    // Copies the data from the given std::array, using T::operator=(const T &).
73044ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
73144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
73220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    T *data() { return mBuffer; }
73320dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    const T *data() const { return mBuffer; }
73420dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
73520dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    T &operator[](size_t index) {
73620dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        return mBuffer[index];
73720dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    }
73820dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
73920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    const T &operator[](size_t index) const {
74020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber        return mBuffer[index];
74120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    }
74220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
7439fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    // equality check, assuming that T::operator== is defined.
7449fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    bool operator==(const hidl_array &other) const {
7459fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        for (size_t i = 0; i < elementCount(); ++i) {
7469fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            if (!(mBuffer[i] == other.mBuffer[i])) {
7479fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong                return false;
7489fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong            }
7499fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        }
7509fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        return true;
7519fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    }
7529fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong
7539fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    inline bool operator!=(const hidl_array &other) const {
7549fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong        return !((*this) == other);
7559fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong    }
7569fcbb36250a4392b12012cf5177c4669ef10e654Yifan Hong
75700a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber    static constexpr size_t size() { return SIZE1; }
75844ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    static constexpr size_t elementCount() { return SIZE1; }
75944ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong
76044ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    // Copies the data to an std::array, using T::operator=(T).
76144ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    operator std_array_type() const {
76244ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        std_array_type array;
76344ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        for (size_t i = 0; i < SIZE1; ++i) {
76444ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong            array[i] = mBuffer[i];
76544ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        }
76644ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong        return array;
76744ab623ccf386f0e470bdc6aa22f261b7dc047cdYifan Hong    }
76800a985c1a87505aae5cdffcf455c6dcc884c3036Andreas Huber
76920dce0887813c368ac5b1a3e311cdecad3800163Andreas Huberprivate:
77020dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber    T mBuffer[SIZE1];
77120dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber};
77220dce0887813c368ac5b1a3e311cdecad3800163Andreas Huber
7737211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen// ----------------------------------------------------------------------
7747211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen// Version functions
7757211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenenstruct hidl_version {
7767211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenenpublic:
777666b76bf8411c7d085068a373b1dcc2a681fab3cChia-I Wu    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
7787211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
7795d5ef7fcf17889a078212fbe75ac15d72a56586cSteven Moreland    bool operator==(const hidl_version& other) const {
7807211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen        return (mMajor == other.get_major() && mMinor == other.get_minor());
7817211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    }
782c28f115754c2ba0ee036bab355b9013d466f2816Martijn Coenen
78319f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    bool operator<(const hidl_version& other) const {
78419f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala        return (mMajor < other.get_major() ||
78519f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala                (mMajor == other.get_major() && mMinor < other.get_minor()));
78619f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    }
78719f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala
78819f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    bool operator>(const hidl_version& other) const {
78919f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala        return other < *this;
79019f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    }
79119f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala
79219f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    bool operator<=(const hidl_version& other) const {
79319f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala        return !(*this > other);
79419f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    }
79519f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala
79619f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    bool operator>=(const hidl_version& other) const {
79719f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala        return !(*this < other);
79819f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala    }
79919f4db58674560ebe6b85dad77af0155a3dddecfEino-Ville Talvala
800097a767ec6001f1a4c68efc5d83c12d0ce6d1fa9Martijn Coenen    constexpr uint16_t get_major() const { return mMajor; }
801097a767ec6001f1a4c68efc5d83c12d0ce6d1fa9Martijn Coenen    constexpr uint16_t get_minor() const { return mMinor; }
8027211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
8037211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenenprivate:
8047211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    uint16_t mMajor;
8057211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    uint16_t mMinor;
8067211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen};
8077211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
8087211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coeneninline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
8097211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen    return hidl_version(major,minor);
8107211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen}
8117211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
812be7a6887b28a1240ba0d944126c3db631342256dYifan Hong///////////////////// toString functions
813be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
8144ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string toString(const void *t);
815be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
816be7a6887b28a1240ba0d944126c3db631342256dYifan Hong// toString alias for numeric types
817be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
818be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toString(T t) {
819be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return std::to_string(t);
820be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
821be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
8224ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajunamespace details {
8234ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
824be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
825be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toHexString(T t, bool prefix = true) {
826be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    std::ostringstream os;
827be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    if (prefix) { os << std::showbase; }
828be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    os << std::hex << t;
829be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return os.str();
830be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
831be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
832be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<>
833be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toHexString(uint8_t t, bool prefix) {
834be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return toHexString(static_cast<int32_t>(t), prefix);
835be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
836be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
837be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<>
838be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toHexString(int8_t t, bool prefix) {
839be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return toHexString(static_cast<int32_t>(t), prefix);
840be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
841be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
8424ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajutemplate<typename Array>
8434ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string arrayToString(const Array &a, size_t size);
8444ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8454ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajutemplate<size_t SIZE1>
8464ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string arraySizeToString() {
8474ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return std::string{"["} + toString(SIZE1) + "]";
8484ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju}
8494ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8504ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajutemplate<size_t SIZE1, size_t SIZE2, size_t... SIZES>
8514ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string arraySizeToString() {
8524ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
8534ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju}
8544ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8554ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajutemplate<typename T, size_t SIZE1>
8564ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string toString(details::const_accessor<T, SIZE1> a) {
8574ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return arrayToString(a, SIZE1);
8584ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju}
8594ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8604ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajutemplate<typename Array>
8614ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string arrayToString(const Array &a, size_t size) {
8624ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    using android::hardware::toString;
8634ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    std::string os;
8644ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    os += "{";
8654ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    for (size_t i = 0; i < size; ++i) {
8664ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju        if (i > 0) {
8674ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju            os += ", ";
8684ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju        }
8694ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju        os += toString(a[i]);
8704ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    }
8714ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    os += "}";
8724ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return os;
8734ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju}
8744ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8754ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajutemplate<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
8764ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajustd::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
8774ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return arrayToString(a, SIZE1);
8784ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju}
8794ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8804ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju}  //namespace details
8814ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju
8824ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsarajuinline std::string toString(const void *t) {
8834ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return details::toHexString(reinterpret_cast<uintptr_t>(t));
884be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
885be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
886be7a6887b28a1240ba0d944126c3db631342256dYifan Hong// debug string dump. There will be quotes around the string!
887be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toString(const hidl_string &hs) {
888be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return std::string{"\""} + hs.c_str() + "\"";
889be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
890be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
891be7a6887b28a1240ba0d944126c3db631342256dYifan Hong// debug string dump
892be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toString(const hidl_handle &hs) {
893be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return toString(hs.getNativeHandle());
894be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
895be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
896be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toString(const hidl_memory &mem) {
897be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
898be7a6887b28a1240ba0d944126c3db631342256dYifan Hong              + toString(mem.size())
899be7a6887b28a1240ba0d944126c3db631342256dYifan Hong              + ", .handle = " + toString(mem.handle()) + "}";
900be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
901be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
902be7a6887b28a1240ba0d944126c3db631342256dYifan Honginline std::string toString(const sp<hidl_death_recipient> &dr) {
903be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return std::string{"death_recipient@"} + toString(dr.get());
904be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
905be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
906be7a6887b28a1240ba0d944126c3db631342256dYifan Hong// debug string dump, assuming that toString(T) is defined.
907be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<typename T>
908be7a6887b28a1240ba0d944126c3db631342256dYifan Hongstd::string toString(const hidl_vec<T> &a) {
909be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    std::string os;
910be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    os += "[" + toString(a.size()) + "]";
9114ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    os += details::arrayToString(a, a.size());
912be7a6887b28a1240ba0d944126c3db631342256dYifan Hong    return os;
913be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
914be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
915be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<typename T, size_t SIZE1>
916be7a6887b28a1240ba0d944126c3db631342256dYifan Hongstd::string toString(const hidl_array<T, SIZE1> &a) {
9174ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return details::arraySizeToString<SIZE1>()
9184ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju            + details::toString(details::const_accessor<T, SIZE1>(a.data()));
919be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
920be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
921be7a6887b28a1240ba0d944126c3db631342256dYifan Hongtemplate<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
922be7a6887b28a1240ba0d944126c3db631342256dYifan Hongstd::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
9234ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju    return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
9244ff88a31348e1c367ba3b6a4d97af215bdf00a99Hridya Valsaraju            + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
925be7a6887b28a1240ba0d944126c3db631342256dYifan Hong}
926be7a6887b28a1240ba0d944126c3db631342256dYifan Hong
9277211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen}  // namespace hardware
9287211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen}  // namespace android
9297211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen
930c28f115754c2ba0ee036bab355b9013d466f2816Martijn Coenen
9317211016cd72b5fa9f61fb8cf77b62faa207362e4Martijn Coenen#endif  // ANDROID_HIDL_SUPPORT_H
932