blob: 03604dcafafd63511d451a2902f1bef457e91326 [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()) {
Yifan Hong51f9c8a2016-12-05 18:47:33 -080048 return true;
49 }
50 if (elementType->isInterface()) {
51 return true;
52 }
53 if (elementType->isHandle()) {
54 return true;
55 }
Steven Moreland397b5e12017-06-08 14:02:26 -070056 if (elementType->isMemory()) {
57 return true;
58 }
Yifan Hong51f9c8a2016-12-05 18:47:33 -080059 if (elementType->isTemplatedType()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -070060 const Type* inner = static_cast<const TemplatedType*>(elementType)->getElementType();
Yifan Hong51f9c8a2016-12-05 18:47:33 -080061 return this->isCompatibleElementType(inner) && !inner->isInterface();
62 }
63 if (elementType->isArray()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -070064 const Type* inner = static_cast<const ArrayType*>(elementType)->getElementType();
Yifan Hong51f9c8a2016-12-05 18:47:33 -080065 return this->isCompatibleElementType(inner) && !inner->isInterface();
66 }
67 return false;
Steven Moreland30bb6a82016-11-30 09:18:34 -080068}
69
Andreas Huber86a112b2016-10-19 14:25:16 -070070bool VectorType::isVector() const {
71 return true;
72}
73
74bool VectorType::isVectorOfBinders() const {
75 return mElementType->isBinder();
76}
77
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -070078bool VectorType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
79 return mElementType->canCheckEquality(visited);
Yifan Hongc6752dc2016-12-20 14:00:14 -080080}
81
Timur Iskhakovb58f4182017-08-29 15:19:24 -070082std::vector<const Reference<Type>*> VectorType::getStrongReferences() const {
Timur Iskhakov40731af2017-08-24 14:18:35 -070083 return {};
84}
85
Steven Moreland979e0992016-09-07 09:18:08 -070086std::string VectorType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070087 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070088 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070089 std::string(specifyNamespaces ? "::android::hardware::" : "")
90 + "hidl_vec<"
Yifan Hong3b320f82016-11-01 15:15:54 -070091 + mElementType->getCppStackType( specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070092 + ">";
93
Andreas Huber881227d2016-08-02 14:20:21 -070094 switch (mode) {
95 case StorageMode_Stack:
96 return base;
97
98 case StorageMode_Argument:
99 return "const " + base + "&";
100
101 case StorageMode_Result:
Andreas Huber86a112b2016-10-19 14:25:16 -0700102 {
103 if (isVectorOfBinders()) {
104 return base;
105 }
106
Andreas Huber881227d2016-08-02 14:20:21 -0700107 return "const " + base + "*";
Andreas Huber86a112b2016-10-19 14:25:16 -0700108 }
Andreas Huber881227d2016-08-02 14:20:21 -0700109 }
110}
111
Yifan Hong4ed13472016-11-02 10:44:11 -0700112std::string VectorType::getJavaType(bool /* forInitializer */) const {
Andreas Huber4c865b72016-09-14 15:26:27 -0700113
Yifan Hong4ed13472016-11-02 10:44:11 -0700114 std::string elementJavaType;
115 if (mElementType->isArray()) {
116 elementJavaType = mElementType->getJavaType();
117 } else {
118 elementJavaType = mElementType->getJavaWrapperType();
119 }
Andreas Huber1b6822b2016-10-18 09:28:40 -0700120
Yifan Hong1af73532016-11-09 14:32:58 -0800121 return "java.util.ArrayList<"
Yifan Hong4ed13472016-11-02 10:44:11 -0700122 + elementJavaType
Andreas Huber1b6822b2016-10-18 09:28:40 -0700123 + ">";
Andreas Huber2831d512016-08-15 09:33:47 -0700124}
125
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700126std::string VectorType::getVtsType() const {
127 return "TYPE_VECTOR";
128}
129
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800130std::string VectorType::getVtsValueName() const {
131 return "vector_value";
132}
133
Andreas Huber881227d2016-08-02 14:20:21 -0700134void VectorType::emitReaderWriter(
135 Formatter &out,
136 const std::string &name,
137 const std::string &parcelObj,
138 bool parcelObjIsPointer,
139 bool isReader,
140 ErrorMode mode) const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700141 if (isVectorOfBinders()) {
142 emitReaderWriterForVectorOfBinders(
143 out, name, parcelObj, parcelObjIsPointer, isReader, mode);
144
145 return;
146 }
147
Yifan Hong3b320f82016-11-01 15:15:54 -0700148 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700149
Iliyan Malchev549e2592016-08-10 08:59:12 -0700150 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700151
152 out << "size_t " << parentName << ";\n\n";
153
154 const std::string parcelObjDeref =
155 parcelObj + (parcelObjIsPointer ? "->" : ".");
156
157 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100158 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700159 << parcelObjDeref
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700160 << "readBuffer("
161 << "sizeof(*"
162 << name
163 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700164 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100165 << ", "
166 << " reinterpret_cast<const void **>("
167 << "&" << name
168 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700169
Martijn Coenen6a082c62017-01-11 12:47:02 +0100170 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700171 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700172 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700173 << parcelObjDeref
174 << "writeBuffer(&"
175 << name
176 << ", sizeof("
177 << name
178 << "), &"
179 << parentName
180 << ");\n";
181
182 handleError(out, mode);
183 }
184
185 emitReaderWriterEmbedded(
186 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700187 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700188 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700189 name /* sanitizedName */ ,
Andreas Huber881227d2016-08-02 14:20:21 -0700190 isReader /* nameIsPointer */,
191 parcelObj,
192 parcelObjIsPointer,
193 isReader,
194 mode,
195 parentName,
196 "0 /* parentOffset */");
197}
198
Andreas Huber86a112b2016-10-19 14:25:16 -0700199void VectorType::emitReaderWriterForVectorOfBinders(
200 Formatter &out,
201 const std::string &name,
202 const std::string &parcelObj,
203 bool parcelObjIsPointer,
204 bool isReader,
205 ErrorMode mode) const {
206 const std::string parcelObjDeref =
207 parcelObj + (parcelObjIsPointer ? "->" : ".");
208
209 if (isReader) {
210 out << "{\n";
211 out.indent();
212
213 const std::string sizeName = "_hidl_" + name + "_size";
214
215 out << "uint64_t "
216 << sizeName
217 << ";\n";
218
219 out << "_hidl_err = "
220 << parcelObjDeref
221 << "readUint64(&"
222 << sizeName
223 << ");\n";
224
225 handleError(out, mode);
226
227 out << name
228 << ".resize("
229 << sizeName
230 << ");\n\n"
231 << "for (size_t _hidl_index = 0; _hidl_index < "
232 << sizeName
233 << "; ++_hidl_index) {\n";
234
235 out.indent();
236
Yifan Hong3b320f82016-11-01 15:15:54 -0700237 out << mElementType->getCppStackType(true /* specifyNamespaces */)
Yifan Hongc8934042016-11-17 17:10:52 -0800238 << " _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700239
240 mElementType->emitReaderWriter(
241 out,
Yifan Hongc8934042016-11-17 17:10:52 -0800242 "_hidl_base",
Andreas Huber86a112b2016-10-19 14:25:16 -0700243 parcelObj,
244 parcelObjIsPointer,
245 isReader,
246 mode);
247
248 out << name
Yifan Hongc8934042016-11-17 17:10:52 -0800249 << "[_hidl_index] = _hidl_base;\n";
Andreas Huber86a112b2016-10-19 14:25:16 -0700250
251 out.unindent();
252 out << "}\n";
253
254 out.unindent();
255 out << "}\n";
256 } else {
257 out << "_hidl_err = "
258 << parcelObjDeref
259 << "writeUint64("
260 << name
261 << ".size());\n";
262
263 handleError(out, mode);
264
265 out << "for (size_t _hidl_index = 0; _hidl_index < "
266 << name
267 << ".size(); ++_hidl_index) {\n";
268
269 out.indent();
270
271 mElementType->emitReaderWriter(
272 out,
273 name + "[_hidl_index]",
274 parcelObj,
275 parcelObjIsPointer,
276 isReader,
277 mode);
278
279 out.unindent();
280 out << "}\n";
281 }
282}
283
Andreas Huber881227d2016-08-02 14:20:21 -0700284void VectorType::emitReaderWriterEmbedded(
285 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700286 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700287 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700288 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700289 bool nameIsPointer,
290 const std::string &parcelObj,
291 bool parcelObjIsPointer,
292 bool isReader,
293 ErrorMode mode,
294 const std::string &parentName,
295 const std::string &offsetText) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700296 std::string baseType = getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700297
Yifan Hongbe2a3732016-10-05 13:33:41 -0700298 const std::string childName = "_hidl_" + sanitizedName + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700299 out << "size_t " << childName << ";\n\n";
300
301 emitReaderWriterEmbeddedForTypeName(
302 out,
303 name,
304 nameIsPointer,
305 parcelObj,
306 parcelObjIsPointer,
307 isReader,
308 mode,
309 parentName,
310 offsetText,
311 baseType,
Yifan Hong244e82d2016-11-11 11:13:57 -0800312 childName,
313 "::android::hardware");
Andreas Huber881227d2016-08-02 14:20:21 -0700314
315 if (!mElementType->needsEmbeddedReadWrite()) {
316 return;
317 }
318
319 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
320
Yifan Hong3b320f82016-11-01 15:15:54 -0700321 baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700322
Andreas Huberf9d49f12016-09-12 14:58:36 -0700323 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
324
325 out << "for (size_t "
326 << iteratorName
327 << " = 0; "
328 << iteratorName
329 << " < "
Andreas Huber881227d2016-08-02 14:20:21 -0700330 << nameDeref
Andreas Huberf9d49f12016-09-12 14:58:36 -0700331 << "size(); ++"
332 << iteratorName
333 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700334
335 out.indent();
336
337 mElementType->emitReaderWriterEmbedded(
338 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700339 depth + 1,
340 (nameIsPointer ? "(*" + name + ")" : name)
341 + "[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700342 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700343 false /* nameIsPointer */,
344 parcelObj,
345 parcelObjIsPointer,
346 isReader,
347 mode,
348 childName,
Yifan Hong3b320f82016-11-01 15:15:54 -0700349 iteratorName + " * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700350
351 out.unindent();
352
353 out << "}\n\n";
354}
355
Yifan Hongbf459bc2016-08-23 16:50:37 -0700356void VectorType::emitResolveReferences(
357 Formatter &out,
358 const std::string &name,
359 bool nameIsPointer,
360 const std::string &parcelObj,
361 bool parcelObjIsPointer,
362 bool isReader,
363 ErrorMode mode) const {
364 emitResolveReferencesEmbeddedHelper(
365 out,
366 0, /* depth */
367 name,
368 name /* sanitizedName */,
369 nameIsPointer,
370 parcelObj,
371 parcelObjIsPointer,
372 isReader,
373 mode,
374 "_hidl_" + name + "_child",
375 "0 /* parentOffset */");
376}
377
378void VectorType::emitResolveReferencesEmbedded(
379 Formatter &out,
380 size_t depth,
381 const std::string &name,
382 const std::string &sanitizedName,
383 bool nameIsPointer,
384 const std::string &parcelObj,
385 bool parcelObjIsPointer,
386 bool isReader,
387 ErrorMode mode,
388 const std::string & /* parentName */,
389 const std::string & /* offsetText */) const {
390 emitResolveReferencesEmbeddedHelper(
391 out, depth, name, sanitizedName, nameIsPointer, parcelObj,
392 parcelObjIsPointer, isReader, mode, "", "");
393}
394
Yifan Hong00f47172016-09-30 14:40:45 -0700395bool VectorType::useParentInEmitResolveReferencesEmbedded() const {
396 // parentName and offsetText is not used in emitResolveReferencesEmbedded
397 return false;
398}
399
Yifan Hongbf459bc2016-08-23 16:50:37 -0700400void VectorType::emitResolveReferencesEmbeddedHelper(
401 Formatter &out,
402 size_t depth,
403 const std::string &name,
404 const std::string &sanitizedName,
405 bool nameIsPointer,
406 const std::string &parcelObj,
407 bool parcelObjIsPointer,
408 bool isReader,
409 ErrorMode mode,
410 const std::string &childName,
411 const std::string &childOffsetText) const {
412 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
413
414 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
Yifan Hong859e53f2016-11-14 19:08:24 -0800415 const std::string nameDerefed = (nameIsPointer ? "*" : "") + name;
Yifan Hong3b320f82016-11-01 15:15:54 -0700416 std::string elementType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700417
418 std::string myChildName = childName, myChildOffset = childOffsetText;
419
420 if(myChildName.empty() && myChildOffset.empty()) {
421 myChildName = "_hidl_" + sanitizedName + "_child";
422 myChildOffset = "0";
423
424 out << "size_t " << myChildName << ";\n";
Yifan Hong859e53f2016-11-14 19:08:24 -0800425 out << "_hidl_err = ::android::hardware::findInParcel("
426 << nameDerefed << ", "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700427 << (parcelObjIsPointer ? "*" : "") << parcelObj << ", "
428 << "&" << myChildName
429 << ");\n";
430
431 handleError(out, mode);
432 }
433
434 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
435
436 out << "for (size_t "
437 << iteratorName
438 << " = 0; "
439 << iteratorName
440 << " < "
441 << nameDeref
442 << "size(); ++"
443 << iteratorName
444 << ") {\n";
445
446 out.indent();
447
448 mElementType->emitResolveReferencesEmbedded(
449 out,
450 depth + 1,
451 (nameIsPointer ? "(*" + name + ")" : name) + "[" + iteratorName + "]",
452 sanitizedName + (nameIsPointer ? "_deref" : "") + "_indexed",
453 false /* nameIsPointer */,
454 parcelObj,
455 parcelObjIsPointer,
456 isReader,
457 mode,
458 myChildName,
459 myChildOffset + " + " +
Yifan Hong3b320f82016-11-01 15:15:54 -0700460 iteratorName + " * sizeof(" + elementType + ")");
Yifan Hongbf459bc2016-08-23 16:50:37 -0700461
462 out.unindent();
463
464 out << "}\n\n";
465}
466
Andreas Huberf630bc82016-09-09 14:52:25 -0700467void VectorType::emitJavaReaderWriter(
468 Formatter &out,
469 const std::string &parcelObj,
470 const std::string &argName,
471 bool isReader) const {
472 if (mElementType->isCompoundType()) {
Andreas Huber4c865b72016-09-14 15:26:27 -0700473
Andreas Huberf630bc82016-09-09 14:52:25 -0700474 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700475 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700476 << ".readVectorFromParcel("
477 << parcelObj
478 << ");\n";
479 } else {
Yifan Hong4ed13472016-11-02 10:44:11 -0700480 out << mElementType->getJavaType()
Andreas Huberf630bc82016-09-09 14:52:25 -0700481 << ".writeVectorToParcel("
482 << parcelObj
483 << ", "
484 << argName
485 << ");\n";
486 }
487
488 return;
489 }
490
Andreas Huber1b6822b2016-10-18 09:28:40 -0700491 if (mElementType->isArray()) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700492 size_t align, size;
493 getAlignmentAndSize(&align, &size);
Andreas Huber1b6822b2016-10-18 09:28:40 -0700494 if (isReader) {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700495 out << " new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700496 << getJavaType(false /* forInitializer */)
Andreas Huber1b6822b2016-10-18 09:28:40 -0700497 << "();\n";
498 }
499
500 out << "{\n";
501 out.indent();
502
Yifan Hong1af73532016-11-09 14:32:58 -0800503 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700504
505 if (isReader) {
506 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700507 << ".readBuffer("
508 << size
509 << " /* size */);\n";
Andreas Huber1b6822b2016-10-18 09:28:40 -0700510 } else {
Andreas Huber1b6822b2016-10-18 09:28:40 -0700511
Yifan Hong1af73532016-11-09 14:32:58 -0800512 out << "new android.os.HwBlob("
Andreas Huber1b6822b2016-10-18 09:28:40 -0700513 << size
514 << " /* size */);\n";
515 }
516
517 emitJavaFieldReaderWriter(
518 out,
519 0 /* depth */,
520 parcelObj,
521 "_hidl_blob",
522 argName,
523 "0 /* offset */",
524 isReader);
525
526 if (!isReader) {
527 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
528 };
529
530 out.unindent();
531 out << "}\n";
532
533 return;
534 }
535
Andreas Huberf630bc82016-09-09 14:52:25 -0700536 emitJavaReaderWriterWithSuffix(
537 out,
538 parcelObj,
539 argName,
540 isReader,
541 mElementType->getJavaSuffix() + "Vector",
542 "" /* extra */);
543}
544
Andreas Huber85eabdb2016-08-25 11:24:49 -0700545void VectorType::emitJavaFieldInitializer(
546 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700547 std::string javaType = getJavaType(false /* forInitializer */);
Andreas Huberf03332a2016-09-22 15:35:43 -0700548
Andreas Huber1b6822b2016-10-18 09:28:40 -0700549 out << "final "
550 << javaType
551 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700552 << fieldName
Andreas Huber1b6822b2016-10-18 09:28:40 -0700553 << " = new "
554 << javaType
555 << "();\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700556}
557
558void VectorType::emitJavaFieldReaderWriter(
559 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700560 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700561 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700562 const std::string &blobName,
563 const std::string &fieldName,
564 const std::string &offset,
565 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700566 VectorType::EmitJavaFieldReaderWriterForElementType(
Andreas Huber709b62d2016-09-19 11:21:18 -0700567 out,
568 depth,
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700569 mElementType.get(),
Andreas Huber709b62d2016-09-19 11:21:18 -0700570 parcelName,
571 blobName,
572 fieldName,
573 offset,
574 isReader);
Andreas Huberf630bc82016-09-09 14:52:25 -0700575}
576
Andreas Huberf630bc82016-09-09 14:52:25 -0700577void VectorType::EmitJavaFieldReaderWriterForElementType(
578 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700579 size_t depth,
Andreas Huberf630bc82016-09-09 14:52:25 -0700580 const Type *elementType,
Andreas Huber709b62d2016-09-19 11:21:18 -0700581 const std::string &parcelName,
Andreas Huberf630bc82016-09-09 14:52:25 -0700582 const std::string &blobName,
583 const std::string &fieldName,
584 const std::string &offset,
585 bool isReader) {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700586 size_t elementAlign, elementSize;
587 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
588
Andreas Huber85eabdb2016-08-25 11:24:49 -0700589 if (isReader) {
590 out << "{\n";
591 out.indent();
592
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700593 out << "int _hidl_vec_size = "
594 << blobName
595 << ".getInt32("
596 << offset
597 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
598
Yifan Hong1af73532016-11-09 14:32:58 -0800599 out << "android.os.HwBlob childBlob = "
Andreas Huber709b62d2016-09-19 11:21:18 -0700600 << parcelName
601 << ".readEmbeddedBuffer(\n";
602
Andreas Huber85eabdb2016-08-25 11:24:49 -0700603 out.indent();
604 out.indent();
605
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700606 out << "_hidl_vec_size * "
607 << elementSize << ","
608 << blobName
Andreas Huber85eabdb2016-08-25 11:24:49 -0700609 << ".handle(),\n"
610 << offset
Martijn Coenen011bb062017-01-13 11:09:41 +0100611 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
612 << "true /* nullable */);\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700613
614 out.unindent();
615 out.unindent();
616
617 out << fieldName << ".clear();\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700618 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
619
620 out << "for (int "
621 << iteratorName
622 << " = 0; "
623 << iteratorName
624 << " < _hidl_vec_size; "
625 << "++"
626 << iteratorName
627 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700628
629 out.indent();
630
Andreas Huberf630bc82016-09-09 14:52:25 -0700631 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700632
Andreas Huberf630bc82016-09-09 14:52:25 -0700633 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700634 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700635 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700636 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700637 "childBlob",
638 "_hidl_vec_element",
Andreas Huber4c865b72016-09-14 15:26:27 -0700639 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700640 true /* isReader */);
641
Andreas Huber1b6822b2016-10-18 09:28:40 -0700642 out << fieldName
643 << ".add(_hidl_vec_element);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700644
645 out.unindent();
646
647 out << "}\n";
648
649 out.unindent();
650 out << "}\n";
651
652 return;
653 }
654
655 out << "{\n";
656 out.indent();
657
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800658 out << "int _hidl_vec_size = "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700659 << fieldName
660 << ".size();\n";
661
662 out << blobName
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800663 << ".putInt32("
Andreas Huber85eabdb2016-08-25 11:24:49 -0700664 << offset
665 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
666
667 out << blobName
668 << ".putBool("
669 << offset
Pavel Maltsevcfa79342016-11-21 22:50:18 -0800670 << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700671
Andreas Huber85eabdb2016-08-25 11:24:49 -0700672 // XXX make HwBlob constructor take a long instead of an int?
Yifan Hong1af73532016-11-09 14:32:58 -0800673 out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700674 << elementSize
675 << "));\n";
676
Andreas Huber4c865b72016-09-14 15:26:27 -0700677 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
678
679 out << "for (int "
680 << iteratorName
681 << " = 0; "
682 << iteratorName
683 << " < _hidl_vec_size; "
684 << "++"
685 << iteratorName
686 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700687
688 out.indent();
689
Andreas Huberf630bc82016-09-09 14:52:25 -0700690 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700691 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700692 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700693 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700694 "childBlob",
Andreas Huberf1abc2a2016-09-28 09:14:43 -0700695 fieldName + ".get(" + iteratorName + ")",
Andreas Huber4c865b72016-09-14 15:26:27 -0700696 iteratorName + " * " + std::to_string(elementSize),
Andreas Huber85eabdb2016-08-25 11:24:49 -0700697 false /* isReader */);
698
699 out.unindent();
700
701 out << "}\n";
702
703 out << blobName
704 << ".putBlob("
705 << offset
706 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
707
708 out.unindent();
709 out << "}\n";
710}
711
Andreas Huber881227d2016-08-02 14:20:21 -0700712bool VectorType::needsEmbeddedReadWrite() const {
713 return true;
714}
715
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700716bool VectorType::deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const {
717 if (mElementType->needsResolveReferences(visited)) {
718 return true;
719 }
720 return TemplatedType::deepNeedsResolveReferences(visited);
Yifan Hongbf459bc2016-08-23 16:50:37 -0700721}
722
Andreas Huber881227d2016-08-02 14:20:21 -0700723bool VectorType::resultNeedsDeref() const {
Andreas Huber86a112b2016-10-19 14:25:16 -0700724 return !isVectorOfBinders();
Andreas Huber881227d2016-08-02 14:20:21 -0700725}
726
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700727bool VectorType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
728 if (!mElementType->isJavaCompatible(visited)) {
Andreas Huberf03332a2016-09-22 15:35:43 -0700729 return false;
730 }
731
732 if (mElementType->isArray()) {
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700733 return static_cast<const ArrayType*>(mElementType.get())->countDimensions() == 1;
Andreas Huberf03332a2016-09-22 15:35:43 -0700734 }
735
Andreas Huber1b6822b2016-10-18 09:28:40 -0700736 if (mElementType->isVector()) {
737 return false;
738 }
739
Andreas Huber86a112b2016-10-19 14:25:16 -0700740 if (isVectorOfBinders()) {
741 return false;
742 }
743
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700744 return TemplatedType::deepIsJavaCompatible(visited);
Andreas Huber70a59e12016-08-16 12:57:01 -0700745}
746
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700747bool VectorType::deepContainsPointer(std::unordered_set<const Type*>* visited) const {
748 if (mElementType->containsPointer(visited)) {
749 return true;
750 }
751 return TemplatedType::deepContainsPointer(visited);
Andreas Huber60d3b222017-03-30 09:10:56 -0700752}
753
Andreas Huber6755e9d2017-04-06 11:09:07 -0700754// All hidl_vec<T> have the same size.
755static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700756
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700757void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700758 *align = 8; // hidl_vec<T>
Andreas Huber6755e9d2017-04-06 11:09:07 -0700759 *size = assertion.size();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700760}
761
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700762void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
763 VectorType::getAlignmentAndSizeStatic(align, size);
764}
765
Andreas Huberc9410c72016-07-28 12:18:40 -0700766} // namespace android
767