/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ScalarType.h" #include namespace android { static const char* const hidlIdentifiers[] = {"bool", "int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t", "float", "double"}; ScalarType::ScalarType(Kind kind, Scope* parent) : Type(parent, hidlIdentifiers[kind]), mKind(kind) {} const ScalarType *ScalarType::resolveToScalarType() const { return this; } bool ScalarType::isValidEnumStorageType() const { // Only integer types. return mKind >= KIND_INT8 && mKind <= KIND_UINT64; } bool ScalarType::isScalar() const { return true; } bool ScalarType::isElidableType() const { return true; } bool ScalarType::deepCanCheckEquality(std::unordered_set* /* visited */) const { return true; } std::string ScalarType::typeName() const { return getCppStackType(); } std::string ScalarType::getCppType(StorageMode, bool) const { static const char *const kName[] = { "bool", "int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t", "float", "double" }; return kName[mKind]; } std::string ScalarType::getJavaType(bool /* forInitializer */) const { static const char *const kName[] = { "boolean", "byte", "byte", "short", "short", "int", "int", "long", "long", "float", "double" }; return kName[mKind]; } std::string ScalarType::getJavaTypeClass() const { static const char *const kName[] = { "Boolean", "Byte", "Byte", "Short", "Short", "Integer", "Integer", "Long", "Long", "Float", "Double" }; return kName[mKind]; } std::string ScalarType::getJavaSuffix() const { static const char *const kSuffix[] = { "Bool", "Int8", "Int8", "Int16", "Int16", "Int32", "Int32", "Int64", "Int64", "Float", "Double" }; return kSuffix[mKind]; } std::string ScalarType::getVtsType() const { return "TYPE_SCALAR"; } std::string ScalarType::getVtsScalarType() const { static const char * const kName[] = { "bool_t", "int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t", "int64_t", "uint64_t", "float_t", "double_t" }; return kName[mKind]; } void ScalarType::emitJavaFieldInitializer(Formatter& out, const std::string& fieldName) const { const std::string typeName = getJavaType(false /* forInitializer */); const std::string fieldDeclaration = typeName + " " + fieldName; emitJavaFieldDefaultInitialValue(out, fieldDeclaration); } void ScalarType::emitJavaFieldDefaultInitialValue(Formatter& out, const std::string& declaredFieldName) const { static const char* const kInitialValue[] = { "false", // boolean "0", // byte "0", // byte "0", // short "0", // short "0", // int "0", // int "0L", // long "0L", // long "0.0f", // float "0.0d" // double }; out << declaredFieldName << " = " << kInitialValue[mKind] << ";\n"; } void ScalarType::emitReaderWriter( Formatter &out, const std::string &name, const std::string &parcelObj, bool parcelObjIsPointer, bool isReader, ErrorMode mode) const { emitReaderWriterWithCast( out, name, parcelObj, parcelObjIsPointer, isReader, mode, false /* needsCast */); } void ScalarType::emitReaderWriterWithCast( Formatter &out, const std::string &name, const std::string &parcelObj, bool parcelObjIsPointer, bool isReader, ErrorMode mode, bool needsCast) const { static const char *const kSuffix[] = { "Bool", "Int8", "Uint8", "Int16", "Uint16", "Int32", "Uint32", "Int64", "Uint64", "Float", "Double" }; const std::string parcelObjDeref = parcelObj + (parcelObjIsPointer ? "->" : "."); out << "_hidl_err = " << parcelObjDeref << (isReader ? "read" : "write") << kSuffix[mKind] << "("; if (needsCast) { out << "(" << getCppStackType() << (isReader ? " *)" : ")"); } if (isReader) { out << "&"; } out << name << ");\n"; handleError(out, mode); } void ScalarType::emitHexDump( Formatter &out, const std::string &streamName, const std::string &name) const { out << streamName << " += toHexString(" << name << ");\n"; } void ScalarType::emitConvertToJavaHexString( Formatter &out, const std::string &name) const { switch(mKind) { case KIND_BOOL: { out << "((" << name << ") ? \"0x1\" : \"0x0\")"; break; } case KIND_INT8: // fallthrough case KIND_UINT8: // fallthrough case KIND_INT16: // fallthrough case KIND_UINT16: { // Because Byte and Short doesn't have toHexString, we have to use Integer.toHexString. out << "Integer.toHexString(" << getJavaTypeClass() << ".toUnsignedInt((" << getJavaType(false /* forInitializer */) << ")(" << name << ")))"; break; } case KIND_INT32: // fallthrough case KIND_UINT32: // fallthrough case KIND_INT64: // fallthrough case KIND_UINT64: { out << getJavaTypeClass() << ".toHexString(" << name << ")"; break; } case KIND_FLOAT: // fallthrough case KIND_DOUBLE: // fallthrough default: { // no hex for floating point numbers. out << name; break; } } } void ScalarType::emitJavaFieldReaderWriter( Formatter &out, size_t /* depth */, const std::string & /* parcelName */, const std::string &blobName, const std::string &fieldName, const std::string &offset, bool isReader) const { if (isReader) { out << fieldName << " = " << blobName << ".get" << getJavaSuffix() << "(" << offset << ");\n"; return; } out << blobName << ".put" << getJavaSuffix() << "(" << offset << ", " << fieldName << ");\n"; } void ScalarType::emitVtsTypeDeclarations(Formatter& out) const { out << "type: " << getVtsType() << "\n"; out << "scalar_type: \"" << getVtsScalarType() << "\"\n"; } void ScalarType::getAlignmentAndSize(size_t *align, size_t *size) const { static const size_t kAlign[] = { 1, // bool, this is NOT standardized! 1, // int8_t 1, // uint8_t 2, // int16_t 2, // uint16_t 4, // int32_t 4, // uint32_t 8, // int64_t 8, // uint64_t 4, // float 8 // double }; *align = *size = kAlign[mKind]; } ScalarType::Kind ScalarType::getKind() const { return mKind; } } // namespace android