blob: 237113eef6eec0c91ab4c9b9b53875b001f8b049 [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
Steven Moreland979e0992016-09-07 09:18:08 -070069void VectorType::addNamedTypesToSet(std::set<const FQName> &set) const {
70 mElementType->addNamedTypesToSet(set);
71}
72
Andreas Huber86a112b2016-10-19 14:25:16 -070073bool VectorType::isVector() const {
74 return true;
75}
76
77bool VectorType::isVectorOfBinders() const {
78 return mElementType->isBinder();
79}
80
Yifan Hongc6752dc2016-12-20 14:00:14 -080081bool VectorType::canCheckEquality() const {
82 return mElementType->canCheckEquality();
83}
84
Steven Moreland979e0992016-09-07 09:18:08 -070085std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070086 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070087 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070088 std::string(specifyNamespaces ? "::android::hardware::" : "")
89 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070090 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070091 + ">";
92
Andreas Huber881227d2016-08-02 14:20:21 -070093 switch (mode) {
94 case StorageMode_Stack:
95 return base;
96
97 case StorageMode_Argument:
98 return "const " + base + "&";
99
100 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -0700101 {
102 if (isVectorOfBinders()) {
103 return base;
104 }
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700107 }
Andreas Huber881227d2016-08-02 14:20:21 -0700108 }
109}
110
Yifan Hong4ed13472016-11-02 10:44:11 -0700111std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700112
Yifan Hong4ed13472016-11-02 10:44:11 -0700113 std::string elementJavaType;
114 if (mElementType->isArray()) {
115 elementJavaType = mElementType->getJavaType();
116 } else {
117 elementJavaType = mElementType->getJavaWrapperType();
118 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700119
Yifan Hong1af73532016-11-09 14:32:58 -0800120 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700121 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700122 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700123}
124
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700125std::string VectorType::getVtsType() const {
126 return "TYPE_VECTOR";
127}
128
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800129std::string VectorType::getVtsValueName() const {
130 return "vector_value";
131}
132
Andreas Huber881227d2016-08-02 14:20:21 -0700133void VectorType::emitReaderWriter(
134 Formatter &out,
135 const std::string &name,
136 const std::string &parcelObj,
137 bool parcelObjIsPointer,
138 bool isReader,
139 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700140 if (isVectorOfBinders()) {
141 emitReaderWriterForVectorOfBinders(
142 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
143
144 return;
145 }
146
Yifan Hong3b320f82016-11-01 15:15:54 -0700147 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700148
Iliyan Malchev549e2592016-08-10 08:59:12 -0700149 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700150
151 out << "size_t " << parentName << ";\n\n";
152
153 const std::string parcelObjDeref =
154 parcelObj + (parcelObjIsPointer ? "->" : ".");
155
156 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100157 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700158 << parcelObjDeref
159 << "readBuffer(&"
160 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100161 << ", "
162 << " reinterpret_cast<const void **>("
163 << "&" << name
164 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700165
Martijn Coenen6a082c62017-01-11 12:47:02 +0100166 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700167 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700168 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700169 << parcelObjDeref
170 << "writeBuffer(&"
171 << name
172 << ", sizeof("
173 << name
174 << "), &"
175 << parentName
176 << ");\n";
177
178 handleError(out, mode);
179 }
180
181 emitReaderWriterEmbedded(
182 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700183 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700184 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700185 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700186 isReader /* nameIsPointer */,
187 parcelObj,
188 parcelObjIsPointer,
189 isReader,
190 mode,
191 parentName,
192 "0 /* parentOffset */");
193}
194
Andreas Huber86a112b2016-10-19 14:25:16 -0700195void VectorType::emitReaderWriterForVectorOfBinders(
196 Formatter &out,
197 const std::string &name,
198 const std::string &parcelObj,
199 bool parcelObjIsPointer,
200 bool isReader,
201 ErrorMode mode) const {
202 const std::string parcelObjDeref =
203 parcelObj + (parcelObjIsPointer ? "->" : ".");
204
205 if (isReader) {
206 out << "{\n";
207 out.indent();
208
209 const std::string sizeName = "_hidl_" + name + "_size";
210
211 out << "uint64_t "
212 << sizeName
213 << ";\n";
214
215 out << "_hidl_err = "
216 << parcelObjDeref
217 << "readUint64(&"
218 << sizeName
219 << ");\n";
220
221 handleError(out, mode);
222
223 out << name
224 << ".resize("
225 << sizeName
226 << ");\n\n"
227 << "for (size_t _hidl_index = 0; _hidl_index < "
228 << sizeName
229 << "; ++_hidl_index) {\n";
230
231 out.indent();
232
Yifan Hong3b320f82016-11-01 15:15:54 -0700233 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800234 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700235
236 mElementType->emitReaderWriter(
237 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800238 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700239 parcelObj,
240 parcelObjIsPointer,
241 isReader,
242 mode);
243
244 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800245 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700246
247 out.unindent();
248 out << "}\n";
249
250 out.unindent();
251 out << "}\n";
252 } else {
253 out << "_hidl_err = "
254 << parcelObjDeref
255 << "writeUint64("
256 << name
257 << ".size());\n";
258
259 handleError(out, mode);
260
261 out << "for (size_t _hidl_index = 0; _hidl_index < "
262 << name
263 << ".size(); ++_hidl_index) {\n";
264
265 out.indent();
266
267 mElementType->emitReaderWriter(
268 out,
269 name + "[_hidl_index]",
270 parcelObj,
271 parcelObjIsPointer,
272 isReader,
273 mode);
274
275 out.unindent();
276 out << "}\n";
277 }
278}
279
Andreas Huber881227d2016-08-02 14:20:21 -0700280void VectorType::emitReaderWriterEmbedded(
281 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700282 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700283 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700284 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700285 bool nameIsPointer,
286 const std::string &parcelObj,
287 bool parcelObjIsPointer,
288 bool isReader,
289 ErrorMode mode,
290 const std::string &parentName,
291 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700292 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700293
Yifan Hongbe2a3732016-10-05 13:33:41 -0700294 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700295 out << "size_t " << childName << ";\n\n";
296
297 emitReaderWriterEmbeddedForTypeName(
298 out,
299 name,
300 nameIsPointer,
301 parcelObj,
302 parcelObjIsPointer,
303 isReader,
304 mode,
305 parentName,
306 offsetText,
307 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800308 childName,
309 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700310
311 if (!mElementType->needsEmbeddedReadWrite()) {
312 return;
313 }
314
315 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
316
Yifan Hong3b320f82016-11-01 15:15:54 -0700317 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700318
Andreas Huberf9d49f12016-09-12 14:58:36 -0700319 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
320
321 out << "for (size_t "
322 << iteratorName
323 << " = 0; "
324 << iteratorName
325 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700326 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700327 << "size(); ++"
328 << iteratorName
329 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700330
331 out.indent();
332
333 mElementType->emitReaderWriterEmbedded(
334 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700335 depth + 1,
336 (nameIsPointer ? "(*" + name + ")" : name)
337 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700338 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700339 false /* nameIsPointer */,
340 parcelObj,
341 parcelObjIsPointer,
342 isReader,
343 mode,
344 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700345 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700346
347 out.unindent();
348
349 out << "}\n\n";
350}
351
Yifan Hongbf459bc2016-08-23 16:50:37 -0700352void VectorType::emitResolveReferences(
353 Formatter &out,
354 const std::string &name,
355 bool nameIsPointer,
356 const std::string &parcelObj,
357 bool parcelObjIsPointer,
358 bool isReader,
359 ErrorMode mode) const {
360 emitResolveReferencesEmbeddedHelper(
361 out,
362 0, /* depth */
363 name,
364 name /* sanitizedName */,
365 nameIsPointer,
366 parcelObj,
367 parcelObjIsPointer,
368 isReader,
369 mode,
370 "_hidl_" + name + "_child",
371 "0 /* parentOffset */");
372}
373
374void VectorType::emitResolveReferencesEmbedded(
375 Formatter &out,
376 size_t depth,
377 const std::string &name,
378 const std::string &sanitizedName,
379 bool nameIsPointer,
380 const std::string &parcelObj,
381 bool parcelObjIsPointer,
382 bool isReader,
383 ErrorMode mode,
384 const std::string & /* parentName */,
385 const std::string & /* offsetText */) const {
386 emitResolveReferencesEmbeddedHelper(
387 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
388 parcelObjIsPointer, isReader, mode, "", "");
389}
390
Yifan Hong00f47172016-09-30 14:40:45 -0700391bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
392 // parentName and offsetText is not used in emitResolveReferencesEmbedded
393 return false;
394}
395
Yifan Hongbf459bc2016-08-23 16:50:37 -0700396void VectorType::emitResolveReferencesEmbeddedHelper(
397 Formatter &out,
398 size_t depth,
399 const std::string &name,
400 const std::string &sanitizedName,
401 bool nameIsPointer,
402 const std::string &parcelObj,
403 bool parcelObjIsPointer,
404 bool isReader,
405 ErrorMode mode,
406 const std::string &childName,
407 const std::string &childOffsetText) const {
408 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
409
410 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800411 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700412 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700413
414 std::string myChildName = childName, myChildOffset = childOffsetText;
415
416 if(myChildName.empty() && myChildOffset.empty()) {
417 myChildName = "_hidl_" + sanitizedName + "_child";
418 myChildOffset = "0";
419
420 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800421 out << "_hidl_err = ::android::hardware::findInParcel("
422 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700423 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
424 << "&" << myChildName
425 << ");\n";
426
427 handleError(out, mode);
428 }
429
430 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
431
432 out << "for (size_t "
433 << iteratorName
434 << " = 0; "
435 << iteratorName
436 << " < "
437 << nameDeref
438 << "size(); ++"
439 << iteratorName
440 << ") {\n";
441
442 out.indent();
443
444 mElementType->emitResolveReferencesEmbedded(
445 out,
446 depth + 1,
447 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
448 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
449 false /* nameIsPointer */,
450 parcelObj,
451 parcelObjIsPointer,
452 isReader,
453 mode,
454 myChildName,
455 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700456 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700457
458 out.unindent();
459
460 out << "}\n\n";
461}
462
Andreas Huberf630bc82016-09-09 14:52:25 -0700463void VectorType::emitJavaReaderWriter(
464 Formatter &out,
465 const std::string &parcelObj,
466 const std::string &argName,
467 bool isReader) const {
468 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700469
Andreas Huberf630bc82016-09-09 14:52:25 -0700470 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700471 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700472 << ".readVectorFromParcel("
473 << parcelObj
474 << ");\n";
475 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700476 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700477 << ".writeVectorToParcel("
478 << parcelObj
479 << ", "
480 << argName
481 << ");\n";
482 }
483
484 return;
485 }
486
Andreas Huber1b6822b2016-10-18 09:28:40 -0700487 if (mElementType->isArray()) {
488 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700489 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700490 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700491 << "();\n";
492 }
493
494 out << "{\n";
495 out.indent();
496
Yifan Hong1af73532016-11-09 14:32:58 -0800497 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700498
499 if (isReader) {
500 out << parcelObj
501 << ".readBuffer();\n";
502 } else {
503 size_t align, size;
504 getAlignmentAndSize(&align, &size);
505
Yifan Hong1af73532016-11-09 14:32:58 -0800506 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700507 << size
508 << " /* size */);\n";
509 }
510
511 emitJavaFieldReaderWriter(
512 out,
513 0 /* depth */,
514 parcelObj,
515 "_hidl_blob",
516 argName,
517 "0 /* offset */",
518 isReader);
519
520 if (!isReader) {
521 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
522 };
523
524 out.unindent();
525 out << "}\n";
526
527 return;
528 }
529
Andreas Huberf630bc82016-09-09 14:52:25 -0700530 emitJavaReaderWriterWithSuffix(
531 out,
532 parcelObj,
533 argName,
534 isReader,
535 mElementType->getJavaSuffix() + "Vector",
536 "" /* extra */);
537}
538
Andreas Huber85eabdb2016-08-25 11:24:49 -0700539void VectorType::emitJavaFieldInitializer(
540 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700541 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700542
Andreas Huber1b6822b2016-10-18 09:28:40 -0700543 out << "final "
544 << javaType
545 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700546 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700547 << " = new "
548 << javaType
549 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700550}
551
552void VectorType::emitJavaFieldReaderWriter(
553 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700554 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700555 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700556 const std::string &blobName,
557 const std::string &fieldName,
558 const std::string &offset,
559 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700560 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700561 out,
562 depth,
563 mElementType,
564 parcelName,
565 blobName,
566 fieldName,
567 offset,
568 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700569}
570
571// static
572void 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) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700581 if (isReader) {
582 out << "{\n";
583 out.indent();
584
Yifan Hong1af73532016-11-09 14:32:58 -0800585 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700586 << parcelName
587 << ".readEmbeddedBuffer(\n";
588
Andreas Huber85eabdb2016-08-25 11:24:49 -0700589 out.indent();
590 out.indent();
591
592 out << blobName
593 << ".handle(),\n"
594 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100595 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
596 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700597
598 out.unindent();
599 out.unindent();
600
601 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800602 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700603 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800604 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700605 << offset
606 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
607
Andreas Huber4c865b72016-09-14 15:26:27 -0700608 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
609
610 out << "for (int "
611 << iteratorName
612 << " = 0; "
613 << iteratorName
614 << " < _hidl_vec_size; "
615 << "++"
616 << iteratorName
617 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700618
619 out.indent();
620
Andreas Huberf630bc82016-09-09 14:52:25 -0700621 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700622
623 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700624 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700625
Andreas Huberf630bc82016-09-09 14:52:25 -0700626 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700627 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700628 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700629 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700630 "childBlob",
631 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700632 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700633 true /* isReader */);
634
Andreas Huber1b6822b2016-10-18 09:28:40 -0700635 out << fieldName
636 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700637
638 out.unindent();
639
640 out << "}\n";
641
642 out.unindent();
643 out << "}\n";
644
645 return;
646 }
647
648 out << "{\n";
649 out.indent();
650
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800651 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700652 << fieldName
653 << ".size();\n";
654
655 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800656 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700657 << offset
658 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
659
660 out << blobName
661 << ".putBool("
662 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800663 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700664
665 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700666 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700667
668 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800669 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700670 << elementSize
671 << "));\n";
672
Andreas Huber4c865b72016-09-14 15:26:27 -0700673 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
674
675 out << "for (int "
676 << iteratorName
677 << " = 0; "
678 << iteratorName
679 << " < _hidl_vec_size; "
680 << "++"
681 << iteratorName
682 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700683
684 out.indent();
685
Andreas Huberf630bc82016-09-09 14:52:25 -0700686 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700687 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700688 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700689 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700690 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700691 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700692 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700693 false /* isReader */);
694
695 out.unindent();
696
697 out << "}\n";
698
699 out << blobName
700 << ".putBlob("
701 << offset
702 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
703
704 out.unindent();
705 out << "}\n";
706}
707
Andreas Huber881227d2016-08-02 14:20:21 -0700708bool VectorType::needsEmbeddedReadWrite() const {
709 return true;
710}
711
Yifan Hongbf459bc2016-08-23 16:50:37 -0700712bool VectorType::needsResolveReferences() const {
713 return mElementType->needsResolveReferences();
714}
715
Andreas Huber881227d2016-08-02 14:20:21 -0700716bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700717 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700718}
719
Andreas Huber70a59e12016-08-16 12:57:01 -0700720bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700721 if (!mElementType->isJavaCompatible()) {
722 return false;
723 }
724
725 if (mElementType->isArray()) {
726 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
727 }
728
Andreas Huber1b6822b2016-10-18 09:28:40 -0700729 if (mElementType->isVector()) {
730 return false;
731 }
732
Andreas Huber86a112b2016-10-19 14:25:16 -0700733 if (isVectorOfBinders()) {
734 return false;
735 }
736
Andreas Huberf03332a2016-09-22 15:35:43 -0700737 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700738}
739
Andreas Huber60d3b222017-03-30 09:10:56 -0700740bool VectorType::containsPointer() const {
741 return mElementType->containsPointer();
742}
743
Andreas Huber6755e9d2017-04-06 11:09:07 -0700744// All hidl_vec<T> have the same size.
745static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700746void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
747 *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
Andreas Huberc9410c72016-07-28 12:18:40 -0700751} // namespace android
752