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 24 Type::Type(std::vector<Qualifier*> *qualifiers) 25 : mQualifiers(qualifiers) 26 {} 27 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 43 void Type::setArrays(std::vector<Expression*> *arrays) { 44 mArrays = arrays; 45 } 46 47 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 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 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 117 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 187 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 201 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 223 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 232 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 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