blob: d946bb1a736db45d13efa2e23aece4d865a72686 [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 Huberf03332a2016-09-22 15:35:43 -070021
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070022#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070023#include <android-base/logging.h>
24
Andreas Huberc9410c72016-07-28 12:18:40 -070025namespace android {
26
Yifan Hongbf459bc2016-08-23 16:50:37 -070027VectorType::VectorType() {
Andreas Huberc9410c72016-07-28 12:18:40 -070028}
29
Steven Moreland30bb6a82016-11-30 09:18:34 -080030std::string VectorType::typeName() const {
31 return "vector" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
32}
33
Yifan Hong51f9c8a2016-12-05 18:47:33 -080034bool VectorType::isCompatibleElementType(Type *elementType) const {
35 if (elementType->isScalar()) {
36 return true;
37 }
38 if (elementType->isString()) {
39 return true;
40 }
41 if (elementType->isEnum()) {
42 return true;
43 }
44 if (elementType->isBitField()) {
45 return true;
46 }
47 if (elementType->isCompoundType()
48 && static_cast<CompoundType *>(elementType)->style() == CompoundType::STYLE_STRUCT) {
49 return true;
50 }
51 if (elementType->isInterface()) {
52 return true;
53 }
54 if (elementType->isHandle()) {
55 return true;
56 }
57 if (elementType->isTemplatedType()) {
58 Type *inner = static_cast<TemplatedType *>(elementType)->getElementType();
59 return this->isCompatibleElementType(inner) && !inner->isInterface();
60 }
61 if (elementType->isArray()) {
62 Type *inner = static_cast<ArrayType *>(elementType)->getElementType();
63 return this->isCompatibleElementType(inner) && !inner->isInterface();
64 }
65 return false;
Steven Moreland30bb6a82016-11-30 09:18:34 -080066}
67
Steven Moreland979e0992016-09-07 09:18:08 -070068void VectorType::addNamedTypesToSet(std::set<const FQName> &set) const {
69 mElementType->addNamedTypesToSet(set);
70}
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
Steven Moreland979e0992016-09-07 09:18:08 -070080std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070081 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070082 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070083 std::string(specifyNamespaces ? "::android::hardware::" : "")
84 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070085 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070086 + ">";
87
Andreas Huber881227d2016-08-02 14:20:21 -070088 switch (mode) {
89 case StorageMode_Stack:
90 return base;
91
92 case StorageMode_Argument:
93 return "const " + base + "&";
94
95 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -070096 {
97 if (isVectorOfBinders()) {
98 return base;
99 }
100
Andreas Huber881227d2016-08-02 14:20:21 -0700101 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700102 }
Andreas Huber881227d2016-08-02 14:20:21 -0700103 }
104}
105
Yifan Hong4ed13472016-11-02 10:44:11 -0700106std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700107
Yifan Hong4ed13472016-11-02 10:44:11 -0700108 std::string elementJavaType;
109 if (mElementType->isArray()) {
110 elementJavaType = mElementType->getJavaType();
111 } else {
112 elementJavaType = mElementType->getJavaWrapperType();
113 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700114
Yifan Hong1af73532016-11-09 14:32:58 -0800115 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700116 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700117 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700118}
119
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700120std::string VectorType::getVtsType() const {
121 return "TYPE_VECTOR";
122}
123
Andreas Huber881227d2016-08-02 14:20:21 -0700124void VectorType::emitReaderWriter(
125 Formatter &out,
126 const std::string &name,
127 const std::string &parcelObj,
128 bool parcelObjIsPointer,
129 bool isReader,
130 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700131 if (isVectorOfBinders()) {
132 emitReaderWriterForVectorOfBinders(
133 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
134
135 return;
136 }
137
Yifan Hong3b320f82016-11-01 15:15:54 -0700138 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700139
Iliyan Malchev549e2592016-08-10 08:59:12 -0700140 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700141
142 out << "size_t " << parentName << ";\n\n";
143
144 const std::string parcelObjDeref =
145 parcelObj + (parcelObjIsPointer ? "->" : ".");
146
147 if (isReader) {
148 out << name
Andreas Huber8a82ff72016-08-04 10:29:39 -0700149 << " = (const ::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -0700150 << baseType
151 << "> *)"
152 << parcelObjDeref
153 << "readBuffer(&"
154 << parentName
155 << ");\n\n";
156
157 out << "if (" << name << " == nullptr) {\n";
158
159 out.indent();
160
Iliyan Malchev549e2592016-08-10 08:59:12 -0700161 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700162 handleError2(out, mode);
163
164 out.unindent();
165 out << "}\n\n";
166 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700167 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700168 << parcelObjDeref
169 << "writeBuffer(&"
170 << name
171 << ", sizeof("
172 << name
173 << "), &"
174 << parentName
175 << ");\n";
176
177 handleError(out, mode);
178 }
179
180 emitReaderWriterEmbedded(
181 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700182 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700183 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700184 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700185 isReader /* nameIsPointer */,
186 parcelObj,
187 parcelObjIsPointer,
188 isReader,
189 mode,
190 parentName,
191 "0 /* parentOffset */");
192}
193
Andreas Huber86a112b2016-10-19 14:25:16 -0700194void VectorType::emitReaderWriterForVectorOfBinders(
195 Formatter &out,
196 const std::string &name,
197 const std::string &parcelObj,
198 bool parcelObjIsPointer,
199 bool isReader,
200 ErrorMode mode) const {
201 const std::string parcelObjDeref =
202 parcelObj + (parcelObjIsPointer ? "->" : ".");
203
204 if (isReader) {
205 out << "{\n";
206 out.indent();
207
208 const std::string sizeName = "_hidl_" + name + "_size";
209
210 out << "uint64_t "
211 << sizeName
212 << ";\n";
213
214 out << "_hidl_err = "
215 << parcelObjDeref
216 << "readUint64(&"
217 << sizeName
218 << ");\n";
219
220 handleError(out, mode);
221
222 out << name
223 << ".resize("
224 << sizeName
225 << ");\n\n"
226 << "for (size_t _hidl_index = 0; _hidl_index < "
227 << sizeName
228 << "; ++_hidl_index) {\n";
229
230 out.indent();
231
Yifan Hong3b320f82016-11-01 15:15:54 -0700232 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800233 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700234
235 mElementType->emitReaderWriter(
236 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800237 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700238 parcelObj,
239 parcelObjIsPointer,
240 isReader,
241 mode);
242
243 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800244 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700245
246 out.unindent();
247 out << "}\n";
248
249 out.unindent();
250 out << "}\n";
251 } else {
252 out << "_hidl_err = "
253 << parcelObjDeref
254 << "writeUint64("
255 << name
256 << ".size());\n";
257
258 handleError(out, mode);
259
260 out << "for (size_t _hidl_index = 0; _hidl_index < "
261 << name
262 << ".size(); ++_hidl_index) {\n";
263
264 out.indent();
265
266 mElementType->emitReaderWriter(
267 out,
268 name + "[_hidl_index]",
269 parcelObj,
270 parcelObjIsPointer,
271 isReader,
272 mode);
273
274 out.unindent();
275 out << "}\n";
276 }
277}
278
Andreas Huber881227d2016-08-02 14:20:21 -0700279void VectorType::emitReaderWriterEmbedded(
280 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700281 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700282 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700283 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700284 bool nameIsPointer,
285 const std::string &parcelObj,
286 bool parcelObjIsPointer,
287 bool isReader,
288 ErrorMode mode,
289 const std::string &parentName,
290 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700291 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700292
Yifan Hongbe2a3732016-10-05 13:33:41 -0700293 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700294 out << "size_t " << childName << ";\n\n";
295
296 emitReaderWriterEmbeddedForTypeName(
297 out,
298 name,
299 nameIsPointer,
300 parcelObj,
301 parcelObjIsPointer,
302 isReader,
303 mode,
304 parentName,
305 offsetText,
306 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800307 childName,
308 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700309
310 if (!mElementType->needsEmbeddedReadWrite()) {
311 return;
312 }
313
314 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
315
Yifan Hong3b320f82016-11-01 15:15:54 -0700316 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700317
Andreas Huberf9d49f12016-09-12 14:58:36 -0700318 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
319
320 out << "for (size_t "
321 << iteratorName
322 << " = 0; "
323 << iteratorName
324 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700325 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700326 << "size(); ++"
327 << iteratorName
328 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700329
330 out.indent();
331
332 mElementType->emitReaderWriterEmbedded(
333 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700334 depth + 1,
335 (nameIsPointer ? "(*" + name + ")" : name)
336 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700337 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700338 false /* nameIsPointer */,
339 parcelObj,
340 parcelObjIsPointer,
341 isReader,
342 mode,
343 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700344 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700345
346 out.unindent();
347
348 out << "}\n\n";
349}
350
Yifan Hongbf459bc2016-08-23 16:50:37 -0700351void VectorType::emitResolveReferences(
352 Formatter &out,
353 const std::string &name,
354 bool nameIsPointer,
355 const std::string &parcelObj,
356 bool parcelObjIsPointer,
357 bool isReader,
358 ErrorMode mode) const {
359 emitResolveReferencesEmbeddedHelper(
360 out,
361 0, /* depth */
362 name,
363 name /* sanitizedName */,
364 nameIsPointer,
365 parcelObj,
366 parcelObjIsPointer,
367 isReader,
368 mode,
369 "_hidl_" + name + "_child",
370 "0 /* parentOffset */");
371}
372
373void VectorType::emitResolveReferencesEmbedded(
374 Formatter &out,
375 size_t depth,
376 const std::string &name,
377 const std::string &sanitizedName,
378 bool nameIsPointer,
379 const std::string &parcelObj,
380 bool parcelObjIsPointer,
381 bool isReader,
382 ErrorMode mode,
383 const std::string & /* parentName */,
384 const std::string & /* offsetText */) const {
385 emitResolveReferencesEmbeddedHelper(
386 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
387 parcelObjIsPointer, isReader, mode, "", "");
388}
389
Yifan Hong00f47172016-09-30 14:40:45 -0700390bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
391 // parentName and offsetText is not used in emitResolveReferencesEmbedded
392 return false;
393}
394
Yifan Hongbf459bc2016-08-23 16:50:37 -0700395void VectorType::emitResolveReferencesEmbeddedHelper(
396 Formatter &out,
397 size_t depth,
398 const std::string &name,
399 const std::string &sanitizedName,
400 bool nameIsPointer,
401 const std::string &parcelObj,
402 bool parcelObjIsPointer,
403 bool isReader,
404 ErrorMode mode,
405 const std::string &childName,
406 const std::string &childOffsetText) const {
407 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
408
409 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800410 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700411 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700412
413 std::string myChildName = childName, myChildOffset = childOffsetText;
414
415 if(myChildName.empty() && myChildOffset.empty()) {
416 myChildName = "_hidl_" + sanitizedName + "_child";
417 myChildOffset = "0";
418
419 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800420 out << "_hidl_err = ::android::hardware::findInParcel("
421 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700422 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
423 << "&" << myChildName
424 << ");\n";
425
426 handleError(out, mode);
427 }
428
429 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
430
431 out << "for (size_t "
432 << iteratorName
433 << " = 0; "
434 << iteratorName
435 << " < "
436 << nameDeref
437 << "size(); ++"
438 << iteratorName
439 << ") {\n";
440
441 out.indent();
442
443 mElementType->emitResolveReferencesEmbedded(
444 out,
445 depth + 1,
446 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
447 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
448 false /* nameIsPointer */,
449 parcelObj,
450 parcelObjIsPointer,
451 isReader,
452 mode,
453 myChildName,
454 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700455 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700456
457 out.unindent();
458
459 out << "}\n\n";
460}
461
Andreas Huberf630bc82016-09-09 14:52:25 -0700462void VectorType::emitJavaReaderWriter(
463 Formatter &out,
464 const std::string &parcelObj,
465 const std::string &argName,
466 bool isReader) const {
467 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700468
Andreas Huberf630bc82016-09-09 14:52:25 -0700469 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700470 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700471 << ".readVectorFromParcel("
472 << parcelObj
473 << ");\n";
474 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700475 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700476 << ".writeVectorToParcel("
477 << parcelObj
478 << ", "
479 << argName
480 << ");\n";
481 }
482
483 return;
484 }
485
Andreas Huber1b6822b2016-10-18 09:28:40 -0700486 if (mElementType->isArray()) {
487 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700488 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700489 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700490 << "();\n";
491 }
492
493 out << "{\n";
494 out.indent();
495
Yifan Hong1af73532016-11-09 14:32:58 -0800496 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700497
498 if (isReader) {
499 out << parcelObj
500 << ".readBuffer();\n";
501 } else {
502 size_t align, size;
503 getAlignmentAndSize(&align, &size);
504
Yifan Hong1af73532016-11-09 14:32:58 -0800505 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700506 << size
507 << " /* size */);\n";
508 }
509
510 emitJavaFieldReaderWriter(
511 out,
512 0 /* depth */,
513 parcelObj,
514 "_hidl_blob",
515 argName,
516 "0 /* offset */",
517 isReader);
518
519 if (!isReader) {
520 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
521 };
522
523 out.unindent();
524 out << "}\n";
525
526 return;
527 }
528
Andreas Huberf630bc82016-09-09 14:52:25 -0700529 emitJavaReaderWriterWithSuffix(
530 out,
531 parcelObj,
532 argName,
533 isReader,
534 mElementType->getJavaSuffix() + "Vector",
535 "" /* extra */);
536}
537
Andreas Huber85eabdb2016-08-25 11:24:49 -0700538void VectorType::emitJavaFieldInitializer(
539 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700540 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700541
Andreas Huber1b6822b2016-10-18 09:28:40 -0700542 out << "final "
543 << javaType
544 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700545 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700546 << " = new "
547 << javaType
548 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700549}
550
551void VectorType::emitJavaFieldReaderWriter(
552 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700553 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700554 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700555 const std::string &blobName,
556 const std::string &fieldName,
557 const std::string &offset,
558 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700559 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700560 out,
561 depth,
562 mElementType,
563 parcelName,
564 blobName,
565 fieldName,
566 offset,
567 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700568}
569
570// static
571void VectorType::EmitJavaFieldReaderWriterForElementType(
572 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700573 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700574 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700575 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700576 const std::string &blobName,
577 const std::string &fieldName,
578 const std::string &offset,
579 bool isReader) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700580 if (isReader) {
581 out << "{\n";
582 out.indent();
583
Yifan Hong1af73532016-11-09 14:32:58 -0800584 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700585 << parcelName
586 << ".readEmbeddedBuffer(\n";
587
Andreas Huber85eabdb2016-08-25 11:24:49 -0700588 out.indent();
589 out.indent();
590
591 out << blobName
592 << ".handle(),\n"
593 << offset
594 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";
595
596 out.unindent();
597 out.unindent();
598
599 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800600 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700601 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800602 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700603 << offset
604 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
605
Andreas Huber4c865b72016-09-14 15:26:27 -0700606 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
607
608 out << "for (int "
609 << iteratorName
610 << " = 0; "
611 << iteratorName
612 << " < _hidl_vec_size; "
613 << "++"
614 << iteratorName
615 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700616
617 out.indent();
618
Andreas Huberf630bc82016-09-09 14:52:25 -0700619 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700620
621 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700622 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700623
Andreas Huberf630bc82016-09-09 14:52:25 -0700624 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700625 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700626 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700627 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700628 "childBlob",
629 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700630 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700631 true /* isReader */);
632
Andreas Huber1b6822b2016-10-18 09:28:40 -0700633 out << fieldName
634 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700635
636 out.unindent();
637
638 out << "}\n";
639
640 out.unindent();
641 out << "}\n";
642
643 return;
644 }
645
646 out << "{\n";
647 out.indent();
648
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800649 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700650 << fieldName
651 << ".size();\n";
652
653 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800654 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700655 << offset
656 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
657
658 out << blobName
659 << ".putBool("
660 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800661 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700662
663 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700664 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700665
666 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800667 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700668 << elementSize
669 << "));\n";
670
Andreas Huber4c865b72016-09-14 15:26:27 -0700671 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
672
673 out << "for (int "
674 << iteratorName
675 << " = 0; "
676 << iteratorName
677 << " < _hidl_vec_size; "
678 << "++"
679 << iteratorName
680 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700681
682 out.indent();
683
Andreas Huberf630bc82016-09-09 14:52:25 -0700684 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700685 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700686 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700687 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700688 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700689 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700690 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700691 false /* isReader */);
692
693 out.unindent();
694
695 out << "}\n";
696
697 out << blobName
698 << ".putBlob("
699 << offset
700 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
701
702 out.unindent();
703 out << "}\n";
704}
705
Andreas Huber881227d2016-08-02 14:20:21 -0700706bool VectorType::needsEmbeddedReadWrite() const {
707 return true;
708}
709
Yifan Hongbf459bc2016-08-23 16:50:37 -0700710bool VectorType::needsResolveReferences() const {
711 return mElementType->needsResolveReferences();
712}
713
Andreas Huber881227d2016-08-02 14:20:21 -0700714bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700715 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700716}
717
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700718status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700719 out << "type: " << getVtsType() << "\n";
720 out << "vector_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700721 out.indent();
722 status_t err = mElementType->emitVtsTypeDeclarations(out);
723 if (err != OK) {
724 return err;
725 }
726 out.unindent();
727 out << "}\n";
728 return OK;
729}
730
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700731status_t VectorType::emitVtsAttributeType(Formatter &out) const {
732 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
733 out.indent();
734 status_t status = mElementType->emitVtsAttributeType(out);
735 if (status != OK) {
736 return status;
737 }
738 out.unindent();
739 out << "}\n";
740 return OK;
741}
742
Andreas Huber70a59e12016-08-16 12:57:01 -0700743bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700744 if (!mElementType->isJavaCompatible()) {
745 return false;
746 }
747
748 if (mElementType->isArray()) {
749 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
750 }
751
Andreas Huber1b6822b2016-10-18 09:28:40 -0700752 if (mElementType->isVector()) {
753 return false;
754 }
755
Andreas Huber86a112b2016-10-19 14:25:16 -0700756 if (isVectorOfBinders()) {
757 return false;
758 }
759
Andreas Huberf03332a2016-09-22 15:35:43 -0700760 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700761}
762
Andreas Huber85eabdb2016-08-25 11:24:49 -0700763void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
764 *align = 8; // hidl_vec<T>
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800765 *size = 16;
Andreas Huber85eabdb2016-08-25 11:24:49 -0700766}
767
Andreas Huberc9410c72016-07-28 12:18:40 -0700768} // namespace android
769