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