blob: b6267c6ac09814b52193d2c36a70fa1203643126 [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 Huberf03332a2016-09-22 15:35:43 -070021
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070022#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070023#include <android-base/logging.h>
24
Andreas Huberc9410c72016-07-28 12:18:40 -070025namespace android {
26
Yifan Hongbf459bc2016-08-23 16:50:37 -070027VectorType::VectorType() {
Andreas Huberc9410c72016-07-28 12:18:40 -070028}
29
Steven Moreland30bb6a82016-11-30 09:18:34 -080030std::string VectorType::typeName() const {
31 return "vector" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
32}
33
Yifan Hong51f9c8a2016-12-05 18:47:33 -080034bool VectorType::isCompatibleElementType(Type *elementType) const {
35 if (elementType->isScalar()) {
36 return true;
37 }
38 if (elementType->isString()) {
39 return true;
40 }
41 if (elementType->isEnum()) {
42 return true;
43 }
44 if (elementType->isBitField()) {
45 return true;
46 }
47 if (elementType->isCompoundType()
48 && static_cast<CompoundType *>(elementType)->style() == CompoundType::STYLE_STRUCT) {
49 return true;
50 }
51 if (elementType->isInterface()) {
52 return true;
53 }
54 if (elementType->isHandle()) {
55 return true;
56 }
57 if (elementType->isTemplatedType()) {
58 Type *inner = static_cast<TemplatedType *>(elementType)->getElementType();
59 return this->isCompatibleElementType(inner) && !inner->isInterface();
60 }
61 if (elementType->isArray()) {
62 Type *inner = static_cast<ArrayType *>(elementType)->getElementType();
63 return this->isCompatibleElementType(inner) && !inner->isInterface();
64 }
65 return false;
Steven Moreland30bb6a82016-11-30 09:18:34 -080066}
67
Steven Moreland979e0992016-09-07 09:18:08 -070068void VectorType::addNamedTypesToSet(std::set<const FQName> &set) const {
69 mElementType->addNamedTypesToSet(set);
70}
71
Andreas Huber86a112b2016-10-19 14:25:16 -070072bool VectorType::isVector() const {
73 return true;
74}
75
76bool VectorType::isVectorOfBinders() const {
77 return mElementType->isBinder();
78}
79
Yifan Hongc6752dc2016-12-20 14:00:14 -080080bool VectorType::canCheckEquality() const {
81 return mElementType->canCheckEquality();
82}
83
Steven Moreland979e0992016-09-07 09:18:08 -070084std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070085 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070086 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070087 std::string(specifyNamespaces ? "::android::hardware::" : "")
88 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070089 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070090 + ">";
91
Andreas Huber881227d2016-08-02 14:20:21 -070092 switch (mode) {
93 case StorageMode_Stack:
94 return base;
95
96 case StorageMode_Argument:
97 return "const " + base + "&";
98
99 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -0700100 {
101 if (isVectorOfBinders()) {
102 return base;
103 }
104
Andreas Huber881227d2016-08-02 14:20:21 -0700105 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700106 }
Andreas Huber881227d2016-08-02 14:20:21 -0700107 }
108}
109
Yifan Hong4ed13472016-11-02 10:44:11 -0700110std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700111
Yifan Hong4ed13472016-11-02 10:44:11 -0700112 std::string elementJavaType;
113 if (mElementType->isArray()) {
114 elementJavaType = mElementType->getJavaType();
115 } else {
116 elementJavaType = mElementType->getJavaWrapperType();
117 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700118
Yifan Hong1af73532016-11-09 14:32:58 -0800119 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700120 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700121 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700122}
123
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700124std::string VectorType::getVtsType() const {
125 return "TYPE_VECTOR";
126}
127
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800128std::string VectorType::getVtsValueName() const {
129 return "vector_value";
130}
131
Andreas Huber881227d2016-08-02 14:20:21 -0700132void VectorType::emitReaderWriter(
133 Formatter &out,
134 const std::string &name,
135 const std::string &parcelObj,
136 bool parcelObjIsPointer,
137 bool isReader,
138 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700139 if (isVectorOfBinders()) {
140 emitReaderWriterForVectorOfBinders(
141 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
142
143 return;
144 }
145
Yifan Hong3b320f82016-11-01 15:15:54 -0700146 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700147
Iliyan Malchev549e2592016-08-10 08:59:12 -0700148 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700149
150 out << "size_t " << parentName << ";\n\n";
151
152 const std::string parcelObjDeref =
153 parcelObj + (parcelObjIsPointer ? "->" : ".");
154
155 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100156 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700157 << parcelObjDeref
158 << "readBuffer(&"
159 << 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()) {
487 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700488 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700489 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700490 << "();\n";
491 }
492
493 out << "{\n";
494 out.indent();
495
Yifan Hong1af73532016-11-09 14:32:58 -0800496 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700497
498 if (isReader) {
499 out << parcelObj
500 << ".readBuffer();\n";
501 } else {
502 size_t align, size;
503 getAlignmentAndSize(&align, &size);
504
Yifan Hong1af73532016-11-09 14:32:58 -0800505 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700506 << size
507 << " /* size */);\n";
508 }
509
510 emitJavaFieldReaderWriter(
511 out,
512 0 /* depth */,
513 parcelObj,
514 "_hidl_blob",
515 argName,
516 "0 /* offset */",
517 isReader);
518
519 if (!isReader) {
520 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
521 };
522
523 out.unindent();
524 out << "}\n";
525
526 return;
527 }
528
Andreas Huberf630bc82016-09-09 14:52:25 -0700529 emitJavaReaderWriterWithSuffix(
530 out,
531 parcelObj,
532 argName,
533 isReader,
534 mElementType->getJavaSuffix() + "Vector",
535 "" /* extra */);
536}
537
Andreas Huber85eabdb2016-08-25 11:24:49 -0700538void VectorType::emitJavaFieldInitializer(
539 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700540 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700541
Andreas Huber1b6822b2016-10-18 09:28:40 -0700542 out << "final "
543 << javaType
544 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700545 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700546 << " = new "
547 << javaType
548 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700549}
550
551void VectorType::emitJavaFieldReaderWriter(
552 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700553 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700554 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700555 const std::string &blobName,
556 const std::string &fieldName,
557 const std::string &offset,
558 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700559 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700560 out,
561 depth,
562 mElementType,
563 parcelName,
564 blobName,
565 fieldName,
566 offset,
567 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700568}
569
570// static
571void VectorType::EmitJavaFieldReaderWriterForElementType(
572 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700573 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700574 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700575 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700576 const std::string &blobName,
577 const std::string &fieldName,
578 const std::string &offset,
579 bool isReader) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700580 if (isReader) {
581 out << "{\n";
582 out.indent();
583
Yifan Hong1af73532016-11-09 14:32:58 -0800584 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700585 << parcelName
586 << ".readEmbeddedBuffer(\n";
587
Andreas Huber85eabdb2016-08-25 11:24:49 -0700588 out.indent();
589 out.indent();
590
591 out << blobName
592 << ".handle(),\n"
593 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100594 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
595 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700596
597 out.unindent();
598 out.unindent();
599
600 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800601 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700602 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800603 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700604 << offset
605 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
606
Andreas Huber4c865b72016-09-14 15:26:27 -0700607 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
608
609 out << "for (int "
610 << iteratorName
611 << " = 0; "
612 << iteratorName
613 << " < _hidl_vec_size; "
614 << "++"
615 << iteratorName
616 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700617
618 out.indent();
619
Andreas Huberf630bc82016-09-09 14:52:25 -0700620 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700621
622 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700623 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700624
Andreas Huberf630bc82016-09-09 14:52:25 -0700625 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700626 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700627 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700628 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700629 "childBlob",
630 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700631 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632 true /* isReader */);
633
Andreas Huber1b6822b2016-10-18 09:28:40 -0700634 out << fieldName
635 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700636
637 out.unindent();
638
639 out << "}\n";
640
641 out.unindent();
642 out << "}\n";
643
644 return;
645 }
646
647 out << "{\n";
648 out.indent();
649
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800650 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700651 << fieldName
652 << ".size();\n";
653
654 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800655 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700656 << offset
657 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
658
659 out << blobName
660 << ".putBool("
661 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800662 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700663
664 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700665 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700666
667 // 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 Huber85eabdb2016-08-25 11:24:49 -0700739void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
740 *align = 8; // hidl_vec<T>
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800741 *size = 16;
Andreas Huber85eabdb2016-08-25 11:24:49 -0700742}
743
Andreas Huberc9410c72016-07-28 12:18:40 -0700744} // namespace android
745