blob: 5854f54ccabb26357a218d6abc20e53470913cfb [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"
20
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070021#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070022#include <android-base/logging.h>
23
Andreas Huberc9410c72016-07-28 12:18:40 -070024namespace android {
25
Yifan Hongbf459bc2016-08-23 16:50:37 -070026VectorType::VectorType() {
Andreas Huberc9410c72016-07-28 12:18:40 -070027}
28
Steven Moreland30bb6a82016-11-30 09:18:34 -080029std::string VectorType::typeName() const {
30 return "vector" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
31}
32
33bool VectorType::isCompatibleElementType(Type *) const {
34 return true;
35}
36
Steven Moreland979e0992016-09-07 09:18:08 -070037void VectorType::addNamedTypesToSet(std::set<const FQName> &set) const {
38 mElementType->addNamedTypesToSet(set);
39}
40
Andreas Huber86a112b2016-10-19 14:25:16 -070041bool VectorType::isVector() const {
42 return true;
43}
44
45bool VectorType::isVectorOfBinders() const {
46 return mElementType->isBinder();
47}
48
Steven Moreland979e0992016-09-07 09:18:08 -070049std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070050 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070051 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070052 std::string(specifyNamespaces ? "::android::hardware::" : "")
53 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070054 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070055 + ">";
56
Andreas Huber881227d2016-08-02 14:20:21 -070057 switch (mode) {
58 case StorageMode_Stack:
59 return base;
60
61 case StorageMode_Argument:
62 return "const " + base + "&";
63
64 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -070065 {
66 if (isVectorOfBinders()) {
67 return base;
68 }
69
Andreas Huber881227d2016-08-02 14:20:21 -070070 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -070071 }
Andreas Huber881227d2016-08-02 14:20:21 -070072 }
73}
74
Yifan Hong4ed13472016-11-02 10:44:11 -070075std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -070076
Yifan Hong4ed13472016-11-02 10:44:11 -070077 std::string elementJavaType;
78 if (mElementType->isArray()) {
79 elementJavaType = mElementType->getJavaType();
80 } else {
81 elementJavaType = mElementType->getJavaWrapperType();
82 }
Andreas Huber1b6822b2016-10-18 09:28:40 -070083
Yifan Hong1af73532016-11-09 14:32:58 -080084 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -070085 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -070086 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -070087}
88
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -070089std::string VectorType::getVtsType() const {
90 return "TYPE_VECTOR";
91}
92
Andreas Huber881227d2016-08-02 14:20:21 -070093void VectorType::emitReaderWriter(
94 Formatter &out,
95 const std::string &name,
96 const std::string &parcelObj,
97 bool parcelObjIsPointer,
98 bool isReader,
99 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700100 if (isVectorOfBinders()) {
101 emitReaderWriterForVectorOfBinders(
102 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
103
104 return;
105 }
106
Yifan Hong3b320f82016-11-01 15:15:54 -0700107 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700108
Iliyan Malchev549e2592016-08-10 08:59:12 -0700109 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700110
111 out << "size_t " << parentName << ";\n\n";
112
113 const std::string parcelObjDeref =
114 parcelObj + (parcelObjIsPointer ? "->" : ".");
115
116 if (isReader) {
117 out << name
Andreas Huber8a82ff72016-08-04 10:29:39 -0700118 << " = (const ::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -0700119 << baseType
120 << "> *)"
121 << parcelObjDeref
122 << "readBuffer(&"
123 << parentName
124 << ");\n\n";
125
126 out << "if (" << name << " == nullptr) {\n";
127
128 out.indent();
129
Iliyan Malchev549e2592016-08-10 08:59:12 -0700130 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700131 handleError2(out, mode);
132
133 out.unindent();
134 out << "}\n\n";
135 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700136 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700137 << parcelObjDeref
138 << "writeBuffer(&"
139 << name
140 << ", sizeof("
141 << name
142 << "), &"
143 << parentName
144 << ");\n";
145
146 handleError(out, mode);
147 }
148
149 emitReaderWriterEmbedded(
150 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700151 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700152 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700153 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700154 isReader /* nameIsPointer */,
155 parcelObj,
156 parcelObjIsPointer,
157 isReader,
158 mode,
159 parentName,
160 "0 /* parentOffset */");
161}
162
Andreas Huber86a112b2016-10-19 14:25:16 -0700163void VectorType::emitReaderWriterForVectorOfBinders(
164 Formatter &out,
165 const std::string &name,
166 const std::string &parcelObj,
167 bool parcelObjIsPointer,
168 bool isReader,
169 ErrorMode mode) const {
170 const std::string parcelObjDeref =
171 parcelObj + (parcelObjIsPointer ? "->" : ".");
172
173 if (isReader) {
174 out << "{\n";
175 out.indent();
176
177 const std::string sizeName = "_hidl_" + name + "_size";
178
179 out << "uint64_t "
180 << sizeName
181 << ";\n";
182
183 out << "_hidl_err = "
184 << parcelObjDeref
185 << "readUint64(&"
186 << sizeName
187 << ");\n";
188
189 handleError(out, mode);
190
191 out << name
192 << ".resize("
193 << sizeName
194 << ");\n\n"
195 << "for (size_t _hidl_index = 0; _hidl_index < "
196 << sizeName
197 << "; ++_hidl_index) {\n";
198
199 out.indent();
200
Yifan Hong3b320f82016-11-01 15:15:54 -0700201 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800202 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700203
204 mElementType->emitReaderWriter(
205 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800206 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700207 parcelObj,
208 parcelObjIsPointer,
209 isReader,
210 mode);
211
212 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800213 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700214
215 out.unindent();
216 out << "}\n";
217
218 out.unindent();
219 out << "}\n";
220 } else {
221 out << "_hidl_err = "
222 << parcelObjDeref
223 << "writeUint64("
224 << name
225 << ".size());\n";
226
227 handleError(out, mode);
228
229 out << "for (size_t _hidl_index = 0; _hidl_index < "
230 << name
231 << ".size(); ++_hidl_index) {\n";
232
233 out.indent();
234
235 mElementType->emitReaderWriter(
236 out,
237 name + "[_hidl_index]",
238 parcelObj,
239 parcelObjIsPointer,
240 isReader,
241 mode);
242
243 out.unindent();
244 out << "}\n";
245 }
246}
247
Andreas Huber881227d2016-08-02 14:20:21 -0700248void VectorType::emitReaderWriterEmbedded(
249 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700250 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700251 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700252 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700253 bool nameIsPointer,
254 const std::string &parcelObj,
255 bool parcelObjIsPointer,
256 bool isReader,
257 ErrorMode mode,
258 const std::string &parentName,
259 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700260 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700261
Yifan Hongbe2a3732016-10-05 13:33:41 -0700262 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700263 out << "size_t " << childName << ";\n\n";
264
265 emitReaderWriterEmbeddedForTypeName(
266 out,
267 name,
268 nameIsPointer,
269 parcelObj,
270 parcelObjIsPointer,
271 isReader,
272 mode,
273 parentName,
274 offsetText,
275 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800276 childName,
277 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700278
279 if (!mElementType->needsEmbeddedReadWrite()) {
280 return;
281 }
282
283 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
284
Yifan Hong3b320f82016-11-01 15:15:54 -0700285 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700286
Andreas Huberf9d49f12016-09-12 14:58:36 -0700287 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
288
289 out << "for (size_t "
290 << iteratorName
291 << " = 0; "
292 << iteratorName
293 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700294 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700295 << "size(); ++"
296 << iteratorName
297 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700298
299 out.indent();
300
301 mElementType->emitReaderWriterEmbedded(
302 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700303 depth + 1,
304 (nameIsPointer ? "(*" + name + ")" : name)
305 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700306 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700307 false /* nameIsPointer */,
308 parcelObj,
309 parcelObjIsPointer,
310 isReader,
311 mode,
312 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700313 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700314
315 out.unindent();
316
317 out << "}\n\n";
318}
319
Yifan Hongbf459bc2016-08-23 16:50:37 -0700320void VectorType::emitResolveReferences(
321 Formatter &out,
322 const std::string &name,
323 bool nameIsPointer,
324 const std::string &parcelObj,
325 bool parcelObjIsPointer,
326 bool isReader,
327 ErrorMode mode) const {
328 emitResolveReferencesEmbeddedHelper(
329 out,
330 0, /* depth */
331 name,
332 name /* sanitizedName */,
333 nameIsPointer,
334 parcelObj,
335 parcelObjIsPointer,
336 isReader,
337 mode,
338 "_hidl_" + name + "_child",
339 "0 /* parentOffset */");
340}
341
342void VectorType::emitResolveReferencesEmbedded(
343 Formatter &out,
344 size_t depth,
345 const std::string &name,
346 const std::string &sanitizedName,
347 bool nameIsPointer,
348 const std::string &parcelObj,
349 bool parcelObjIsPointer,
350 bool isReader,
351 ErrorMode mode,
352 const std::string & /* parentName */,
353 const std::string & /* offsetText */) const {
354 emitResolveReferencesEmbeddedHelper(
355 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
356 parcelObjIsPointer, isReader, mode, "", "");
357}
358
Yifan Hong00f47172016-09-30 14:40:45 -0700359bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
360 // parentName and offsetText is not used in emitResolveReferencesEmbedded
361 return false;
362}
363
Yifan Hongbf459bc2016-08-23 16:50:37 -0700364void VectorType::emitResolveReferencesEmbeddedHelper(
365 Formatter &out,
366 size_t depth,
367 const std::string &name,
368 const std::string &sanitizedName,
369 bool nameIsPointer,
370 const std::string &parcelObj,
371 bool parcelObjIsPointer,
372 bool isReader,
373 ErrorMode mode,
374 const std::string &childName,
375 const std::string &childOffsetText) const {
376 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
377
378 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800379 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700380 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700381
382 std::string myChildName = childName, myChildOffset = childOffsetText;
383
384 if(myChildName.empty() && myChildOffset.empty()) {
385 myChildName = "_hidl_" + sanitizedName + "_child";
386 myChildOffset = "0";
387
388 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800389 out << "_hidl_err = ::android::hardware::findInParcel("
390 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700391 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
392 << "&" << myChildName
393 << ");\n";
394
395 handleError(out, mode);
396 }
397
398 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
399
400 out << "for (size_t "
401 << iteratorName
402 << " = 0; "
403 << iteratorName
404 << " < "
405 << nameDeref
406 << "size(); ++"
407 << iteratorName
408 << ") {\n";
409
410 out.indent();
411
412 mElementType->emitResolveReferencesEmbedded(
413 out,
414 depth + 1,
415 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
416 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
417 false /* nameIsPointer */,
418 parcelObj,
419 parcelObjIsPointer,
420 isReader,
421 mode,
422 myChildName,
423 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700424 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700425
426 out.unindent();
427
428 out << "}\n\n";
429}
430
Andreas Huberf630bc82016-09-09 14:52:25 -0700431void VectorType::emitJavaReaderWriter(
432 Formatter &out,
433 const std::string &parcelObj,
434 const std::string &argName,
435 bool isReader) const {
436 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700437
Andreas Huberf630bc82016-09-09 14:52:25 -0700438 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700439 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700440 << ".readVectorFromParcel("
441 << parcelObj
442 << ");\n";
443 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700444 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700445 << ".writeVectorToParcel("
446 << parcelObj
447 << ", "
448 << argName
449 << ");\n";
450 }
451
452 return;
453 }
454
Andreas Huber1b6822b2016-10-18 09:28:40 -0700455 if (mElementType->isArray()) {
456 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700457 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700458 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700459 << "();\n";
460 }
461
462 out << "{\n";
463 out.indent();
464
Yifan Hong1af73532016-11-09 14:32:58 -0800465 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700466
467 if (isReader) {
468 out << parcelObj
469 << ".readBuffer();\n";
470 } else {
471 size_t align, size;
472 getAlignmentAndSize(&align, &size);
473
Yifan Hong1af73532016-11-09 14:32:58 -0800474 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700475 << size
476 << " /* size */);\n";
477 }
478
479 emitJavaFieldReaderWriter(
480 out,
481 0 /* depth */,
482 parcelObj,
483 "_hidl_blob",
484 argName,
485 "0 /* offset */",
486 isReader);
487
488 if (!isReader) {
489 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
490 };
491
492 out.unindent();
493 out << "}\n";
494
495 return;
496 }
497
Andreas Huberf630bc82016-09-09 14:52:25 -0700498 emitJavaReaderWriterWithSuffix(
499 out,
500 parcelObj,
501 argName,
502 isReader,
503 mElementType->getJavaSuffix() + "Vector",
504 "" /* extra */);
505}
506
Andreas Huber85eabdb2016-08-25 11:24:49 -0700507void VectorType::emitJavaFieldInitializer(
508 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700509 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700510
Andreas Huber1b6822b2016-10-18 09:28:40 -0700511 out << "final "
512 << javaType
513 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700514 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700515 << " = new "
516 << javaType
517 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700518}
519
520void VectorType::emitJavaFieldReaderWriter(
521 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700522 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700523 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700524 const std::string &blobName,
525 const std::string &fieldName,
526 const std::string &offset,
527 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700528 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700529 out,
530 depth,
531 mElementType,
532 parcelName,
533 blobName,
534 fieldName,
535 offset,
536 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700537}
538
539// static
540void VectorType::EmitJavaFieldReaderWriterForElementType(
541 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700542 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700543 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700544 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700545 const std::string &blobName,
546 const std::string &fieldName,
547 const std::string &offset,
548 bool isReader) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700549 if (isReader) {
550 out << "{\n";
551 out.indent();
552
Yifan Hong1af73532016-11-09 14:32:58 -0800553 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700554 << parcelName
555 << ".readEmbeddedBuffer(\n";
556
Andreas Huber85eabdb2016-08-25 11:24:49 -0700557 out.indent();
558 out.indent();
559
560 out << blobName
561 << ".handle(),\n"
562 << offset
563 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";
564
565 out.unindent();
566 out.unindent();
567
568 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800569 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700570 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800571 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700572 << offset
573 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
574
Andreas Huber4c865b72016-09-14 15:26:27 -0700575 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
576
577 out << "for (int "
578 << iteratorName
579 << " = 0; "
580 << iteratorName
581 << " < _hidl_vec_size; "
582 << "++"
583 << iteratorName
584 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700585
586 out.indent();
587
Andreas Huberf630bc82016-09-09 14:52:25 -0700588 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700589
590 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700591 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700592
Andreas Huberf630bc82016-09-09 14:52:25 -0700593 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700594 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700595 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700596 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700597 "childBlob",
598 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700599 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700600 true /* isReader */);
601
Andreas Huber1b6822b2016-10-18 09:28:40 -0700602 out << fieldName
603 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700604
605 out.unindent();
606
607 out << "}\n";
608
609 out.unindent();
610 out << "}\n";
611
612 return;
613 }
614
615 out << "{\n";
616 out.indent();
617
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800618 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700619 << fieldName
620 << ".size();\n";
621
622 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800623 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700624 << offset
625 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
626
627 out << blobName
628 << ".putBool("
629 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800630 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700631
632 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700633 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700634
635 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800636 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700637 << elementSize
638 << "));\n";
639
Andreas Huber4c865b72016-09-14 15:26:27 -0700640 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
641
642 out << "for (int "
643 << iteratorName
644 << " = 0; "
645 << iteratorName
646 << " < _hidl_vec_size; "
647 << "++"
648 << iteratorName
649 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700650
651 out.indent();
652
Andreas Huberf630bc82016-09-09 14:52:25 -0700653 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700654 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700655 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700656 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700657 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700658 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700659 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700660 false /* isReader */);
661
662 out.unindent();
663
664 out << "}\n";
665
666 out << blobName
667 << ".putBlob("
668 << offset
669 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
670
671 out.unindent();
672 out << "}\n";
673}
674
Andreas Huber881227d2016-08-02 14:20:21 -0700675bool VectorType::needsEmbeddedReadWrite() const {
676 return true;
677}
678
Yifan Hongbf459bc2016-08-23 16:50:37 -0700679bool VectorType::needsResolveReferences() const {
680 return mElementType->needsResolveReferences();
681}
682
Andreas Huber881227d2016-08-02 14:20:21 -0700683bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700684 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700685}
686
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700687status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700688 out << "type: " << getVtsType() << "\n";
689 out << "vector_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700690 out.indent();
691 status_t err = mElementType->emitVtsTypeDeclarations(out);
692 if (err != OK) {
693 return err;
694 }
695 out.unindent();
696 out << "}\n";
697 return OK;
698}
699
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700700status_t VectorType::emitVtsAttributeType(Formatter &out) const {
701 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
702 out.indent();
703 status_t status = mElementType->emitVtsAttributeType(out);
704 if (status != OK) {
705 return status;
706 }
707 out.unindent();
708 out << "}\n";
709 return OK;
710}
711
Andreas Huber70a59e12016-08-16 12:57:01 -0700712bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700713 if (!mElementType->isJavaCompatible()) {
714 return false;
715 }
716
717 if (mElementType->isArray()) {
718 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
719 }
720
Andreas Huber1b6822b2016-10-18 09:28:40 -0700721 if (mElementType->isVector()) {
722 return false;
723 }
724
Andreas Huber86a112b2016-10-19 14:25:16 -0700725 if (isVectorOfBinders()) {
726 return false;
727 }
728
Andreas Huberf03332a2016-09-22 15:35:43 -0700729 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700730}
731
Andreas Huber85eabdb2016-08-25 11:24:49 -0700732void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
733 *align = 8; // hidl_vec<T>
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800734 *size = 16;
Andreas Huber85eabdb2016-08-25 11:24:49 -0700735}
736
Andreas Huberc9410c72016-07-28 12:18:40 -0700737} // namespace android
738