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