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