• 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 "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