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