blob: d09c226997d2cb0a45a5770c00e69af362ba8bb6 [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 }
Steven Moreland397b5e12017-06-08 14:02:26 -070058 if (elementType->isMemory()) {
59 return true;
60 }
Yifan Hong51f9c8a2016-12-05 18:47:33 -080061 if (elementType->isTemplatedType()) {
62 Type *inner = static_cast<TemplatedType *>(elementType)->getElementType();
63 return this->isCompatibleElementType(inner) && !inner->isInterface();
64 }
65 if (elementType->isArray()) {
66 Type *inner = static_cast<ArrayType *>(elementType)->getElementType();
67 return this->isCompatibleElementType(inner) && !inner->isInterface();
68 }
69 return false;
Steven Moreland30bb6a82016-11-30 09:18:34 -080070}
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
Timur Iskhakov40731af2017-08-24 14:18:35 -070084std::vector<Reference<Type>> VectorType::getStrongReferences() const {
85 return {};
86}
87
Steven Moreland979e0992016-09-07 09:18:08 -070088std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070089 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070090 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070091 std::string(specifyNamespaces ? "::android::hardware::" : "")
92 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070093 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070094 + ">";
95
Andreas Huber881227d2016-08-02 14:20:21 -070096 switch (mode) {
97 case StorageMode_Stack:
98 return base;
99
100 case StorageMode_Argument:
101 return "const " + base + "&";
102
103 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -0700104 {
105 if (isVectorOfBinders()) {
106 return base;
107 }
108
Andreas Huber881227d2016-08-02 14:20:21 -0700109 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700110 }
Andreas Huber881227d2016-08-02 14:20:21 -0700111 }
112}
113
Yifan Hong4ed13472016-11-02 10:44:11 -0700114std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700115
Yifan Hong4ed13472016-11-02 10:44:11 -0700116 std::string elementJavaType;
117 if (mElementType->isArray()) {
118 elementJavaType = mElementType->getJavaType();
119 } else {
120 elementJavaType = mElementType->getJavaWrapperType();
121 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700122
Yifan Hong1af73532016-11-09 14:32:58 -0800123 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700124 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700125 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700126}
127
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700128std::string VectorType::getVtsType() const {
129 return "TYPE_VECTOR";
130}
131
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800132std::string VectorType::getVtsValueName() const {
133 return "vector_value";
134}
135
Andreas Huber881227d2016-08-02 14:20:21 -0700136void VectorType::emitReaderWriter(
137 Formatter &out,
138 const std::string &name,
139 const std::string &parcelObj,
140 bool parcelObjIsPointer,
141 bool isReader,
142 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700143 if (isVectorOfBinders()) {
144 emitReaderWriterForVectorOfBinders(
145 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
146
147 return;
148 }
149
Yifan Hong3b320f82016-11-01 15:15:54 -0700150 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700151
Iliyan Malchev549e2592016-08-10 08:59:12 -0700152 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700153
154 out << "size_t " << parentName << ";\n\n";
155
156 const std::string parcelObjDeref =
157 parcelObj + (parcelObjIsPointer ? "->" : ".");
158
159 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100160 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700161 << parcelObjDeref
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700162 << "readBuffer("
163 << "sizeof(*"
164 << name
165 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700166 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100167 << ", "
168 << " reinterpret_cast<const void **>("
169 << "&" << name
170 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700171
Martijn Coenen6a082c62017-01-11 12:47:02 +0100172 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700173 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700174 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700175 << parcelObjDeref
176 << "writeBuffer(&"
177 << name
178 << ", sizeof("
179 << name
180 << "), &"
181 << parentName
182 << ");\n";
183
184 handleError(out, mode);
185 }
186
187 emitReaderWriterEmbedded(
188 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700189 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700190 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700191 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700192 isReader /* nameIsPointer */,
193 parcelObj,
194 parcelObjIsPointer,
195 isReader,
196 mode,
197 parentName,
198 "0 /* parentOffset */");
199}
200
Andreas Huber86a112b2016-10-19 14:25:16 -0700201void VectorType::emitReaderWriterForVectorOfBinders(
202 Formatter &out,
203 const std::string &name,
204 const std::string &parcelObj,
205 bool parcelObjIsPointer,
206 bool isReader,
207 ErrorMode mode) const {
208 const std::string parcelObjDeref =
209 parcelObj + (parcelObjIsPointer ? "->" : ".");
210
211 if (isReader) {
212 out << "{\n";
213 out.indent();
214
215 const std::string sizeName = "_hidl_" + name + "_size";
216
217 out << "uint64_t "
218 << sizeName
219 << ";\n";
220
221 out << "_hidl_err = "
222 << parcelObjDeref
223 << "readUint64(&"
224 << sizeName
225 << ");\n";
226
227 handleError(out, mode);
228
229 out << name
230 << ".resize("
231 << sizeName
232 << ");\n\n"
233 << "for (size_t _hidl_index = 0; _hidl_index < "
234 << sizeName
235 << "; ++_hidl_index) {\n";
236
237 out.indent();
238
Yifan Hong3b320f82016-11-01 15:15:54 -0700239 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800240 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700241
242 mElementType->emitReaderWriter(
243 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800244 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700245 parcelObj,
246 parcelObjIsPointer,
247 isReader,
248 mode);
249
250 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800251 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700252
253 out.unindent();
254 out << "}\n";
255
256 out.unindent();
257 out << "}\n";
258 } else {
259 out << "_hidl_err = "
260 << parcelObjDeref
261 << "writeUint64("
262 << name
263 << ".size());\n";
264
265 handleError(out, mode);
266
267 out << "for (size_t _hidl_index = 0; _hidl_index < "
268 << name
269 << ".size(); ++_hidl_index) {\n";
270
271 out.indent();
272
273 mElementType->emitReaderWriter(
274 out,
275 name + "[_hidl_index]",
276 parcelObj,
277 parcelObjIsPointer,
278 isReader,
279 mode);
280
281 out.unindent();
282 out << "}\n";
283 }
284}
285
Andreas Huber881227d2016-08-02 14:20:21 -0700286void VectorType::emitReaderWriterEmbedded(
287 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700288 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700289 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700290 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700291 bool nameIsPointer,
292 const std::string &parcelObj,
293 bool parcelObjIsPointer,
294 bool isReader,
295 ErrorMode mode,
296 const std::string &parentName,
297 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700298 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700299
Yifan Hongbe2a3732016-10-05 13:33:41 -0700300 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700301 out << "size_t " << childName << ";\n\n";
302
303 emitReaderWriterEmbeddedForTypeName(
304 out,
305 name,
306 nameIsPointer,
307 parcelObj,
308 parcelObjIsPointer,
309 isReader,
310 mode,
311 parentName,
312 offsetText,
313 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800314 childName,
315 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700316
317 if (!mElementType->needsEmbeddedReadWrite()) {
318 return;
319 }
320
321 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
322
Yifan Hong3b320f82016-11-01 15:15:54 -0700323 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700324
Andreas Huberf9d49f12016-09-12 14:58:36 -0700325 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
326
327 out << "for (size_t "
328 << iteratorName
329 << " = 0; "
330 << iteratorName
331 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700332 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700333 << "size(); ++"
334 << iteratorName
335 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700336
337 out.indent();
338
339 mElementType->emitReaderWriterEmbedded(
340 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700341 depth + 1,
342 (nameIsPointer ? "(*" + name + ")" : name)
343 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700344 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700345 false /* nameIsPointer */,
346 parcelObj,
347 parcelObjIsPointer,
348 isReader,
349 mode,
350 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700351 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700352
353 out.unindent();
354
355 out << "}\n\n";
356}
357
Yifan Hongbf459bc2016-08-23 16:50:37 -0700358void VectorType::emitResolveReferences(
359 Formatter &out,
360 const std::string &name,
361 bool nameIsPointer,
362 const std::string &parcelObj,
363 bool parcelObjIsPointer,
364 bool isReader,
365 ErrorMode mode) const {
366 emitResolveReferencesEmbeddedHelper(
367 out,
368 0, /* depth */
369 name,
370 name /* sanitizedName */,
371 nameIsPointer,
372 parcelObj,
373 parcelObjIsPointer,
374 isReader,
375 mode,
376 "_hidl_" + name + "_child",
377 "0 /* parentOffset */");
378}
379
380void VectorType::emitResolveReferencesEmbedded(
381 Formatter &out,
382 size_t depth,
383 const std::string &name,
384 const std::string &sanitizedName,
385 bool nameIsPointer,
386 const std::string &parcelObj,
387 bool parcelObjIsPointer,
388 bool isReader,
389 ErrorMode mode,
390 const std::string & /* parentName */,
391 const std::string & /* offsetText */) const {
392 emitResolveReferencesEmbeddedHelper(
393 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
394 parcelObjIsPointer, isReader, mode, "", "");
395}
396
Yifan Hong00f47172016-09-30 14:40:45 -0700397bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
398 // parentName and offsetText is not used in emitResolveReferencesEmbedded
399 return false;
400}
401
Yifan Hongbf459bc2016-08-23 16:50:37 -0700402void VectorType::emitResolveReferencesEmbeddedHelper(
403 Formatter &out,
404 size_t depth,
405 const std::string &name,
406 const std::string &sanitizedName,
407 bool nameIsPointer,
408 const std::string &parcelObj,
409 bool parcelObjIsPointer,
410 bool isReader,
411 ErrorMode mode,
412 const std::string &childName,
413 const std::string &childOffsetText) const {
414 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
415
416 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800417 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700418 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700419
420 std::string myChildName = childName, myChildOffset = childOffsetText;
421
422 if(myChildName.empty() && myChildOffset.empty()) {
423 myChildName = "_hidl_" + sanitizedName + "_child";
424 myChildOffset = "0";
425
426 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800427 out << "_hidl_err = ::android::hardware::findInParcel("
428 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700429 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
430 << "&" << myChildName
431 << ");\n";
432
433 handleError(out, mode);
434 }
435
436 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
437
438 out << "for (size_t "
439 << iteratorName
440 << " = 0; "
441 << iteratorName
442 << " < "
443 << nameDeref
444 << "size(); ++"
445 << iteratorName
446 << ") {\n";
447
448 out.indent();
449
450 mElementType->emitResolveReferencesEmbedded(
451 out,
452 depth + 1,
453 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
454 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
455 false /* nameIsPointer */,
456 parcelObj,
457 parcelObjIsPointer,
458 isReader,
459 mode,
460 myChildName,
461 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700462 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700463
464 out.unindent();
465
466 out << "}\n\n";
467}
468
Andreas Huberf630bc82016-09-09 14:52:25 -0700469void VectorType::emitJavaReaderWriter(
470 Formatter &out,
471 const std::string &parcelObj,
472 const std::string &argName,
473 bool isReader) const {
474 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700475
Andreas Huberf630bc82016-09-09 14:52:25 -0700476 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700477 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700478 << ".readVectorFromParcel("
479 << parcelObj
480 << ");\n";
481 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700482 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700483 << ".writeVectorToParcel("
484 << parcelObj
485 << ", "
486 << argName
487 << ");\n";
488 }
489
490 return;
491 }
492
Andreas Huber1b6822b2016-10-18 09:28:40 -0700493 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700494 size_t align, size;
495 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700496 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700497 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700498 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700499 << "();\n";
500 }
501
502 out << "{\n";
503 out.indent();
504
Yifan Hong1af73532016-11-09 14:32:58 -0800505 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700506
507 if (isReader) {
508 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700509 << ".readBuffer("
510 << size
511 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700512 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700513
Yifan Hong1af73532016-11-09 14:32:58 -0800514 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700515 << size
516 << " /* size */);\n";
517 }
518
519 emitJavaFieldReaderWriter(
520 out,
521 0 /* depth */,
522 parcelObj,
523 "_hidl_blob",
524 argName,
525 "0 /* offset */",
526 isReader);
527
528 if (!isReader) {
529 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
530 };
531
532 out.unindent();
533 out << "}\n";
534
535 return;
536 }
537
Andreas Huberf630bc82016-09-09 14:52:25 -0700538 emitJavaReaderWriterWithSuffix(
539 out,
540 parcelObj,
541 argName,
542 isReader,
543 mElementType->getJavaSuffix() + "Vector",
544 "" /* extra */);
545}
546
Andreas Huber85eabdb2016-08-25 11:24:49 -0700547void VectorType::emitJavaFieldInitializer(
548 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700549 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700550
Andreas Huber1b6822b2016-10-18 09:28:40 -0700551 out << "final "
552 << javaType
553 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700554 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700555 << " = new "
556 << javaType
557 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700558}
559
560void VectorType::emitJavaFieldReaderWriter(
561 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700562 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700563 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700564 const std::string &blobName,
565 const std::string &fieldName,
566 const std::string &offset,
567 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700568 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700569 out,
570 depth,
571 mElementType,
572 parcelName,
573 blobName,
574 fieldName,
575 offset,
576 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700577}
578
Andreas Huberf630bc82016-09-09 14:52:25 -0700579void VectorType::EmitJavaFieldReaderWriterForElementType(
580 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700581 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700582 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700583 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700584 const std::string &blobName,
585 const std::string &fieldName,
586 const std::string &offset,
587 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700588 size_t elementAlign, elementSize;
589 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
590
Andreas Huber85eabdb2016-08-25 11:24:49 -0700591 if (isReader) {
592 out << "{\n";
593 out.indent();
594
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700595 out << "int _hidl_vec_size = "
596 << blobName
597 << ".getInt32("
598 << offset
599 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
600
Yifan Hong1af73532016-11-09 14:32:58 -0800601 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700602 << parcelName
603 << ".readEmbeddedBuffer(\n";
604
Andreas Huber85eabdb2016-08-25 11:24:49 -0700605 out.indent();
606 out.indent();
607
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700608 out << "_hidl_vec_size * "
609 << elementSize << ","
610 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700611 << ".handle(),\n"
612 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100613 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
614 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700615
616 out.unindent();
617 out.unindent();
618
619 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700620 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
621
622 out << "for (int "
623 << iteratorName
624 << " = 0; "
625 << iteratorName
626 << " < _hidl_vec_size; "
627 << "++"
628 << iteratorName
629 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700630
631 out.indent();
632
Andreas Huberf630bc82016-09-09 14:52:25 -0700633 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700634
Andreas Huberf630bc82016-09-09 14:52:25 -0700635 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700636 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700637 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700638 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700639 "childBlob",
640 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700641 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700642 true /* isReader */);
643
Andreas Huber1b6822b2016-10-18 09:28:40 -0700644 out << fieldName
645 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700646
647 out.unindent();
648
649 out << "}\n";
650
651 out.unindent();
652 out << "}\n";
653
654 return;
655 }
656
657 out << "{\n";
658 out.indent();
659
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800660 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700661 << fieldName
662 << ".size();\n";
663
664 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800665 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700666 << offset
667 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
668
669 out << blobName
670 << ".putBool("
671 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800672 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700673
Andreas Huber85eabdb2016-08-25 11:24:49 -0700674 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800675 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700676 << elementSize
677 << "));\n";
678
Andreas Huber4c865b72016-09-14 15:26:27 -0700679 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
680
681 out << "for (int "
682 << iteratorName
683 << " = 0; "
684 << iteratorName
685 << " < _hidl_vec_size; "
686 << "++"
687 << iteratorName
688 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700689
690 out.indent();
691
Andreas Huberf630bc82016-09-09 14:52:25 -0700692 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700693 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700694 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700695 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700696 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700697 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700698 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700699 false /* isReader */);
700
701 out.unindent();
702
703 out << "}\n";
704
705 out << blobName
706 << ".putBlob("
707 << offset
708 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
709
710 out.unindent();
711 out << "}\n";
712}
713
Andreas Huber881227d2016-08-02 14:20:21 -0700714bool VectorType::needsEmbeddedReadWrite() const {
715 return true;
716}
717
Yifan Hongbf459bc2016-08-23 16:50:37 -0700718bool VectorType::needsResolveReferences() const {
719 return mElementType->needsResolveReferences();
720}
721
Andreas Huber881227d2016-08-02 14:20:21 -0700722bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700723 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700724}
725
Andreas Huber70a59e12016-08-16 12:57:01 -0700726bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700727 if (!mElementType->isJavaCompatible()) {
728 return false;
729 }
730
731 if (mElementType->isArray()) {
Timur Iskhakov505316c2017-08-05 03:38:59 +0000732 return static_cast<ArrayType*>(mElementType.get())->countDimensions() == 1;
Andreas Huberf03332a2016-09-22 15:35:43 -0700733 }
734
Andreas Huber1b6822b2016-10-18 09:28:40 -0700735 if (mElementType->isVector()) {
736 return false;
737 }
738
Andreas Huber86a112b2016-10-19 14:25:16 -0700739 if (isVectorOfBinders()) {
740 return false;
741 }
742
Andreas Huberf03332a2016-09-22 15:35:43 -0700743 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700744}
745
Andreas Huber60d3b222017-03-30 09:10:56 -0700746bool VectorType::containsPointer() const {
747 return mElementType->containsPointer();
748}
749
Andreas Huber6755e9d2017-04-06 11:09:07 -0700750// All hidl_vec<T> have the same size.
751static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700752
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700753void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700754 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700755 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700756}
757
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700758void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
759 VectorType::getAlignmentAndSizeStatic(align, size);
760}
761
Andreas Huberc9410c72016-07-28 12:18:40 -0700762} // namespace android
763