blob: 2689ab4e53227580a25c3675ba7d7d8b721ba075 [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
Andreas Huberebfeb362016-08-25 13:39:05 -070050 // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
51 static const size_t kOffsetOfBuffer;
52
Martijn Coenen72110162016-08-19 14:28:25 +020053private:
54 char *mBuffer;
55 size_t mSize; // NOT including the terminating '\0'.
56 bool mOwnsBuffer;
57
58 hidl_string &setTo(const char *data, size_t size);
59};
60
61template<typename T>
62struct hidl_vec {
63 hidl_vec()
64 : mBuffer(NULL),
65 mSize(0),
66 mOwnsBuffer(true) {
67 }
68
69 hidl_vec(const hidl_vec<T> &other)
70 : mBuffer(NULL),
71 mSize(0),
72 mOwnsBuffer(true) {
73 *this = other;
74 }
75
76 ~hidl_vec() {
77 if (mOwnsBuffer) {
78 delete[] mBuffer;
79 }
80 mBuffer = NULL;
81 }
82
83 // Reference an existing array _WITHOUT_ taking ownership. It is the
84 // caller's responsibility to ensure that the underlying memory stays
85 // valid for the lifetime of this hidl_vec.
86 void setToExternal(T *data, size_t size) {
87 if (mOwnsBuffer) {
88 delete [] mBuffer;
89 }
90 mBuffer = data;
91 mSize = size;
92 mOwnsBuffer = false;
93 }
94
95 hidl_vec &operator=(const hidl_vec &other) {
96 if (this != &other) {
97 if (mOwnsBuffer) {
98 delete[] mBuffer;
99 }
100 mBuffer = NULL;
101 mSize = other.mSize;
102 mOwnsBuffer = true;
103 if (mSize > 0) {
104 mBuffer = new T[mSize];
105 for (size_t i = 0; i < mSize; ++i) {
106 mBuffer[i] = other.mBuffer[i];
107 }
108 }
109 }
110
111 return *this;
112 }
113
114 size_t size() const {
115 return mSize;
116 }
117
118 T &operator[](size_t index) {
119 return mBuffer[index];
120 }
121
122 const T &operator[](size_t index) const {
123 return mBuffer[index];
124 }
125
126 void resize(size_t size) {
127 T *newBuffer = new T[size];
128
129 for (size_t i = 0; i < std::min(size, mSize); ++i) {
130 newBuffer[i] = mBuffer[i];
131 }
132
133 if (mOwnsBuffer) {
134 delete[] mBuffer;
135 }
136 mBuffer = newBuffer;
137
138 mSize = size;
139 mOwnsBuffer = true;
140 }
141
142 status_t readEmbeddedFromParcel(
143 const Parcel &parcel,
144 size_t parentHandle,
145 size_t parentOffset,
146 size_t *handle);
147
148 status_t writeEmbeddedToParcel(
149 Parcel *parcel,
150 size_t parentHandle,
151 size_t parentOffset,
152 size_t *handle) const;
153
154private:
155 T *mBuffer;
156 size_t mSize;
157 bool mOwnsBuffer;
158};
159
160template<typename T>
161status_t hidl_vec<T>::readEmbeddedFromParcel(
162 const Parcel &parcel,
163 size_t parentHandle,
164 size_t parentOffset,
165 size_t *handle) {
166 const void *ptr = parcel.readEmbeddedBuffer(
167 handle,
168 parentHandle,
169 parentOffset + offsetof(hidl_vec<T>, mBuffer));
170
171 return ptr != NULL ? OK : UNKNOWN_ERROR;
172}
173
174template<typename T>
175status_t hidl_vec<T>::writeEmbeddedToParcel(
176 Parcel *parcel,
177 size_t parentHandle,
178 size_t parentOffset,
179 size_t *handle) const {
180 return parcel->writeEmbeddedBuffer(
181 mBuffer,
182 sizeof(T) * mSize,
183 handle,
184 parentHandle,
185 parentOffset + offsetof(hidl_vec<T>, mBuffer));
186}
187
188// ----------------------------------------------------------------------
189// Version functions
190struct hidl_version {
191public:
192 hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {};
193
194 bool operator==(const hidl_version& other) {
195 return (mMajor == other.get_major() && mMinor == other.get_minor());
196 }
197 uint16_t get_major() const { return mMajor; }
198 uint16_t get_minor() const { return mMinor; }
199
200 android::status_t writeToParcel(android::hardware::Parcel& parcel) const {
201 return parcel.writeUint32((uint32_t) mMajor << 16 | mMinor);
202 }
203
204 static hidl_version* readFromParcel(const android::hardware::Parcel& parcel) {
205 uint32_t version;
206 android::status_t status = parcel.readUint32(&version);
207 if (status != OK) {
208 return nullptr;
209 } else {
210 return new hidl_version(version >> 16, version & 0xFFFF);
211 }
212 }
213
214private:
215 uint16_t mMajor;
216 uint16_t mMinor;
217};
218
219inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
220 return hidl_version(major,minor);
221}
222
223} // namespace hardware
224} // namespace android
225
226#endif // ANDROID_HIDL_SUPPORT_H
227