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 "ScalarType.h" 18 19 #include <hidl-util/Formatter.h> 20 21 namespace android { 22 23 static const char* const hidlIdentifiers[] = {"bool", "int8_t", "uint8_t", "int16_t", 24 "uint16_t", "int32_t", "uint32_t", "int64_t", 25 "uint64_t", "float", "double"}; 26 27 ScalarType::ScalarType(Kind kind, Scope* parent) 28 : Type(parent, hidlIdentifiers[kind]), mKind(kind) {} 29 30 const ScalarType *ScalarType::resolveToScalarType() const { 31 return this; 32 } 33 34 bool ScalarType::isValidEnumStorageType() const { 35 // Only integer types. 36 return mKind >= KIND_INT8 && mKind <= KIND_UINT64; 37 } 38 39 bool ScalarType::isScalar() const { 40 return true; 41 } 42 43 bool ScalarType::isElidableType() const { 44 return true; 45 } 46 47 bool ScalarType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const { 48 return true; 49 } 50 51 std::string ScalarType::typeName() const { 52 return getCppStackType(); 53 } 54 55 std::string ScalarType::getCppType(StorageMode, bool) const { 56 static const char *const kName[] = { 57 "bool", 58 "int8_t", 59 "uint8_t", 60 "int16_t", 61 "uint16_t", 62 "int32_t", 63 "uint32_t", 64 "int64_t", 65 "uint64_t", 66 "float", 67 "double" 68 }; 69 70 return kName[mKind]; 71 } 72 73 std::string ScalarType::getJavaType(bool /* forInitializer */) const { 74 static const char *const kName[] = { 75 "boolean", 76 "byte", 77 "byte", 78 "short", 79 "short", 80 "int", 81 "int", 82 "long", 83 "long", 84 "float", 85 "double" 86 }; 87 88 return kName[mKind]; 89 } 90 91 std::string ScalarType::getJavaTypeClass() const { 92 static const char *const kName[] = { 93 "Boolean", 94 "Byte", 95 "Byte", 96 "Short", 97 "Short", 98 "Integer", 99 "Integer", 100 "Long", 101 "Long", 102 "Float", 103 "Double" 104 }; 105 106 return kName[mKind]; 107 } 108 109 std::string ScalarType::getJavaSuffix() const { 110 static const char *const kSuffix[] = { 111 "Bool", 112 "Int8", 113 "Int8", 114 "Int16", 115 "Int16", 116 "Int32", 117 "Int32", 118 "Int64", 119 "Int64", 120 "Float", 121 "Double" 122 }; 123 124 return kSuffix[mKind]; 125 } 126 127 std::string ScalarType::getVtsType() const { 128 return "TYPE_SCALAR"; 129 } 130 131 std::string ScalarType::getVtsScalarType() const { 132 static const char * const kName[] = { 133 "bool_t", 134 "int8_t", 135 "uint8_t", 136 "int16_t", 137 "uint16_t", 138 "int32_t", 139 "uint32_t", 140 "int64_t", 141 "uint64_t", 142 "float_t", 143 "double_t" 144 }; 145 146 return kName[mKind]; 147 } 148 149 void ScalarType::emitJavaFieldInitializer(Formatter& out, const std::string& fieldName) const { 150 const std::string typeName = getJavaType(false /* forInitializer */); 151 const std::string fieldDeclaration = typeName + " " + fieldName; 152 153 emitJavaFieldDefaultInitialValue(out, fieldDeclaration); 154 } 155 156 void ScalarType::emitJavaFieldDefaultInitialValue(Formatter& out, 157 const std::string& declaredFieldName) const { 158 static const char* const kInitialValue[] = { 159 "false", // boolean 160 "0", // byte 161 "0", // byte 162 "0", // short 163 "0", // short 164 "0", // int 165 "0", // int 166 "0L", // long 167 "0L", // long 168 "0.0f", // float 169 "0.0d" // double 170 }; 171 172 out << declaredFieldName << " = " << kInitialValue[mKind] << ";\n"; 173 } 174 175 void ScalarType::emitReaderWriter( 176 Formatter &out, 177 const std::string &name, 178 const std::string &parcelObj, 179 bool parcelObjIsPointer, 180 bool isReader, 181 ErrorMode mode) const { 182 emitReaderWriterWithCast( 183 out, 184 name, 185 parcelObj, 186 parcelObjIsPointer, 187 isReader, 188 mode, 189 false /* needsCast */); 190 } 191 192 void ScalarType::emitReaderWriterWithCast( 193 Formatter &out, 194 const std::string &name, 195 const std::string &parcelObj, 196 bool parcelObjIsPointer, 197 bool isReader, 198 ErrorMode mode, 199 bool needsCast) const { 200 static const char *const kSuffix[] = { 201 "Bool", 202 "Int8", 203 "Uint8", 204 "Int16", 205 "Uint16", 206 "Int32", 207 "Uint32", 208 "Int64", 209 "Uint64", 210 "Float", 211 "Double" 212 }; 213 214 const std::string parcelObjDeref = 215 parcelObj + (parcelObjIsPointer ? "->" : "."); 216 217 out << "_hidl_err = " 218 << parcelObjDeref 219 << (isReader ? "read" : "write") 220 << kSuffix[mKind] 221 << "("; 222 223 if (needsCast) { 224 out << "(" 225 << getCppStackType() 226 << (isReader ? " *)" : ")"); 227 } 228 229 if (isReader) { 230 out << "&"; 231 } 232 233 out << name 234 << ");\n"; 235 236 handleError(out, mode); 237 } 238 239 void ScalarType::emitHexDump( 240 Formatter &out, 241 const std::string &streamName, 242 const std::string &name) const { 243 out << streamName << " += toHexString(" << name << ");\n"; 244 } 245 246 void ScalarType::emitConvertToJavaHexString( 247 Formatter &out, 248 const std::string &name) const { 249 switch(mKind) { 250 case KIND_BOOL: { 251 out << "((" << name << ") ? \"0x1\" : \"0x0\")"; 252 break; 253 } 254 case KIND_INT8: // fallthrough 255 case KIND_UINT8: // fallthrough 256 case KIND_INT16: // fallthrough 257 case KIND_UINT16: { 258 // Because Byte and Short doesn't have toHexString, we have to use Integer.toHexString. 259 out << "Integer.toHexString(" << getJavaTypeClass() << ".toUnsignedInt((" 260 << getJavaType(false /* forInitializer */) << ")(" << name << ")))"; 261 break; 262 } 263 case KIND_INT32: // fallthrough 264 case KIND_UINT32: // fallthrough 265 case KIND_INT64: // fallthrough 266 case KIND_UINT64: { 267 out << getJavaTypeClass() << ".toHexString(" << name << ")"; 268 break; 269 } 270 case KIND_FLOAT: // fallthrough 271 case KIND_DOUBLE: // fallthrough 272 default: { 273 // no hex for floating point numbers. 274 out << name; 275 break; 276 } 277 } 278 } 279 280 void ScalarType::emitJavaFieldReaderWriter( 281 Formatter &out, 282 size_t /* depth */, 283 const std::string & /* parcelName */, 284 const std::string &blobName, 285 const std::string &fieldName, 286 const std::string &offset, 287 bool isReader) const { 288 if (isReader) { 289 out << fieldName 290 << " = " 291 << blobName 292 << ".get" 293 << getJavaSuffix() 294 << "(" 295 << offset 296 << ");\n"; 297 298 return; 299 } 300 301 out << blobName 302 << ".put" 303 << getJavaSuffix() 304 << "(" 305 << offset 306 << ", " 307 << fieldName 308 << ");\n"; 309 } 310 311 void ScalarType::emitVtsTypeDeclarations(Formatter& out) const { 312 out << "type: " << getVtsType() << "\n"; 313 out << "scalar_type: \"" << getVtsScalarType() << "\"\n"; 314 } 315 316 void ScalarType::getAlignmentAndSize(size_t *align, size_t *size) const { 317 static const size_t kAlign[] = { 318 1, // bool, this is NOT standardized! 319 1, // int8_t 320 1, // uint8_t 321 2, // int16_t 322 2, // uint16_t 323 4, // int32_t 324 4, // uint32_t 325 8, // int64_t 326 8, // uint64_t 327 4, // float 328 8 // double 329 }; 330 331 *align = *size = kAlign[mKind]; 332 } 333 334 ScalarType::Kind ScalarType::getKind() const { 335 return mKind; 336 } 337 338 } // namespace android 339 340