11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/*
21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project
31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License.
61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at
71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software
111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and
141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License.
151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */
161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber
17c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber#include "ArrayType.h"
18c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
19a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <hidl-util/Formatter.h>
20881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber#include <android-base/logging.h>
21881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
22f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong#include "ConstantExpression.h"
23f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
24c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android {
25c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
26f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongArrayType::ArrayType(ArrayType *srcArray, ConstantExpression *size)
27709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    : mElementType(srcArray->mElementType),
285706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong      mSizes(srcArray->mSizes) {
29bd33e3854555589f312c4d6d89491e2f5cc2f782Yifan Hong    prependDimension(size);
30709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber}
31709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
32f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongArrayType::ArrayType(Type *elementType, ConstantExpression *size)
33709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    : mElementType(elementType) {
34bd33e3854555589f312c4d6d89491e2f5cc2f782Yifan Hong    prependDimension(size);
35709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber}
36709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
37bd33e3854555589f312c4d6d89491e2f5cc2f782Yifan Hongvoid ArrayType::prependDimension(ConstantExpression *size) {
385706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong    mSizes.insert(mSizes.begin(), size);
39c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}
40c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
41bd33e3854555589f312c4d6d89491e2f5cc2f782Yifan Hongvoid ArrayType::appendDimension(ConstantExpression *size) {
425706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong    mSizes.push_back(size);
43bd33e3854555589f312c4d6d89491e2f5cc2f782Yifan Hong}
44bd33e3854555589f312c4d6d89491e2f5cc2f782Yifan Hong
45f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Hubersize_t ArrayType::countDimensions() const {
46f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    return mSizes.size();
47f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber}
48f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
49709b62dbda6184770bb34470ff550e02c1643e67Andreas Huberbool ArrayType::isArray() const {
50709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    return true;
51709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber}
52709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
53c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hongbool ArrayType::canCheckEquality() const {
54c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong    return mElementType->canCheckEquality();
55c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong}
56c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong
57f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas HuberType *ArrayType::getElementType() const {
58f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    return mElementType;
59f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber}
60f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
618b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Morelandstd::string ArrayType::typeName() const {
628b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland    if (dimension() == 1) {
638b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland        return "array of " + mElementType->typeName();
648b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland    }
658b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland
668b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland    return std::to_string(dimension()) + "d array of " + mElementType->typeName();
678b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland}
688b66d53dffa4e91c932d09b8be21c8d2edc8ab78Steven Moreland
69979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string ArrayType::getCppType(StorageMode mode,
70979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland                                  bool specifyNamespaces) const {
713b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string base = mElementType->getCppStackType(specifyNamespaces);
72709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
73c46e9842bd82d9c70e08b37a4507b448b285d6c6Steven Moreland    std::string space = specifyNamespaces ? "::android::hardware::" : "";
74c46e9842bd82d9c70e08b37a4507b448b285d6c6Steven Moreland    std::string arrayType = space + "hidl_array<" + base;
75881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
76f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    for (size_t i = 0; i < mSizes.size(); ++i) {
77f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber        arrayType += ", ";
785706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        arrayType += mSizes[i]->cppValue();
79f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
805706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        if (!mSizes[i]->descriptionIsTrivial()) {
815706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong            arrayType += " /* ";
825706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong            arrayType += mSizes[i]->description();
835706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong            arrayType += " */";
845706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        }
85f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
86f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
87f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    arrayType += ">";
88881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
89881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    switch (mode) {
90881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        case StorageMode_Stack:
91f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            return arrayType;
92881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
93881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        case StorageMode_Argument:
94f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            return "const " + arrayType + "&";
95f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
96881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        case StorageMode_Result:
97f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            return "const " + arrayType + "*";
98881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
99f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
100f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    CHECK(!"Should not be here");
101881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
102881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
10330b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hongstd::string ArrayType::getInternalDataCppType() const {
10430b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong    std::string result = mElementType->getCppStackType();
10530b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong    for (size_t i = 0; i < mSizes.size(); ++i) {
10630b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong        result += "[";
10730b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong        result += mSizes[i]->cppValue();
10830b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong        result += "]";
10930b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong    }
11030b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong    return result;
11130b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong}
11230b5d1ffe964d0b82008bfc8f4b8e61ab3bac86fYifan Hong
1134ed1347cd29e6e07acad368891bb03078c798abaYifan Hongstd::string ArrayType::getJavaType(bool forInitializer) const {
1144ed1347cd29e6e07acad368891bb03078c798abaYifan Hong    std::string base =
1154ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        mElementType->getJavaType(forInitializer);
116709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
117f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (size_t i = 0; i < mSizes.size(); ++i) {
1184ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        base += "[";
119709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
120709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        if (forInitializer) {
1214ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            base += mSizes[i]->javaValue();
122709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        }
123709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
1245706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        if (!forInitializer || !mSizes[i]->descriptionIsTrivial()) {
1255706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong            if (forInitializer)
1264ed1347cd29e6e07acad368891bb03078c798abaYifan Hong                base += " ";
1274ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            base += "/* " + mSizes[i]->description() + " */";
1285706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        }
129f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
1304ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        base += "]";
1314c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    }
1324c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber
1334c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    return base;
1342831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
1352831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
136f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huberstd::string ArrayType::getJavaWrapperType() const {
137f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    return mElementType->getJavaWrapperType();
138f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber}
139f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
140c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhangstd::string ArrayType::getVtsType() const {
141c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    return "TYPE_ARRAY";
142c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang}
143c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang
144881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid ArrayType::emitReaderWriter(
145881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
146881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
147881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
148881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
149881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
150881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
1513b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    std::string baseType = mElementType->getCppStackType();
152881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
153549e2598843dcc092a6049bbd9e209c249b1b11aIliyan Malchev    const std::string parentName = "_hidl_" + name + "_parent";
154881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
155881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "size_t " << parentName << ";\n\n";
156881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
157881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    const std::string parcelObjDeref =
158881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        parcelObj + (parcelObjIsPointer ? "->" : ".");
159881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
160b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen    size_t numArrayElements = 1;
161b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen    for (auto size : mSizes) {
162b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen        numArrayElements *= size->castSizeT();
163b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen    }
164881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    if (isReader) {
1656a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen        out << "_hidl_err = "
166881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parcelObjDeref
167b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << "readBuffer("
168b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << numArrayElements
169b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << " * sizeof("
170b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << baseType
171b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << "), &"
172881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parentName
1736a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << ", "
1746a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << " reinterpret_cast<const void **>("
1756a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << "&" << name
1766a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << "));\n\n";
177881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1786a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen        handleError(out, mode);
179881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    } else {
180f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
181549e2598843dcc092a6049bbd9e209c249b1b11aIliyan Malchev        out << "_hidl_err = "
182881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parcelObjDeref
183881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << "writeBuffer("
184881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << name
185f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            << ".data(), "
186f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            << numArrayElements
187f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            << " * sizeof("
188881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << baseType
189881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << "), &"
190881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parentName
191881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << ");\n";
192881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
193881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        handleError(out, mode);
194881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
195881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
196881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    emitReaderWriterEmbedded(
197881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            out,
198f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber            0 /* depth */,
199881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            name,
200be2a3737675b83dd61b52c11f0d7549fa1276739Yifan Hong            name /* sanitizedName */,
201881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            isReader /* nameIsPointer */,
202881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObj,
203881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObjIsPointer,
204881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            isReader,
205881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            mode,
206881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parentName,
207881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            "0 /* parentOffset */");
208881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
209881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
210881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid ArrayType::emitReaderWriterEmbedded(
211881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
212f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        size_t depth,
213881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
214be2a3737675b83dd61b52c11f0d7549fa1276739Yifan Hong        const std::string &sanitizedName,
215881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool nameIsPointer,
216881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
217881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
218881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
219881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode,
220881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parentName,
221881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &offsetText) const {
222881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    if (!mElementType->needsEmbeddedReadWrite()) {
223881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        return;
224881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
225881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
226881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
227881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
2283b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    std::string baseType = mElementType->getCppStackType();
229881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
230f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber    std::string iteratorName = "_hidl_index_" + std::to_string(depth);
231f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber
232f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber    out << "for (size_t "
233f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << iteratorName
234f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << " = 0; "
235f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << iteratorName
236f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << " < "
237bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << dimension()
238f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << "; ++"
239f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << iteratorName
240f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        << ") {\n";
241881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
242881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
243881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
244881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    mElementType->emitReaderWriterEmbedded(
245881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            out,
246f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber            depth + 1,
247f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber            nameDeref + "data()[" + iteratorName + "]",
248be2a3737675b83dd61b52c11f0d7549fa1276739Yifan Hong            sanitizedName + "_indexed",
249881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            false /* nameIsPointer */,
250881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObj,
251881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObjIsPointer,
252881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            isReader,
253881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            mode,
254881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parentName,
255f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber            offsetText
256f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber                + " + " + iteratorName + " * sizeof("
257f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber                + baseType
258f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber                + ")");
259881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
260881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
261881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
262881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "}\n\n";
263881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
264881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
265bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hongvoid ArrayType::emitResolveReferences(
266bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            Formatter &out,
267bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &name,
268bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            bool nameIsPointer,
269bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &parcelObj,
270bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            bool parcelObjIsPointer,
271bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            bool isReader,
272bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            ErrorMode mode) const {
273bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    emitResolveReferencesEmbedded(
274bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        out,
275bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        0 /* depth */,
276bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        name,
277bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        name /* sanitizedName */,
278bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        nameIsPointer,
279bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        parcelObj,
280bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        parcelObjIsPointer,
281bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        isReader,
282bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        mode,
283bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        "_hidl_" + name + "_parent",
284bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        "0 /* parentOffset */");
285bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong}
286bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
287bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hongvoid ArrayType::emitResolveReferencesEmbedded(
288bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            Formatter &out,
289bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            size_t depth,
290bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &name,
291bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &sanitizedName,
292bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            bool nameIsPointer,
293bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &parcelObj,
294bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            bool parcelObjIsPointer,
295bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            bool isReader,
296bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            ErrorMode mode,
297bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &parentName,
298bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong            const std::string &offsetText) const {
299bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    CHECK(needsResolveReferences() && mElementType->needsResolveReferences());
300bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
301bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
302bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
3033b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    std::string baseType = mElementType->getCppStackType();
304bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
305bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    std::string iteratorName = "_hidl_index_" + std::to_string(depth);
306bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
307bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    out << "for (size_t "
308bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << iteratorName
309bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << " = 0; "
310bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << iteratorName
311bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << " < "
312bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << dimension()
313bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << "; ++"
314bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << iteratorName
315bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        << ") {\n";
316bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
317bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    out.indent();
318bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
319bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    mElementType->emitResolveReferencesEmbedded(
320bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        out,
321bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        depth + 1,
322bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        nameDeref + "data()[" + iteratorName + "]",
323bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        sanitizedName + "_indexed",
324bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        false /* nameIsPointer */,
325bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        parcelObj,
326bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        parcelObjIsPointer,
327bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        isReader,
328bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        mode,
329bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        parentName,
330bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        offsetText + " + " + iteratorName + " * sizeof("
331bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        + baseType
332bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong        + ")");
333bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
334bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    out.unindent();
335bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
336bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    out << "}\n\n";
337bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong}
338bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
339e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid ArrayType::emitJavaDump(
340e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
341e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
342e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
343e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(java.util.Arrays."
344e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << (countDimensions() > 1 ? "deepToString" : "toString")
345e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "("
346e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
347e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
348e45b5303e072043679483a70606f6c00dde17382Yifan Hong
349e45b5303e072043679483a70606f6c00dde17382Yifan Hong
350881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberbool ArrayType::needsEmbeddedReadWrite() const {
351881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return mElementType->needsEmbeddedReadWrite();
352881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
353881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
354bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hongbool ArrayType::needsResolveReferences() const {
355bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    return mElementType->needsResolveReferences();
356bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong}
357bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
358f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huberbool ArrayType::resultNeedsDeref() const {
359f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber    return true;
360f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber}
361f03332ac955bc6cb22873e236868eacfc3bf78ccAndreas Huber
3622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Hubervoid ArrayType::emitJavaReaderWriter(
3632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        Formatter &out,
3642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const std::string &parcelObj,
3652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const std::string &argName,
3662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        bool isReader) const {
367b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen    size_t align, size;
368b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen    getAlignmentAndSize(&align, &size);
369b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen
370709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    if (isReader) {
371709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << "new "
3724ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            << getJavaType(true /* forInitializer */)
373709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << ";\n";
374709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    }
3754c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber
376709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    out << "{\n";
377709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    out.indent();
378f630bc8736003dcf4aac3dfe47167beb6beb6c6aAndreas Huber
3791af73531ba32b3dfc6ef23a8bf0172dd00be43ccYifan Hong    out << "android.os.HwBlob _hidl_blob = ";
380709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
381709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    if (isReader) {
382709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << parcelObj
383b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << ".readBuffer("
384b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << size
385b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << " /* size */);\n";
386709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    } else {
3871af73531ba32b3dfc6ef23a8bf0172dd00be43ccYifan Hong        out << "new android.os.HwBlob("
388709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << size
389709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << " /* size */);\n";
390f630bc8736003dcf4aac3dfe47167beb6beb6c6aAndreas Huber    }
391f630bc8736003dcf4aac3dfe47167beb6beb6c6aAndreas Huber
392709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    emitJavaFieldReaderWriter(
3932831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out,
394709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            0 /* depth */,
3952831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            parcelObj,
396709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            "_hidl_blob",
3972831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            argName,
398709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            "0 /* offset */",
399709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            isReader);
400709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
401709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    if (!isReader) {
402709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << parcelObj << ".writeBuffer(_hidl_blob);\n";
403709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    }
404709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
405709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    out.unindent();
406709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    out << "}\n";
4072831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
4082831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
40985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid ArrayType::emitJavaFieldInitializer(
41085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out, const std::string &fieldName) const {
4114ed1347cd29e6e07acad368891bb03078c798abaYifan Hong    std::string typeName = getJavaType(false /* forInitializer */);
4124ed1347cd29e6e07acad368891bb03078c798abaYifan Hong    std::string initName = getJavaType(true /* forInitializer */);
4134c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber
414cd5e666ab52890842304b5778d438129693a5f39Andreas Huber    out << "final "
4154c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        << typeName
4164c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        << " "
41785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << fieldName
41885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << " = new "
4194ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        << initName
4204c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        << ";\n";
42185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
42285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
42385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid ArrayType::emitJavaFieldReaderWriter(
42485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
4254c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
426709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
42785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
42885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
42985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
43085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
43190e8fc2f8b9430e1dea9267a01e9a85bf1d7ffa9Andreas Huber    out << "{\n";
43290e8fc2f8b9430e1dea9267a01e9a85bf1d7ffa9Andreas Huber    out.indent();
43390e8fc2f8b9430e1dea9267a01e9a85bf1d7ffa9Andreas Huber
434709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    std::string offsetName = "_hidl_array_offset_" + std::to_string(depth);
435709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    out << "long " << offsetName << " = " << offset << ";\n";
436709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
437709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    std::string indexString;
438709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    for (size_t dim = 0; dim < mSizes.size(); ++dim) {
439709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        std::string iteratorName =
440709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            "_hidl_index_" + std::to_string(depth) + "_" + std::to_string(dim);
441709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
442709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << "for (int "
443709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << iteratorName
444709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << " = 0; "
445709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << iteratorName
446709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << " < "
4475706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong            << mSizes[dim]->javaValue()
448709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << "; ++"
449709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << iteratorName
450709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << ") {\n";
4514c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber
452709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out.indent();
45385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
454709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        indexString += "[" + iteratorName + "]";
455709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    }
45685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
457709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    if (isReader && mElementType->isCompoundType()) {
458709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        std::string typeName =
4594ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            mElementType->getJavaType(false /* forInitializer */);
460709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
461709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << fieldName
462709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << indexString
463709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << " = new "
464709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << typeName
465709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << "();\n";
466709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    }
46785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
46885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mElementType->emitJavaFieldReaderWriter(
46985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber            out,
4704c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber            depth + 1,
471709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            parcelName,
47285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber            blobName,
473709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            fieldName + indexString,
474709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            offsetName,
47585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber            isReader);
47685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
477709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    size_t elementAlign, elementSize;
478709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    mElementType->getAlignmentAndSize(&elementAlign, &elementSize);
479709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
480709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    out << offsetName << " += " << std::to_string(elementSize) << ";\n";
481709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber
482709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    for (size_t dim = 0; dim < mSizes.size(); ++dim) {
483709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out.unindent();
484709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << "}\n";
485709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    }
48690e8fc2f8b9430e1dea9267a01e9a85bf1d7ffa9Andreas Huber
48790e8fc2f8b9430e1dea9267a01e9a85bf1d7ffa9Andreas Huber    out.unindent();
48890e8fc2f8b9430e1dea9267a01e9a85bf1d7ffa9Andreas Huber    out << "}\n";
48985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
49085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
4915158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t ArrayType::emitVtsTypeDeclarations(Formatter &out) const {
492c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
4933b23fa32af9d8f04e89e08c60aafc7f2ef1b27d3Zhuoyao Zhang    out << "vector_size: " << mSizes[0]->value() << "\n";
494c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "vector_value: {\n";
4955158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
496eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang    // Simple array case.
497eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang    if (mSizes.size() == 1) {
498eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        status_t err = mElementType->emitVtsTypeDeclarations(out);
499eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        if (err != OK) {
500eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang            return err;
501eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        }
502eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang    } else {  // Multi-dimension array case.
503eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        for (size_t index = 1; index < mSizes.size(); index++) {
504eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang            out << "type: " << getVtsType() << "\n";
5053b23fa32af9d8f04e89e08c60aafc7f2ef1b27d3Zhuoyao Zhang            out << "vector_size: " << mSizes[index]->value() << "\n";
506eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang            out << "vector_value: {\n";
507eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang            out.indent();
508eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang            if (index == mSizes.size() - 1) {
509eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang                status_t err = mElementType->emitVtsTypeDeclarations(out);
510eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang                if (err != OK) {
511eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang                    return err;
512eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang                }
513eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang            }
514eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        }
515eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang    }
516eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang    for (size_t index = 0; index < mSizes.size(); index++) {
517eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        out.unindent();
518eb355ee0b307d651497f606271a15fbb3dcd2e47Zhuoyao Zhang        out << "}\n";
5195158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
5205158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
5215158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
5225158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
52370a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huberbool ArrayType::isJavaCompatible() const {
52470a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber    return mElementType->isJavaCompatible();
52570a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber}
52670a59e1dc3dcf32f791d2dd7966111d4adf32ecaAndreas Huber
52760d3b22101e911242d2d41c8dc8309e8706f1fe1Andreas Huberbool ArrayType::containsPointer() const {
52860d3b22101e911242d2d41c8dc8309e8706f1fe1Andreas Huber    return mElementType->containsPointer();
52960d3b22101e911242d2d41c8dc8309e8706f1fe1Andreas Huber}
53060d3b22101e911242d2d41c8dc8309e8706f1fe1Andreas Huber
53185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid ArrayType::getAlignmentAndSize(size_t *align, size_t *size) const {
53285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mElementType->getAlignmentAndSize(align, size);
53385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
534709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    for (auto sizeInDimension : mSizes) {
5355706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        (*size) *= sizeInDimension->castSizeT();
536709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber    }
53785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
53885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
539bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hongsize_t ArrayType::dimension() const {
540bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    size_t numArrayElements = 1;
541bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    for (auto size : mSizes) {
5425706a43b2955b30f5611588dadfb9e33c7aa4c89Yifan Hong        numArrayElements *= size->castSizeT();
543bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    }
544bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong    return numArrayElements;
545bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong}
546bf459bcedc2ab1a22a9cc290fbcc0a5462e63690Yifan Hong
547c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
548c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
549