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