blob: 1019424050ebb6ecd9a1ea526370a8d69d0dc259 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "VectorType.h"
18
19#include "Formatter.h"
20
Andreas Huber881227d2016-08-02 14:20:21 -070021#include <android-base/logging.h>
22
Andreas Huberc9410c72016-07-28 12:18:40 -070023namespace android {
24
25VectorType::VectorType(Type *elementType)
26 : mElementType(elementType) {
27}
28
Andreas Huber881227d2016-08-02 14:20:21 -070029std::string VectorType::getCppType(StorageMode mode, std::string *extra) const {
30 const std::string base =
Andreas Huber8a82ff72016-08-04 10:29:39 -070031 "::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -070032 + mElementType->getCppType(extra)
33 + ">";
34
35 CHECK(extra->empty());
36
37 switch (mode) {
38 case StorageMode_Stack:
39 return base;
40
41 case StorageMode_Argument:
42 return "const " + base + "&";
43
44 case StorageMode_Result:
45 return "const " + base + "*";
46 }
47}
48
Andreas Huber2831d512016-08-15 09:33:47 -070049std::string VectorType::getJavaType() const {
50 return mElementType->getJavaType() + "[]";
51}
52
53std::string VectorType::getJavaSuffix() const {
54 return mElementType->getJavaSuffix() + "Vector";
55}
56
Andreas Huber881227d2016-08-02 14:20:21 -070057void VectorType::emitReaderWriter(
58 Formatter &out,
59 const std::string &name,
60 const std::string &parcelObj,
61 bool parcelObjIsPointer,
62 bool isReader,
63 ErrorMode mode) const {
64 std::string baseExtra;
65 std::string baseType = mElementType->getCppType(&baseExtra);
66
Iliyan Malchev549e2592016-08-10 08:59:12 -070067 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -070068
69 out << "size_t " << parentName << ";\n\n";
70
71 const std::string parcelObjDeref =
72 parcelObj + (parcelObjIsPointer ? "->" : ".");
73
74 if (isReader) {
75 out << name
Andreas Huber8a82ff72016-08-04 10:29:39 -070076 << " = (const ::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -070077 << baseType
78 << "> *)"
79 << parcelObjDeref
80 << "readBuffer(&"
81 << parentName
82 << ");\n\n";
83
84 out << "if (" << name << " == nullptr) {\n";
85
86 out.indent();
87
Iliyan Malchev549e2592016-08-10 08:59:12 -070088 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
Andreas Huber881227d2016-08-02 14:20:21 -070089 handleError2(out, mode);
90
91 out.unindent();
92 out << "}\n\n";
93 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -070094 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -070095 << parcelObjDeref
96 << "writeBuffer(&"
97 << name
98 << ", sizeof("
99 << name
100 << "), &"
101 << parentName
102 << ");\n";
103
104 handleError(out, mode);
105 }
106
107 emitReaderWriterEmbedded(
108 out,
109 name,
110 isReader /* nameIsPointer */,
111 parcelObj,
112 parcelObjIsPointer,
113 isReader,
114 mode,
115 parentName,
116 "0 /* parentOffset */");
117}
118
119void VectorType::emitReaderWriterEmbedded(
120 Formatter &out,
121 const std::string &name,
122 bool nameIsPointer,
123 const std::string &parcelObj,
124 bool parcelObjIsPointer,
125 bool isReader,
126 ErrorMode mode,
127 const std::string &parentName,
128 const std::string &offsetText) const {
129 std::string baseExtra;
130 std::string baseType = Type::getCppType(&baseExtra);
131
Iliyan Malchev549e2592016-08-10 08:59:12 -0700132 const std::string childName = "_hidl_" + name + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700133 out << "size_t " << childName << ";\n\n";
134
135 emitReaderWriterEmbeddedForTypeName(
136 out,
137 name,
138 nameIsPointer,
139 parcelObj,
140 parcelObjIsPointer,
141 isReader,
142 mode,
143 parentName,
144 offsetText,
145 baseType,
146 childName);
147
148 if (!mElementType->needsEmbeddedReadWrite()) {
149 return;
150 }
151
152 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
153
154 baseType = mElementType->getCppType(&baseExtra);
155
Iliyan Malchev549e2592016-08-10 08:59:12 -0700156 out << "for (size_t _hidl_index = 0; _hidl_index < "
Andreas Huber881227d2016-08-02 14:20:21 -0700157 << nameDeref
Iliyan Malchev549e2592016-08-10 08:59:12 -0700158 << "size(); ++_hidl_index) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700159
160 out.indent();
161
162 mElementType->emitReaderWriterEmbedded(
163 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -0700164 (nameIsPointer ? "(*" + name + ")" : name) + "[_hidl_index]",
Andreas Huber881227d2016-08-02 14:20:21 -0700165 false /* nameIsPointer */,
166 parcelObj,
167 parcelObjIsPointer,
168 isReader,
169 mode,
170 childName,
Iliyan Malchev549e2592016-08-10 08:59:12 -0700171 "_hidl_index * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700172
173 out.unindent();
174
175 out << "}\n\n";
176}
177
Andreas Huber85eabdb2016-08-25 11:24:49 -0700178void VectorType::emitJavaFieldInitializer(
179 Formatter &out, const std::string &fieldName) const {
180 out << "final Vector<"
181 << mElementType->getJavaWrapperType()
182 << "> "
183 << fieldName
184 << " = new Vector();\n";
185}
186
187void VectorType::emitJavaFieldReaderWriter(
188 Formatter &out,
189 const std::string &blobName,
190 const std::string &fieldName,
191 const std::string &offset,
192 bool isReader) const {
193 if (isReader) {
194 out << "{\n";
195 out.indent();
196
197 out << "HwBlob childBlob = parcel.readEmbeddedBuffer(\n";
198 out.indent();
199 out.indent();
200
201 out << blobName
202 << ".handle(),\n"
203 << offset
204 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";
205
206 out.unindent();
207 out.unindent();
208
209 out << fieldName << ".clear();\n";
210 out << "long _hidl_vec_size = "
211 << blobName
212 << ".getInt64("
213 << offset
214 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
215
216 out << "for (int _hidl_index = 0; _hidl_index < _hidl_vec_size; "
217 << "++_hidl_index) {\n";
218
219 out.indent();
220
221 mElementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
222
223 size_t elementAlign, elementSize;
224 mElementType->getAlignmentAndSize(&elementAlign, &elementSize);
225
226 mElementType->emitJavaFieldReaderWriter(
227 out,
228 "childBlob",
229 "_hidl_vec_element",
230 "_hidl_index * " + std::to_string(elementSize),
231 true /* isReader */);
232
233 out << fieldName
234 << ".add(_hidl_vec_element);\n";
235
236 out.unindent();
237
238 out << "}\n";
239
240 out.unindent();
241 out << "}\n";
242
243 return;
244 }
245
246 out << "{\n";
247 out.indent();
248
249 out << "long _hidl_vec_size = "
250 << fieldName
251 << ".size();\n";
252
253 out << blobName
254 << ".putInt64("
255 << offset
256 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
257
258 out << blobName
259 << ".putBool("
260 << offset
261 << " + 16 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
262
263 size_t elementAlign, elementSize;
264 mElementType->getAlignmentAndSize(&elementAlign, &elementSize);
265
266 // XXX make HwBlob constructor take a long instead of an int?
267 out << "HwBlob childBlob = new HwBlob((int)(_hidl_vec_size * "
268 << elementSize
269 << "));\n";
270
271 out << "for (int _hidl_index = 0; _hidl_index < _hidl_vec_size; "
272 << "++_hidl_index) {\n";
273
274 out.indent();
275
276 mElementType->emitJavaFieldReaderWriter(
277 out,
278 "childBlob",
279 fieldName + ".elementAt(_hidl_index)",
280 "_hidl_index * " + std::to_string(elementSize),
281 false /* isReader */);
282
283 out.unindent();
284
285 out << "}\n";
286
287 out << blobName
288 << ".putBlob("
289 << offset
290 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
291
292 out.unindent();
293 out << "}\n";
294}
295
Andreas Huber881227d2016-08-02 14:20:21 -0700296bool VectorType::needsEmbeddedReadWrite() const {
297 return true;
298}
299
300bool VectorType::resultNeedsDeref() const {
301 return true;
302}
303
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700304status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
305 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
306 out.indent();
307 status_t err = mElementType->emitVtsTypeDeclarations(out);
308 if (err != OK) {
309 return err;
310 }
311 out.unindent();
312 out << "}\n";
313 return OK;
314}
315
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700316status_t VectorType::emitVtsAttributeType(Formatter &out) const {
317 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
318 out.indent();
319 status_t status = mElementType->emitVtsAttributeType(out);
320 if (status != OK) {
321 return status;
322 }
323 out.unindent();
324 out << "}\n";
325 return OK;
326}
327
Andreas Huber70a59e12016-08-16 12:57:01 -0700328bool VectorType::isJavaCompatible() const {
329 return mElementType->isJavaCompatible();
330}
331
Andreas Huber85eabdb2016-08-25 11:24:49 -0700332void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
333 *align = 8; // hidl_vec<T>
334 *size = 24;
335}
336
Andreas Huberc9410c72016-07-28 12:18:40 -0700337} // namespace android
338