| /* |
| * 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 { |
| |
| ScalarType::ScalarType(Kind kind, Scope* parent) : Type(parent), 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::getJavaWrapperType() 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::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(" << getJavaWrapperType() << ".toUnsignedInt((" |
| << getJavaType(false /* forInitializer */) << ")(" << name << ")))"; |
| break; |
| } |
| case KIND_INT32: // fallthrough |
| case KIND_UINT32: // fallthrough |
| case KIND_INT64: // fallthrough |
| case KIND_UINT64: { |
| out << getJavaWrapperType() << ".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 |
| |