blob: 9bdd91eef82fa5e8a4b591a660a221d50a55edce [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
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700159 << "readBuffer("
160 << "sizeof(*"
161 << name
162 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700163 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100164 << ", "
165 << " reinterpret_cast<const void **>("
166 << "&" << name
167 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700168
Martijn Coenen6a082c62017-01-11 12:47:02 +0100169 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700170 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700171 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700172 << parcelObjDeref
173 << "writeBuffer(&"
174 << name
175 << ", sizeof("
176 << name
177 << "), &"
178 << parentName
179 << ");\n";
180
181 handleError(out, mode);
182 }
183
184 emitReaderWriterEmbedded(
185 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700186 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700187 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700188 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700189 isReader /* nameIsPointer */,
190 parcelObj,
191 parcelObjIsPointer,
192 isReader,
193 mode,
194 parentName,
195 "0 /* parentOffset */");
196}
197
Andreas Huber86a112b2016-10-19 14:25:16 -0700198void VectorType::emitReaderWriterForVectorOfBinders(
199 Formatter &out,
200 const std::string &name,
201 const std::string &parcelObj,
202 bool parcelObjIsPointer,
203 bool isReader,
204 ErrorMode mode) const {
205 const std::string parcelObjDeref =
206 parcelObj + (parcelObjIsPointer ? "->" : ".");
207
208 if (isReader) {
209 out << "{\n";
210 out.indent();
211
212 const std::string sizeName = "_hidl_" + name + "_size";
213
214 out << "uint64_t "
215 << sizeName
216 << ";\n";
217
218 out << "_hidl_err = "
219 << parcelObjDeref
220 << "readUint64(&"
221 << sizeName
222 << ");\n";
223
224 handleError(out, mode);
225
226 out << name
227 << ".resize("
228 << sizeName
229 << ");\n\n"
230 << "for (size_t _hidl_index = 0; _hidl_index < "
231 << sizeName
232 << "; ++_hidl_index) {\n";
233
234 out.indent();
235
Yifan Hong3b320f82016-11-01 15:15:54 -0700236 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800237 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700238
239 mElementType->emitReaderWriter(
240 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800241 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700242 parcelObj,
243 parcelObjIsPointer,
244 isReader,
245 mode);
246
247 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800248 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700249
250 out.unindent();
251 out << "}\n";
252
253 out.unindent();
254 out << "}\n";
255 } else {
256 out << "_hidl_err = "
257 << parcelObjDeref
258 << "writeUint64("
259 << name
260 << ".size());\n";
261
262 handleError(out, mode);
263
264 out << "for (size_t _hidl_index = 0; _hidl_index < "
265 << name
266 << ".size(); ++_hidl_index) {\n";
267
268 out.indent();
269
270 mElementType->emitReaderWriter(
271 out,
272 name + "[_hidl_index]",
273 parcelObj,
274 parcelObjIsPointer,
275 isReader,
276 mode);
277
278 out.unindent();
279 out << "}\n";
280 }
281}
282
Andreas Huber881227d2016-08-02 14:20:21 -0700283void VectorType::emitReaderWriterEmbedded(
284 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700285 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700286 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700287 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700288 bool nameIsPointer,
289 const std::string &parcelObj,
290 bool parcelObjIsPointer,
291 bool isReader,
292 ErrorMode mode,
293 const std::string &parentName,
294 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700295 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700296
Yifan Hongbe2a3732016-10-05 13:33:41 -0700297 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700298 out << "size_t " << childName << ";\n\n";
299
300 emitReaderWriterEmbeddedForTypeName(
301 out,
302 name,
303 nameIsPointer,
304 parcelObj,
305 parcelObjIsPointer,
306 isReader,
307 mode,
308 parentName,
309 offsetText,
310 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800311 childName,
312 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700313
314 if (!mElementType->needsEmbeddedReadWrite()) {
315 return;
316 }
317
318 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
319
Yifan Hong3b320f82016-11-01 15:15:54 -0700320 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700321
Andreas Huberf9d49f12016-09-12 14:58:36 -0700322 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
323
324 out << "for (size_t "
325 << iteratorName
326 << " = 0; "
327 << iteratorName
328 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700329 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700330 << "size(); ++"
331 << iteratorName
332 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700333
334 out.indent();
335
336 mElementType->emitReaderWriterEmbedded(
337 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700338 depth + 1,
339 (nameIsPointer ? "(*" + name + ")" : name)
340 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700341 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700342 false /* nameIsPointer */,
343 parcelObj,
344 parcelObjIsPointer,
345 isReader,
346 mode,
347 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700348 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700349
350 out.unindent();
351
352 out << "}\n\n";
353}
354
Yifan Hongbf459bc2016-08-23 16:50:37 -0700355void VectorType::emitResolveReferences(
356 Formatter &out,
357 const std::string &name,
358 bool nameIsPointer,
359 const std::string &parcelObj,
360 bool parcelObjIsPointer,
361 bool isReader,
362 ErrorMode mode) const {
363 emitResolveReferencesEmbeddedHelper(
364 out,
365 0, /* depth */
366 name,
367 name /* sanitizedName */,
368 nameIsPointer,
369 parcelObj,
370 parcelObjIsPointer,
371 isReader,
372 mode,
373 "_hidl_" + name + "_child",
374 "0 /* parentOffset */");
375}
376
377void VectorType::emitResolveReferencesEmbedded(
378 Formatter &out,
379 size_t depth,
380 const std::string &name,
381 const std::string &sanitizedName,
382 bool nameIsPointer,
383 const std::string &parcelObj,
384 bool parcelObjIsPointer,
385 bool isReader,
386 ErrorMode mode,
387 const std::string & /* parentName */,
388 const std::string & /* offsetText */) const {
389 emitResolveReferencesEmbeddedHelper(
390 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
391 parcelObjIsPointer, isReader, mode, "", "");
392}
393
Yifan Hong00f47172016-09-30 14:40:45 -0700394bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
395 // parentName and offsetText is not used in emitResolveReferencesEmbedded
396 return false;
397}
398
Yifan Hongbf459bc2016-08-23 16:50:37 -0700399void VectorType::emitResolveReferencesEmbeddedHelper(
400 Formatter &out,
401 size_t depth,
402 const std::string &name,
403 const std::string &sanitizedName,
404 bool nameIsPointer,
405 const std::string &parcelObj,
406 bool parcelObjIsPointer,
407 bool isReader,
408 ErrorMode mode,
409 const std::string &childName,
410 const std::string &childOffsetText) const {
411 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
412
413 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800414 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700415 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700416
417 std::string myChildName = childName, myChildOffset = childOffsetText;
418
419 if(myChildName.empty() && myChildOffset.empty()) {
420 myChildName = "_hidl_" + sanitizedName + "_child";
421 myChildOffset = "0";
422
423 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800424 out << "_hidl_err = ::android::hardware::findInParcel("
425 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700426 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
427 << "&" << myChildName
428 << ");\n";
429
430 handleError(out, mode);
431 }
432
433 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
434
435 out << "for (size_t "
436 << iteratorName
437 << " = 0; "
438 << iteratorName
439 << " < "
440 << nameDeref
441 << "size(); ++"
442 << iteratorName
443 << ") {\n";
444
445 out.indent();
446
447 mElementType->emitResolveReferencesEmbedded(
448 out,
449 depth + 1,
450 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
451 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
452 false /* nameIsPointer */,
453 parcelObj,
454 parcelObjIsPointer,
455 isReader,
456 mode,
457 myChildName,
458 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700459 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700460
461 out.unindent();
462
463 out << "}\n\n";
464}
465
Andreas Huberf630bc82016-09-09 14:52:25 -0700466void VectorType::emitJavaReaderWriter(
467 Formatter &out,
468 const std::string &parcelObj,
469 const std::string &argName,
470 bool isReader) const {
471 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700472
Andreas Huberf630bc82016-09-09 14:52:25 -0700473 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700474 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700475 << ".readVectorFromParcel("
476 << parcelObj
477 << ");\n";
478 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700479 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700480 << ".writeVectorToParcel("
481 << parcelObj
482 << ", "
483 << argName
484 << ");\n";
485 }
486
487 return;
488 }
489
Andreas Huber1b6822b2016-10-18 09:28:40 -0700490 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700491 size_t align, size;
492 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700493 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700494 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700495 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700496 << "();\n";
497 }
498
499 out << "{\n";
500 out.indent();
501
Yifan Hong1af73532016-11-09 14:32:58 -0800502 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700503
504 if (isReader) {
505 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700506 << ".readBuffer("
507 << size
508 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700509 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700510
Yifan Hong1af73532016-11-09 14:32:58 -0800511 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700512 << size
513 << " /* size */);\n";
514 }
515
516 emitJavaFieldReaderWriter(
517 out,
518 0 /* depth */,
519 parcelObj,
520 "_hidl_blob",
521 argName,
522 "0 /* offset */",
523 isReader);
524
525 if (!isReader) {
526 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
527 };
528
529 out.unindent();
530 out << "}\n";
531
532 return;
533 }
534
Andreas Huberf630bc82016-09-09 14:52:25 -0700535 emitJavaReaderWriterWithSuffix(
536 out,
537 parcelObj,
538 argName,
539 isReader,
540 mElementType->getJavaSuffix() + "Vector",
541 "" /* extra */);
542}
543
Andreas Huber85eabdb2016-08-25 11:24:49 -0700544void VectorType::emitJavaFieldInitializer(
545 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700546 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700547
Andreas Huber1b6822b2016-10-18 09:28:40 -0700548 out << "final "
549 << javaType
550 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700551 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700552 << " = new "
553 << javaType
554 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700555}
556
557void VectorType::emitJavaFieldReaderWriter(
558 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700559 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700560 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700561 const std::string &blobName,
562 const std::string &fieldName,
563 const std::string &offset,
564 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700565 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700566 out,
567 depth,
568 mElementType,
569 parcelName,
570 blobName,
571 fieldName,
572 offset,
573 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700574}
575
576// static
577void VectorType::EmitJavaFieldReaderWriterForElementType(
578 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700579 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700580 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700581 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700582 const std::string &blobName,
583 const std::string &fieldName,
584 const std::string &offset,
585 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700586 size_t elementAlign, elementSize;
587 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
588
Andreas Huber85eabdb2016-08-25 11:24:49 -0700589 if (isReader) {
590 out << "{\n";
591 out.indent();
592
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700593 out << "int _hidl_vec_size = "
594 << blobName
595 << ".getInt32("
596 << offset
597 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
598
Yifan Hong1af73532016-11-09 14:32:58 -0800599 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700600 << parcelName
601 << ".readEmbeddedBuffer(\n";
602
Andreas Huber85eabdb2016-08-25 11:24:49 -0700603 out.indent();
604 out.indent();
605
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700606 out << "_hidl_vec_size * "
607 << elementSize << ","
608 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700609 << ".handle(),\n"
610 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100611 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
612 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700613
614 out.unindent();
615 out.unindent();
616
617 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700618 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
619
620 out << "for (int "
621 << iteratorName
622 << " = 0; "
623 << iteratorName
624 << " < _hidl_vec_size; "
625 << "++"
626 << iteratorName
627 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700628
629 out.indent();
630
Andreas Huberf630bc82016-09-09 14:52:25 -0700631 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632
Andreas Huberf630bc82016-09-09 14:52:25 -0700633 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700634 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700635 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700636 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700637 "childBlob",
638 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700639 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700640 true /* isReader */);
641
Andreas Huber1b6822b2016-10-18 09:28:40 -0700642 out << fieldName
643 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700644
645 out.unindent();
646
647 out << "}\n";
648
649 out.unindent();
650 out << "}\n";
651
652 return;
653 }
654
655 out << "{\n";
656 out.indent();
657
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800658 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700659 << fieldName
660 << ".size();\n";
661
662 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800663 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700664 << offset
665 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
666
667 out << blobName
668 << ".putBool("
669 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800670 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700671
Andreas Huber85eabdb2016-08-25 11:24:49 -0700672 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800673 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700674 << elementSize
675 << "));\n";
676
Andreas Huber4c865b72016-09-14 15:26:27 -0700677 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
678
679 out << "for (int "
680 << iteratorName
681 << " = 0; "
682 << iteratorName
683 << " < _hidl_vec_size; "
684 << "++"
685 << iteratorName
686 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700687
688 out.indent();
689
Andreas Huberf630bc82016-09-09 14:52:25 -0700690 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700691 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700692 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700693 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700694 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700695 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700696 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700697 false /* isReader */);
698
699 out.unindent();
700
701 out << "}\n";
702
703 out << blobName
704 << ".putBlob("
705 << offset
706 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
707
708 out.unindent();
709 out << "}\n";
710}
711
Andreas Huber881227d2016-08-02 14:20:21 -0700712bool VectorType::needsEmbeddedReadWrite() const {
713 return true;
714}
715
Yifan Hongbf459bc2016-08-23 16:50:37 -0700716bool VectorType::needsResolveReferences() const {
717 return mElementType->needsResolveReferences();
718}
719
Andreas Huber881227d2016-08-02 14:20:21 -0700720bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700721 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700722}
723
Andreas Huber70a59e12016-08-16 12:57:01 -0700724bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700725 if (!mElementType->isJavaCompatible()) {
726 return false;
727 }
728
729 if (mElementType->isArray()) {
730 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
731 }
732
Andreas Huber1b6822b2016-10-18 09:28:40 -0700733 if (mElementType->isVector()) {
734 return false;
735 }
736
Andreas Huber86a112b2016-10-19 14:25:16 -0700737 if (isVectorOfBinders()) {
738 return false;
739 }
740
Andreas Huberf03332a2016-09-22 15:35:43 -0700741 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700742}
743
Andreas Huber60d3b222017-03-30 09:10:56 -0700744bool VectorType::containsPointer() const {
745 return mElementType->containsPointer();
746}
747
Andreas Huber6755e9d2017-04-06 11:09:07 -0700748// All hidl_vec<T> have the same size.
749static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700750
751// static
752void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700753 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700754 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700755}
756
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700757void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
758 VectorType::getAlignmentAndSizeStatic(align, size);
759}
760
Andreas Huberc9410c72016-07-28 12:18:40 -0700761} // namespace android
762