blob: 9ddb1712018ba8e9a54a1582c74aefedfef5cef7 [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
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
Andreas Huberc9410c72016-07-28 12:18:40 -070022namespace android {
23
24VectorType::VectorType(Type *elementType)
25 : mElementType(elementType) {
26}
27
Steven Moreland979e0992016-09-07 09:18:08 -070028void VectorType::addNamedTypesToSet(std::set<const FQName> &set) const {
29 mElementType->addNamedTypesToSet(set);
30}
31
32std::string VectorType::getCppType(StorageMode mode,
33 std::string *extra,
34 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070035 const std::string base =
Steven Moreland979e0992016-09-07 09:18:08 -070036 std::string(specifyNamespaces ? "::android::hardware::" : "")
37 + "hidl_vec<"
38 + mElementType->getCppType(extra, specifyNamespaces)
Andreas Huber881227d2016-08-02 14:20:21 -070039 + ">";
40
41 CHECK(extra->empty());
42
43 switch (mode) {
44 case StorageMode_Stack:
45 return base;
46
47 case StorageMode_Argument:
48 return "const " + base + "&";
49
50 case StorageMode_Result:
51 return "const " + base + "*";
52 }
53}
54
Andreas Huber2831d512016-08-15 09:33:47 -070055std::string VectorType::getJavaType() const {
56 return mElementType->getJavaType() + "[]";
57}
58
Andreas Huber881227d2016-08-02 14:20:21 -070059void VectorType::emitReaderWriter(
60 Formatter &out,
61 const std::string &name,
62 const std::string &parcelObj,
63 bool parcelObjIsPointer,
64 bool isReader,
65 ErrorMode mode) const {
66 std::string baseExtra;
67 std::string baseType = mElementType->getCppType(&baseExtra);
68
Iliyan Malchev549e2592016-08-10 08:59:12 -070069 const std::string parentName = "_hidl_" + name + "_parent";
Andreas Huber881227d2016-08-02 14:20:21 -070070
71 out << "size_t " << parentName << ";\n\n";
72
73 const std::string parcelObjDeref =
74 parcelObj + (parcelObjIsPointer ? "->" : ".");
75
76 if (isReader) {
77 out << name
Andreas Huber8a82ff72016-08-04 10:29:39 -070078 << " = (const ::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -070079 << baseType
80 << "> *)"
81 << parcelObjDeref
82 << "readBuffer(&"
83 << parentName
84 << ");\n\n";
85
86 out << "if (" << name << " == nullptr) {\n";
87
88 out.indent();
89
Iliyan Malchev549e2592016-08-10 08:59:12 -070090 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
Andreas Huber881227d2016-08-02 14:20:21 -070091 handleError2(out, mode);
92
93 out.unindent();
94 out << "}\n\n";
95 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -070096 out << "_hidl_err = "
Andreas Huber881227d2016-08-02 14:20:21 -070097 << parcelObjDeref
98 << "writeBuffer(&"
99 << name
100 << ", sizeof("
101 << name
102 << "), &"
103 << parentName
104 << ");\n";
105
106 handleError(out, mode);
107 }
108
109 emitReaderWriterEmbedded(
110 out,
111 name,
112 isReader /* nameIsPointer */,
113 parcelObj,
114 parcelObjIsPointer,
115 isReader,
116 mode,
117 parentName,
118 "0 /* parentOffset */");
119}
120
121void VectorType::emitReaderWriterEmbedded(
122 Formatter &out,
123 const std::string &name,
124 bool nameIsPointer,
125 const std::string &parcelObj,
126 bool parcelObjIsPointer,
127 bool isReader,
128 ErrorMode mode,
129 const std::string &parentName,
130 const std::string &offsetText) const {
131 std::string baseExtra;
132 std::string baseType = Type::getCppType(&baseExtra);
133
Iliyan Malchev549e2592016-08-10 08:59:12 -0700134 const std::string childName = "_hidl_" + name + "_child";
Andreas Huber881227d2016-08-02 14:20:21 -0700135 out << "size_t " << childName << ";\n\n";
136
137 emitReaderWriterEmbeddedForTypeName(
138 out,
139 name,
140 nameIsPointer,
141 parcelObj,
142 parcelObjIsPointer,
143 isReader,
144 mode,
145 parentName,
146 offsetText,
147 baseType,
148 childName);
149
150 if (!mElementType->needsEmbeddedReadWrite()) {
151 return;
152 }
153
154 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
155
156 baseType = mElementType->getCppType(&baseExtra);
157
Iliyan Malchev549e2592016-08-10 08:59:12 -0700158 out << "for (size_t _hidl_index = 0; _hidl_index < "
Andreas Huber881227d2016-08-02 14:20:21 -0700159 << nameDeref
Iliyan Malchev549e2592016-08-10 08:59:12 -0700160 << "size(); ++_hidl_index) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700161
162 out.indent();
163
164 mElementType->emitReaderWriterEmbedded(
165 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -0700166 (nameIsPointer ? "(*" + name + ")" : name) + "[_hidl_index]",
Andreas Huber881227d2016-08-02 14:20:21 -0700167 false /* nameIsPointer */,
168 parcelObj,
169 parcelObjIsPointer,
170 isReader,
171 mode,
172 childName,
Iliyan Malchev549e2592016-08-10 08:59:12 -0700173 "_hidl_index * sizeof(" + baseType + ")");
Andreas Huber881227d2016-08-02 14:20:21 -0700174
175 out.unindent();
176
177 out << "}\n\n";
178}
179
Andreas Huberf630bc82016-09-09 14:52:25 -0700180void VectorType::emitJavaReaderWriter(
181 Formatter &out,
182 const std::string &parcelObj,
183 const std::string &argName,
184 bool isReader) const {
185 if (mElementType->isCompoundType()) {
186 if (isReader) {
187 out << mElementType->getJavaType()
188 << ".readVectorFromParcel("
189 << parcelObj
190 << ");\n";
191 } else {
192 out << mElementType->getJavaType()
193 << ".writeVectorToParcel("
194 << parcelObj
195 << ", "
196 << argName
197 << ");\n";
198 }
199
200 return;
201 }
202
203 emitJavaReaderWriterWithSuffix(
204 out,
205 parcelObj,
206 argName,
207 isReader,
208 mElementType->getJavaSuffix() + "Vector",
209 "" /* extra */);
210}
211
Andreas Huber85eabdb2016-08-25 11:24:49 -0700212void VectorType::emitJavaFieldInitializer(
213 Formatter &out, const std::string &fieldName) const {
214 out << "final Vector<"
215 << mElementType->getJavaWrapperType()
216 << "> "
217 << fieldName
218 << " = new Vector();\n";
219}
220
221void VectorType::emitJavaFieldReaderWriter(
222 Formatter &out,
223 const std::string &blobName,
224 const std::string &fieldName,
225 const std::string &offset,
226 bool isReader) const {
Andreas Huberf630bc82016-09-09 14:52:25 -0700227 VectorType::EmitJavaFieldReaderWriterForElementType(
228 out, mElementType, blobName, fieldName, offset, isReader);
229}
230
231// static
232void VectorType::EmitJavaFieldReaderWriterForElementType(
233 Formatter &out,
234 const Type *elementType,
235 const std::string &blobName,
236 const std::string &fieldName,
237 const std::string &offset,
238 bool isReader) {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700239 if (isReader) {
240 out << "{\n";
241 out.indent();
242
243 out << "HwBlob childBlob = parcel.readEmbeddedBuffer(\n";
244 out.indent();
245 out.indent();
246
247 out << blobName
248 << ".handle(),\n"
249 << offset
250 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */);\n\n";
251
252 out.unindent();
253 out.unindent();
254
255 out << fieldName << ".clear();\n";
256 out << "long _hidl_vec_size = "
257 << blobName
258 << ".getInt64("
259 << offset
260 << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
261
262 out << "for (int _hidl_index = 0; _hidl_index < _hidl_vec_size; "
263 << "++_hidl_index) {\n";
264
265 out.indent();
266
Andreas Huberf630bc82016-09-09 14:52:25 -0700267 elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
Andreas Huber85eabdb2016-08-25 11:24:49 -0700268
269 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700270 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700271
Andreas Huberf630bc82016-09-09 14:52:25 -0700272 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700273 out,
274 "childBlob",
275 "_hidl_vec_element",
276 "_hidl_index * " + std::to_string(elementSize),
277 true /* isReader */);
278
279 out << fieldName
280 << ".add(_hidl_vec_element);\n";
281
282 out.unindent();
283
284 out << "}\n";
285
286 out.unindent();
287 out << "}\n";
288
289 return;
290 }
291
292 out << "{\n";
293 out.indent();
294
295 out << "long _hidl_vec_size = "
296 << fieldName
297 << ".size();\n";
298
299 out << blobName
300 << ".putInt64("
301 << offset
302 << " + 8 /* offsetof(hidl_vec<T>, mSize) */, _hidl_vec_size);\n";
303
304 out << blobName
305 << ".putBool("
306 << offset
307 << " + 16 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
308
309 size_t elementAlign, elementSize;
Andreas Huberf630bc82016-09-09 14:52:25 -0700310 elementType->getAlignmentAndSize(&elementAlign, &elementSize);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700311
312 // XXX make HwBlob constructor take a long instead of an int?
313 out << "HwBlob childBlob = new HwBlob((int)(_hidl_vec_size * "
314 << elementSize
315 << "));\n";
316
317 out << "for (int _hidl_index = 0; _hidl_index < _hidl_vec_size; "
318 << "++_hidl_index) {\n";
319
320 out.indent();
321
Andreas Huberf630bc82016-09-09 14:52:25 -0700322 elementType->emitJavaFieldReaderWriter(
Andreas Huber85eabdb2016-08-25 11:24:49 -0700323 out,
324 "childBlob",
325 fieldName + ".elementAt(_hidl_index)",
326 "_hidl_index * " + std::to_string(elementSize),
327 false /* isReader */);
328
329 out.unindent();
330
331 out << "}\n";
332
333 out << blobName
334 << ".putBlob("
335 << offset
336 << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */, childBlob);\n";
337
338 out.unindent();
339 out << "}\n";
340}
341
Andreas Huber881227d2016-08-02 14:20:21 -0700342bool VectorType::needsEmbeddedReadWrite() const {
343 return true;
344}
345
346bool VectorType::resultNeedsDeref() const {
347 return true;
348}
349
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700350status_t VectorType::emitVtsTypeDeclarations(Formatter &out) const {
351 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
352 out.indent();
353 status_t err = mElementType->emitVtsTypeDeclarations(out);
354 if (err != OK) {
355 return err;
356 }
357 out.unindent();
358 out << "}\n";
359 return OK;
360}
361
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700362status_t VectorType::emitVtsAttributeType(Formatter &out) const {
363 out << "type: TYPE_VECTOR\n" << "vector_value: {\n";
364 out.indent();
365 status_t status = mElementType->emitVtsAttributeType(out);
366 if (status != OK) {
367 return status;
368 }
369 out.unindent();
370 out << "}\n";
371 return OK;
372}
373
Andreas Huber70a59e12016-08-16 12:57:01 -0700374bool VectorType::isJavaCompatible() const {
375 return mElementType->isJavaCompatible();
376}
377
Andreas Huber85eabdb2016-08-25 11:24:49 -0700378void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
379 *align = 8; // hidl_vec<T>
380 *size = 24;
381}
382
Andreas Huberc9410c72016-07-28 12:18:40 -0700383} // namespace android
384