1 /*
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
17 #include "Type.h"
18 #include <sstream>
19
20 #include <hidl-util/StringHelper.h>
21
22 namespace android {
23
Type(std::vector<Qualifier * > * qualifiers)24 Type::Type(std::vector<Qualifier*> *qualifiers)
25 : mQualifiers(qualifiers)
26 {}
27
~Type()28 Type::~Type() {
29 if(mArrays != nullptr) {
30 for(auto* array : *mArrays) {
31 delete array;
32 }
33 }
34
35 if(mQualifiers != nullptr) {
36 for(auto* qual : *mQualifiers) {
37 delete qual;
38 }
39 }
40 delete mQualifiers;}
41
42
setArrays(std::vector<Expression * > * arrays)43 void Type::setArrays(std::vector<Expression*> *arrays) {
44 mArrays = arrays;
45 }
46
decorateName(const std::string & name) const47 const std::string Type::decorateName(const std::string &name) const {
48 std::stringstream ss;
49
50 std::string special = getSpecialTypeName();
51
52 if(special.empty()) {
53 ss << getHidlType();
54 } else {
55 ss << special;
56 }
57
58 ss << " " << name;
59
60 return ss.str();
61 }
62
63 std::map<std::string, std::string> Type::kSignedToUnsignedMap = {
64 { "char", "uint8_t" },
65 { "short", "uint16_t" },
66 { "int", "uint32_t" },
67 { "long", "uint64_t" },
68 { "int8_t", "uint8_t" },
69 { "int16_t", "uint16_t" },
70 { "int32_t", "uint32_t" },
71 { "int64_t", "uint64_t" },
72 };
73
signedToUnsigned(const std::string & signedType)74 const std::string Type::signedToUnsigned(const std::string &signedType) {
75 auto it = kSignedToUnsignedMap.find(signedType);
76
77 if (it == kCToHidlMap.end()) {
78 return "";
79 }
80
81 return (*it).second;
82 }
83
84 std::map<std::string, std::string> Type::kCToHidlMap = {
85 { "char", "int8_t /* NOTE: char */" },
86 { "short", "int16_t" },
87 { "int", "int32_t" },
88 { "long", "int64_t"},
89 { "native_handle_t", "handle" },
90 { "size_t", "uint64_t" },
91 { "int8_t", "int8_t" },
92 { "uint8_t", "uint8_t" },
93 { "int16_t", "int16_t" },
94 { "uint16_t", "uint16_t" },
95 { "int32_t", "int32_t" },
96 { "uint32_t", "uint32_t" },
97 { "int64_t", "int64_t" },
98 { "uint64_t", "uint64_t" },
99 { "float", "float" },
100 { "double", "double" },
101 { "bool", "bool" },
102 { "wchar_t", "int32_t /* NOTE: wchar_t */"},
103 // { "hidl_string", "string" },
104 // { "hidl_vec", "vec"},
105 };
106
cToHidlType(const std::string & cType)107 const std::string Type::cToHidlType(const std::string &cType) {
108 auto it = kCToHidlMap.find(cType);
109
110 if (it == kCToHidlMap.end()) {
111 return "";
112 }
113
114 return (*it).second;
115 }
116
getHidlType() const117 const std::string Type::getHidlType() const {
118 if (mQualifiers == nullptr) {
119 return "";
120 }
121
122 std::stringstream ss;
123
124 for (auto it = mQualifiers->begin(); it != mQualifiers->end(); ++it) {
125 if (it != mQualifiers->begin()) {
126 ss << " ";
127 }
128
129 switch((*it)->qualification) {
130 case Type::Qualifier::STRUCT:
131 case Type::Qualifier::UNION:
132 case Type::Qualifier::ENUM:
133 case Type::Qualifier::POINTER:
134 case Type::Qualifier::CONST: {
135 ss << "/* "
136 << Type::qualifierText((*it)->qualification)
137 << " */";
138 break;
139 }
140 case Type::Qualifier::ID: {
141 std::string id = (*it)->id;
142 std::string conversion = cToHidlType(id);
143 if (!conversion.empty()) {
144 ss << conversion;
145 } else {
146 std::string baseName = StringHelper::RTrim(id, "_t");
147 ss << StringHelper::ToPascalCase(baseName);
148 }
149 break;
150 }
151 case Type::Qualifier::GENERICS: {
152 ss << "<"
153 << (*it)->generics->decorateName("")
154 << ">";
155 break;
156 }
157 case Type::Qualifier::UNSIGNED: {
158 auto next = it + 1;
159 if (next == mQualifiers->end()) {
160 ss << "uint32_t"; // 'unsigned a' -> 'uint32_t a'
161 break;
162 }
163 std::string unsignedType = signedToUnsigned((*next)->id);
164 if(unsignedType.empty()) {
165 ss << Type::qualifierText((*it)->qualification);
166 } else {
167 ss << unsignedType;
168 ++it;
169 }
170 break;
171 }
172 default: {
173 ss << Type::qualifierText((*it)->qualification);
174 }
175 }
176 }
177
178 if (mArrays != nullptr) {
179 for (const auto &array : *mArrays) {
180 ss << "[" << array->toString() << "]";
181 }
182 }
183
184 return ss.str();
185 }
186
getRawQualifierList() const187 const std::string Type::getRawQualifierList() const {
188 if (mQualifiers == nullptr) {
189 return "";
190 }
191
192 std::stringstream ss;
193
194 for(auto* qualifier : *mQualifiers) {
195 ss << Type::qualifierText(qualifier->qualification) << " ";
196 }
197
198 return ss.str();
199 }
200
getSpecialTypeName() const201 const std::string Type::getSpecialTypeName() const {
202 // this makes for a relatively expensive comparison, but it is
203 // readable until the converstion get nailed down.
204 std::string qualifiers = getRawQualifierList();
205
206 if (qualifiers == "const ID * " ||
207 qualifiers == "ID * ") {
208
209 std::string id = mQualifiers->at(mQualifiers->size() - 2)->id;
210
211 if (id == "char") {
212 return "string";
213 } else {
214 // can't tell if it's a hidl_vec or a pointer
215 // return "vec<" + id + ">";
216 return "";
217 }
218 }
219
220 return "";
221 }
222
isVoid() const223 bool Type::isVoid() const {
224 if (mQualifiers->size() == 0) {
225 return true;
226 }
227
228 return mQualifiers->size() == 1 &&
229 (*mQualifiers)[0]->qualification == Type::Qualifier::VOID;
230 }
231
isHwDevice() const232 bool Type::isHwDevice() const {
233 if (mQualifiers->size() < 2) {
234 return false;
235 }
236
237 return (*mQualifiers)[0]->qualification == Type::Qualifier::STRUCT &&
238 (*mQualifiers)[1]->qualification == Type::Qualifier::ID &&
239 (*mQualifiers)[1]->id == "hw_device_t";
240 }
241
removeLastId()242 std::string Type::removeLastId() {
243 if(mQualifiers == nullptr || mQualifiers->size() == 0) {
244 return "";
245 }
246
247 Qualifier *last = (*mQualifiers)[mQualifiers->size() - 1];
248
249 if(last == nullptr || last->qualification != Qualifier::ID) {
250 return "";
251 }
252
253 std::string ret{last->id};
254
255 mQualifiers->erase(mQualifiers->end() - 1);
256
257 return ret;
258 }
259
260 } //namespace android
261