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 "StringType.h"
18
19 #include "HidlTypeAssertion.h"
20
21 #include <hidl-util/Formatter.h>
22
23 namespace android {
24
StringType(Scope * parent)25 StringType::StringType(Scope* parent) : Type(parent, "string") {}
26
isString() const27 bool StringType::isString() const {
28 return true;
29 }
30
deepCanCheckEquality(std::unordered_set<const Type * > *) const31 bool StringType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
32 return true;
33 }
34
typeName() const35 std::string StringType::typeName() const {
36 return "string";
37 }
38
getCppType(StorageMode mode,bool specifyNamespaces) const39 std::string StringType::getCppType(StorageMode mode,
40 bool specifyNamespaces) const {
41 const std::string base =
42 std::string(specifyNamespaces ? "::android::hardware::" : "")
43 + "hidl_string";
44
45 switch (mode) {
46 case StorageMode_Stack:
47 return base;
48
49 case StorageMode_Argument:
50 return "const " + base + "&";
51
52 case StorageMode_Result:
53 return "const " + base + "*";
54 }
55 }
56
getJavaType(bool) const57 std::string StringType::getJavaType(bool /* forInitializer */) const {
58 return "String";
59 }
60
getJavaSuffix() const61 std::string StringType::getJavaSuffix() const {
62 return "String";
63 }
64
getVtsType() const65 std::string StringType::getVtsType() const {
66 return "TYPE_STRING";
67 }
68
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const69 void StringType::emitReaderWriter(
70 Formatter &out,
71 const std::string &name,
72 const std::string &parcelObj,
73 bool parcelObjIsPointer,
74 bool isReader,
75 ErrorMode mode) const {
76 const std::string parentName = "_hidl_" + name + "_parent";
77 out << "size_t " << parentName << ";\n\n";
78
79 const std::string parcelObjDeref =
80 parcelObj + (parcelObjIsPointer ? "->" : ".");
81
82 if (isReader) {
83 out << "_hidl_err = "
84 << parcelObjDeref
85 << "readBuffer("
86 << "sizeof(*"
87 << name
88 << "), &"
89 << parentName
90 << ", "
91 << " reinterpret_cast<const void **>("
92 << "&" << name
93 << "));\n\n";
94
95 handleError(out, mode);
96 } else {
97 out << "_hidl_err = "
98 << parcelObjDeref
99 << "writeBuffer(&"
100 << name
101 << ", sizeof("
102 << name
103 << "), &"
104 << parentName
105 << ");\n";
106
107 handleError(out, mode);
108 }
109
110 emitReaderWriterEmbedded(
111 out,
112 0 /* depth */,
113 name,
114 name /* sanitizedName */,
115 isReader /* nameIsPointer */,
116 parcelObj,
117 parcelObjIsPointer,
118 isReader,
119 mode,
120 parentName,
121 "0 /* parentOffset */");
122 }
123
emitReaderWriterEmbedded(Formatter & out,size_t,const std::string & name,const std::string &,bool nameIsPointer,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode,const std::string & parentName,const std::string & offsetText) const124 void StringType::emitReaderWriterEmbedded(
125 Formatter &out,
126 size_t /* depth */,
127 const std::string &name,
128 const std::string & /*sanitizedName*/,
129 bool nameIsPointer,
130 const std::string &parcelObj,
131 bool parcelObjIsPointer,
132 bool isReader,
133 ErrorMode mode,
134 const std::string &parentName,
135 const std::string &offsetText) const {
136 emitReaderWriterEmbeddedForTypeName(
137 out,
138 name,
139 nameIsPointer,
140 parcelObj,
141 parcelObjIsPointer,
142 isReader,
143 mode,
144 parentName,
145 offsetText,
146 "::android::hardware::hidl_string",
147 "" /* childName */,
148 "::android::hardware");
149 }
150
emitJavaFieldInitializer(Formatter & out,const std::string & fieldName) const151 void StringType::emitJavaFieldInitializer(
152 Formatter &out, const std::string &fieldName) const {
153 emitJavaFieldDefaultInitialValue(out, "String " + fieldName);
154 }
155
emitJavaFieldDefaultInitialValue(Formatter & out,const std::string & declaredFieldName) const156 void StringType::emitJavaFieldDefaultInitialValue(
157 Formatter &out, const std::string &declaredFieldName) const {
158 out << declaredFieldName << " = new String();\n";
159 }
160
emitJavaFieldReaderWriter(Formatter & out,size_t,const std::string & parcelName,const std::string & blobName,const std::string & fieldName,const std::string & offset,bool isReader) const161 void StringType::emitJavaFieldReaderWriter(
162 Formatter &out,
163 size_t /* depth */,
164 const std::string &parcelName,
165 const std::string &blobName,
166 const std::string &fieldName,
167 const std::string &offset,
168 bool isReader) const {
169 if (isReader) {
170 out << fieldName
171 << " = "
172 << blobName
173 << ".getString("
174 << offset
175 << ");\n";
176
177 out << "\n"
178 << parcelName
179 << ".readEmbeddedBuffer(\n";
180
181 out.indent();
182 out.indent();
183
184 // hidl_string's embedded buffer is never null(able), because it defaults to a
185 // buffer containing an empty string.
186 out << "(" << getJavaTypeCast(fieldName) << ").getBytes().length + 1,\n"
187 << blobName
188 << ".handle(),\n"
189 << offset
190 << " + 0 /* offsetof(hidl_string, mBuffer) */,"
191 << "false /* nullable */);\n\n";
192
193 out.unindent();
194 out.unindent();
195
196 return;
197 }
198
199 out << blobName
200 << ".putString("
201 << offset
202 << ", "
203 << fieldName
204 << ");\n";
205 }
206
needsEmbeddedReadWrite() const207 bool StringType::needsEmbeddedReadWrite() const {
208 return true;
209 }
210
resultNeedsDeref() const211 bool StringType::resultNeedsDeref() const {
212 return true;
213 }
214
emitVtsTypeDeclarations(Formatter & out) const215 void StringType::emitVtsTypeDeclarations(Formatter& out) const {
216 out << "type: " << getVtsType() << "\n";
217 }
218
219 static HidlTypeAssertion assertion("hidl_string", 16 /* size */);
getAlignmentAndSize(size_t * align,size_t * size) const220 void StringType::getAlignmentAndSize(size_t *align, size_t *size) const {
221 *align = 8; // hidl_string
222 *size = assertion.size();
223 }
224
225 } // namespace android
226
227