blob: a1b79402094331b64d6df056c09613919c8b0f53 [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 Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Andreas Huberf03332a2016-09-22 15:35:43 -070022
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070023#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070024#include <android-base/logging.h>
25
Andreas Huberc9410c72016-07-28 12:18:40 -070026namespace android {
27
Timur Iskhakov63f39902017-08-29 15:47:29 -070028VectorType::VectorType(Scope* parent) : TemplatedType(parent) {}
Andreas Huberc9410c72016-07-28 12:18:40 -070029
Timur Iskhakov3f1d26e2017-08-30 15:35:53 -070030std::string VectorType::templatedTypeName() const {
31 return "vector";
Steven Moreland30bb6a82016-11-30 09:18:34 -080032}
33
Timur Iskhakov24e605b2017-08-30 14:02:55 -070034bool VectorType::isCompatibleElementType(const Type* elementType) const {
Yifan Hong51f9c8a2016-12-05 18:47:33 -080035 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 }
Steven Moreland3aa0d712017-12-11 16:54:00 -080047 if (elementType->isCompoundType()) {
Steven Morelandd927e5c2018-07-10 16:03:43 -070048 if (static_cast<const CompoundType*>(elementType)->containsInterface()) {
49 return false;
50 }
Yifan Hong51f9c8a2016-12-05 18:47:33 -080051 return true;
52 }
53 if (elementType->isInterface()) {
54 return true;
55 }
56 if (elementType->isHandle()) {
57 return true;
58 }
Steven Moreland397b5e12017-06-08 14:02:26 -070059 if (elementType->isMemory()) {
60 return true;
61 }
Yifan Hong51f9c8a2016-12-05 18:47:33 -080062 if (elementType->isTemplatedType()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -070063 const Type* inner = static_cast<const TemplatedType*>(elementType)->getElementType();
Yifan Hong51f9c8a2016-12-05 18:47:33 -080064 return this->isCompatibleElementType(inner) && !inner->isInterface();
65 }
66 if (elementType->isArray()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -070067 const Type* inner = static_cast<const ArrayType*>(elementType)->getElementType();
Yifan Hong51f9c8a2016-12-05 18:47:33 -080068 return this->isCompatibleElementType(inner) && !inner->isInterface();
69 }
70 return false;
Steven Moreland30bb6a82016-11-30 09:18:34 -080071}
72
Andreas Huber86a112b2016-10-19 14:25:16 -070073bool VectorType::isVector() const {
74 return true;
75}
76
77bool VectorType::isVectorOfBinders() const {
78 return mElementType->isBinder();
79}
80
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -070081bool VectorType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
82 return mElementType->canCheckEquality(visited);
Yifan Hongc6752dc2016-12-20 14:00:14 -080083}
84
Timur Iskhakovb58f4182017-08-29 15:19:24 -070085std::vector<const Reference<Type>*> VectorType::getStrongReferences() const {
Timur Iskhakov40731af2017-08-24 14:18:35 -070086 return {};
87}
88
Steven Moreland979e0992016-09-07 09:18:08 -070089std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070090 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070091 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070092 std::string(specifyNamespaces ? "::android::hardware::" : "")
93 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070094 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070095 + ">";
96
Andreas Huber881227d2016-08-02 14:20:21 -070097 switch (mode) {
98 case StorageMode_Stack:
99 return base;
100
101 case StorageMode_Argument:
102 return "const " + base + "&";
103
104 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -0700105 {
106 if (isVectorOfBinders()) {
107 return base;
108 }
109
Andreas Huber881227d2016-08-02 14:20:21 -0700110 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700111 }
Andreas Huber881227d2016-08-02 14:20:21 -0700112 }
113}
114
Yifan Hong4ed13472016-11-02 10:44:11 -0700115std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700116
Yifan Hong4ed13472016-11-02 10:44:11 -0700117 std::string elementJavaType;
118 if (mElementType->isArray()) {
119 elementJavaType = mElementType->getJavaType();
120 } else {
121 elementJavaType = mElementType->getJavaWrapperType();
122 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700123
Yifan Hong1af73532016-11-09 14:32:58 -0800124 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700125 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700126 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700127}
128
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700129std::string VectorType::getVtsType() const {
130 return "TYPE_VECTOR";
131}
132
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800133std::string VectorType::getVtsValueName() const {
134 return "vector_value";
135}
136
Andreas Huber881227d2016-08-02 14:20:21 -0700137void VectorType::emitReaderWriter(
138 Formatter &out,
139 const std::string &name,
140 const std::string &parcelObj,
141 bool parcelObjIsPointer,
142 bool isReader,
143 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700144 if (isVectorOfBinders()) {
145 emitReaderWriterForVectorOfBinders(
146 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
147
148 return;
149 }
150
Yifan Hong3b320f82016-11-01 15:15:54 -0700151 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700152
Iliyan Malchev549e2592016-08-10 08:59:12 -0700153 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700154
155 out << "size_t " << parentName << ";\n\n";
156
157 const std::string parcelObjDeref =
158 parcelObj + (parcelObjIsPointer ? "->" : ".");
159
160 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100161 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700162 << parcelObjDeref
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700163 << "readBuffer("
164 << "sizeof(*"
165 << name
166 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700167 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100168 << ", "
169 << " reinterpret_cast<const void **>("
170 << "&" << name
171 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700172
Martijn Coenen6a082c62017-01-11 12:47:02 +0100173 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700174 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700175 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700176 << parcelObjDeref
177 << "writeBuffer(&"
178 << name
179 << ", sizeof("
180 << name
181 << "), &"
182 << parentName
183 << ");\n";
184
185 handleError(out, mode);
186 }
187
188 emitReaderWriterEmbedded(
189 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700190 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700191 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700192 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700193 isReader /* nameIsPointer */,
194 parcelObj,
195 parcelObjIsPointer,
196 isReader,
197 mode,
198 parentName,
199 "0 /* parentOffset */");
200}
201
Andreas Huber86a112b2016-10-19 14:25:16 -0700202void VectorType::emitReaderWriterForVectorOfBinders(
203 Formatter &out,
204 const std::string &name,
205 const std::string &parcelObj,
206 bool parcelObjIsPointer,
207 bool isReader,
208 ErrorMode mode) const {
209 const std::string parcelObjDeref =
210 parcelObj + (parcelObjIsPointer ? "->" : ".");
211
212 if (isReader) {
213 out << "{\n";
214 out.indent();
215
216 const std::string sizeName = "_hidl_" + name + "_size";
217
218 out << "uint64_t "
219 << sizeName
220 << ";\n";
221
222 out << "_hidl_err = "
223 << parcelObjDeref
224 << "readUint64(&"
225 << sizeName
226 << ");\n";
227
228 handleError(out, mode);
229
230 out << name
231 << ".resize("
232 << sizeName
233 << ");\n\n"
234 << "for (size_t _hidl_index = 0; _hidl_index < "
235 << sizeName
236 << "; ++_hidl_index) {\n";
237
238 out.indent();
239
Yifan Hong3b320f82016-11-01 15:15:54 -0700240 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800241 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700242
243 mElementType->emitReaderWriter(
244 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800245 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700246 parcelObj,
247 parcelObjIsPointer,
248 isReader,
249 mode);
250
251 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800252 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700253
254 out.unindent();
255 out << "}\n";
256
257 out.unindent();
258 out << "}\n";
259 } else {
260 out << "_hidl_err = "
261 << parcelObjDeref
262 << "writeUint64("
263 << name
264 << ".size());\n";
265
266 handleError(out, mode);
267
268 out << "for (size_t _hidl_index = 0; _hidl_index < "
269 << name
270 << ".size(); ++_hidl_index) {\n";
271
272 out.indent();
273
274 mElementType->emitReaderWriter(
275 out,
276 name + "[_hidl_index]",
277 parcelObj,
278 parcelObjIsPointer,
279 isReader,
280 mode);
281
282 out.unindent();
283 out << "}\n";
284 }
285}
286
Andreas Huber881227d2016-08-02 14:20:21 -0700287void VectorType::emitReaderWriterEmbedded(
288 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700289 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700290 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700291 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700292 bool nameIsPointer,
293 const std::string &parcelObj,
294 bool parcelObjIsPointer,
295 bool isReader,
296 ErrorMode mode,
297 const std::string &parentName,
298 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700299 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700300
Yifan Hongbe2a3732016-10-05 13:33:41 -0700301 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700302 out << "size_t " << childName << ";\n\n";
303
304 emitReaderWriterEmbeddedForTypeName(
305 out,
306 name,
307 nameIsPointer,
308 parcelObj,
309 parcelObjIsPointer,
310 isReader,
311 mode,
312 parentName,
313 offsetText,
314 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800315 childName,
316 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700317
318 if (!mElementType->needsEmbeddedReadWrite()) {
319 return;
320 }
321
322 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
323
Yifan Hong3b320f82016-11-01 15:15:54 -0700324 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700325
Andreas Huberf9d49f12016-09-12 14:58:36 -0700326 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
327
328 out << "for (size_t "
329 << iteratorName
330 << " = 0; "
331 << iteratorName
332 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700333 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700334 << "size(); ++"
335 << iteratorName
336 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700337
338 out.indent();
339
340 mElementType->emitReaderWriterEmbedded(
341 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700342 depth + 1,
343 (nameIsPointer ? "(*" + name + ")" : name)
344 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700345 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700346 false /* nameIsPointer */,
347 parcelObj,
348 parcelObjIsPointer,
349 isReader,
350 mode,
351 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700352 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700353
354 out.unindent();
355
356 out << "}\n\n";
357}
358
Yifan Hongbf459bc2016-08-23 16:50:37 -0700359void VectorType::emitResolveReferences(
360 Formatter &out,
361 const std::string &name,
362 bool nameIsPointer,
363 const std::string &parcelObj,
364 bool parcelObjIsPointer,
365 bool isReader,
366 ErrorMode mode) const {
367 emitResolveReferencesEmbeddedHelper(
368 out,
369 0, /* depth */
370 name,
371 name /* sanitizedName */,
372 nameIsPointer,
373 parcelObj,
374 parcelObjIsPointer,
375 isReader,
376 mode,
377 "_hidl_" + name + "_child",
378 "0 /* parentOffset */");
379}
380
381void VectorType::emitResolveReferencesEmbedded(
382 Formatter &out,
383 size_t depth,
384 const std::string &name,
385 const std::string &sanitizedName,
386 bool nameIsPointer,
387 const std::string &parcelObj,
388 bool parcelObjIsPointer,
389 bool isReader,
390 ErrorMode mode,
391 const std::string & /* parentName */,
392 const std::string & /* offsetText */) const {
393 emitResolveReferencesEmbeddedHelper(
394 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
395 parcelObjIsPointer, isReader, mode, "", "");
396}
397
Yifan Hong00f47172016-09-30 14:40:45 -0700398bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
399 // parentName and offsetText is not used in emitResolveReferencesEmbedded
400 return false;
401}
402
Yifan Hongbf459bc2016-08-23 16:50:37 -0700403void VectorType::emitResolveReferencesEmbeddedHelper(
404 Formatter &out,
405 size_t depth,
406 const std::string &name,
407 const std::string &sanitizedName,
408 bool nameIsPointer,
409 const std::string &parcelObj,
410 bool parcelObjIsPointer,
411 bool isReader,
412 ErrorMode mode,
413 const std::string &childName,
414 const std::string &childOffsetText) const {
415 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
416
417 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800418 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700419 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700420
421 std::string myChildName = childName, myChildOffset = childOffsetText;
422
423 if(myChildName.empty() && myChildOffset.empty()) {
424 myChildName = "_hidl_" + sanitizedName + "_child";
425 myChildOffset = "0";
426
427 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800428 out << "_hidl_err = ::android::hardware::findInParcel("
429 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700430 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
431 << "&" << myChildName
432 << ");\n";
433
434 handleError(out, mode);
435 }
436
437 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
438
439 out << "for (size_t "
440 << iteratorName
441 << " = 0; "
442 << iteratorName
443 << " < "
444 << nameDeref
445 << "size(); ++"
446 << iteratorName
447 << ") {\n";
448
449 out.indent();
450
451 mElementType->emitResolveReferencesEmbedded(
452 out,
453 depth + 1,
454 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
455 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
456 false /* nameIsPointer */,
457 parcelObj,
458 parcelObjIsPointer,
459 isReader,
460 mode,
461 myChildName,
462 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700463 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700464
465 out.unindent();
466
467 out << "}\n\n";
468}
469
Andreas Huberf630bc82016-09-09 14:52:25 -0700470void VectorType::emitJavaReaderWriter(
471 Formatter &out,
472 const std::string &parcelObj,
473 const std::string &argName,
474 bool isReader) const {
475 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700476
Andreas Huberf630bc82016-09-09 14:52:25 -0700477 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700478 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700479 << ".readVectorFromParcel("
480 << parcelObj
481 << ");\n";
482 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700483 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700484 << ".writeVectorToParcel("
485 << parcelObj
486 << ", "
487 << argName
488 << ");\n";
489 }
490
491 return;
492 }
493
Andreas Huber1b6822b2016-10-18 09:28:40 -0700494 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700495 size_t align, size;
496 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700497 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700498 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700499 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700500 << "();\n";
501 }
502
503 out << "{\n";
504 out.indent();
505
Yifan Hong1af73532016-11-09 14:32:58 -0800506 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700507
508 if (isReader) {
509 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700510 << ".readBuffer("
511 << size
512 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700513 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700514
Yifan Hong1af73532016-11-09 14:32:58 -0800515 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700516 << size
517 << " /* size */);\n";
518 }
519
520 emitJavaFieldReaderWriter(
521 out,
522 0 /* depth */,
523 parcelObj,
524 "_hidl_blob",
525 argName,
526 "0 /* offset */",
527 isReader);
528
529 if (!isReader) {
530 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
531 };
532
533 out.unindent();
534 out << "}\n";
535
536 return;
537 }
538
Andreas Huberf630bc82016-09-09 14:52:25 -0700539 emitJavaReaderWriterWithSuffix(
540 out,
541 parcelObj,
542 argName,
543 isReader,
544 mElementType->getJavaSuffix() + "Vector",
545 "" /* extra */);
546}
547
Andreas Huber85eabdb2016-08-25 11:24:49 -0700548void VectorType::emitJavaFieldInitializer(
549 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700550 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700551
Andreas Huber1b6822b2016-10-18 09:28:40 -0700552 out << "final "
553 << javaType
554 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700555 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700556 << " = new "
557 << javaType
558 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700559}
560
561void VectorType::emitJavaFieldReaderWriter(
562 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700563 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700564 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700565 const std::string &blobName,
566 const std::string &fieldName,
567 const std::string &offset,
568 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700569 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700570 out,
571 depth,
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700572 mElementType.get(),
Andreas Huber709b62d2016-09-19 11:21:18 -0700573 parcelName,
574 blobName,
575 fieldName,
576 offset,
577 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700578}
579
Andreas Huberf630bc82016-09-09 14:52:25 -0700580void VectorType::EmitJavaFieldReaderWriterForElementType(
581 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700582 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700583 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700584 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700585 const std::string &blobName,
586 const std::string &fieldName,
587 const std::string &offset,
588 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700589 size_t elementAlign, elementSize;
590 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
591
Andreas Huber85eabdb2016-08-25 11:24:49 -0700592 if (isReader) {
593 out << "{\n";
594 out.indent();
595
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700596 out << "int _hidl_vec_size = "
597 << blobName
598 << ".getInt32("
599 << offset
600 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
601
Yifan Hong1af73532016-11-09 14:32:58 -0800602 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700603 << parcelName
604 << ".readEmbeddedBuffer(\n";
605
Andreas Huber85eabdb2016-08-25 11:24:49 -0700606 out.indent();
607 out.indent();
608
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700609 out << "_hidl_vec_size * "
610 << elementSize << ","
611 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700612 << ".handle(),\n"
613 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100614 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
615 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700616
617 out.unindent();
618 out.unindent();
619
620 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700621 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
622
623 out << "for (int "
624 << iteratorName
625 << " = 0; "
626 << iteratorName
627 << " < _hidl_vec_size; "
628 << "++"
629 << iteratorName
630 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700631
632 out.indent();
633
Andreas Huberf630bc82016-09-09 14:52:25 -0700634 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700635
Andreas Huberf630bc82016-09-09 14:52:25 -0700636 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700637 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700638 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700639 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700640 "childBlob",
641 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700642 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700643 true /* isReader */);
644
Andreas Huber1b6822b2016-10-18 09:28:40 -0700645 out << fieldName
646 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700647
648 out.unindent();
649
650 out << "}\n";
651
652 out.unindent();
653 out << "}\n";
654
655 return;
656 }
657
658 out << "{\n";
659 out.indent();
660
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800661 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700662 << fieldName
663 << ".size();\n";
664
665 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800666 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700667 << offset
668 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
669
670 out << blobName
671 << ".putBool("
672 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800673 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700674
Andreas Huber85eabdb2016-08-25 11:24:49 -0700675 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800676 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700677 << elementSize
678 << "));\n";
679
Andreas Huber4c865b72016-09-14 15:26:27 -0700680 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
681
682 out << "for (int "
683 << iteratorName
684 << " = 0; "
685 << iteratorName
686 << " < _hidl_vec_size; "
687 << "++"
688 << iteratorName
689 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700690
691 out.indent();
692
Andreas Huberf630bc82016-09-09 14:52:25 -0700693 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700694 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700695 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700696 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700697 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700698 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700699 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700700 false /* isReader */);
701
702 out.unindent();
703
704 out << "}\n";
705
706 out << blobName
707 << ".putBlob("
708 << offset
709 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
710
711 out.unindent();
712 out << "}\n";
713}
714
Andreas Huber881227d2016-08-02 14:20:21 -0700715bool VectorType::needsEmbeddedReadWrite() const {
716 return true;
717}
718
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700719bool VectorType::deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const {
720 if (mElementType->needsResolveReferences(visited)) {
721 return true;
722 }
723 return TemplatedType::deepNeedsResolveReferences(visited);
Yifan Hongbf459bc2016-08-23 16:50:37 -0700724}
725
Andreas Huber881227d2016-08-02 14:20:21 -0700726bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700727 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700728}
729
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700730bool VectorType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
731 if (!mElementType->isJavaCompatible(visited)) {
Andreas Huberf03332a2016-09-22 15:35:43 -0700732 return false;
733 }
734
735 if (mElementType->isArray()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700736 return static_cast<const ArrayType*>(mElementType.get())->countDimensions() == 1;
Andreas Huberf03332a2016-09-22 15:35:43 -0700737 }
738
Andreas Huber1b6822b2016-10-18 09:28:40 -0700739 if (mElementType->isVector()) {
740 return false;
741 }
742
Andreas Huber86a112b2016-10-19 14:25:16 -0700743 if (isVectorOfBinders()) {
744 return false;
745 }
746
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700747 return TemplatedType::deepIsJavaCompatible(visited);
Andreas Huber70a59e12016-08-16 12:57:01 -0700748}
749
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700750bool VectorType::deepContainsPointer(std::unordered_set<const Type*>* visited) const {
751 if (mElementType->containsPointer(visited)) {
752 return true;
753 }
754 return TemplatedType::deepContainsPointer(visited);
Andreas Huber60d3b222017-03-30 09:10:56 -0700755}
756
Andreas Huber6755e9d2017-04-06 11:09:07 -0700757// All hidl_vec<T> have the same size.
758static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700759
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700760void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700761 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700762 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700763}
764
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700765void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
766 VectorType::getAlignmentAndSizeStatic(align, size);
767}
768
Andreas Huberc9410c72016-07-28 12:18:40 -0700769} // namespace android
770