blob: 22c997f616b76376f3f0055d257b93d3e10253a4 [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
Andreas Huberf03332a2016-09-22 15:35:43 -070019#include "ArrayType.h"
Yifan Hong51f9c8a2016-12-05 18:47:33 -080020#include "CompoundType.h"
Andreas Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Andreas Huberf03332a2016-09-22 15:35:43 -070022
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070023#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070024#include <android-base/logging.h>
25
Andreas Huberc9410c72016-07-28 12:18:40 -070026namespace android {
27
Yifan Hongbf459bc2016-08-23 16:50:37 -070028VectorType::VectorType() {
Andreas Huberc9410c72016-07-28 12:18:40 -070029}
30
Steven Moreland30bb6a82016-11-30 09:18:34 -080031std::string VectorType::typeName() const {
32 return "vector" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
33}
34
Yifan Hong51f9c8a2016-12-05 18:47:33 -080035bool VectorType::isCompatibleElementType(Type *elementType) const {
36 if (elementType->isScalar()) {
37 return true;
38 }
39 if (elementType->isString()) {
40 return true;
41 }
42 if (elementType->isEnum()) {
43 return true;
44 }
45 if (elementType->isBitField()) {
46 return true;
47 }
48 if (elementType->isCompoundType()
49 && static_cast<CompoundType *>(elementType)->style() == CompoundType::STYLE_STRUCT) {
50 return true;
51 }
52 if (elementType->isInterface()) {
53 return true;
54 }
55 if (elementType->isHandle()) {
56 return true;
57 }
58 if (elementType->isTemplatedType()) {
59 Type *inner = static_cast<TemplatedType *>(elementType)->getElementType();
60 return this->isCompatibleElementType(inner) && !inner->isInterface();
61 }
62 if (elementType->isArray()) {
63 Type *inner = static_cast<ArrayType *>(elementType)->getElementType();
64 return this->isCompatibleElementType(inner) && !inner->isInterface();
65 }
66 return false;
Steven Moreland30bb6a82016-11-30 09:18:34 -080067}
68
Andreas Huber86a112b2016-10-19 14:25:16 -070069bool VectorType::isVector() const {
70 return true;
71}
72
73bool VectorType::isVectorOfBinders() const {
74 return mElementType->isBinder();
75}
76
Yifan Hongc6752dc2016-12-20 14:00:14 -080077bool VectorType::canCheckEquality() const {
78 return mElementType->canCheckEquality();
79}
80
Steven Moreland979e0992016-09-07 09:18:08 -070081std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070082 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070083 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070084 std::string(specifyNamespaces ? "::android::hardware::" : "")
85 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070086 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070087 + ">";
88
Andreas Huber881227d2016-08-02 14:20:21 -070089 switch (mode) {
90 case StorageMode_Stack:
91 return base;
92
93 case StorageMode_Argument:
94 return "const " + base + "&";
95
96 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -070097 {
98 if (isVectorOfBinders()) {
99 return base;
100 }
101
Andreas Huber881227d2016-08-02 14:20:21 -0700102 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700103 }
Andreas Huber881227d2016-08-02 14:20:21 -0700104 }
105}
106
Yifan Hong4ed13472016-11-02 10:44:11 -0700107std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700108
Yifan Hong4ed13472016-11-02 10:44:11 -0700109 std::string elementJavaType;
110 if (mElementType->isArray()) {
111 elementJavaType = mElementType->getJavaType();
112 } else {
113 elementJavaType = mElementType->getJavaWrapperType();
114 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700115
Yifan Hong1af73532016-11-09 14:32:58 -0800116 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700117 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700118 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700119}
120
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700121std::string VectorType::getVtsType() const {
122 return "TYPE_VECTOR";
123}
124
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800125std::string VectorType::getVtsValueName() const {
126 return "vector_value";
127}
128
Andreas Huber881227d2016-08-02 14:20:21 -0700129void VectorType::emitReaderWriter(
130 Formatter &out,
131 const std::string &name,
132 const std::string &parcelObj,
133 bool parcelObjIsPointer,
134 bool isReader,
135 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700136 if (isVectorOfBinders()) {
137 emitReaderWriterForVectorOfBinders(
138 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
139
140 return;
141 }
142
Yifan Hong3b320f82016-11-01 15:15:54 -0700143 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700144
Iliyan Malchev549e2592016-08-10 08:59:12 -0700145 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700146
147 out << "size_t " << parentName << ";\n\n";
148
149 const std::string parcelObjDeref =
150 parcelObj + (parcelObjIsPointer ? "->" : ".");
151
152 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100153 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700154 << parcelObjDeref
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700155 << "readBuffer("
156 << "sizeof(*"
157 << name
158 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700159 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100160 << ", "
161 << " reinterpret_cast<const void **>("
162 << "&" << name
163 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700164
Martijn Coenen6a082c62017-01-11 12:47:02 +0100165 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700166 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700167 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700168 << parcelObjDeref
169 << "writeBuffer(&"
170 << name
171 << ", sizeof("
172 << name
173 << "), &"
174 << parentName
175 << ");\n";
176
177 handleError(out, mode);
178 }
179
180 emitReaderWriterEmbedded(
181 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700182 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700183 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700184 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700185 isReader /* nameIsPointer */,
186 parcelObj,
187 parcelObjIsPointer,
188 isReader,
189 mode,
190 parentName,
191 "0 /* parentOffset */");
192}
193
Andreas Huber86a112b2016-10-19 14:25:16 -0700194void VectorType::emitReaderWriterForVectorOfBinders(
195 Formatter &out,
196 const std::string &name,
197 const std::string &parcelObj,
198 bool parcelObjIsPointer,
199 bool isReader,
200 ErrorMode mode) const {
201 const std::string parcelObjDeref =
202 parcelObj + (parcelObjIsPointer ? "->" : ".");
203
204 if (isReader) {
205 out << "{\n";
206 out.indent();
207
208 const std::string sizeName = "_hidl_" + name + "_size";
209
210 out << "uint64_t "
211 << sizeName
212 << ";\n";
213
214 out << "_hidl_err = "
215 << parcelObjDeref
216 << "readUint64(&"
217 << sizeName
218 << ");\n";
219
220 handleError(out, mode);
221
222 out << name
223 << ".resize("
224 << sizeName
225 << ");\n\n"
226 << "for (size_t _hidl_index = 0; _hidl_index < "
227 << sizeName
228 << "; ++_hidl_index) {\n";
229
230 out.indent();
231
Yifan Hong3b320f82016-11-01 15:15:54 -0700232 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800233 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700234
235 mElementType->emitReaderWriter(
236 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800237 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700238 parcelObj,
239 parcelObjIsPointer,
240 isReader,
241 mode);
242
243 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800244 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700245
246 out.unindent();
247 out << "}\n";
248
249 out.unindent();
250 out << "}\n";
251 } else {
252 out << "_hidl_err = "
253 << parcelObjDeref
254 << "writeUint64("
255 << name
256 << ".size());\n";
257
258 handleError(out, mode);
259
260 out << "for (size_t _hidl_index = 0; _hidl_index < "
261 << name
262 << ".size(); ++_hidl_index) {\n";
263
264 out.indent();
265
266 mElementType->emitReaderWriter(
267 out,
268 name + "[_hidl_index]",
269 parcelObj,
270 parcelObjIsPointer,
271 isReader,
272 mode);
273
274 out.unindent();
275 out << "}\n";
276 }
277}
278
Andreas Huber881227d2016-08-02 14:20:21 -0700279void VectorType::emitReaderWriterEmbedded(
280 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700281 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700282 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700283 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700284 bool nameIsPointer,
285 const std::string &parcelObj,
286 bool parcelObjIsPointer,
287 bool isReader,
288 ErrorMode mode,
289 const std::string &parentName,
290 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700291 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700292
Yifan Hongbe2a3732016-10-05 13:33:41 -0700293 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700294 out << "size_t " << childName << ";\n\n";
295
296 emitReaderWriterEmbeddedForTypeName(
297 out,
298 name,
299 nameIsPointer,
300 parcelObj,
301 parcelObjIsPointer,
302 isReader,
303 mode,
304 parentName,
305 offsetText,
306 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800307 childName,
308 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700309
310 if (!mElementType->needsEmbeddedReadWrite()) {
311 return;
312 }
313
314 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
315
Yifan Hong3b320f82016-11-01 15:15:54 -0700316 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700317
Andreas Huberf9d49f12016-09-12 14:58:36 -0700318 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
319
320 out << "for (size_t "
321 << iteratorName
322 << " = 0; "
323 << iteratorName
324 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700325 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700326 << "size(); ++"
327 << iteratorName
328 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700329
330 out.indent();
331
332 mElementType->emitReaderWriterEmbedded(
333 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700334 depth + 1,
335 (nameIsPointer ? "(*" + name + ")" : name)
336 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700337 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700338 false /* nameIsPointer */,
339 parcelObj,
340 parcelObjIsPointer,
341 isReader,
342 mode,
343 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700344 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700345
346 out.unindent();
347
348 out << "}\n\n";
349}
350
Yifan Hongbf459bc2016-08-23 16:50:37 -0700351void VectorType::emitResolveReferences(
352 Formatter &out,
353 const std::string &name,
354 bool nameIsPointer,
355 const std::string &parcelObj,
356 bool parcelObjIsPointer,
357 bool isReader,
358 ErrorMode mode) const {
359 emitResolveReferencesEmbeddedHelper(
360 out,
361 0, /* depth */
362 name,
363 name /* sanitizedName */,
364 nameIsPointer,
365 parcelObj,
366 parcelObjIsPointer,
367 isReader,
368 mode,
369 "_hidl_" + name + "_child",
370 "0 /* parentOffset */");
371}
372
373void VectorType::emitResolveReferencesEmbedded(
374 Formatter &out,
375 size_t depth,
376 const std::string &name,
377 const std::string &sanitizedName,
378 bool nameIsPointer,
379 const std::string &parcelObj,
380 bool parcelObjIsPointer,
381 bool isReader,
382 ErrorMode mode,
383 const std::string & /* parentName */,
384 const std::string & /* offsetText */) const {
385 emitResolveReferencesEmbeddedHelper(
386 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
387 parcelObjIsPointer, isReader, mode, "", "");
388}
389
Yifan Hong00f47172016-09-30 14:40:45 -0700390bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
391 // parentName and offsetText is not used in emitResolveReferencesEmbedded
392 return false;
393}
394
Yifan Hongbf459bc2016-08-23 16:50:37 -0700395void VectorType::emitResolveReferencesEmbeddedHelper(
396 Formatter &out,
397 size_t depth,
398 const std::string &name,
399 const std::string &sanitizedName,
400 bool nameIsPointer,
401 const std::string &parcelObj,
402 bool parcelObjIsPointer,
403 bool isReader,
404 ErrorMode mode,
405 const std::string &childName,
406 const std::string &childOffsetText) const {
407 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
408
409 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800410 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700411 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700412
413 std::string myChildName = childName, myChildOffset = childOffsetText;
414
415 if(myChildName.empty() && myChildOffset.empty()) {
416 myChildName = "_hidl_" + sanitizedName + "_child";
417 myChildOffset = "0";
418
419 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800420 out << "_hidl_err = ::android::hardware::findInParcel("
421 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700422 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
423 << "&" << myChildName
424 << ");\n";
425
426 handleError(out, mode);
427 }
428
429 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
430
431 out << "for (size_t "
432 << iteratorName
433 << " = 0; "
434 << iteratorName
435 << " < "
436 << nameDeref
437 << "size(); ++"
438 << iteratorName
439 << ") {\n";
440
441 out.indent();
442
443 mElementType->emitResolveReferencesEmbedded(
444 out,
445 depth + 1,
446 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
447 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
448 false /* nameIsPointer */,
449 parcelObj,
450 parcelObjIsPointer,
451 isReader,
452 mode,
453 myChildName,
454 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700455 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700456
457 out.unindent();
458
459 out << "}\n\n";
460}
461
Andreas Huberf630bc82016-09-09 14:52:25 -0700462void VectorType::emitJavaReaderWriter(
463 Formatter &out,
464 const std::string &parcelObj,
465 const std::string &argName,
466 bool isReader) const {
467 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700468
Andreas Huberf630bc82016-09-09 14:52:25 -0700469 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700470 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700471 << ".readVectorFromParcel("
472 << parcelObj
473 << ");\n";
474 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700475 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700476 << ".writeVectorToParcel("
477 << parcelObj
478 << ", "
479 << argName
480 << ");\n";
481 }
482
483 return;
484 }
485
Andreas Huber1b6822b2016-10-18 09:28:40 -0700486 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700487 size_t align, size;
488 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700489 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700490 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700491 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700492 << "();\n";
493 }
494
495 out << "{\n";
496 out.indent();
497
Yifan Hong1af73532016-11-09 14:32:58 -0800498 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700499
500 if (isReader) {
501 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700502 << ".readBuffer("
503 << size
504 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700505 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700506
Yifan Hong1af73532016-11-09 14:32:58 -0800507 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700508 << size
509 << " /* size */);\n";
510 }
511
512 emitJavaFieldReaderWriter(
513 out,
514 0 /* depth */,
515 parcelObj,
516 "_hidl_blob",
517 argName,
518 "0 /* offset */",
519 isReader);
520
521 if (!isReader) {
522 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
523 };
524
525 out.unindent();
526 out << "}\n";
527
528 return;
529 }
530
Andreas Huberf630bc82016-09-09 14:52:25 -0700531 emitJavaReaderWriterWithSuffix(
532 out,
533 parcelObj,
534 argName,
535 isReader,
536 mElementType->getJavaSuffix() + "Vector",
537 "" /* extra */);
538}
539
Andreas Huber85eabdb2016-08-25 11:24:49 -0700540void VectorType::emitJavaFieldInitializer(
541 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700542 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700543
Andreas Huber1b6822b2016-10-18 09:28:40 -0700544 out << "final "
545 << javaType
546 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700547 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700548 << " = new "
549 << javaType
550 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700551}
552
553void VectorType::emitJavaFieldReaderWriter(
554 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700555 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700556 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700557 const std::string &blobName,
558 const std::string &fieldName,
559 const std::string &offset,
560 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700561 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700562 out,
563 depth,
564 mElementType,
565 parcelName,
566 blobName,
567 fieldName,
568 offset,
569 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700570}
571
Andreas Huberf630bc82016-09-09 14:52:25 -0700572void VectorType::EmitJavaFieldReaderWriterForElementType(
573 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700574 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700575 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700576 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700577 const std::string &blobName,
578 const std::string &fieldName,
579 const std::string &offset,
580 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700581 size_t elementAlign, elementSize;
582 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
583
Andreas Huber85eabdb2016-08-25 11:24:49 -0700584 if (isReader) {
585 out << "{\n";
586 out.indent();
587
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700588 out << "int _hidl_vec_size = "
589 << blobName
590 << ".getInt32("
591 << offset
592 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
593
Yifan Hong1af73532016-11-09 14:32:58 -0800594 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700595 << parcelName
596 << ".readEmbeddedBuffer(\n";
597
Andreas Huber85eabdb2016-08-25 11:24:49 -0700598 out.indent();
599 out.indent();
600
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700601 out << "_hidl_vec_size * "
602 << elementSize << ","
603 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700604 << ".handle(),\n"
605 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100606 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
607 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700608
609 out.unindent();
610 out.unindent();
611
612 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700613 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
614
615 out << "for (int "
616 << iteratorName
617 << " = 0; "
618 << iteratorName
619 << " < _hidl_vec_size; "
620 << "++"
621 << iteratorName
622 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700623
624 out.indent();
625
Andreas Huberf630bc82016-09-09 14:52:25 -0700626 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700627
Andreas Huberf630bc82016-09-09 14:52:25 -0700628 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700629 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700630 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700631 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632 "childBlob",
633 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700634 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700635 true /* isReader */);
636
Andreas Huber1b6822b2016-10-18 09:28:40 -0700637 out << fieldName
638 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700639
640 out.unindent();
641
642 out << "}\n";
643
644 out.unindent();
645 out << "}\n";
646
647 return;
648 }
649
650 out << "{\n";
651 out.indent();
652
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800653 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700654 << fieldName
655 << ".size();\n";
656
657 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800658 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700659 << offset
660 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
661
662 out << blobName
663 << ".putBool("
664 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800665 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700666
Andreas Huber85eabdb2016-08-25 11:24:49 -0700667 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800668 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700669 << elementSize
670 << "));\n";
671
Andreas Huber4c865b72016-09-14 15:26:27 -0700672 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
673
674 out << "for (int "
675 << iteratorName
676 << " = 0; "
677 << iteratorName
678 << " < _hidl_vec_size; "
679 << "++"
680 << iteratorName
681 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700682
683 out.indent();
684
Andreas Huberf630bc82016-09-09 14:52:25 -0700685 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700686 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700687 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700688 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700689 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700690 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700691 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700692 false /* isReader */);
693
694 out.unindent();
695
696 out << "}\n";
697
698 out << blobName
699 << ".putBlob("
700 << offset
701 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
702
703 out.unindent();
704 out << "}\n";
705}
706
Andreas Huber881227d2016-08-02 14:20:21 -0700707bool VectorType::needsEmbeddedReadWrite() const {
708 return true;
709}
710
Yifan Hongbf459bc2016-08-23 16:50:37 -0700711bool VectorType::needsResolveReferences() const {
712 return mElementType->needsResolveReferences();
713}
714
Andreas Huber881227d2016-08-02 14:20:21 -0700715bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700716 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700717}
718
Andreas Huber70a59e12016-08-16 12:57:01 -0700719bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700720 if (!mElementType->isJavaCompatible()) {
721 return false;
722 }
723
724 if (mElementType->isArray()) {
725 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
726 }
727
Andreas Huber1b6822b2016-10-18 09:28:40 -0700728 if (mElementType->isVector()) {
729 return false;
730 }
731
Andreas Huber86a112b2016-10-19 14:25:16 -0700732 if (isVectorOfBinders()) {
733 return false;
734 }
735
Andreas Huberf03332a2016-09-22 15:35:43 -0700736 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700737}
738
Andreas Huber60d3b222017-03-30 09:10:56 -0700739bool VectorType::containsPointer() const {
740 return mElementType->containsPointer();
741}
742
Andreas Huber6755e9d2017-04-06 11:09:07 -0700743// All hidl_vec<T> have the same size.
744static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700745
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700746void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700747 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700748 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700749}
750
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700751void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
752 VectorType::getAlignmentAndSizeStatic(align, size);
753}
754
Andreas Huberc9410c72016-07-28 12:18:40 -0700755} // namespace android
756