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