blob: c36b7ecd39ba497ef1c8c0bc18b67e0df1852e37 [file] [log] [blame]
Martijn Coenen72110162016-08-19 14:28:25 +02001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HIDL_SUPPORT_H
18#define ANDROID_HIDL_SUPPORT_H
19
20#include <hwbinder/Parcel.h>
21
22namespace android {
23namespace hardware {
24
25struct hidl_string {
26 hidl_string();
27 ~hidl_string();
28
29 hidl_string(const hidl_string &);
30 hidl_string &operator=(const hidl_string &);
31
32 const char *c_str() const;
33 size_t size() const;
34 bool empty() const;
35
36 hidl_string &operator=(const char *s);
37 void clear();
38
39 // Reference an external char array. Ownership is _not_ transferred.
40 // Caller is responsible for ensuring that underlying memory is valid
41 // for the lifetime of this hidl_string.
42 void setToExternal(const char *data, size_t size);
43
44 status_t readEmbeddedFromParcel(
45 const Parcel &parcel, size_t parentHandle, size_t parentOffset);
46
47 status_t writeEmbeddedToParcel(
48 Parcel *parcel, size_t parentHandle, size_t parentOffset) const;
49
50private:
51 char *mBuffer;
52 size_t mSize; // NOT including the terminating '\0'.
53 bool mOwnsBuffer;
54
55 hidl_string &setTo(const char *data, size_t size);
56};
57
58template<typename T>
59struct hidl_vec {
60 hidl_vec()
61 : mBuffer(NULL),
62 mSize(0),
63 mOwnsBuffer(true) {
64 }
65
66 hidl_vec(const hidl_vec<T> &other)
67 : mBuffer(NULL),
68 mSize(0),
69 mOwnsBuffer(true) {
70 *this = other;
71 }
72
73 ~hidl_vec() {
74 if (mOwnsBuffer) {
75 delete[] mBuffer;
76 }
77 mBuffer = NULL;
78 }
79
80 // Reference an existing array _WITHOUT_ taking ownership. It is the
81 // caller's responsibility to ensure that the underlying memory stays
82 // valid for the lifetime of this hidl_vec.
83 void setToExternal(T *data, size_t size) {
84 if (mOwnsBuffer) {
85 delete [] mBuffer;
86 }
87 mBuffer = data;
88 mSize = size;
89 mOwnsBuffer = false;
90 }
91
92 hidl_vec &operator=(const hidl_vec &other) {
93 if (this != &other) {
94 if (mOwnsBuffer) {
95 delete[] mBuffer;
96 }
97 mBuffer = NULL;
98 mSize = other.mSize;
99 mOwnsBuffer = true;
100 if (mSize > 0) {
101 mBuffer = new T[mSize];
102 for (size_t i = 0; i < mSize; ++i) {
103 mBuffer[i] = other.mBuffer[i];
104 }
105 }
106 }
107
108 return *this;
109 }
110
111 size_t size() const {
112 return mSize;
113 }
114
115 T &operator[](size_t index) {
116 return mBuffer[index];
117 }
118
119 const T &operator[](size_t index) const {
120 return mBuffer[index];
121 }
122
123 void resize(size_t size) {
124 T *newBuffer = new T[size];
125
126 for (size_t i = 0; i < std::min(size, mSize); ++i) {
127 newBuffer[i] = mBuffer[i];
128 }
129
130 if (mOwnsBuffer) {
131 delete[] mBuffer;
132 }
133 mBuffer = newBuffer;
134
135 mSize = size;
136 mOwnsBuffer = true;
137 }
138
139 status_t readEmbeddedFromParcel(
140 const Parcel &parcel,
141 size_t parentHandle,
142 size_t parentOffset,
143 size_t *handle);
144
145 status_t writeEmbeddedToParcel(
146 Parcel *parcel,
147 size_t parentHandle,
148 size_t parentOffset,
149 size_t *handle) const;
150
151private:
152 T *mBuffer;
153 size_t mSize;
154 bool mOwnsBuffer;
155};
156
157template<typename T>
158status_t hidl_vec<T>::readEmbeddedFromParcel(
159 const Parcel &parcel,
160 size_t parentHandle,
161 size_t parentOffset,
162 size_t *handle) {
163 const void *ptr = parcel.readEmbeddedBuffer(
164 handle,
165 parentHandle,
166 parentOffset + offsetof(hidl_vec<T>, mBuffer));
167
168 return ptr != NULL ? OK : UNKNOWN_ERROR;
169}
170
171template<typename T>
172status_t hidl_vec<T>::writeEmbeddedToParcel(
173 Parcel *parcel,
174 size_t parentHandle,
175 size_t parentOffset,
176 size_t *handle) const {
177 return parcel->writeEmbeddedBuffer(
178 mBuffer,
179 sizeof(T) * mSize,
180 handle,
181 parentHandle,
182 parentOffset + offsetof(hidl_vec<T>, mBuffer));
183}
184
185// ----------------------------------------------------------------------
186// Version functions
187struct hidl_version {
188public:
189 hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
190
191 bool operator==(const hidl_version& other) {
192 return (mMajor == other.get_major() && mMinor == other.get_minor());
193 }
194 uint16_t get_major() const { return mMajor; }
195 uint16_t get_minor() const { return mMinor; }
196
197 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
198 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
199 }
200
201 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
202 uint32_t version;
203 android::status_t status = parcel.readUint32(&version);
204 if (status != OK) {
205 return nullptr;
206 } else {
207 return new hidl_version(version >> 16, version & 0xFFFF);
208 }
209 }
210
211private:
212 uint16_t mMajor;
213 uint16_t mMinor;
214};
215
216inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
217 return hidl_version(major,minor);
218}
219
220} // namespace hardware
221} // namespace android
222
223#endif // ANDROID_HIDL_SUPPORT_H
224