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