blob: 8168992aac6a97b4c540c8a86bed8fc0c6ee97fb [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 "ArrayType.h"
18
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070019#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070020#include <android-base/logging.h>
21
Yifan Hongf24fa852016-09-23 11:03:15 -070022#include "ConstantExpression.h"
23
Andreas Huberc9410c72016-07-28 12:18:40 -070024namespace android {
25
Yifan Hongf24fa852016-09-23 11:03:15 -070026ArrayType::ArrayType(ArrayType *srcArray, ConstantExpression *size)
Andreas Huber709b62d2016-09-19 11:21:18 -070027 : mElementType(srcArray->mElementType),
Yifan Hong5706a432016-11-02 09:44:18 -070028 mSizes(srcArray->mSizes) {
Yifan Hongbd33e382016-11-02 13:30:17 -070029 prependDimension(size);
Andreas Huber709b62d2016-09-19 11:21:18 -070030}
31
Yifan Hongf24fa852016-09-23 11:03:15 -070032ArrayType::ArrayType(Type *elementType, ConstantExpression *size)
Andreas Huber709b62d2016-09-19 11:21:18 -070033 : mElementType(elementType) {
Yifan Hongbd33e382016-11-02 13:30:17 -070034 prependDimension(size);
Andreas Huber709b62d2016-09-19 11:21:18 -070035}
36
Yifan Hongbd33e382016-11-02 13:30:17 -070037void ArrayType::prependDimension(ConstantExpression *size) {
Yifan Hong5706a432016-11-02 09:44:18 -070038 mSizes.insert(mSizes.begin(), size);
Andreas Huberc9410c72016-07-28 12:18:40 -070039}
40
Yifan Hongbd33e382016-11-02 13:30:17 -070041void ArrayType::appendDimension(ConstantExpression *size) {
Yifan Hong5706a432016-11-02 09:44:18 -070042 mSizes.push_back(size);
Yifan Hongbd33e382016-11-02 13:30:17 -070043}
44
Andreas Huberf03332a2016-09-22 15:35:43 -070045size_t ArrayType::countDimensions() const {
46 return mSizes.size();
47}
48
Steven Moreland979e0992016-09-07 09:18:08 -070049void ArrayType::addNamedTypesToSet(std::set<const FQName> &set) const {
50 mElementType->addNamedTypesToSet(set);
51}
52
Andreas Huber709b62d2016-09-19 11:21:18 -070053bool ArrayType::isArray() const {
54 return true;
55}
56
Yifan Hongc6752dc2016-12-20 14:00:14 -080057bool ArrayType::canCheckEquality() const {
58 return mElementType->canCheckEquality();
59}
60
Andreas Huberf03332a2016-09-22 15:35:43 -070061Type *ArrayType::getElementType() const {
62 return mElementType;
63}
64
Steven Moreland979e0992016-09-07 09:18:08 -070065std::string ArrayType::getCppType(StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -070066 bool specifyNamespaces) const {
Yifan Hong3b320f82016-11-01 15:15:54 -070067 const std::string base = mElementType->getCppStackType(specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -070068
Steven Morelandc46e9842016-11-02 13:21:26 -070069 std::string space = specifyNamespaces ? "::android::hardware::" : "";
70 std::string arrayType = space + "hidl_array<" + base;
Andreas Huberf03332a2016-09-22 15:35:43 -070071
72 for (size_t i = 0; i < mSizes.size(); ++i) {
73 arrayType += ", ";
Yifan Hong5706a432016-11-02 09:44:18 -070074 arrayType += mSizes[i]->cppValue();
Andreas Huberf03332a2016-09-22 15:35:43 -070075
Yifan Hong5706a432016-11-02 09:44:18 -070076 if (!mSizes[i]->descriptionIsTrivial()) {
77 arrayType += " /* ";
78 arrayType += mSizes[i]->description();
79 arrayType += " */";
80 }
Andreas Huber709b62d2016-09-19 11:21:18 -070081 }
82
Andreas Huberf03332a2016-09-22 15:35:43 -070083 arrayType += ">";
Andreas Huber881227d2016-08-02 14:20:21 -070084
85 switch (mode) {
86 case StorageMode_Stack:
Andreas Huberf03332a2016-09-22 15:35:43 -070087 return arrayType;
Andreas Huber881227d2016-08-02 14:20:21 -070088
89 case StorageMode_Argument:
Andreas Huberf03332a2016-09-22 15:35:43 -070090 return "const " + arrayType + "&";
91
Andreas Huber881227d2016-08-02 14:20:21 -070092 case StorageMode_Result:
Andreas Huberf03332a2016-09-22 15:35:43 -070093 return "const " + arrayType + "*";
Andreas Huber881227d2016-08-02 14:20:21 -070094 }
Andreas Huberf03332a2016-09-22 15:35:43 -070095
96 CHECK(!"Should not be here");
Andreas Huber881227d2016-08-02 14:20:21 -070097}
98
Yifan Hong30b5d1f2017-04-03 12:19:25 -070099std::string ArrayType::getInternalDataCppType() const {
100 std::string result = mElementType->getCppStackType();
101 for (size_t i = 0; i < mSizes.size(); ++i) {
102 result += "[";
103 result += mSizes[i]->cppValue();
104 result += "]";
105 }
106 return result;
107}
108
Yifan Hong4ed13472016-11-02 10:44:11 -0700109std::string ArrayType::getJavaType(bool forInitializer) const {
110 std::string base =
111 mElementType->getJavaType(forInitializer);
Andreas Huber709b62d2016-09-19 11:21:18 -0700112
Yifan Hongf24fa852016-09-23 11:03:15 -0700113 for (size_t i = 0; i < mSizes.size(); ++i) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700114 base += "[";
Andreas Huber709b62d2016-09-19 11:21:18 -0700115
116 if (forInitializer) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700117 base += mSizes[i]->javaValue();
Andreas Huber709b62d2016-09-19 11:21:18 -0700118 }
119
Yifan Hong5706a432016-11-02 09:44:18 -0700120 if (!forInitializer || !mSizes[i]->descriptionIsTrivial()) {
121 if (forInitializer)
Yifan Hong4ed13472016-11-02 10:44:11 -0700122 base += " ";
123 base += "/* " + mSizes[i]->description() + " */";
Yifan Hong5706a432016-11-02 09:44:18 -0700124 }
Yifan Hongf24fa852016-09-23 11:03:15 -0700125
Yifan Hong4ed13472016-11-02 10:44:11 -0700126 base += "]";
Andreas Huber4c865b72016-09-14 15:26:27 -0700127 }
Andreas Huber4c865b72016-09-14 15:26:27 -0700128
129 return base;
Andreas Huber2831d512016-08-15 09:33:47 -0700130}
131
Andreas Huberf03332a2016-09-22 15:35:43 -0700132std::string ArrayType::getJavaWrapperType() const {
133 return mElementType->getJavaWrapperType();
134}
135
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700136std::string ArrayType::getVtsType() const {
137 return "TYPE_ARRAY";
138}
139
Andreas Huber881227d2016-08-02 14:20:21 -0700140void ArrayType::emitReaderWriter(
141 Formatter &out,
142 const std::string &name,
143 const std::string &parcelObj,
144 bool parcelObjIsPointer,
145 bool isReader,
146 ErrorMode mode) const {
Yifan Hong3b320f82016-11-01 15:15:54 -0700147 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700148
Iliyan Malchev549e2592016-08-10 08:59:12 -0700149 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -0700150
151 out << "size_t " << parentName << ";\n\n";
152
153 const std::string parcelObjDeref =
154 parcelObj + (parcelObjIsPointer ? "->" : ".");
155
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700156 size_t numArrayElements = 1;
157 for (auto size : mSizes) {
158 numArrayElements *= size->castSizeT();
159 }
Andreas Huber881227d2016-08-02 14:20:21 -0700160 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 << numArrayElements
165 << " * sizeof("
166 << baseType
167 << "), &"
Andreas Huber881227d2016-08-02 14:20:21 -0700168 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100169 << ", "
170 << " reinterpret_cast<const void **>("
171 << "&" << name
172 << "));\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700173
Martijn Coenen6a082c62017-01-11 12:47:02 +0100174 handleError(out, mode);
Andreas Huber881227d2016-08-02 14:20:21 -0700175 } else {
Andreas Huberf03332a2016-09-22 15:35:43 -0700176
Iliyan Malchev549e2592016-08-10 08:59:12 -0700177 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -0700178 << parcelObjDeref
179 << "writeBuffer("
180 << name
Andreas Huberf03332a2016-09-22 15:35:43 -0700181 << ".data(), "
182 << numArrayElements
183 << " * sizeof("
Andreas Huber881227d2016-08-02 14:20:21 -0700184 << baseType
185 << "), &"
186 << parentName
187 << ");\n";
188
189 handleError(out, mode);
190 }
191
192 emitReaderWriterEmbedded(
193 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700194 0 /* depth */,
Andreas Huber881227d2016-08-02 14:20:21 -0700195 name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700196 name /* sanitizedName */,
Andreas Huber881227d2016-08-02 14:20:21 -0700197 isReader /* nameIsPointer */,
198 parcelObj,
199 parcelObjIsPointer,
200 isReader,
201 mode,
202 parentName,
203 "0 /* parentOffset */");
204}
205
206void ArrayType::emitReaderWriterEmbedded(
207 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700208 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700209 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700210 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700211 bool nameIsPointer,
212 const std::string &parcelObj,
213 bool parcelObjIsPointer,
214 bool isReader,
215 ErrorMode mode,
216 const std::string &parentName,
217 const std::string &offsetText) const {
218 if (!mElementType->needsEmbeddedReadWrite()) {
219 return;
220 }
221
222 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
223
Yifan Hong3b320f82016-11-01 15:15:54 -0700224 std::string baseType = mElementType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700225
Andreas Huberf9d49f12016-09-12 14:58:36 -0700226 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
227
228 out << "for (size_t "
229 << iteratorName
230 << " = 0; "
231 << iteratorName
232 << " < "
Yifan Hongbf459bc2016-08-23 16:50:37 -0700233 << dimension()
Andreas Huberf9d49f12016-09-12 14:58:36 -0700234 << "; ++"
235 << iteratorName
236 << ") {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700237
238 out.indent();
239
240 mElementType->emitReaderWriterEmbedded(
241 out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700242 depth + 1,
Andreas Huberf03332a2016-09-22 15:35:43 -0700243 nameDeref + "data()[" + iteratorName + "]",
Yifan Hongbe2a3732016-10-05 13:33:41 -0700244 sanitizedName + "_indexed",
Andreas Huber881227d2016-08-02 14:20:21 -0700245 false /* nameIsPointer */,
246 parcelObj,
247 parcelObjIsPointer,
248 isReader,
249 mode,
250 parentName,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700251 offsetText
252 + " + " + iteratorName + " * sizeof("
253 + baseType
Andreas Huberf9d49f12016-09-12 14:58:36 -0700254 + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700255
256 out.unindent();
257
258 out << "}\n\n";
259}
260
Yifan Hongbf459bc2016-08-23 16:50:37 -0700261void ArrayType::emitResolveReferences(
262 Formatter &out,
263 const std::string &name,
264 bool nameIsPointer,
265 const std::string &parcelObj,
266 bool parcelObjIsPointer,
267 bool isReader,
268 ErrorMode mode) const {
269 emitResolveReferencesEmbedded(
270 out,
271 0 /* depth */,
272 name,
273 name /* sanitizedName */,
274 nameIsPointer,
275 parcelObj,
276 parcelObjIsPointer,
277 isReader,
278 mode,
279 "_hidl_" + name + "_parent",
280 "0 /* parentOffset */");
281}
282
283void ArrayType::emitResolveReferencesEmbedded(
284 Formatter &out,
285 size_t depth,
286 const std::string &name,
287 const std::string &sanitizedName,
288 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 {
295 CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
296
297 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
298
Yifan Hong3b320f82016-11-01 15:15:54 -0700299 std::string baseType = mElementType->getCppStackType();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700300
301 std::string iteratorName = "_hidl_index_" + std::to_string(depth);
302
303 out << "for (size_t "
304 << iteratorName
305 << " = 0; "
306 << iteratorName
307 << " < "
308 << dimension()
309 << "; ++"
310 << iteratorName
311 << ") {\n";
312
313 out.indent();
314
315 mElementType->emitResolveReferencesEmbedded(
316 out,
317 depth + 1,
318 nameDeref + "data()[" + iteratorName + "]",
319 sanitizedName + "_indexed",
320 false /* nameIsPointer */,
321 parcelObj,
322 parcelObjIsPointer,
323 isReader,
324 mode,
325 parentName,
326 offsetText + " + " + iteratorName + " * sizeof("
327 + baseType
328 + ")");
329
330 out.unindent();
331
332 out << "}\n\n";
333}
334
Yifan Honge45b5302017-02-22 10:49:07 -0800335void ArrayType::emitJavaDump(
336 Formatter &out,
337 const std::string &streamName,
338 const std::string &name) const {
339 out << streamName << ".append(java.util.Arrays."
340 << (countDimensions() > 1 ? "deepToString" : "toString")
341 << "("
342 << name << "));\n";
343}
344
345
Andreas Huber881227d2016-08-02 14:20:21 -0700346bool ArrayType::needsEmbeddedReadWrite() const {
347 return mElementType->needsEmbeddedReadWrite();
348}
349
Yifan Hongbf459bc2016-08-23 16:50:37 -0700350bool ArrayType::needsResolveReferences() const {
351 return mElementType->needsResolveReferences();
352}
353
Andreas Huberf03332a2016-09-22 15:35:43 -0700354bool ArrayType::resultNeedsDeref() const {
355 return true;
356}
357
Andreas Huber2831d512016-08-15 09:33:47 -0700358void ArrayType::emitJavaReaderWriter(
359 Formatter &out,
360 const std::string &parcelObj,
361 const std::string &argName,
362 bool isReader) const {
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700363 size_t align, size;
364 getAlignmentAndSize(&align, &size);
365
Andreas Huber709b62d2016-09-19 11:21:18 -0700366 if (isReader) {
Andreas Huber709b62d2016-09-19 11:21:18 -0700367 out << "new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700368 << getJavaType(true /* forInitializer */)
Andreas Huber709b62d2016-09-19 11:21:18 -0700369 << ";\n";
Andreas Huberf630bc82016-09-09 14:52:25 -0700370 }
371
Andreas Huber709b62d2016-09-19 11:21:18 -0700372 out << "{\n";
373 out.indent();
374
Yifan Hong1af73532016-11-09 14:32:58 -0800375 out << "android.os.HwBlob _hidl_blob = ";
Andreas Huber709b62d2016-09-19 11:21:18 -0700376
377 if (isReader) {
378 out << parcelObj
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700379 << ".readBuffer("
380 << size
381 << " /* size */);\n";
Andreas Huber709b62d2016-09-19 11:21:18 -0700382 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800383 out << "new android.os.HwBlob("
Andreas Huber709b62d2016-09-19 11:21:18 -0700384 << size
385 << " /* size */);\n";
386 }
387
388 emitJavaFieldReaderWriter(
Andreas Huber2831d512016-08-15 09:33:47 -0700389 out,
Andreas Huber709b62d2016-09-19 11:21:18 -0700390 0 /* depth */,
Andreas Huber2831d512016-08-15 09:33:47 -0700391 parcelObj,
Andreas Huber709b62d2016-09-19 11:21:18 -0700392 "_hidl_blob",
Andreas Huber2831d512016-08-15 09:33:47 -0700393 argName,
Andreas Huber709b62d2016-09-19 11:21:18 -0700394 "0 /* offset */",
395 isReader);
396
397 if (!isReader) {
398 out << parcelObj << ".writeBuffer(_hidl_blob);\n";
399 }
400
401 out.unindent();
402 out << "}\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700403}
404
Andreas Huber85eabdb2016-08-25 11:24:49 -0700405void ArrayType::emitJavaFieldInitializer(
406 Formatter &out, const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700407 std::string typeName = getJavaType(false /* forInitializer */);
408 std::string initName = getJavaType(true /* forInitializer */);
Andreas Huber4c865b72016-09-14 15:26:27 -0700409
Andreas Hubercd5e6662016-08-30 15:02:59 -0700410 out << "final "
Andreas Huber4c865b72016-09-14 15:26:27 -0700411 << typeName
Andreas Huber4c865b72016-09-14 15:26:27 -0700412 << " "
Andreas Huber85eabdb2016-08-25 11:24:49 -0700413 << fieldName
414 << " = new "
Yifan Hong4ed13472016-11-02 10:44:11 -0700415 << initName
Andreas Huber4c865b72016-09-14 15:26:27 -0700416 << ";\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700417}
418
419void ArrayType::emitJavaFieldReaderWriter(
420 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700421 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700422 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700423 const std::string &blobName,
424 const std::string &fieldName,
425 const std::string &offset,
426 bool isReader) const {
Andreas Huber90e8fc22016-09-21 16:36:15 -0700427 out << "{\n";
428 out.indent();
429
Andreas Huber709b62d2016-09-19 11:21:18 -0700430 std::string offsetName = "_hidl_array_offset_" + std::to_string(depth);
431 out << "long " << offsetName << " = " << offset << ";\n";
Andreas Huber4c865b72016-09-14 15:26:27 -0700432
Andreas Huber709b62d2016-09-19 11:21:18 -0700433 std::string indexString;
434 for (size_t dim = 0; dim < mSizes.size(); ++dim) {
435 std::string iteratorName =
436 "_hidl_index_" + std::to_string(depth) + "_" + std::to_string(dim);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700437
Andreas Huber709b62d2016-09-19 11:21:18 -0700438 out << "for (int "
439 << iteratorName
440 << " = 0; "
441 << iteratorName
442 << " < "
Yifan Hong5706a432016-11-02 09:44:18 -0700443 << mSizes[dim]->javaValue()
Andreas Huber709b62d2016-09-19 11:21:18 -0700444 << "; ++"
445 << iteratorName
446 << ") {\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700447
Andreas Huber709b62d2016-09-19 11:21:18 -0700448 out.indent();
449
450 indexString += "[" + iteratorName + "]";
451 }
452
453 if (isReader && mElementType->isCompoundType()) {
Andreas Huber709b62d2016-09-19 11:21:18 -0700454 std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700455 mElementType->getJavaType(false /* forInitializer */);
Andreas Huber709b62d2016-09-19 11:21:18 -0700456
457 out << fieldName
458 << indexString
459 << " = new "
460 << typeName
461 << "();\n";
462 }
Andreas Huber85eabdb2016-08-25 11:24:49 -0700463
464 mElementType->emitJavaFieldReaderWriter(
465 out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700466 depth + 1,
Andreas Huber709b62d2016-09-19 11:21:18 -0700467 parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700468 blobName,
Andreas Huber709b62d2016-09-19 11:21:18 -0700469 fieldName + indexString,
470 offsetName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700471 isReader);
472
Andreas Huber709b62d2016-09-19 11:21:18 -0700473 size_t elementAlign, elementSize;
474 mElementType->getAlignmentAndSize(&elementAlign, &elementSize);
475
476 out << offsetName << " += " << std::to_string(elementSize) << ";\n";
477
478 for (size_t dim = 0; dim < mSizes.size(); ++dim) {
479 out.unindent();
480 out << "}\n";
481 }
Andreas Huber90e8fc22016-09-21 16:36:15 -0700482
483 out.unindent();
484 out << "}\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -0700485}
486
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700487status_t ArrayType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700488 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhang3b23fa32017-01-23 18:19:15 -0800489 out << "vector_size: " << mSizes[0]->value() << "\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700490 out << "vector_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700491 out.indent();
Zhuoyao Zhangeb355ee2016-10-20 16:00:40 -0700492 // Simple array case.
493 if (mSizes.size() == 1) {
494 status_t err = mElementType->emitVtsTypeDeclarations(out);
495 if (err != OK) {
496 return err;
497 }
498 } else { // Multi-dimension array case.
499 for (size_t index = 1; index < mSizes.size(); index++) {
500 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhang3b23fa32017-01-23 18:19:15 -0800501 out << "vector_size: " << mSizes[index]->value() << "\n";
Zhuoyao Zhangeb355ee2016-10-20 16:00:40 -0700502 out << "vector_value: {\n";
503 out.indent();
Zhuoyao Zhangeb355ee2016-10-20 16:00:40 -0700504 if (index == mSizes.size() - 1) {
505 status_t err = mElementType->emitVtsTypeDeclarations(out);
506 if (err != OK) {
507 return err;
508 }
509 }
510 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700511 }
Zhuoyao Zhangeb355ee2016-10-20 16:00:40 -0700512 for (size_t index = 0; index < mSizes.size(); index++) {
513 out.unindent();
514 out << "}\n";
515 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700516 return OK;
517}
518
Andreas Huber70a59e12016-08-16 12:57:01 -0700519bool ArrayType::isJavaCompatible() const {
520 return mElementType->isJavaCompatible();
521}
522
Andreas Huber60d3b222017-03-30 09:10:56 -0700523bool ArrayType::containsPointer() const {
524 return mElementType->containsPointer();
525}
526
Andreas Huber85eabdb2016-08-25 11:24:49 -0700527void ArrayType::getAlignmentAndSize(size_t *align, size_t *size) const {
528 mElementType->getAlignmentAndSize(align, size);
529
Andreas Huber709b62d2016-09-19 11:21:18 -0700530 for (auto sizeInDimension : mSizes) {
Yifan Hong5706a432016-11-02 09:44:18 -0700531 (*size) *= sizeInDimension->castSizeT();
Andreas Huber709b62d2016-09-19 11:21:18 -0700532 }
Andreas Huber85eabdb2016-08-25 11:24:49 -0700533}
534
Yifan Hongbf459bc2016-08-23 16:50:37 -0700535size_t ArrayType::dimension() const {
536 size_t numArrayElements = 1;
537 for (auto size : mSizes) {
Yifan Hong5706a432016-11-02 09:44:18 -0700538 numArrayElements *= size->castSizeT();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700539 }
540 return numArrayElements;
541}
542
Andreas Huberc9410c72016-07-28 12:18:40 -0700543} // namespace android
544