blob: d1cec2d5b27e3c03ead170cd6bce31172b08dea4 [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001#include "VectorType.h"
2
3#include "Formatter.h"
4
Andreas Huber881227d2016-08-02 14:20:21 -07005#include <android-base/logging.h>
6
Andreas Huberc9410c72016-07-28 12:18:40 -07007namespace android {
8
9VectorType::VectorType(Type *elementType)
10 : mElementType(elementType) {
11}
12
Andreas Huber881227d2016-08-02 14:20:21 -070013std::string VectorType::getCppType(StorageMode mode, std::string *extra) const {
14 const std::string base =
Andreas Huber8a82ff72016-08-04 10:29:39 -070015 "::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -070016 + mElementType->getCppType(extra)
17 + ">";
18
19 CHECK(extra->empty());
20
21 switch (mode) {
22 case StorageMode_Stack:
23 return base;
24
25 case StorageMode_Argument:
26 return "const " + base + "&";
27
28 case StorageMode_Result:
29 return "const " + base + "*";
30 }
31}
32
33void VectorType::emitReaderWriter(
34 Formatter &out,
35 const std::string &name,
36 const std::string &parcelObj,
37 bool parcelObjIsPointer,
38 bool isReader,
39 ErrorMode mode) const {
40 std::string baseExtra;
41 std::string baseType = mElementType->getCppType(&baseExtra);
42
43 const std::string parentName = "_aidl_" + name + "_parent";
44
45 out << "size_t " << parentName << ";\n\n";
46
47 const std::string parcelObjDeref =
48 parcelObj + (parcelObjIsPointer ? "->" : ".");
49
50 if (isReader) {
51 out << name
Andreas Huber8a82ff72016-08-04 10:29:39 -070052 << " = (const ::android::hardware::hidl_vec<"
Andreas Huber881227d2016-08-02 14:20:21 -070053 << baseType
54 << "> *)"
55 << parcelObjDeref
56 << "readBuffer(&"
57 << parentName
58 << ");\n\n";
59
60 out << "if (" << name << " == nullptr) {\n";
61
62 out.indent();
63
64 out << "_aidl_err = ::android::UNKNOWN_ERROR;\n";
65 handleError2(out, mode);
66
67 out.unindent();
68 out << "}\n\n";
69 } else {
70 out << "_aidl_err = "
71 << parcelObjDeref
72 << "writeBuffer(&"
73 << name
74 << ", sizeof("
75 << name
76 << "), &"
77 << parentName
78 << ");\n";
79
80 handleError(out, mode);
81 }
82
83 emitReaderWriterEmbedded(
84 out,
85 name,
86 isReader /* nameIsPointer */,
87 parcelObj,
88 parcelObjIsPointer,
89 isReader,
90 mode,
91 parentName,
92 "0 /* parentOffset */");
93}
94
95void VectorType::emitReaderWriterEmbedded(
96 Formatter &out,
97 const std::string &name,
98 bool nameIsPointer,
99 const std::string &parcelObj,
100 bool parcelObjIsPointer,
101 bool isReader,
102 ErrorMode mode,
103 const std::string &parentName,
104 const std::string &offsetText) const {
105 std::string baseExtra;
106 std::string baseType = Type::getCppType(&baseExtra);
107
108 const std::string childName = "_aidl_" + name + "_child";
109 out << "size_t " << childName << ";\n\n";
110
111 emitReaderWriterEmbeddedForTypeName(
112 out,
113 name,
114 nameIsPointer,
115 parcelObj,
116 parcelObjIsPointer,
117 isReader,
118 mode,
119 parentName,
120 offsetText,
121 baseType,
122 childName);
123
124 if (!mElementType->needsEmbeddedReadWrite()) {
125 return;
126 }
127
128 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
129
130 baseType = mElementType->getCppType(&baseExtra);
131
132 out << "for (size_t _aidl_index = 0; _aidl_index < "
133 << nameDeref
134 << "count; ++_aidl_index) {\n";
135
136 out.indent();
137
138 mElementType->emitReaderWriterEmbedded(
139 out,
140 nameDeref + "buffer[_aidl_index]",
141 false /* nameIsPointer */,
142 parcelObj,
143 parcelObjIsPointer,
144 isReader,
145 mode,
146 childName,
147 "_aidl_index * sizeof(" + baseType + ")");
148
149 out.unindent();
150
151 out << "}\n\n";
152}
153
154bool VectorType::needsEmbeddedReadWrite() const {
155 return true;
156}
157
158bool VectorType::resultNeedsDeref() const {
159 return true;
160}
161
Andreas Huberc9410c72016-07-28 12:18:40 -0700162} // namespace android
163