• 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,Scope * parent)23 ScalarType::ScalarType(Kind kind, Scope* parent) : Type(parent), mKind(kind) {}
24 
resolveToScalarType() const25 const ScalarType *ScalarType::resolveToScalarType() const {
26     return this;
27 }
28 
isValidEnumStorageType() const29 bool ScalarType::isValidEnumStorageType() const {
30     // Only integer types.
31     return mKind >= KIND_INT8 && mKind <= KIND_UINT64;
32 }
33 
isScalar() const34 bool ScalarType::isScalar() const {
35     return true;
36 }
37 
isElidableType() const38 bool ScalarType::isElidableType() const {
39     return true;
40 }
41 
deepCanCheckEquality(std::unordered_set<const Type * > *) const42 bool ScalarType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
43     return true;
44 }
45 
typeName() const46 std::string ScalarType::typeName() const {
47     return getCppStackType();
48 }
49 
getCppType(StorageMode,bool) const50 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 
getJavaType(bool) const68 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 
getJavaTypeClass() const86 std::string ScalarType::getJavaTypeClass() 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 
getJavaSuffix() const104 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 
getVtsType() const122 std::string ScalarType::getVtsType() const {
123     return "TYPE_SCALAR";
124 }
125 
getVtsScalarType() const126 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 
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const144 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 
emitReaderWriterWithCast(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode,bool needsCast) const161 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 
emitHexDump(Formatter & out,const std::string & streamName,const std::string & name) const208 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 
emitConvertToJavaHexString(Formatter & out,const std::string & name) const215 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(" << getJavaTypeClass() << ".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 << getJavaTypeClass() << ".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 
emitJavaFieldReaderWriter(Formatter & out,size_t,const std::string &,const std::string & blobName,const std::string & fieldName,const std::string & offset,bool isReader) const249 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 
emitVtsTypeDeclarations(Formatter & out) const280 void ScalarType::emitVtsTypeDeclarations(Formatter& out) const {
281     out << "type: " << getVtsType() << "\n";
282     out << "scalar_type: \"" << getVtsScalarType() << "\"\n";
283 }
284 
getAlignmentAndSize(size_t * align,size_t * size) const285 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 
getKind() const303 ScalarType::Kind ScalarType::getKind() const {
304     return mKind;
305 }
306 
307 }  // namespace android
308 
309