Import declaration of hidl_memory and hidl_vec.
authorjiseob.jang <jiseob.jang@samsung.com>
Thu, 22 Mar 2018 11:25:21 +0000 (20:25 +0900)
committer최형규/동작제어Lab(SR)/Senior Engineer/삼성전자 <hk0110.choi@samsung.com>
Thu, 22 Mar 2018 11:45:47 +0000 (20:45 +0900)
This commit imports declaration of hidl_memory and hidl_vec.

Signed-off-by: jiseob.jang <jiseob.jang@samsung.com>
12 files changed:
src/runtime/ref/CMakeLists.txt
src/runtime/ref/nn/CMakeLists.txt
src/runtime/ref/nn/common/CMakeLists.txt
src/runtime/ref/nn/depend/CMakeLists.txt [new file with mode: 0644]
src/runtime/ref/nn/depend/libcutils/CMakeLists.txt [new file with mode: 0644]
src/runtime/ref/nn/depend/libcutils/include/cutils/native_handle.h [new file with mode: 0644]
src/runtime/ref/nn/depend/libcutils/native_handle.c [new file with mode: 0644]
src/runtime/ref/nn/depend/libhidl/CMakeLists.txt [new file with mode: 0644]
src/runtime/ref/nn/depend/libhidl/base/CMakeLists.txt [new file with mode: 0644]
src/runtime/ref/nn/depend/libhidl/base/include/hidl/HidlInternal.h [new file with mode: 0644]
src/runtime/ref/nn/depend/libhidl/base/include/hidl/HidlSupport.h [new file with mode: 0644]
src/runtime/ref/nn/runtime/CMakeLists.txt

index 4f8a97c..01a2464 100644 (file)
@@ -1 +1,2 @@
+set(CMAKE_C_FLAGS "-std=c99")
 add_subdirectory(nn)
index 127d8a1..49c9f00 100644 (file)
@@ -1,2 +1,6 @@
+SET(SRCS)
+SET(INC_DIRS)
+
+add_subdirectory(depend)
 add_subdirectory(runtime)
 add_subdirectory(common)
index a01f3b5..2f6c6ce 100644 (file)
@@ -1,5 +1,7 @@
 # Library `runtime_ref_common`
 SET (RUNTIME_SRCS CpuExecutor.cpp)
+SET (DEPEND_SRCS ${SRCS})
+SET (DEPEND_INCS ${INC_DIRS})
 
-add_library(runtime_ref_common SHARED ${RUNTIME_SRCS})
-include_directories(runtime_ref_common PRIVATE . include ../runtime/include)
+add_library(runtime_ref_common SHARED ${RUNTIME_SRCS} ${DEPEND_SRCS})
+include_directories(runtime_ref_common PRIVATE . include ../runtime/include ${DEPEND_INCS})
diff --git a/src/runtime/ref/nn/depend/CMakeLists.txt b/src/runtime/ref/nn/depend/CMakeLists.txt
new file mode 100644 (file)
index 0000000..af91a5c
--- /dev/null
@@ -0,0 +1,21 @@
+#ADD_SUBDIRECTORY(android-base)
+#ADD_SUBDIRECTORY(external)
+#ADD_SUBDIRECTORY(hal)
+#ADD_SUBDIRECTORY(libc)
+ADD_SUBDIRECTORY(libcutils)
+ADD_SUBDIRECTORY(libhidl)
+#ADD_SUBDIRECTORY(libhwbinder)
+#ADD_SUBDIRECTORY(liblog)
+#ADD_SUBDIRECTORY(libsystem)
+#ADD_SUBDIRECTORY(libutils)
+#ADD_SUBDIRECTORY(libvndksupport)
+
+SET(INC_DIRS
+  ${INC_DIRS}
+  PARENT_SCOPE
+)
+
+SET(SRCS
+  ${SRCS}
+  PARENT_SCOPE
+)
diff --git a/src/runtime/ref/nn/depend/libcutils/CMakeLists.txt b/src/runtime/ref/nn/depend/libcutils/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fd0cc94
--- /dev/null
@@ -0,0 +1,27 @@
+
+SET(CUR_INCS
+  ${CMAKE_CURRENT_SOURCE_DIR}/include
+)
+
+
+SET(INC_DIRS
+  ${INC_DIRS}
+  ${CUR_INCS}
+  PARENT_SCOPE
+)
+
+SET(CUR_SRCS
+#  ${CMAKE_CURRENT_SOURCE_DIR}/ashmem-host.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/native_handle.c
+#  ${CMAKE_CURRENT_SOURCE_DIR}/properties.cpp
+#  ${CMAKE_CURRENT_SOURCE_DIR}/sched_policy.cpp
+#  ${CMAKE_CURRENT_SOURCE_DIR}/sockets.cpp
+#  ${CMAKE_CURRENT_SOURCE_DIR}/threads.c
+#  ${CMAKE_CURRENT_SOURCE_DIR}/trace-host.c
+)
+
+SET(SRCS
+  ${SRCS}
+  ${CUR_SRCS}
+  PARENT_SCOPE
+)
diff --git a/src/runtime/ref/nn/depend/libcutils/include/cutils/native_handle.h b/src/runtime/ref/nn/depend/libcutils/include/cutils/native_handle.h
new file mode 100644 (file)
index 0000000..abe6dd6
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NATIVE_HANDLE_H_
+#define NATIVE_HANDLE_H_
+
+#include <stdalign.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Declare a char array for use with native_handle_init */
+#define NATIVE_HANDLE_DECLARE_STORAGE(name, maxFds, maxInts) \
+    alignas(native_handle_t) char name[                            \
+      sizeof(native_handle_t) + sizeof(int) * (maxFds + maxInts)]
+
+typedef struct native_handle
+{
+    int version;        /* sizeof(native_handle_t) */
+    int numFds;         /* number of file-descriptors at &data[0] */
+    int numInts;        /* number of ints at &data[numFds] */
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
+#endif
+    int data[0];        /* numFds + numInts ints */
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+} native_handle_t;
+
+typedef const native_handle_t* buffer_handle_t;
+
+/*
+ * native_handle_close
+ * 
+ * closes the file descriptors contained in this native_handle_t
+ * 
+ * return 0 on success, or a negative error code on failure
+ * 
+ */
+int native_handle_close(const native_handle_t* h);
+
+/*
+ * native_handle_init
+ *
+ * Initializes a native_handle_t from storage.  storage must be declared with
+ * NATIVE_HANDLE_DECLARE_STORAGE.  numFds and numInts must not respectively
+ * exceed maxFds and maxInts used to declare the storage.
+ */
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts);
+
+/*
+ * native_handle_create
+ * 
+ * creates a native_handle_t and initializes it. must be destroyed with
+ * native_handle_delete().
+ * 
+ */
+native_handle_t* native_handle_create(int numFds, int numInts);
+
+/*
+ * native_handle_clone
+ *
+ * creates a native_handle_t and initializes it from another native_handle_t.
+ * Must be destroyed with native_handle_delete().
+ *
+ */
+native_handle_t* native_handle_clone(const native_handle_t* handle);
+
+/*
+ * native_handle_delete
+ * 
+ * frees a native_handle_t allocated with native_handle_create().
+ * This ONLY frees the memory allocated for the native_handle_t, but doesn't
+ * close the file descriptors; which can be achieved with native_handle_close().
+ * 
+ * return 0 on success, or a negative error code on failure
+ * 
+ */
+int native_handle_delete(native_handle_t* h);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NATIVE_HANDLE_H_ */
diff --git a/src/runtime/ref/nn/depend/libcutils/native_handle.c b/src/runtime/ref/nn/depend/libcutils/native_handle.c
new file mode 100644 (file)
index 0000000..95bbc41
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/native_handle.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const int kMaxNativeFds = 1024;
+static const int kMaxNativeInts = 1024;
+
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts) {
+    if ((uintptr_t) storage % alignof(native_handle_t)) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    native_handle_t* handle = (native_handle_t*) storage;
+    handle->version = sizeof(native_handle_t);
+    handle->numFds = numFds;
+    handle->numInts = numInts;
+    return handle;
+}
+
+native_handle_t* native_handle_create(int numFds, int numInts) {
+    if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    size_t mallocSize = sizeof(native_handle_t) + (sizeof(int) * (numFds + numInts));
+    native_handle_t* h = malloc(mallocSize);
+    if (h) {
+        h->version = sizeof(native_handle_t);
+        h->numFds = numFds;
+        h->numInts = numInts;
+    }
+    return h;
+}
+
+native_handle_t* native_handle_clone(const native_handle_t* handle) {
+    native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
+    if (clone == NULL) return NULL;
+
+    for (int i = 0; i < handle->numFds; i++) {
+        clone->data[i] = dup(handle->data[i]);
+        if (clone->data[i] == -1) {
+            clone->numFds = i;
+            native_handle_close(clone);
+            native_handle_delete(clone);
+            return NULL;
+        }
+    }
+
+    memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
+           sizeof(int) * handle->numInts);
+
+    return clone;
+}
+
+int native_handle_delete(native_handle_t* h) {
+    if (h) {
+        if (h->version != sizeof(native_handle_t)) return -EINVAL;
+        free(h);
+    }
+    return 0;
+}
+
+int native_handle_close(const native_handle_t* h) {
+    if (h->version != sizeof(native_handle_t)) return -EINVAL;
+
+    int saved_errno = errno;
+    const int numFds = h->numFds;
+    for (int i = 0; i < numFds; ++i) {
+        close(h->data[i]);
+    }
+    errno = saved_errno;
+    return 0;
+}
diff --git a/src/runtime/ref/nn/depend/libhidl/CMakeLists.txt b/src/runtime/ref/nn/depend/libhidl/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2476ef9
--- /dev/null
@@ -0,0 +1,13 @@
+ADD_SUBDIRECTORY(base)
+#ADD_SUBDIRECTORY(libhidlmemory)
+#ADD_SUBDIRECTORY(transport)
+
+SET(INC_DIRS
+  ${INC_DIRS}
+  PARENT_SCOPE
+)
+
+SET(SRCS
+  ${SRCS}
+  PARENT_SCOPE
+)
diff --git a/src/runtime/ref/nn/depend/libhidl/base/CMakeLists.txt b/src/runtime/ref/nn/depend/libhidl/base/CMakeLists.txt
new file mode 100644 (file)
index 0000000..95a245e
--- /dev/null
@@ -0,0 +1,24 @@
+
+SET(CUR_INCS
+   ${CMAKE_CURRENT_SOURCE_DIR}/include
+)
+
+
+SET(INC_DIRS
+  ${INC_DIRS}
+  ${CUR_INCS}
+  PARENT_SCOPE
+)
+
+SET(CUR_SRCS
+#  ${CMAKE_CURRENT_SOURCE_DIR}/HidlInternal.cpp
+#  ${CMAKE_CURRENT_SOURCE_DIR}/HidlSupport.cpp
+#  ${CMAKE_CURRENT_SOURCE_DIR}/Status.cpp
+#  ${CMAKE_CURRENT_SOURCE_DIR}/TaskRunner.cpp
+)
+
+SET(SRCS
+  ${SRCS}
+  ${CUR_SRCS}
+  PARENT_SCOPE
+)
diff --git a/src/runtime/ref/nn/depend/libhidl/base/include/hidl/HidlInternal.h b/src/runtime/ref/nn/depend/libhidl/base/include/hidl/HidlInternal.h
new file mode 100644 (file)
index 0000000..0f0be36
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HIDL_INTERNAL_H
+#define ANDROID_HIDL_INTERNAL_H
+
+#include <cstdint>
+#include <dirent.h>
+#include <functional>
+#include <string>
+#include <vector>
+#include <utility>
+
+#include "Log.h"
+
+namespace android {
+namespace hardware {
+namespace details {
+
+//Templated classes can use the below method
+//to avoid creating dependencies on liblog.
+void logAlwaysFatal(const char *message) {
+    LOG(FATAL) << message;
+}
+
+// HIDL client/server code should *NOT* use this class.
+//
+// hidl_pointer wraps a pointer without taking ownership,
+// and stores it in a union with a uint64_t. This ensures
+// that we always have enough space to store a pointer,
+// regardless of whether we're running in a 32-bit or 64-bit
+// process.
+template<typename T>
+struct hidl_pointer {
+    hidl_pointer()
+        : _pad(0) {
+    }
+    hidl_pointer(T* ptr) : hidl_pointer() { mPointer = ptr; }
+    hidl_pointer(const hidl_pointer<T>& other) : hidl_pointer() { mPointer = other.mPointer; }
+    hidl_pointer(hidl_pointer<T>&& other) : hidl_pointer() { *this = std::move(other); }
+
+    hidl_pointer &operator=(const hidl_pointer<T>& other) {
+        mPointer = other.mPointer;
+        return *this;
+    }
+    hidl_pointer &operator=(hidl_pointer<T>&& other) {
+        mPointer = other.mPointer;
+        other.mPointer = nullptr;
+        return *this;
+    }
+    hidl_pointer &operator=(T* ptr) {
+        mPointer = ptr;
+        return *this;
+    }
+
+    operator T*() const {
+        return mPointer;
+    }
+    explicit operator void*() const { // requires explicit cast to avoid ambiguity
+        return mPointer;
+    }
+    T& operator*() const {
+        return *mPointer;
+    }
+    T* operator->() const {
+        return mPointer;
+    }
+    T &operator[](size_t index) {
+        return mPointer[index];
+    }
+    const T &operator[](size_t index) const {
+        return mPointer[index];
+    }
+
+private:
+    union {
+        T* mPointer;
+        uint64_t _pad;
+    };
+};
+
+#define HAL_LIBRARY_PATH_SYSTEM_64BIT "/system/lib64/hw/"
+#define HAL_LIBRARY_PATH_VNDK_SP_64BIT "/system/lib64/vndk-sp/hw/"
+#define HAL_LIBRARY_PATH_VENDOR_64BIT "/vendor/lib64/hw/"
+#define HAL_LIBRARY_PATH_ODM_64BIT    "/odm/lib64/hw/"
+#define HAL_LIBRARY_PATH_SYSTEM_32BIT "/system/lib/hw/"
+#define HAL_LIBRARY_PATH_VNDK_SP_32BIT "/system/lib/vndk-sp/hw/"
+#define HAL_LIBRARY_PATH_VENDOR_32BIT "/vendor/lib/hw/"
+#define HAL_LIBRARY_PATH_ODM_32BIT    "/odm/lib/hw/"
+
+#if defined(__LP64__)
+#define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_64BIT
+#define HAL_LIBRARY_PATH_VNDK_SP HAL_LIBRARY_PATH_VNDK_SP_64BIT
+#define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_64BIT
+#define HAL_LIBRARY_PATH_ODM    HAL_LIBRARY_PATH_ODM_64BIT
+#else
+#define HAL_LIBRARY_PATH_SYSTEM HAL_LIBRARY_PATH_SYSTEM_32BIT
+#define HAL_LIBRARY_PATH_VNDK_SP HAL_LIBRARY_PATH_VNDK_SP_32BIT
+#define HAL_LIBRARY_PATH_VENDOR HAL_LIBRARY_PATH_VENDOR_32BIT
+#define HAL_LIBRARY_PATH_ODM    HAL_LIBRARY_PATH_ODM_32BIT
+#endif
+
+}  // namespace details
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HIDL_INTERNAL_H
diff --git a/src/runtime/ref/nn/depend/libhidl/base/include/hidl/HidlSupport.h b/src/runtime/ref/nn/depend/libhidl/base/include/hidl/HidlSupport.h
new file mode 100644 (file)
index 0000000..3fbf53d
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HIDL_SUPPORT_H
+#define ANDROID_HIDL_SUPPORT_H
+
+//#include <algorithm>
+//#include <array>
+#include <iterator>
+#include <cutils/native_handle.h>
+#include <hidl/HidlInternal.h>
+//#include <hidl/Status.h>
+#include <map>
+//#include <sstream>
+#include <stddef.h>
+#include <tuple>
+#include <type_traits>
+//#include <utils/Errors.h>
+//#include <utils/RefBase.h>
+//#include <utils/StrongPointer.h>
+#include <vector>
+#include <string>
+
+namespace android {
+
+// this file is included by all hidl interface, so we must forward declare the
+// IMemory and IBase types.
+namespace hidl {
+namespace memory {
+namespace V1_0 {
+    struct IMemory;
+}; // namespace V1_0
+}; // namespace manager
+}; // namespace hidl
+
+namespace hidl {
+namespace base {
+namespace V1_0 {
+    struct IBase;
+}; // namespace V1_0
+}; // namespace base
+}; // namespace hidl
+
+namespace hardware {
+
+// hidl_memory is a structure that can be used to transfer
+// pieces of shared memory between processes. The assumption
+// of this object is that the memory remains accessible as
+// long as the file descriptors in the enclosed mHandle
+// - as well as all of its cross-process dups() - remain opened.
+struct hidl_memory {
+
+    hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
+    }
+
+    /**
+     * Creates a hidl_memory object, but doesn't take ownership of
+     * the passed in native_handle_t; callers are responsible for
+     * making sure the handle remains valid while this object is
+     * used.
+     */
+    hidl_memory(const std::string &name, const native_handle_t *handle, size_t size)
+      :  mHandle(handle),
+         mSize(size),
+         mName(name)
+    {
+//        mName = const_cast<std::string>(name);
+    }
+
+    // copy constructor
+    hidl_memory(const hidl_memory& other) {
+        *this = other;
+    }
+
+    // copy assignment
+    hidl_memory &operator=(const hidl_memory &other) {
+        if (this != &other) {
+            mHandle = other.mHandle;
+            mSize = other.mSize;
+            mName = other.mName;
+        }
+
+        return *this;
+    }
+
+    // move constructor
+    hidl_memory(hidl_memory&& other) noexcept {
+        *this = std::move(other);
+    }
+
+    // move assignment
+    hidl_memory &operator=(hidl_memory &&other) noexcept {
+        if (this != &other) {
+            mHandle = std::move(other.mHandle);
+            mSize = other.mSize;
+            mName = std::move(other.mName);
+            other.mSize = 0;
+        }
+
+        return *this;
+    }
+
+
+    ~hidl_memory() {
+    }
+
+    const native_handle_t* handle() const {
+        return mHandle;
+    }
+
+    const std::string &name() const {
+        return mName;
+    }
+
+    uint64_t size() const {
+        return mSize;
+    }
+
+    // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
+    static const size_t kOffsetOfHandle;
+    // offsetof(hidl_memory, mName) exposed since mHandle is private.
+    static const size_t kOffsetOfName;
+
+private:
+    const native_handle_t *mHandle;
+    uint64_t mSize;
+    std::string mName;  // TODO-NNRT: This was hidl_string.
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+template<typename T>
+struct hidl_vec {
+    hidl_vec()
+        : mBuffer(NULL),
+          mSize(0),
+          mOwnsBuffer(true) {
+        static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
+    }
+
+    hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
+        *this = other;
+    }
+
+    hidl_vec(hidl_vec<T> &&other) noexcept
+    : mOwnsBuffer(false) {
+        *this = std::move(other);
+    }
+
+    hidl_vec(const std::initializer_list<T> list)
+            : mOwnsBuffer(true) {
+        if (list.size() > UINT32_MAX) {
+            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
+        }
+        mSize = static_cast<uint32_t>(list.size());
+        mBuffer = new T[mSize];
+
+        size_t idx = 0;
+        for (auto it = list.begin(); it != list.end(); ++it) {
+            mBuffer[idx++] = *it;
+        }
+    }
+
+    hidl_vec(const std::vector<T> &other) : hidl_vec() {
+        *this = other;
+    }
+
+    template <typename InputIterator,
+              typename = typename std::enable_if<std::is_convertible<
+                  typename std::iterator_traits<InputIterator>::iterator_category,
+                  std::input_iterator_tag>::value>::type>
+    hidl_vec(InputIterator first, InputIterator last) : mOwnsBuffer(true) {
+        auto size = std::distance(first, last);
+        if (size > static_cast<int64_t>(UINT32_MAX)) {
+            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
+        }
+        if (size < 0) {
+            details::logAlwaysFatal("size can't be negative.");
+        }
+        mSize = static_cast<uint32_t>(size);
+        mBuffer = new T[mSize];
+
+        size_t idx = 0;
+        for (; first != last; ++first) {
+            mBuffer[idx++] = static_cast<T>(*first);
+        }
+    }
+
+    ~hidl_vec() {
+        if (mOwnsBuffer) {
+            delete[] mBuffer;
+        }
+        mBuffer = NULL;
+    }
+
+    // Reference an existing array, optionally taking ownership. It is the
+    // caller's responsibility to ensure that the underlying memory stays
+    // valid for the lifetime of this hidl_vec.
+    void setToExternal(T *data, size_t size, bool shouldOwn = false) {
+        if (mOwnsBuffer) {
+            delete [] mBuffer;
+        }
+        mBuffer = data;
+        if (size > UINT32_MAX) {
+            details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
+        }
+        mSize = static_cast<uint32_t>(size);
+        mOwnsBuffer = shouldOwn;
+    }
+
+    T *data() {
+        return mBuffer;
+    }
+
+    const T *data() const {
+        return mBuffer;
+    }
+
+    T *releaseData() {
+        if (!mOwnsBuffer && mSize > 0) {
+            resize(mSize);
+        }
+        mOwnsBuffer = false;
+        return mBuffer;
+    }
+
+    hidl_vec &operator=(hidl_vec &&other) noexcept {
+        if (mOwnsBuffer) {
+            delete[] mBuffer;
+        }
+        mBuffer = other.mBuffer;
+        mSize = other.mSize;
+        mOwnsBuffer = other.mOwnsBuffer;
+        other.mOwnsBuffer = false;
+        return *this;
+    }
+
+    hidl_vec &operator=(const hidl_vec &other) {
+        if (this != &other) {
+            if (mOwnsBuffer) {
+                delete[] mBuffer;
+            }
+            copyFrom(other, other.mSize);
+        }
+
+        return *this;
+    }
+
+    // copy from an std::vector.
+    hidl_vec &operator=(const std::vector<T> &other) {
+        if (mOwnsBuffer) {
+            delete[] mBuffer;
+        }
+        copyFrom(other, other.size());
+        return *this;
+    }
+
+    // cast to an std::vector.
+    operator std::vector<T>() const {
+        std::vector<T> v(mSize);
+        for (size_t i = 0; i < mSize; ++i) {
+            v[i] = mBuffer[i];
+        }
+        return v;
+    }
+
+    // equality check, assuming that T::operator== is defined.
+    bool operator==(const hidl_vec &other) const {
+        if (mSize != other.size()) {
+            return false;
+        }
+        for (size_t i = 0; i < mSize; ++i) {
+            if (!(mBuffer[i] == other.mBuffer[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // inequality check, assuming that T::operator== is defined.
+    inline bool operator!=(const hidl_vec &other) const {
+        return !((*this) == other);
+    }
+
+    size_t size() const {
+        return mSize;
+    }
+
+    T &operator[](size_t index) {
+        return mBuffer[index];
+    }
+
+    const T &operator[](size_t index) const {
+        return mBuffer[index];
+    }
+
+    void resize(size_t size) {
+        if (size > UINT32_MAX) {
+            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
+        }
+        T *newBuffer = new T[size];
+
+        for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
+            newBuffer[i] = mBuffer[i];
+        }
+
+        if (mOwnsBuffer) {
+            delete[] mBuffer;
+        }
+        mBuffer = newBuffer;
+
+        mSize = static_cast<uint32_t>(size);
+        mOwnsBuffer = true;
+    }
+
+    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
+    static const size_t kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);
+
+private:
+    // Define std interator interface for walking the array contents
+    template<bool is_const>
+    class iter : public std::iterator<
+            std::random_access_iterator_tag, /* Category */
+            T,
+            ptrdiff_t, /* Distance */
+            typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
+            typename std::conditional<is_const, const T &, T &>::type /* Reference */>
+    {
+        using traits = std::iterator_traits<iter>;
+        using ptr_type = typename traits::pointer;
+        using ref_type = typename traits::reference;
+        using diff_type = typename traits::difference_type;
+    public:
+        iter(ptr_type ptr) : mPtr(ptr) { }
+        inline iter &operator++()    { mPtr++; return *this; }
+        inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
+        inline iter &operator--()    { mPtr--; return *this; }
+        inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
+        inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
+        inline iter  operator+(diff_type n) const { return mPtr + n; }
+        inline iter  operator-(diff_type n) const { return mPtr - n; }
+        inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
+        inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
+        inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
+        inline ref_type operator*() const  { return *mPtr; }
+        inline ptr_type operator->() const { return mPtr; }
+        inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
+        inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
+        inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
+        inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
+        inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
+        inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
+        inline ref_type operator[](size_t n) const { return mPtr[n]; }
+    private:
+        ptr_type mPtr;
+    };
+public:
+    using iterator       = iter<false /* is_const */>;
+    using const_iterator = iter<true  /* is_const */>;
+
+    iterator begin() { return data(); }
+    iterator end() { return data()+mSize; }
+    const_iterator begin() const { return data(); }
+    const_iterator end() const { return data()+mSize; }
+
+private:
+    details::hidl_pointer<T> mBuffer;
+    uint32_t mSize;
+    bool mOwnsBuffer;
+
+    // copy from an array-like object, assuming my resources are freed.
+    template <typename Array>
+    void copyFrom(const Array &data, size_t size) {
+        mSize = static_cast<uint32_t>(size);
+        mOwnsBuffer = true;
+        if (mSize > 0) {
+            mBuffer = new T[size];
+            for (size_t i = 0; i < size; ++i) {
+                mBuffer[i] = data[i];
+            }
+        } else {
+            mBuffer = NULL;
+        }
+    }
+};
+
+}  // namespace hardware
+}  // namespace android
+
+
+#endif  // ANDROID_HIDL_SUPPORT_H
index cd44a0c..79e8a39 100644 (file)
@@ -2,9 +2,11 @@
 SET (RUNTIME_SRCS NeuralNetworks.cpp
                   ModelBuilder.cpp
                   CompilationBuilder.cpp)
+SET (DEPEND_SRCS ${SRCS})
+SET (DEPEND_INCS ${INC_DIRS})
 
-add_library(runtime SHARED ${RUNTIME_SRCS})
-include_directories(runtime PRIVATE . include ../include)
+add_library(runtime SHARED ${RUNTIME_SRCS} ${DEPEND_SRCS})
+include_directories(runtime PRIVATE . include ../include ${DEPEND_INCS})
 
 # Executable `runtime_run` (Dummy runner executable for simple testing bring-up stage)
 # TODO remove the executable later