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
addNamedTypesToSet(std::set<const FQName> &) const36 void ScalarType::addNamedTypesToSet(std::set<const FQName> &) const {
37 // do nothing
38 }
39
isScalar() const40 bool ScalarType::isScalar() const {
41 return true;
42 }
43
isElidableType() const44 bool ScalarType::isElidableType() const {
45 return true;
46 }
47
canCheckEquality() const48 bool ScalarType::canCheckEquality() const {
49 return true;
50 }
51
typeName() const52 std::string ScalarType::typeName() const {
53 return getCppStackType();
54 }
55
getCppType(StorageMode,bool) const56 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
getJavaType(bool) const74 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
getJavaWrapperType() const92 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
getJavaSuffix() const110 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
getVtsType() const128 std::string ScalarType::getVtsType() const {
129 return "TYPE_SCALAR";
130 }
131
getVtsScalarType() const132 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
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const150 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
emitReaderWriterWithCast(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode,bool needsCast) const167 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
emitHexDump(Formatter & out,const std::string & streamName,const std::string & name) const214 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
emitConvertToJavaHexString(Formatter & out,const std::string & name) const221 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
emitJavaFieldReaderWriter(Formatter & out,size_t,const std::string &,const std::string & blobName,const std::string & fieldName,const std::string & offset,bool isReader) const255 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
emitVtsTypeDeclarations(Formatter & out) const286 status_t ScalarType::emitVtsTypeDeclarations(Formatter &out) const {
287 out << "type: " << getVtsType() << "\n";
288 out << "scalar_type: \"" << getVtsScalarType() << "\"\n";
289 return OK;
290 }
291
getAlignmentAndSize(size_t * align,size_t * size) const292 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
getKind() const310 ScalarType::Kind ScalarType::getKind() const {
311 return mKind;
312 }
313
314 } // namespace android
315
316