blob: ff219942bfeb59ad26a9def5e1c7e6e2291ff5e4 [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) {
152 out << name
Andreas Huber8a82ff72016-08-04 10:29:39 -0700153 << " = (const ::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -0700154 << baseType
155 << "> *)"
156 << parcelObjDeref
157 << "readBuffer(&"
158 << parentName
159 << ");\n\n";
160
161 out << "if (" << name << " == nullptr) {\n";
162
163 out.indent();
164
Iliyan Malchev549e2592016-08-10 08:59:12 -0700165 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700166 handleError2(out, mode);
167
168 out.unindent();
169 out << "}\n\n";
170 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700171 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700172 << parcelObjDeref
173 << "writeBuffer(&"
174 << name
175 << ", sizeof("
176 << name
177 << "), &"
178 << parentName
179 << ");\n";
180
181 handleError(out, mode);
182 }
183
184 emitReaderWriterEmbedded(
185 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700186 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700187 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700188 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700189 isReader /* nameIsPointer */,
190 parcelObj,
191 parcelObjIsPointer,
192 isReader,
193 mode,
194 parentName,
195 "0 /* parentOffset */");
196}
197
Andreas Huber86a112b2016-10-19 14:25:16 -0700198void VectorType::emitReaderWriterForVectorOfBinders(
199 Formatter &out,
200 const std::string &name,
201 const std::string &parcelObj,
202 bool parcelObjIsPointer,
203 bool isReader,
204 ErrorMode mode) const {
205 const std::string parcelObjDeref =
206 parcelObj + (parcelObjIsPointer ? "->" : ".");
207
208 if (isReader) {
209 out << "{\n";
210 out.indent();
211
212 const std::string sizeName = "_hidl_" + name + "_size";
213
214 out << "uint64_t "
215 << sizeName
216 << ";\n";
217
218 out << "_hidl_err = "
219 << parcelObjDeref
220 << "readUint64(&"
221 << sizeName
222 << ");\n";
223
224 handleError(out, mode);
225
226 out << name
227 << ".resize("
228 << sizeName
229 << ");\n\n"
230 << "for (size_t _hidl_index = 0; _hidl_index < "
231 << sizeName
232 << "; ++_hidl_index) {\n";
233
234 out.indent();
235
Yifan Hong3b320f82016-11-01 15:15:54 -0700236 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800237 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700238
239 mElementType->emitReaderWriter(
240 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800241 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700242 parcelObj,
243 parcelObjIsPointer,
244 isReader,
245 mode);
246
247 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800248 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700249
250 out.unindent();
251 out << "}\n";
252
253 out.unindent();
254 out << "}\n";
255 } else {
256 out << "_hidl_err = "
257 << parcelObjDeref
258 << "writeUint64("
259 << name
260 << ".size());\n";
261
262 handleError(out, mode);
263
264 out << "for (size_t _hidl_index = 0; _hidl_index < "
265 << name
266 << ".size(); ++_hidl_index) {\n";
267
268 out.indent();
269
270 mElementType->emitReaderWriter(
271 out,
272 name + "[_hidl_index]",
273 parcelObj,
274 parcelObjIsPointer,
275 isReader,
276 mode);
277
278 out.unindent();
279 out << "}\n";
280 }
281}
282
Andreas Huber881227d2016-08-02 14:20:21 -0700283void VectorType::emitReaderWriterEmbedded(
284 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700285 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700286 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700287 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700288 bool nameIsPointer,
289 const std::string &parcelObj,
290 bool parcelObjIsPointer,
291 bool isReader,
292 ErrorMode mode,
293 const std::string &parentName,
294 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700295 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700296
Yifan Hongbe2a3732016-10-05 13:33:41 -0700297 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700298 out << "size_t " << childName << ";\n\n";
299
300 emitReaderWriterEmbeddedForTypeName(
301 out,
302 name,
303 nameIsPointer,
304 parcelObj,
305 parcelObjIsPointer,
306 isReader,
307 mode,
308 parentName,
309 offsetText,
310 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800311 childName,
312 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700313
314 if (!mElementType->needsEmbeddedReadWrite()) {
315 return;
316 }
317
318 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
319
Yifan Hong3b320f82016-11-01 15:15:54 -0700320 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700321
Andreas Huberf9d49f12016-09-12 14:58:36 -0700322 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
323
324 out << "for (size_t "
325 << iteratorName
326 << " = 0; "
327 << iteratorName
328 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700329 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700330 << "size(); ++"
331 << iteratorName
332 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700333
334 out.indent();
335
336 mElementType->emitReaderWriterEmbedded(
337 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700338 depth + 1,
339 (nameIsPointer ? "(*" + name + ")" : name)
340 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700341 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700342 false /* nameIsPointer */,
343 parcelObj,
344 parcelObjIsPointer,
345 isReader,
346 mode,
347 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700348 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700349
350 out.unindent();
351
352 out << "}\n\n";
353}
354
Yifan Hongbf459bc2016-08-23 16:50:37 -0700355void VectorType::emitResolveReferences(
356 Formatter &out,
357 const std::string &name,
358 bool nameIsPointer,
359 const std::string &parcelObj,
360 bool parcelObjIsPointer,
361 bool isReader,
362 ErrorMode mode) const {
363 emitResolveReferencesEmbeddedHelper(
364 out,
365 0, /* depth */
366 name,
367 name /* sanitizedName */,
368 nameIsPointer,
369 parcelObj,
370 parcelObjIsPointer,
371 isReader,
372 mode,
373 "_hidl_" + name + "_child",
374 "0 /* parentOffset */");
375}
376
377void VectorType::emitResolveReferencesEmbedded(
378 Formatter &out,
379 size_t depth,
380 const std::string &name,
381 const std::string &sanitizedName,
382 bool nameIsPointer,
383 const std::string &parcelObj,
384 bool parcelObjIsPointer,
385 bool isReader,
386 ErrorMode mode,
387 const std::string & /* parentName */,
388 const std::string & /* offsetText */) const {
389 emitResolveReferencesEmbeddedHelper(
390 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
391 parcelObjIsPointer, isReader, mode, "", "");
392}
393
Yifan Hong00f47172016-09-30 14:40:45 -0700394bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
395 // parentName and offsetText is not used in emitResolveReferencesEmbedded
396 return false;
397}
398
Yifan Hongbf459bc2016-08-23 16:50:37 -0700399void VectorType::emitResolveReferencesEmbeddedHelper(
400 Formatter &out,
401 size_t depth,
402 const std::string &name,
403 const std::string &sanitizedName,
404 bool nameIsPointer,
405 const std::string &parcelObj,
406 bool parcelObjIsPointer,
407 bool isReader,
408 ErrorMode mode,
409 const std::string &childName,
410 const std::string &childOffsetText) const {
411 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
412
413 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800414 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700415 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700416
417 std::string myChildName = childName, myChildOffset = childOffsetText;
418
419 if(myChildName.empty() && myChildOffset.empty()) {
420 myChildName = "_hidl_" + sanitizedName + "_child";
421 myChildOffset = "0";
422
423 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800424 out << "_hidl_err = ::android::hardware::findInParcel("
425 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700426 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
427 << "&" << myChildName
428 << ");\n";
429
430 handleError(out, mode);
431 }
432
433 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
434
435 out << "for (size_t "
436 << iteratorName
437 << " = 0; "
438 << iteratorName
439 << " < "
440 << nameDeref
441 << "size(); ++"
442 << iteratorName
443 << ") {\n";
444
445 out.indent();
446
447 mElementType->emitResolveReferencesEmbedded(
448 out,
449 depth + 1,
450 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
451 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
452 false /* nameIsPointer */,
453 parcelObj,
454 parcelObjIsPointer,
455 isReader,
456 mode,
457 myChildName,
458 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700459 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700460
461 out.unindent();
462
463 out << "}\n\n";
464}
465
Andreas Huberf630bc82016-09-09 14:52:25 -0700466void VectorType::emitJavaReaderWriter(
467 Formatter &out,
468 const std::string &parcelObj,
469 const std::string &argName,
470 bool isReader) const {
471 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700472
Andreas Huberf630bc82016-09-09 14:52:25 -0700473 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700474 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700475 << ".readVectorFromParcel("
476 << parcelObj
477 << ");\n";
478 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700479 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700480 << ".writeVectorToParcel("
481 << parcelObj
482 << ", "
483 << argName
484 << ");\n";
485 }
486
487 return;
488 }
489
Andreas Huber1b6822b2016-10-18 09:28:40 -0700490 if (mElementType->isArray()) {
491 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700492 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700493 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700494 << "();\n";
495 }
496
497 out << "{\n";
498 out.indent();
499
Yifan Hong1af73532016-11-09 14:32:58 -0800500 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700501
502 if (isReader) {
503 out << parcelObj
504 << ".readBuffer();\n";
505 } else {
506 size_t align, size;
507 getAlignmentAndSize(&align, &size);
508
Yifan Hong1af73532016-11-09 14:32:58 -0800509 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700510 << size
511 << " /* size */);\n";
512 }
513
514 emitJavaFieldReaderWriter(
515 out,
516 0 /* depth */,
517 parcelObj,
518 "_hidl_blob",
519 argName,
520 "0 /* offset */",
521 isReader);
522
523 if (!isReader) {
524 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
525 };
526
527 out.unindent();
528 out << "}\n";
529
530 return;
531 }
532
Andreas Huberf630bc82016-09-09 14:52:25 -0700533 emitJavaReaderWriterWithSuffix(
534 out,
535 parcelObj,
536 argName,
537 isReader,
538 mElementType->getJavaSuffix() + "Vector",
539 "" /* extra */);
540}
541
Andreas Huber85eabdb2016-08-25 11:24:49 -0700542void VectorType::emitJavaFieldInitializer(
543 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700544 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700545
Andreas Huber1b6822b2016-10-18 09:28:40 -0700546 out << "final "
547 << javaType
548 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700549 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700550 << " = new "
551 << javaType
552 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700553}
554
555void VectorType::emitJavaFieldReaderWriter(
556 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700557 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700558 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700559 const std::string &blobName,
560 const std::string &fieldName,
561 const std::string &offset,
562 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700563 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700564 out,
565 depth,
566 mElementType,
567 parcelName,
568 blobName,
569 fieldName,
570 offset,
571 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700572}
573
574// static
575void VectorType::EmitJavaFieldReaderWriterForElementType(
576 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700577 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700578 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700579 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700580 const std::string &blobName,
581 const std::string &fieldName,
582 const std::string &offset,
583 bool isReader) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700584 if (isReader) {
585 out << "{\n";
586 out.indent();
587
Yifan Hong1af73532016-11-09 14:32:58 -0800588 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700589 << parcelName
590 << ".readEmbeddedBuffer(\n";
591
Andreas Huber85eabdb2016-08-25 11:24:49 -0700592 out.indent();
593 out.indent();
594
595 out << blobName
596 << ".handle(),\n"
597 << offset
598 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";
599
600 out.unindent();
601 out.unindent();
602
603 out << fieldName << ".clear();\n";
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800604 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700605 << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800606 << ".getInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700607 << offset
608 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
609
Andreas Huber4c865b72016-09-14 15:26:27 -0700610 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
611
612 out << "for (int "
613 << iteratorName
614 << " = 0; "
615 << iteratorName
616 << " < _hidl_vec_size; "
617 << "++"
618 << iteratorName
619 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700620
621 out.indent();
622
Andreas Huberf630bc82016-09-09 14:52:25 -0700623 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700624
625 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700626 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700627
Andreas Huberf630bc82016-09-09 14:52:25 -0700628 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700629 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700630 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700631 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632 "childBlob",
633 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700634 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700635 true /* isReader */);
636
Andreas Huber1b6822b2016-10-18 09:28:40 -0700637 out << fieldName
638 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700639
640 out.unindent();
641
642 out << "}\n";
643
644 out.unindent();
645 out << "}\n";
646
647 return;
648 }
649
650 out << "{\n";
651 out.indent();
652
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800653 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700654 << fieldName
655 << ".size();\n";
656
657 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800658 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700659 << offset
660 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
661
662 out << blobName
663 << ".putBool("
664 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800665 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700666
667 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700668 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700669
670 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800671 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700672 << elementSize
673 << "));\n";
674
Andreas Huber4c865b72016-09-14 15:26:27 -0700675 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
676
677 out << "for (int "
678 << iteratorName
679 << " = 0; "
680 << iteratorName
681 << " < _hidl_vec_size; "
682 << "++"
683 << iteratorName
684 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700685
686 out.indent();
687
Andreas Huberf630bc82016-09-09 14:52:25 -0700688 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700689 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700690 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700691 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700692 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700693 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700694 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700695 false /* isReader */);
696
697 out.unindent();
698
699 out << "}\n";
700
701 out << blobName
702 << ".putBlob("
703 << offset
704 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
705
706 out.unindent();
707 out << "}\n";
708}
709
Andreas Huber881227d2016-08-02 14:20:21 -0700710bool VectorType::needsEmbeddedReadWrite() const {
711 return true;
712}
713
Yifan Hongbf459bc2016-08-23 16:50:37 -0700714bool VectorType::needsResolveReferences() const {
715 return mElementType->needsResolveReferences();
716}
717
Andreas Huber881227d2016-08-02 14:20:21 -0700718bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700719 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700720}
721
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700722status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700723 out << "type: " << getVtsType() << "\n";
724 out << "vector_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700725 out.indent();
726 status_t err = mElementType->emitVtsTypeDeclarations(out);
727 if (err != OK) {
728 return err;
729 }
730 out.unindent();
731 out << "}\n";
732 return OK;
733}
734
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700735status_t VectorType::emitVtsAttributeType(Formatter &out) const {
736 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
737 out.indent();
738 status_t status = mElementType->emitVtsAttributeType(out);
739 if (status != OK) {
740 return status;
741 }
742 out.unindent();
743 out << "}\n";
744 return OK;
745}
746
Andreas Huber70a59e12016-08-16 12:57:01 -0700747bool VectorType::isJavaCompatible() const {
Andreas Huberf03332a2016-09-22 15:35:43 -0700748 if (!mElementType->isJavaCompatible()) {
749 return false;
750 }
751
752 if (mElementType->isArray()) {
753 return static_cast<ArrayType *>(mElementType)->countDimensions() == 1;
754 }
755
Andreas Huber1b6822b2016-10-18 09:28:40 -0700756 if (mElementType->isVector()) {
757 return false;
758 }
759
Andreas Huber86a112b2016-10-19 14:25:16 -0700760 if (isVectorOfBinders()) {
761 return false;
762 }
763
Andreas Huberf03332a2016-09-22 15:35:43 -0700764 return true;
Andreas Huber70a59e12016-08-16 12:57:01 -0700765}
766
Andreas Huber85eabdb2016-08-25 11:24:49 -0700767void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
768 *align = 8; // hidl_vec<T>
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800769 *size = 16;
Andreas Huber85eabdb2016-08-25 11:24:49 -0700770}
771
Andreas Huberc9410c72016-07-28 12:18:40 -0700772} // namespace android
773