blob: f883da742346d6f1ccba6c90ca54434ac2899280 [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 {
Steven Moreland7df0f392018-10-31 13:23:22 -070078 return mElementType->isInterface();
Andreas Huber86a112b2016-10-19 14:25:16 -070079}
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 {
Nirav Atre66842a92018-06-28 18:14:13 -0700116 const std::string elementJavaType = mElementType->isTemplatedType()
117 ? mElementType->getJavaType()
118 : mElementType->getJavaTypeClass();
Andreas Huber4c865b72016-09-14 15:26:27 -0700119
Nirav Atre66842a92018-06-28 18:14:13 -0700120 return "java.util.ArrayList<" + elementJavaType + ">";
121}
Andreas Huber1b6822b2016-10-18 09:28:40 -0700122
Nirav Atre66842a92018-06-28 18:14:13 -0700123std::string VectorType::getJavaTypeClass() const {
124 return "java.util.ArrayList";
Andreas Huber2831d512016-08-15 09:33:47 -0700125}
126
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700127std::string VectorType::getVtsType() const {
128 return "TYPE_VECTOR";
129}
130
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800131std::string VectorType::getVtsValueName() const {
132 return "vector_value";
133}
134
Andreas Huber881227d2016-08-02 14:20:21 -0700135void VectorType::emitReaderWriter(
136 Formatter &out,
137 const std::string &name,
138 const std::string &parcelObj,
139 bool parcelObjIsPointer,
140 bool isReader,
141 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700142 if (isVectorOfBinders()) {
143 emitReaderWriterForVectorOfBinders(
144 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
145
146 return;
147 }
148
Yifan Hong3b320f82016-11-01 15:15:54 -0700149 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700150
Iliyan Malchev549e2592016-08-10 08:59:12 -0700151 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700152
153 out << "size_t " << parentName << ";\n\n";
154
155 const std::string parcelObjDeref =
156 parcelObj + (parcelObjIsPointer ? "->" : ".");
157
158 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100159 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700160 << parcelObjDeref
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700161 << "readBuffer("
162 << "sizeof(*"
163 << name
164 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700165 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100166 << ", "
167 << " reinterpret_cast<const void **>("
168 << "&" << name
169 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700170
Martijn Coenen6a082c62017-01-11 12:47:02 +0100171 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700172 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700173 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700174 << parcelObjDeref
175 << "writeBuffer(&"
176 << name
177 << ", sizeof("
178 << name
179 << "), &"
180 << parentName
181 << ");\n";
182
183 handleError(out, mode);
184 }
185
186 emitReaderWriterEmbedded(
187 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700188 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700189 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700190 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700191 isReader /* nameIsPointer */,
192 parcelObj,
193 parcelObjIsPointer,
194 isReader,
195 mode,
196 parentName,
197 "0 /* parentOffset */");
198}
199
Andreas Huber86a112b2016-10-19 14:25:16 -0700200void VectorType::emitReaderWriterForVectorOfBinders(
201 Formatter &out,
202 const std::string &name,
203 const std::string &parcelObj,
204 bool parcelObjIsPointer,
205 bool isReader,
206 ErrorMode mode) const {
207 const std::string parcelObjDeref =
208 parcelObj + (parcelObjIsPointer ? "->" : ".");
209
210 if (isReader) {
211 out << "{\n";
212 out.indent();
213
214 const std::string sizeName = "_hidl_" + name + "_size";
215
216 out << "uint64_t "
217 << sizeName
218 << ";\n";
219
220 out << "_hidl_err = "
221 << parcelObjDeref
222 << "readUint64(&"
223 << sizeName
224 << ");\n";
225
226 handleError(out, mode);
227
228 out << name
229 << ".resize("
230 << sizeName
231 << ");\n\n"
232 << "for (size_t _hidl_index = 0; _hidl_index < "
233 << sizeName
234 << "; ++_hidl_index) {\n";
235
236 out.indent();
237
Yifan Hong3b320f82016-11-01 15:15:54 -0700238 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800239 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700240
241 mElementType->emitReaderWriter(
242 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800243 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700244 parcelObj,
245 parcelObjIsPointer,
246 isReader,
247 mode);
248
249 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800250 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700251
252 out.unindent();
253 out << "}\n";
254
255 out.unindent();
256 out << "}\n";
257 } else {
258 out << "_hidl_err = "
259 << parcelObjDeref
260 << "writeUint64("
261 << name
262 << ".size());\n";
263
264 handleError(out, mode);
265
266 out << "for (size_t _hidl_index = 0; _hidl_index < "
267 << name
268 << ".size(); ++_hidl_index) {\n";
269
270 out.indent();
271
272 mElementType->emitReaderWriter(
273 out,
274 name + "[_hidl_index]",
275 parcelObj,
276 parcelObjIsPointer,
277 isReader,
278 mode);
279
280 out.unindent();
281 out << "}\n";
282 }
283}
284
Andreas Huber881227d2016-08-02 14:20:21 -0700285void VectorType::emitReaderWriterEmbedded(
286 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700287 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700288 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700289 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700290 bool nameIsPointer,
291 const std::string &parcelObj,
292 bool parcelObjIsPointer,
293 bool isReader,
294 ErrorMode mode,
295 const std::string &parentName,
296 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700297 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700298
Yifan Hongbe2a3732016-10-05 13:33:41 -0700299 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700300 out << "size_t " << childName << ";\n\n";
301
302 emitReaderWriterEmbeddedForTypeName(
303 out,
304 name,
305 nameIsPointer,
306 parcelObj,
307 parcelObjIsPointer,
308 isReader,
309 mode,
310 parentName,
311 offsetText,
312 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800313 childName,
314 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700315
316 if (!mElementType->needsEmbeddedReadWrite()) {
317 return;
318 }
319
320 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
321
Yifan Hong3b320f82016-11-01 15:15:54 -0700322 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700323
Andreas Huberf9d49f12016-09-12 14:58:36 -0700324 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
325
326 out << "for (size_t "
327 << iteratorName
328 << " = 0; "
329 << iteratorName
330 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700331 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700332 << "size(); ++"
333 << iteratorName
334 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700335
336 out.indent();
337
338 mElementType->emitReaderWriterEmbedded(
339 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700340 depth + 1,
341 (nameIsPointer ? "(*" + name + ")" : name)
342 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700343 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700344 false /* nameIsPointer */,
345 parcelObj,
346 parcelObjIsPointer,
347 isReader,
348 mode,
349 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700350 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700351
352 out.unindent();
353
354 out << "}\n\n";
355}
356
Yifan Hongbf459bc2016-08-23 16:50:37 -0700357void VectorType::emitResolveReferences(
358 Formatter &out,
359 const std::string &name,
360 bool nameIsPointer,
361 const std::string &parcelObj,
362 bool parcelObjIsPointer,
363 bool isReader,
364 ErrorMode mode) const {
365 emitResolveReferencesEmbeddedHelper(
366 out,
367 0, /* depth */
368 name,
369 name /* sanitizedName */,
370 nameIsPointer,
371 parcelObj,
372 parcelObjIsPointer,
373 isReader,
374 mode,
375 "_hidl_" + name + "_child",
376 "0 /* parentOffset */");
377}
378
379void VectorType::emitResolveReferencesEmbedded(
380 Formatter &out,
381 size_t depth,
382 const std::string &name,
383 const std::string &sanitizedName,
384 bool nameIsPointer,
385 const std::string &parcelObj,
386 bool parcelObjIsPointer,
387 bool isReader,
388 ErrorMode mode,
389 const std::string & /* parentName */,
390 const std::string & /* offsetText */) const {
391 emitResolveReferencesEmbeddedHelper(
392 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
393 parcelObjIsPointer, isReader, mode, "", "");
394}
395
Yifan Hong00f47172016-09-30 14:40:45 -0700396bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
397 // parentName and offsetText is not used in emitResolveReferencesEmbedded
398 return false;
399}
400
Yifan Hongbf459bc2016-08-23 16:50:37 -0700401void VectorType::emitResolveReferencesEmbeddedHelper(
402 Formatter &out,
403 size_t depth,
404 const std::string &name,
405 const std::string &sanitizedName,
406 bool nameIsPointer,
407 const std::string &parcelObj,
408 bool parcelObjIsPointer,
409 bool isReader,
410 ErrorMode mode,
411 const std::string &childName,
412 const std::string &childOffsetText) const {
413 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
414
415 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800416 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700417 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700418
419 std::string myChildName = childName, myChildOffset = childOffsetText;
420
421 if(myChildName.empty() && myChildOffset.empty()) {
422 myChildName = "_hidl_" + sanitizedName + "_child";
423 myChildOffset = "0";
424
425 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800426 out << "_hidl_err = ::android::hardware::findInParcel("
427 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700428 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
429 << "&" << myChildName
430 << ");\n";
431
432 handleError(out, mode);
433 }
434
435 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
436
437 out << "for (size_t "
438 << iteratorName
439 << " = 0; "
440 << iteratorName
441 << " < "
442 << nameDeref
443 << "size(); ++"
444 << iteratorName
445 << ") {\n";
446
447 out.indent();
448
449 mElementType->emitResolveReferencesEmbedded(
450 out,
451 depth + 1,
452 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
453 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
454 false /* nameIsPointer */,
455 parcelObj,
456 parcelObjIsPointer,
457 isReader,
458 mode,
459 myChildName,
460 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700461 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700462
463 out.unindent();
464
465 out << "}\n\n";
466}
467
Andreas Huberf630bc82016-09-09 14:52:25 -0700468void VectorType::emitJavaReaderWriter(
469 Formatter &out,
470 const std::string &parcelObj,
471 const std::string &argName,
472 bool isReader) const {
473 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700474
Andreas Huberf630bc82016-09-09 14:52:25 -0700475 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700476 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700477 << ".readVectorFromParcel("
478 << parcelObj
479 << ");\n";
480 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700481 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700482 << ".writeVectorToParcel("
483 << parcelObj
484 << ", "
485 << argName
486 << ");\n";
487 }
488
489 return;
490 }
491
Andreas Huber1b6822b2016-10-18 09:28:40 -0700492 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700493 size_t align, size;
494 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700495 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700496 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700497 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700498 << "();\n";
499 }
500
501 out << "{\n";
502 out.indent();
503
Yifan Hong1af73532016-11-09 14:32:58 -0800504 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700505
506 if (isReader) {
507 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700508 << ".readBuffer("
509 << size
510 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700511 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700512
Yifan Hong1af73532016-11-09 14:32:58 -0800513 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700514 << size
515 << " /* size */);\n";
516 }
517
518 emitJavaFieldReaderWriter(
519 out,
520 0 /* depth */,
521 parcelObj,
522 "_hidl_blob",
523 argName,
524 "0 /* offset */",
525 isReader);
526
527 if (!isReader) {
528 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
529 };
530
531 out.unindent();
532 out << "}\n";
533
534 return;
535 }
536
Andreas Huberf630bc82016-09-09 14:52:25 -0700537 emitJavaReaderWriterWithSuffix(
538 out,
539 parcelObj,
540 argName,
541 isReader,
542 mElementType->getJavaSuffix() + "Vector",
543 "" /* extra */);
544}
545
Andreas Huber85eabdb2016-08-25 11:24:49 -0700546void VectorType::emitJavaFieldInitializer(
547 Formatter &out, const std::string &fieldName) const {
Nirav Atre66842a92018-06-28 18:14:13 -0700548 const std::string typeName = getJavaType(false /* forInitializer */);
Nirav Atre1d565622018-07-13 15:41:21 -0700549 const std::string fieldDeclaration = typeName + " " + fieldName;
Andreas Huberf03332a2016-09-22 15:35:43 -0700550
Nirav Atre66842a92018-06-28 18:14:13 -0700551 emitJavaFieldDefaultInitialValue(out, fieldDeclaration);
552}
553
554void VectorType::emitJavaFieldDefaultInitialValue(
555 Formatter &out, const std::string &declaredFieldName) const {
556 out << declaredFieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700557 << " = new "
Nirav Atre66842a92018-06-28 18:14:13 -0700558 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700559 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700560}
561
562void VectorType::emitJavaFieldReaderWriter(
563 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700564 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700565 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700566 const std::string &blobName,
567 const std::string &fieldName,
568 const std::string &offset,
569 bool isReader) const {
Nirav Atre66842a92018-06-28 18:14:13 -0700570
571 const std::string fieldNameWithCast = isReader
572 ? "(" + getJavaTypeCast(fieldName) + ")"
573 : fieldName;
574
Andreas Huberf630bc82016-09-09 14:52:25 -0700575 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700576 out,
577 depth,
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700578 mElementType.get(),
Andreas Huber709b62d2016-09-19 11:21:18 -0700579 parcelName,
580 blobName,
Nirav Atre66842a92018-06-28 18:14:13 -0700581 fieldNameWithCast,
Andreas Huber709b62d2016-09-19 11:21:18 -0700582 offset,
583 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700584}
585
Andreas Huberf630bc82016-09-09 14:52:25 -0700586void VectorType::EmitJavaFieldReaderWriterForElementType(
587 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700588 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700589 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700590 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700591 const std::string &blobName,
592 const std::string &fieldName,
593 const std::string &offset,
594 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700595 size_t elementAlign, elementSize;
596 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
597
Andreas Huber85eabdb2016-08-25 11:24:49 -0700598 if (isReader) {
599 out << "{\n";
600 out.indent();
601
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700602 out << "int _hidl_vec_size = "
603 << blobName
604 << ".getInt32("
605 << offset
606 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
607
Yifan Hong1af73532016-11-09 14:32:58 -0800608 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700609 << parcelName
610 << ".readEmbeddedBuffer(\n";
611
Andreas Huber85eabdb2016-08-25 11:24:49 -0700612 out.indent();
613 out.indent();
614
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700615 out << "_hidl_vec_size * "
616 << elementSize << ","
617 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700618 << ".handle(),\n"
619 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100620 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
621 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700622
623 out.unindent();
624 out.unindent();
625
626 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700627 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
628
629 out << "for (int "
630 << iteratorName
631 << " = 0; "
632 << iteratorName
633 << " < _hidl_vec_size; "
634 << "++"
635 << iteratorName
636 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700637
638 out.indent();
639
Andreas Huberf630bc82016-09-09 14:52:25 -0700640 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700641
Andreas Huberf630bc82016-09-09 14:52:25 -0700642 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700643 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700644 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700645 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700646 "childBlob",
647 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700648 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700649 true /* isReader */);
650
Andreas Huber1b6822b2016-10-18 09:28:40 -0700651 out << fieldName
652 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700653
654 out.unindent();
655
656 out << "}\n";
657
658 out.unindent();
659 out << "}\n";
660
661 return;
662 }
663
664 out << "{\n";
665 out.indent();
666
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800667 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700668 << fieldName
669 << ".size();\n";
670
671 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800672 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700673 << offset
674 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
675
676 out << blobName
677 << ".putBool("
678 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800679 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700680
Andreas Huber85eabdb2016-08-25 11:24:49 -0700681 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800682 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700683 << elementSize
684 << "));\n";
685
Andreas Huber4c865b72016-09-14 15:26:27 -0700686 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
687
688 out << "for (int "
689 << iteratorName
690 << " = 0; "
691 << iteratorName
692 << " < _hidl_vec_size; "
693 << "++"
694 << iteratorName
695 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700696
697 out.indent();
698
Andreas Huberf630bc82016-09-09 14:52:25 -0700699 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700700 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700701 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700702 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700703 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700704 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700705 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700706 false /* isReader */);
707
708 out.unindent();
709
710 out << "}\n";
711
712 out << blobName
713 << ".putBlob("
714 << offset
715 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
716
717 out.unindent();
718 out << "}\n";
719}
720
Andreas Huber881227d2016-08-02 14:20:21 -0700721bool VectorType::needsEmbeddedReadWrite() const {
722 return true;
723}
724
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700725bool VectorType::deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const {
726 if (mElementType->needsResolveReferences(visited)) {
727 return true;
728 }
729 return TemplatedType::deepNeedsResolveReferences(visited);
Yifan Hongbf459bc2016-08-23 16:50:37 -0700730}
731
Andreas Huber881227d2016-08-02 14:20:21 -0700732bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700733 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700734}
735
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700736bool VectorType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
737 if (!mElementType->isJavaCompatible(visited)) {
Andreas Huberf03332a2016-09-22 15:35:43 -0700738 return false;
739 }
740
741 if (mElementType->isArray()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700742 return static_cast<const ArrayType*>(mElementType.get())->countDimensions() == 1;
Andreas Huberf03332a2016-09-22 15:35:43 -0700743 }
744
Andreas Huber1b6822b2016-10-18 09:28:40 -0700745 if (mElementType->isVector()) {
746 return false;
747 }
748
Andreas Huber86a112b2016-10-19 14:25:16 -0700749 if (isVectorOfBinders()) {
750 return false;
751 }
752
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700753 return TemplatedType::deepIsJavaCompatible(visited);
Andreas Huber70a59e12016-08-16 12:57:01 -0700754}
755
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700756bool VectorType::deepContainsPointer(std::unordered_set<const Type*>* visited) const {
757 if (mElementType->containsPointer(visited)) {
758 return true;
759 }
760 return TemplatedType::deepContainsPointer(visited);
Andreas Huber60d3b222017-03-30 09:10:56 -0700761}
762
Andreas Huber6755e9d2017-04-06 11:09:07 -0700763// All hidl_vec<T> have the same size.
764static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700765
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700766void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700767 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700768 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700769}
770
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700771void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
772 VectorType::getAlignmentAndSizeStatic(align, size);
773}
774
Andreas Huberc9410c72016-07-28 12:18:40 -0700775} // namespace android
776