blob: 1c1271a19238941a7dd91482e97b4e02d5be5ee7 [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
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
Andreas Huber881227d2016-08-02 14:20:21 -0700128void VectorType::emitReaderWriter(
129 Formatter &out,
130 const std::string &name,
131 const std::string &parcelObj,
132 bool parcelObjIsPointer,
133 bool isReader,
134 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700135 if (isVectorOfBinders()) {
136 emitReaderWriterForVectorOfBinders(
137 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
138
139 return;
140 }
141
Yifan Hong3b320f82016-11-01 15:15:54 -0700142 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700143
Iliyan Malchev549e2592016-08-10 08:59:12 -0700144 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700145
146 out << "size_t " << parentName << ";\n\n";
147
148 const std::string parcelObjDeref =
149 parcelObj + (parcelObjIsPointer ? "->" : ".");
150
151 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100152 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700153 << parcelObjDeref
154 << "readBuffer(&"
155 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100156 << ", "
157 << " reinterpret_cast<const void **>("
158 << "&" << name
159 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700160
Martijn Coenen6a082c62017-01-11 12:47:02 +0100161 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700162 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700163 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700164 << parcelObjDeref
165 << "writeBuffer(&"
166 << name
167 << ", sizeof("
168 << name
169 << "), &"
170 << parentName
171 << ");\n";
172
173 handleError(out, mode);
174 }
175
176 emitReaderWriterEmbedded(
177 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700178 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700179 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700180 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700181 isReader /* nameIsPointer */,
182 parcelObj,
183 parcelObjIsPointer,
184 isReader,
185 mode,
186 parentName,
187 "0 /* parentOffset */");
188}
189
Andreas Huber86a112b2016-10-19 14:25:16 -0700190void VectorType::emitReaderWriterForVectorOfBinders(
191 Formatter &out,
192 const std::string &name,
193 const std::string &parcelObj,
194 bool parcelObjIsPointer,
195 bool isReader,
196 ErrorMode mode) const {
197 const std::string parcelObjDeref =
198 parcelObj + (parcelObjIsPointer ? "->" : ".");
199
200 if (isReader) {
201 out << "{\n";
202 out.indent();
203
204 const std::string sizeName = "_hidl_" + name + "_size";
205
206 out << "uint64_t "
207 << sizeName
208 << ";\n";
209
210 out << "_hidl_err = "
211 << parcelObjDeref
212 << "readUint64(&"
213 << sizeName
214 << ");\n";
215
216 handleError(out, mode);
217
218 out << name
219 << ".resize("
220 << sizeName
221 << ");\n\n"
222 << "for (size_t _hidl_index = 0; _hidl_index < "
223 << sizeName
224 << "; ++_hidl_index) {\n";
225
226 out.indent();
227
Yifan Hong3b320f82016-11-01 15:15:54 -0700228 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800229 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700230
231 mElementType->emitReaderWriter(
232 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800233 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700234 parcelObj,
235 parcelObjIsPointer,
236 isReader,
237 mode);
238
239 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800240 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700241
242 out.unindent();
243 out << "}\n";
244
245 out.unindent();
246 out << "}\n";
247 } else {
248 out << "_hidl_err = "
249 << parcelObjDeref
250 << "writeUint64("
251 << name
252 << ".size());\n";
253
254 handleError(out, mode);
255
256 out << "for (size_t _hidl_index = 0; _hidl_index < "
257 << name
258 << ".size(); ++_hidl_index) {\n";
259
260 out.indent();
261
262 mElementType->emitReaderWriter(
263 out,
264 name + "[_hidl_index]",
265 parcelObj,
266 parcelObjIsPointer,
267 isReader,
268 mode);
269
270 out.unindent();
271 out << "}\n";
272 }
273}
274
Andreas Huber881227d2016-08-02 14:20:21 -0700275void VectorType::emitReaderWriterEmbedded(
276 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700277 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700278 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700279 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700280 bool nameIsPointer,
281 const std::string &parcelObj,
282 bool parcelObjIsPointer,
283 bool isReader,
284 ErrorMode mode,
285 const std::string &parentName,
286 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700287 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700288
Yifan Hongbe2a3732016-10-05 13:33:41 -0700289 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700290 out << "size_t " << childName << ";\n\n";
291
292 emitReaderWriterEmbeddedForTypeName(
293 out,
294 name,
295 nameIsPointer,
296 parcelObj,
297 parcelObjIsPointer,
298 isReader,
299 mode,
300 parentName,
301 offsetText,
302 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800303 childName,
304 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700305
306 if (!mElementType->needsEmbeddedReadWrite()) {
307 return;
308 }
309
310 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
311
Yifan Hong3b320f82016-11-01 15:15:54 -0700312 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700313
Andreas Huberf9d49f12016-09-12 14:58:36 -0700314 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
315
316 out << "for (size_t "
317 << iteratorName
318 << " = 0; "
319 << iteratorName
320 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700321 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700322 << "size(); ++"
323 << iteratorName
324 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700325
326 out.indent();
327
328 mElementType->emitReaderWriterEmbedded(
329 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700330 depth + 1,
331 (nameIsPointer ? "(*" + name + ")" : name)
332 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700333 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700334 false /* nameIsPointer */,
335 parcelObj,
336 parcelObjIsPointer,
337 isReader,
338 mode,
339 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700340 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700341
342 out.unindent();
343
344 out << "}\n\n";
345}
346
Yifan Hongbf459bc2016-08-23 16:50:37 -0700347void VectorType::emitResolveReferences(
348 Formatter &out,
349 const std::string &name,
350 bool nameIsPointer,
351 const std::string &parcelObj,
352 bool parcelObjIsPointer,
353 bool isReader,
354 ErrorMode mode) const {
355 emitResolveReferencesEmbeddedHelper(
356 out,
357 0, /* depth */
358 name,
359 name /* sanitizedName */,
360 nameIsPointer,
361 parcelObj,
362 parcelObjIsPointer,
363 isReader,
364 mode,
365 "_hidl_" + name + "_child",
366 "0 /* parentOffset */");
367}
368
369void VectorType::emitResolveReferencesEmbedded(
370 Formatter &out,
371 size_t depth,
372 const std::string &name,
373 const std::string &sanitizedName,
374 bool nameIsPointer,
375 const std::string &parcelObj,
376 bool parcelObjIsPointer,
377 bool isReader,
378 ErrorMode mode,
379 const std::string & /* parentName */,
380 const std::string & /* offsetText */) const {
381 emitResolveReferencesEmbeddedHelper(
382 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
383 parcelObjIsPointer, isReader, mode, "", "");
384}
385
Yifan Hong00f47172016-09-30 14:40:45 -0700386bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
387 // parentName and offsetText is not used in emitResolveReferencesEmbedded
388 return false;
389}
390
Yifan Hongbf459bc2016-08-23 16:50:37 -0700391void VectorType::emitResolveReferencesEmbeddedHelper(
392 Formatter &out,
393 size_t depth,
394 const std::string &name,
395 const std::string &sanitizedName,
396 bool nameIsPointer,
397 const std::string &parcelObj,
398 bool parcelObjIsPointer,
399 bool isReader,
400 ErrorMode mode,
401 const std::string &childName,
402 const std::string &childOffsetText) const {
403 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
404
405 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800406 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700407 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700408
409 std::string myChildName = childName, myChildOffset = childOffsetText;
410
411 if(myChildName.empty() && myChildOffset.empty()) {
412 myChildName = "_hidl_" + sanitizedName + "_child";
413 myChildOffset = "0";
414
415 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800416 out << "_hidl_err = ::android::hardware::findInParcel("
417 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700418 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
419 << "&" << myChildName
420 << ");\n";
421
422 handleError(out, mode);
423 }
424
425 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
426
427 out << "for (size_t "
428 << iteratorName
429 << " = 0; "
430 << iteratorName
431 << " < "
432 << nameDeref
433 << "size(); ++"
434 << iteratorName
435 << ") {\n";
436
437 out.indent();
438
439 mElementType->emitResolveReferencesEmbedded(
440 out,
441 depth + 1,
442 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
443 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
444 false /* nameIsPointer */,
445 parcelObj,
446 parcelObjIsPointer,
447 isReader,
448 mode,
449 myChildName,
450 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700451 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700452
453 out.unindent();
454
455 out << "}\n\n";
456}
457
Andreas Huberf630bc82016-09-09 14:52:25 -0700458void VectorType::emitJavaReaderWriter(
459 Formatter &out,
460 const std::string &parcelObj,
461 const std::string &argName,
462 bool isReader) const {
463 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700464
Andreas Huberf630bc82016-09-09 14:52:25 -0700465 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700466 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700467 << ".readVectorFromParcel("
468 << parcelObj
469 << ");\n";
470 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700471 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700472 << ".writeVectorToParcel("
473 << parcelObj
474 << ", "
475 << argName
476 << ");\n";
477 }
478
479 return;
480 }
481
Andreas Huber1b6822b2016-10-18 09:28:40 -0700482 if (mElementType->isArray()) {
483 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700484 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700485 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700486 << "();\n";
487 }
488
489 out << "{\n";
490 out.indent();
491
Yifan Hong1af73532016-11-09 14:32:58 -0800492 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700493
494 if (isReader) {
495 out << parcelObj
496 << ".readBuffer();\n";
497 } else {
498 size_t align, size;
499 getAlignmentAndSize(&align, &size);
500
Yifan Hong1af73532016-11-09 14:32:58 -0800501 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700502 << size
503 << " /* size */);\n";
504 }
505
506 emitJavaFieldReaderWriter(
507 out,
508 0 /* depth */,
509 parcelObj,
510 "_hidl_blob",
511 argName,
512 "0 /* offset */",
513 isReader);
514
515 if (!isReader) {
516 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
517 };
518
519 out.unindent();
520 out << "}\n";
521
522 return;
523 }
524
Andreas Huberf630bc82016-09-09 14:52:25 -0700525 emitJavaReaderWriterWithSuffix(
526 out,
527 parcelObj,
528 argName,
529 isReader,
530 mElementType->getJavaSuffix() + "Vector",
531 "" /* extra */);
532}
533
Andreas Huber85eabdb2016-08-25 11:24:49 -0700534void VectorType::emitJavaFieldInitializer(
535 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700536 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700537
Andreas Huber1b6822b2016-10-18 09:28:40 -0700538 out << "final "
539 << javaType
540 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700541 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700542 << " = new "
543 << javaType
544 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700545}
546
547void VectorType::emitJavaFieldReaderWriter(
548 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700549 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700550 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700551 const std::string &blobName,
552 const std::string &fieldName,
553 const std::string &offset,
554 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700555 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700556 out,
557 depth,
558 mElementType,
559 parcelName,
560 blobName,
561 fieldName,
562 offset,
563 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700564}
565
566// static
567void VectorType::EmitJavaFieldReaderWriterForElementType(
568 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700569 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700570 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700571 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700572 const std::string &blobName,
573 const std::string &fieldName,
574 const std::string &offset,
575 bool isReader) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700576 if (isReader) {
577 out << "{\n";
578 out.indent();
579
Yifan Hong1af73532016-11-09 14:32:58 -0800580 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700581 << parcelName
582 << ".readEmbeddedBuffer(\n";
583
Andreas Huber85eabdb2016-08-25 11:24:49 -0700584 out.indent();
585 out.indent();
586
587 out << blobName
588 << ".handle(),\n"
589 << offset
590 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";
591
592 out.unindent();
593 out.unindent();
594
595 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800596 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700597 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800598 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700599 << offset
600 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
601
Andreas Huber4c865b72016-09-14 15:26:27 -0700602 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
603
604 out << "for (int "
605 << iteratorName
606 << " = 0; "
607 << iteratorName
608 << " < _hidl_vec_size; "
609 << "++"
610 << iteratorName
611 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700612
613 out.indent();
614
Andreas Huberf630bc82016-09-09 14:52:25 -0700615 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700616
617 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700618 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700619
Andreas Huberf630bc82016-09-09 14:52:25 -0700620 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700621 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700622 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700623 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700624 "childBlob",
625 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700626 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700627 true /* isReader */);
628
Andreas Huber1b6822b2016-10-18 09:28:40 -0700629 out << fieldName
630 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700631
632 out.unindent();
633
634 out << "}\n";
635
636 out.unindent();
637 out << "}\n";
638
639 return;
640 }
641
642 out << "{\n";
643 out.indent();
644
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800645 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700646 << fieldName
647 << ".size();\n";
648
649 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800650 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700651 << offset
652 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
653
654 out << blobName
655 << ".putBool("
656 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800657 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700658
659 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700660 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700661
662 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800663 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700664 << elementSize
665 << "));\n";
666
Andreas Huber4c865b72016-09-14 15:26:27 -0700667 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
668
669 out << "for (int "
670 << iteratorName
671 << " = 0; "
672 << iteratorName
673 << " < _hidl_vec_size; "
674 << "++"
675 << iteratorName
676 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700677
678 out.indent();
679
Andreas Huberf630bc82016-09-09 14:52:25 -0700680 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700681 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700682 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700683 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700684 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700685 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700686 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700687 false /* isReader */);
688
689 out.unindent();
690
691 out << "}\n";
692
693 out << blobName
694 << ".putBlob("
695 << offset
696 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
697
698 out.unindent();
699 out << "}\n";
700}
701
Andreas Huber881227d2016-08-02 14:20:21 -0700702bool VectorType::needsEmbeddedReadWrite() const {
703 return true;
704}
705
Yifan Hongbf459bc2016-08-23 16:50:37 -0700706bool VectorType::needsResolveReferences() const {
707 return mElementType->needsResolveReferences();
708}
709
Andreas Huber881227d2016-08-02 14:20:21 -0700710bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700711 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700712}
713
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700714status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700715 out << "type: " << getVtsType() << "\n";
716 out << "vector_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700717 out.indent();
718 status_t err = mElementType->emitVtsTypeDeclarations(out);
719 if (err != OK) {
720 return err;
721 }
722 out.unindent();
723 out << "}\n";
724 return OK;
725}
726
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700727status_t VectorType::emitVtsAttributeType(Formatter &out) const {
728 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
729 out.indent();
730 status_t status = mElementType->emitVtsAttributeType(out);
731 if (status != OK) {
732 return status;
733 }
734 out.unindent();
735 out << "}\n";
736 return OK;
737}
738
Andreas Huber70a59e12016-08-16 12:57:01 -0700739bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700740 if (!mElementType->isJavaCompatible()) {
741 return false;
742 }
743
744 if (mElementType->isArray()) {
745 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
746 }
747
Andreas Huber1b6822b2016-10-18 09:28:40 -0700748 if (mElementType->isVector()) {
749 return false;
750 }
751
Andreas Huber86a112b2016-10-19 14:25:16 -0700752 if (isVectorOfBinders()) {
753 return false;
754 }
755
Andreas Huberf03332a2016-09-22 15:35:43 -0700756 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700757}
758
Andreas Huber85eabdb2016-08-25 11:24:49 -0700759void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
760 *align = 8; // hidl_vec<T>
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800761 *size = 16;
Andreas Huber85eabdb2016-08-25 11:24:49 -0700762}
763
Andreas Huberc9410c72016-07-28 12:18:40 -0700764} // namespace android
765