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