blob: a58ea2cd8a3d6376ea41ee810181c8a1060fedb6 [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
Martijn Coenen011bb062017-01-13 11:09:41 +0100590 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
591 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700592
593 out.unindent();
594 out.unindent();
595
596 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800597 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700598 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800599 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700600 << offset
601 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
602
Andreas Huber4c865b72016-09-14 15:26:27 -0700603 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
604
605 out << "for (int "
606 << iteratorName
607 << " = 0; "
608 << iteratorName
609 << " < _hidl_vec_size; "
610 << "++"
611 << iteratorName
612 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700613
614 out.indent();
615
Andreas Huberf630bc82016-09-09 14:52:25 -0700616 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700617
618 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700619 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700620
Andreas Huberf630bc82016-09-09 14:52:25 -0700621 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700622 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700623 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700624 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700625 "childBlob",
626 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700627 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700628 true /* isReader */);
629
Andreas Huber1b6822b2016-10-18 09:28:40 -0700630 out << fieldName
631 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632
633 out.unindent();
634
635 out << "}\n";
636
637 out.unindent();
638 out << "}\n";
639
640 return;
641 }
642
643 out << "{\n";
644 out.indent();
645
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800646 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700647 << fieldName
648 << ".size();\n";
649
650 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800651 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700652 << offset
653 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
654
655 out << blobName
656 << ".putBool("
657 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800658 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700659
660 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700661 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700662
663 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800664 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700665 << elementSize
666 << "));\n";
667
Andreas Huber4c865b72016-09-14 15:26:27 -0700668 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
669
670 out << "for (int "
671 << iteratorName
672 << " = 0; "
673 << iteratorName
674 << " < _hidl_vec_size; "
675 << "++"
676 << iteratorName
677 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700678
679 out.indent();
680
Andreas Huberf630bc82016-09-09 14:52:25 -0700681 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700682 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700683 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700684 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700685 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700686 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700687 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700688 false /* isReader */);
689
690 out.unindent();
691
692 out << "}\n";
693
694 out << blobName
695 << ".putBlob("
696 << offset
697 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
698
699 out.unindent();
700 out << "}\n";
701}
702
Andreas Huber881227d2016-08-02 14:20:21 -0700703bool VectorType::needsEmbeddedReadWrite() const {
704 return true;
705}
706
Yifan Hongbf459bc2016-08-23 16:50:37 -0700707bool VectorType::needsResolveReferences() const {
708 return mElementType->needsResolveReferences();
709}
710
Andreas Huber881227d2016-08-02 14:20:21 -0700711bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700712 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700713}
714
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700715status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700716 out << "type: " << getVtsType() << "\n";
717 out << "vector_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700718 out.indent();
719 status_t err = mElementType->emitVtsTypeDeclarations(out);
720 if (err != OK) {
721 return err;
722 }
723 out.unindent();
724 out << "}\n";
725 return OK;
726}
727
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700728status_t VectorType::emitVtsAttributeType(Formatter &out) const {
729 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
730 out.indent();
731 status_t status = mElementType->emitVtsAttributeType(out);
732 if (status != OK) {
733 return status;
734 }
735 out.unindent();
736 out << "}\n";
737 return OK;
738}
739
Andreas Huber70a59e12016-08-16 12:57:01 -0700740bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700741 if (!mElementType->isJavaCompatible()) {
742 return false;
743 }
744
745 if (mElementType->isArray()) {
746 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
747 }
748
Andreas Huber1b6822b2016-10-18 09:28:40 -0700749 if (mElementType->isVector()) {
750 return false;
751 }
752
Andreas Huber86a112b2016-10-19 14:25:16 -0700753 if (isVectorOfBinders()) {
754 return false;
755 }
756
Andreas Huberf03332a2016-09-22 15:35:43 -0700757 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700758}
759
Andreas Huber85eabdb2016-08-25 11:24:49 -0700760void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
761 *align = 8; // hidl_vec<T>
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800762 *size = 16;
Andreas Huber85eabdb2016-08-25 11:24:49 -0700763}
764
Andreas Huberc9410c72016-07-28 12:18:40 -0700765} // namespace android
766