blob: 50ceef09e30a074859909c6ef09012184cb0560f [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
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
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700158 << "readBuffer("
159 << "sizeof(*"
160 << name
161 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700162 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100163 << ", "
164 << " reinterpret_cast<const void **>("
165 << "&" << name
166 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700167
Martijn Coenen6a082c62017-01-11 12:47:02 +0100168 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700169 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700170 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700171 << parcelObjDeref
172 << "writeBuffer(&"
173 << name
174 << ", sizeof("
175 << name
176 << "), &"
177 << parentName
178 << ");\n";
179
180 handleError(out, mode);
181 }
182
183 emitReaderWriterEmbedded(
184 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700185 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700186 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700187 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700188 isReader /* nameIsPointer */,
189 parcelObj,
190 parcelObjIsPointer,
191 isReader,
192 mode,
193 parentName,
194 "0 /* parentOffset */");
195}
196
Andreas Huber86a112b2016-10-19 14:25:16 -0700197void VectorType::emitReaderWriterForVectorOfBinders(
198 Formatter &out,
199 const std::string &name,
200 const std::string &parcelObj,
201 bool parcelObjIsPointer,
202 bool isReader,
203 ErrorMode mode) const {
204 const std::string parcelObjDeref =
205 parcelObj + (parcelObjIsPointer ? "->" : ".");
206
207 if (isReader) {
208 out << "{\n";
209 out.indent();
210
211 const std::string sizeName = "_hidl_" + name + "_size";
212
213 out << "uint64_t "
214 << sizeName
215 << ";\n";
216
217 out << "_hidl_err = "
218 << parcelObjDeref
219 << "readUint64(&"
220 << sizeName
221 << ");\n";
222
223 handleError(out, mode);
224
225 out << name
226 << ".resize("
227 << sizeName
228 << ");\n\n"
229 << "for (size_t _hidl_index = 0; _hidl_index < "
230 << sizeName
231 << "; ++_hidl_index) {\n";
232
233 out.indent();
234
Yifan Hong3b320f82016-11-01 15:15:54 -0700235 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800236 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700237
238 mElementType->emitReaderWriter(
239 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800240 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700241 parcelObj,
242 parcelObjIsPointer,
243 isReader,
244 mode);
245
246 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800247 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700248
249 out.unindent();
250 out << "}\n";
251
252 out.unindent();
253 out << "}\n";
254 } else {
255 out << "_hidl_err = "
256 << parcelObjDeref
257 << "writeUint64("
258 << name
259 << ".size());\n";
260
261 handleError(out, mode);
262
263 out << "for (size_t _hidl_index = 0; _hidl_index < "
264 << name
265 << ".size(); ++_hidl_index) {\n";
266
267 out.indent();
268
269 mElementType->emitReaderWriter(
270 out,
271 name + "[_hidl_index]",
272 parcelObj,
273 parcelObjIsPointer,
274 isReader,
275 mode);
276
277 out.unindent();
278 out << "}\n";
279 }
280}
281
Andreas Huber881227d2016-08-02 14:20:21 -0700282void VectorType::emitReaderWriterEmbedded(
283 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700284 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700285 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700286 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700287 bool nameIsPointer,
288 const std::string &parcelObj,
289 bool parcelObjIsPointer,
290 bool isReader,
291 ErrorMode mode,
292 const std::string &parentName,
293 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700294 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700295
Yifan Hongbe2a3732016-10-05 13:33:41 -0700296 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700297 out << "size_t " << childName << ";\n\n";
298
299 emitReaderWriterEmbeddedForTypeName(
300 out,
301 name,
302 nameIsPointer,
303 parcelObj,
304 parcelObjIsPointer,
305 isReader,
306 mode,
307 parentName,
308 offsetText,
309 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800310 childName,
311 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700312
313 if (!mElementType->needsEmbeddedReadWrite()) {
314 return;
315 }
316
317 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
318
Yifan Hong3b320f82016-11-01 15:15:54 -0700319 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700320
Andreas Huberf9d49f12016-09-12 14:58:36 -0700321 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
322
323 out << "for (size_t "
324 << iteratorName
325 << " = 0; "
326 << iteratorName
327 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700328 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700329 << "size(); ++"
330 << iteratorName
331 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700332
333 out.indent();
334
335 mElementType->emitReaderWriterEmbedded(
336 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700337 depth + 1,
338 (nameIsPointer ? "(*" + name + ")" : name)
339 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700340 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700341 false /* nameIsPointer */,
342 parcelObj,
343 parcelObjIsPointer,
344 isReader,
345 mode,
346 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700347 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700348
349 out.unindent();
350
351 out << "}\n\n";
352}
353
Yifan Hongbf459bc2016-08-23 16:50:37 -0700354void VectorType::emitResolveReferences(
355 Formatter &out,
356 const std::string &name,
357 bool nameIsPointer,
358 const std::string &parcelObj,
359 bool parcelObjIsPointer,
360 bool isReader,
361 ErrorMode mode) const {
362 emitResolveReferencesEmbeddedHelper(
363 out,
364 0, /* depth */
365 name,
366 name /* sanitizedName */,
367 nameIsPointer,
368 parcelObj,
369 parcelObjIsPointer,
370 isReader,
371 mode,
372 "_hidl_" + name + "_child",
373 "0 /* parentOffset */");
374}
375
376void VectorType::emitResolveReferencesEmbedded(
377 Formatter &out,
378 size_t depth,
379 const std::string &name,
380 const std::string &sanitizedName,
381 bool nameIsPointer,
382 const std::string &parcelObj,
383 bool parcelObjIsPointer,
384 bool isReader,
385 ErrorMode mode,
386 const std::string & /* parentName */,
387 const std::string & /* offsetText */) const {
388 emitResolveReferencesEmbeddedHelper(
389 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
390 parcelObjIsPointer, isReader, mode, "", "");
391}
392
Yifan Hong00f47172016-09-30 14:40:45 -0700393bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
394 // parentName and offsetText is not used in emitResolveReferencesEmbedded
395 return false;
396}
397
Yifan Hongbf459bc2016-08-23 16:50:37 -0700398void VectorType::emitResolveReferencesEmbeddedHelper(
399 Formatter &out,
400 size_t depth,
401 const std::string &name,
402 const std::string &sanitizedName,
403 bool nameIsPointer,
404 const std::string &parcelObj,
405 bool parcelObjIsPointer,
406 bool isReader,
407 ErrorMode mode,
408 const std::string &childName,
409 const std::string &childOffsetText) const {
410 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
411
412 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800413 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700414 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700415
416 std::string myChildName = childName, myChildOffset = childOffsetText;
417
418 if(myChildName.empty() && myChildOffset.empty()) {
419 myChildName = "_hidl_" + sanitizedName + "_child";
420 myChildOffset = "0";
421
422 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800423 out << "_hidl_err = ::android::hardware::findInParcel("
424 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700425 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
426 << "&" << myChildName
427 << ");\n";
428
429 handleError(out, mode);
430 }
431
432 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
433
434 out << "for (size_t "
435 << iteratorName
436 << " = 0; "
437 << iteratorName
438 << " < "
439 << nameDeref
440 << "size(); ++"
441 << iteratorName
442 << ") {\n";
443
444 out.indent();
445
446 mElementType->emitResolveReferencesEmbedded(
447 out,
448 depth + 1,
449 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
450 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
451 false /* nameIsPointer */,
452 parcelObj,
453 parcelObjIsPointer,
454 isReader,
455 mode,
456 myChildName,
457 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700458 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700459
460 out.unindent();
461
462 out << "}\n\n";
463}
464
Andreas Huberf630bc82016-09-09 14:52:25 -0700465void VectorType::emitJavaReaderWriter(
466 Formatter &out,
467 const std::string &parcelObj,
468 const std::string &argName,
469 bool isReader) const {
470 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700471
Andreas Huberf630bc82016-09-09 14:52:25 -0700472 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700473 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700474 << ".readVectorFromParcel("
475 << parcelObj
476 << ");\n";
477 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700478 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700479 << ".writeVectorToParcel("
480 << parcelObj
481 << ", "
482 << argName
483 << ");\n";
484 }
485
486 return;
487 }
488
Andreas Huber1b6822b2016-10-18 09:28:40 -0700489 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700490 size_t align, size;
491 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700492 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700493 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700494 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700495 << "();\n";
496 }
497
498 out << "{\n";
499 out.indent();
500
Yifan Hong1af73532016-11-09 14:32:58 -0800501 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700502
503 if (isReader) {
504 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700505 << ".readBuffer("
506 << size
507 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700508 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700509
Yifan Hong1af73532016-11-09 14:32:58 -0800510 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700511 << size
512 << " /* size */);\n";
513 }
514
515 emitJavaFieldReaderWriter(
516 out,
517 0 /* depth */,
518 parcelObj,
519 "_hidl_blob",
520 argName,
521 "0 /* offset */",
522 isReader);
523
524 if (!isReader) {
525 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
526 };
527
528 out.unindent();
529 out << "}\n";
530
531 return;
532 }
533
Andreas Huberf630bc82016-09-09 14:52:25 -0700534 emitJavaReaderWriterWithSuffix(
535 out,
536 parcelObj,
537 argName,
538 isReader,
539 mElementType->getJavaSuffix() + "Vector",
540 "" /* extra */);
541}
542
Andreas Huber85eabdb2016-08-25 11:24:49 -0700543void VectorType::emitJavaFieldInitializer(
544 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700545 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700546
Andreas Huber1b6822b2016-10-18 09:28:40 -0700547 out << "final "
548 << javaType
549 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700550 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700551 << " = new "
552 << javaType
553 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700554}
555
556void VectorType::emitJavaFieldReaderWriter(
557 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700558 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700559 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700560 const std::string &blobName,
561 const std::string &fieldName,
562 const std::string &offset,
563 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700564 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700565 out,
566 depth,
567 mElementType,
568 parcelName,
569 blobName,
570 fieldName,
571 offset,
572 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700573}
574
Andreas Huberf630bc82016-09-09 14:52:25 -0700575void VectorType::EmitJavaFieldReaderWriterForElementType(
576 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700577 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700578 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700579 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700580 const std::string &blobName,
581 const std::string &fieldName,
582 const std::string &offset,
583 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700584 size_t elementAlign, elementSize;
585 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
586
Andreas Huber85eabdb2016-08-25 11:24:49 -0700587 if (isReader) {
588 out << "{\n";
589 out.indent();
590
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700591 out << "int _hidl_vec_size = "
592 << blobName
593 << ".getInt32("
594 << offset
595 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
596
Yifan Hong1af73532016-11-09 14:32:58 -0800597 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700598 << parcelName
599 << ".readEmbeddedBuffer(\n";
600
Andreas Huber85eabdb2016-08-25 11:24:49 -0700601 out.indent();
602 out.indent();
603
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700604 out << "_hidl_vec_size * "
605 << elementSize << ","
606 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700607 << ".handle(),\n"
608 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100609 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
610 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700611
612 out.unindent();
613 out.unindent();
614
615 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700616 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
617
618 out << "for (int "
619 << iteratorName
620 << " = 0; "
621 << iteratorName
622 << " < _hidl_vec_size; "
623 << "++"
624 << iteratorName
625 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700626
627 out.indent();
628
Andreas Huberf630bc82016-09-09 14:52:25 -0700629 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700630
Andreas Huberf630bc82016-09-09 14:52:25 -0700631 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700633 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700634 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700635 "childBlob",
636 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700637 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700638 true /* isReader */);
639
Andreas Huber1b6822b2016-10-18 09:28:40 -0700640 out << fieldName
641 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700642
643 out.unindent();
644
645 out << "}\n";
646
647 out.unindent();
648 out << "}\n";
649
650 return;
651 }
652
653 out << "{\n";
654 out.indent();
655
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800656 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700657 << fieldName
658 << ".size();\n";
659
660 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800661 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700662 << offset
663 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
664
665 out << blobName
666 << ".putBool("
667 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800668 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700669
Andreas Huber85eabdb2016-08-25 11:24:49 -0700670 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800671 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700672 << elementSize
673 << "));\n";
674
Andreas Huber4c865b72016-09-14 15:26:27 -0700675 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
676
677 out << "for (int "
678 << iteratorName
679 << " = 0; "
680 << iteratorName
681 << " < _hidl_vec_size; "
682 << "++"
683 << iteratorName
684 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700685
686 out.indent();
687
Andreas Huberf630bc82016-09-09 14:52:25 -0700688 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700689 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700690 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700691 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700692 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700693 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700694 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700695 false /* isReader */);
696
697 out.unindent();
698
699 out << "}\n";
700
701 out << blobName
702 << ".putBlob("
703 << offset
704 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
705
706 out.unindent();
707 out << "}\n";
708}
709
Andreas Huber881227d2016-08-02 14:20:21 -0700710bool VectorType::needsEmbeddedReadWrite() const {
711 return true;
712}
713
Yifan Hongbf459bc2016-08-23 16:50:37 -0700714bool VectorType::needsResolveReferences() const {
715 return mElementType->needsResolveReferences();
716}
717
Andreas Huber881227d2016-08-02 14:20:21 -0700718bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700719 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700720}
721
Andreas Huber70a59e12016-08-16 12:57:01 -0700722bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700723 if (!mElementType->isJavaCompatible()) {
724 return false;
725 }
726
727 if (mElementType->isArray()) {
Timur Iskhakov505316c2017-08-05 03:38:59 +0000728 return static_cast<ArrayType*>(mElementType.get())->countDimensions() == 1;
Andreas Huberf03332a2016-09-22 15:35:43 -0700729 }
730
Andreas Huber1b6822b2016-10-18 09:28:40 -0700731 if (mElementType->isVector()) {
732 return false;
733 }
734
Andreas Huber86a112b2016-10-19 14:25:16 -0700735 if (isVectorOfBinders()) {
736 return false;
737 }
738
Andreas Huberf03332a2016-09-22 15:35:43 -0700739 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700740}
741
Andreas Huber60d3b222017-03-30 09:10:56 -0700742bool VectorType::containsPointer() const {
743 return mElementType->containsPointer();
744}
745
Andreas Huber6755e9d2017-04-06 11:09:07 -0700746// All hidl_vec<T> have the same size.
747static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700748
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700749void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700750 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700751 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700752}
753
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700754void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
755 VectorType::getAlignmentAndSizeStatic(align, size);
756}
757
Andreas Huberc9410c72016-07-28 12:18:40 -0700758} // namespace android
759