340 lines
8.2 KiB
C++
340 lines
8.2 KiB
C++
/*
|
|
* 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 <hidl-util/Formatter.h>
|
|
|
|
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<const Type*>* /* 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
|
|
|