1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hdi_array_type_emitter.h"
17
18 namespace OHOS {
19 namespace Idl {
GetTypeKind()20 TypeKind HdiArrayTypeEmitter::GetTypeKind()
21 {
22 return TypeKind::TYPE_ARRAY;
23 }
24
EmitCType(TypeMode mode) const25 std::string HdiArrayTypeEmitter::EmitCType(TypeMode mode) const
26 {
27 switch (mode) {
28 case TypeMode::NO_MODE:
29 return StringHelper::Format("%s*", elementEmitter_->EmitCType(TypeMode::NO_MODE).c_str());
30 case TypeMode::PARAM_IN: {
31 TypeKind elemType = elementEmitter_->GetTypeKind();
32 if ((elemType == TypeKind::TYPE_STRING) || (elemType == TypeKind::TYPE_NATIVE_BUFFER)) {
33 return StringHelper::Format("%s*", elementEmitter_->EmitCType(TypeMode::NO_MODE).c_str());
34 }
35 return StringHelper::Format("const %s*", elementEmitter_->EmitCType(TypeMode::NO_MODE).c_str());
36 }
37 case TypeMode::PARAM_OUT:
38 return StringHelper::Format("%s*", elementEmitter_->EmitCType(TypeMode::NO_MODE).c_str());
39 case TypeMode::LOCAL_VAR:
40 return StringHelper::Format("%s*", elementEmitter_->EmitCType(TypeMode::NO_MODE).c_str());
41 default:
42 return "unknown type";
43 }
44 }
45
EmitCppType(TypeMode mode) const46 std::string HdiArrayTypeEmitter::EmitCppType(TypeMode mode) const
47 {
48 switch (mode) {
49 case TypeMode::NO_MODE:
50 return StringHelper::Format("std::vector<%s>", elementEmitter_->EmitCppType().c_str());
51 case TypeMode::PARAM_IN:
52 return StringHelper::Format("const std::vector<%s>&", elementEmitter_->EmitCppType().c_str());
53 case TypeMode::PARAM_OUT:
54 return StringHelper::Format("std::vector<%s>&", elementEmitter_->EmitCppType().c_str());
55 case TypeMode::LOCAL_VAR:
56 return StringHelper::Format("std::vector<%s>", elementEmitter_->EmitCppType().c_str());
57 default:
58 return "unknow type";
59 }
60 }
61
EmitJavaType(TypeMode mode,bool isInnerType) const62 std::string HdiArrayTypeEmitter::EmitJavaType(TypeMode mode, bool isInnerType) const
63 {
64 return StringHelper::Format("%s[]", elementEmitter_->EmitJavaType(TypeMode::NO_MODE, false).c_str());
65 }
66
EmitCWriteVar(TypeMode mode,const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const67 void HdiArrayTypeEmitter::EmitCWriteVar(TypeMode mode, const std::string &name,
68 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
69 {
70 std::string parcelName = (mode == TypeMode::PARAM_IN) ? dataParcelName_ : replyParcelName_;
71 std::string lenName = StringHelper::Format("%sLen", name.c_str());
72 TypeKind elemType = elementEmitter_->GetTypeKind();
73 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
74 sb.Append(prefix).AppendFormat("if (!WritePodArray(%s, %s, sizeof(%s), %s)) {\n", parcelName.c_str(),
75 name.c_str(), elementEmitter_->EmitCType().c_str(), lenName.c_str());
76 sb.Append(prefix + TAB)
77 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
78 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
79 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
80 sb.Append(prefix).Append("}\n");
81 return;
82 } else if (elemType == TypeKind::TYPE_STRING) {
83 sb.Append(prefix).AppendFormat(
84 "if (!WriteStringArray(%s, %s, %s)) {\n", parcelName.c_str(), name.c_str(), lenName.c_str());
85 sb.Append(prefix + TAB)
86 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
87 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
88 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
89 sb.Append(prefix).Append("}\n");
90 return;
91 }
92
93 sb.Append(prefix).AppendFormat("if ((%s == NULL && %s != 0) || (%s != NULL && %s == 0)) {\n",
94 name.c_str(), lenName.c_str(), name.c_str(), lenName.c_str());
95 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: %s is invalid\", __func__);\n", name.c_str());
96 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
97 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
98 sb.Append(prefix).Append("}\n\n");
99
100 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint32(%s, %s)) {\n", parcelName.c_str(), lenName.c_str());
101 sb.Append(prefix + TAB)
102 .AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
103 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
104 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
105 sb.Append(prefix).Append("}\n\n");
106
107 if (Options::GetInstance().DoGenerateKernelCode()) {
108 sb.Append(prefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
109 } else {
110 sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
111 }
112
113 std::string elementName = "";
114 if ((elemType == TypeKind::TYPE_STRUCT) || (elemType == TypeKind::TYPE_UNION)) {
115 elementName = StringHelper::Format("&%s[i]", name.c_str());
116 } else {
117 elementName = StringHelper::Format("%s[i]", name.c_str());
118 }
119 elementEmitter_->EmitCWriteVar(mode, elementName, gotoLabel, sb, prefix + TAB);
120 sb.Append(prefix).Append("}\n");
121 }
122
EmitCProxyWriteOutVar(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const123 void HdiArrayTypeEmitter::EmitCProxyWriteOutVar(const std::string &name, const std::string &gotoLabel,
124 StringBuilder &sb, const std::string &prefix) const
125 {
126 std::string lenName = StringHelper::Format("%sLen", name.c_str());
127 sb.Append(prefix).AppendFormat("if (%s == NULL || %s == NULL || *%s == 0) {\n", name.c_str(), lenName.c_str(),
128 lenName.c_str());
129 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: %s is invalid\", __func__);\n", name.c_str());
130 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
131 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
132 sb.Append(prefix).Append("}\n\n");
133 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint32(%s, *%s)) {\n", dataParcelName_.c_str(), lenName.c_str());
134 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", lenName.c_str());
135 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
136 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
137 sb.Append(prefix).Append("}\n\n");
138 }
139
EmitCProxyReadVar(const std::string & name,bool isInnerType,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const140 void HdiArrayTypeEmitter::EmitCProxyReadVar(const std::string &name, bool isInnerType, const std::string &gotoLabel,
141 StringBuilder &sb, const std::string &prefix) const
142 {
143 std::string lenName = StringHelper::Format("%sLen", name.c_str());
144 TypeKind elemType = elementEmitter_->GetTypeKind();
145 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
146 sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, %s, sizeof(%s), %s)) {\n", replyParcelName_.c_str(),
147 name.c_str(), elementEmitter_->EmitCType().c_str(), lenName.c_str());
148 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
149 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
150 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
151 sb.Append(prefix).Append("}\n");
152 return;
153 } else if (elemType == TypeKind::TYPE_STRING) {
154 sb.Append(prefix).AppendFormat(
155 "if (!ReadStringArray(%s, %s, %s)) {\n", replyParcelName_.c_str(), name.c_str(), lenName.c_str());
156 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
157 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
158 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
159 sb.Append(prefix).Append("}\n");
160 return;
161 }
162
163 sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, %s)) {\n", replyParcelName_.c_str(), lenName.c_str());
164 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.c_str());
165 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
166 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
167 sb.Append(prefix).Append("}\n\n");
168
169 sb.Append(prefix).AppendFormat("%s(*%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
170 CHECK_VALUE_RET_GOTO_MACRO, lenName.c_str(), MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCType().c_str(),
171 errorCodeName_.c_str(), gotoLabel.c_str());
172
173 if (Options::GetInstance().DoGenerateKernelCode()) {
174 sb.Append(prefix).AppendFormat("for (i = 0; i < *%s; i++) {\n", lenName.c_str());
175 } else {
176 sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < *%s; i++) {\n", lenName.c_str());
177 }
178
179 if (elemType == TypeKind::TYPE_STRUCT) {
180 std::string element = StringHelper::Format("&%s[i]", name.c_str());
181 elementEmitter_->EmitCProxyReadVar(element, true, gotoLabel, sb, prefix + TAB);
182 } else if ((elemType == TypeKind::TYPE_FILEDESCRIPTOR) || (elemType == TypeKind::TYPE_NATIVE_BUFFER)) {
183 std::string element = StringHelper::Format("%s[i]", name.c_str());
184 elementEmitter_->EmitCProxyReadVar(element, true, gotoLabel, sb, prefix + TAB);
185 } else {
186 std::string element = StringHelper::Format("&%s[i]", name.c_str());
187 elementEmitter_->EmitCProxyReadVar(element, true, gotoLabel, sb, prefix + TAB);
188 }
189 sb.Append(prefix).Append("}\n");
190 }
191
EmitCStubReadVar(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const192 void HdiArrayTypeEmitter::EmitCStubReadVar(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
193 const std::string &prefix) const
194 {
195 std::string lenName = StringHelper::Format("%sLen", name.c_str());
196 TypeKind elemType = elementEmitter_->GetTypeKind();
197 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
198 sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, (void **)&%s, sizeof(%s), &%s)) {\n",
199 dataParcelName_.c_str(), name.c_str(), elementEmitter_->EmitCType().c_str(), lenName.c_str());
200 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
201 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
202 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
203 sb.Append(prefix).Append("}\n");
204 return;
205 } else if (elemType == TypeKind::TYPE_STRING) {
206 sb.Append(prefix).AppendFormat(
207 "if (!ReadStringArray(%s, &%s, &%s)) {\n", dataParcelName_.c_str(), name.c_str(), lenName.c_str());
208 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
209 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
210 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
211 sb.Append(prefix).Append("}\n");
212 return;
213 }
214
215 sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, &%s)) {\n", dataParcelName_.c_str(), lenName.c_str());
216 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.c_str());
217 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
218 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
219 sb.Append(prefix).Append("}\n\n");
220 sb.Append(prefix).AppendFormat("%s(%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
221 CHECK_VALUE_RET_GOTO_MACRO, lenName.c_str(), MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCType().c_str(),
222 errorCodeName_.c_str(), gotoLabel.c_str());
223
224 sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.c_str());
225 EmitCMallocVar(name, lenName, gotoLabel, sb, prefix + TAB);
226 sb.Append("\n");
227
228 if (Options::GetInstance().DoGenerateKernelCode()) {
229 sb.Append(prefix + TAB).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
230 } else {
231 sb.Append(prefix + TAB).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
232 }
233 if (elemType == TypeKind::TYPE_STRUCT) {
234 std::string element = StringHelper::Format("&%s[i]", name.c_str());
235 elementEmitter_->EmitCStubReadVar(element, gotoLabel, sb, prefix + TAB + TAB);
236 } else if ((elemType == TypeKind::TYPE_FILEDESCRIPTOR) || (elemType == TypeKind::TYPE_NATIVE_BUFFER)) {
237 std::string element = StringHelper::Format("%s[i]", name.c_str());
238 elementEmitter_->EmitCStubReadVar(element, gotoLabel, sb, prefix + TAB + TAB);
239 } else {
240 std::string element = StringHelper::Format("&%s[i]", name.c_str());
241 elementEmitter_->EmitCStubReadVar(element, gotoLabel, sb, prefix + TAB + TAB);
242 }
243 sb.Append(prefix + TAB).Append("}\n");
244 sb.Append(prefix).Append("}\n");
245 }
246
EmitCStubReadOutVar(const std::string & memFlagName,const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const247 void HdiArrayTypeEmitter::EmitCStubReadOutVar(const std::string &memFlagName, const std::string &name,
248 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
249 {
250 std::string lenName = StringHelper::Format("%sLen", name.c_str());
251
252 sb.Append(prefix).AppendFormat("if (%s) {\n", memFlagName.c_str());
253 sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufReadUint32(%s, &%s)) {\n",
254 dataParcelName_.c_str(), lenName.c_str());
255 sb.Append(prefix + TAB + TAB)
256 .AppendFormat("HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.c_str());
257 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
258 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
259 sb.Append(prefix + TAB).Append("}\n\n");
260 sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
261 CHECK_VALUE_RET_GOTO_MACRO, lenName.c_str(), MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCType().c_str(),
262 errorCodeName_.c_str(), gotoLabel.c_str());
263
264 sb.Append(prefix + TAB).AppendFormat("if (%s > 0) {\n", lenName.c_str());
265 EmitCMallocVar(name, lenName, gotoLabel, sb, prefix + TAB + TAB);
266 sb.Append(prefix + TAB).Append("}\n");
267 sb.Append(prefix).Append("} else {\n");
268 sb.Append(prefix + TAB).AppendFormat("%s = (%s*)OsalMemCalloc(%s);\n", name.c_str(),
269 elementEmitter_->EmitCType().c_str(), MAX_BUFF_SIZE_MACRO);
270 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", name.c_str());
271 sb.Append(prefix + TAB + TAB)
272 .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", name.c_str());
273 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", errorCodeName_.c_str());
274 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
275 sb.Append(prefix + TAB).Append("}\n");
276
277 sb.Append(prefix + TAB).AppendFormat("%sLen = (%s / sizeof(%s));\n", name.c_str(),
278 MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCType().c_str());
279 sb.Append(prefix).Append("}\n\n");
280 }
281
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const282 void HdiArrayTypeEmitter::EmitCppWriteVar(const std::string &parcelName, const std::string &name,
283 StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
284 {
285 TypeKind elemType = elementEmitter_->GetTypeKind();
286 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
287 sb.Append(prefix).AppendFormat("if (!WritePodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
288 sb.Append(prefix + TAB)
289 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
290 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
291 sb.Append(prefix).Append("}\n");
292 return;
293 }
294
295 sb.Append(prefix).AppendFormat("if (!%s.WriteUint32(%s.size())) {\n", parcelName.c_str(), name.c_str());
296 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s size failed!\", __func__);\n", name.c_str());
297 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
298 sb.Append(prefix).Append("}\n");
299
300 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
301 sb.Append(prefix).AppendFormat("if (!%s.empty()) {\n", name.c_str());
302 sb.Append(prefix + TAB).AppendFormat("if (!%s.WriteUnpadBuffer(", parcelName.c_str());
303 sb.AppendFormat("(const void*)%s.data(), sizeof(%s) * %s.size())) {\n", name.c_str(),
304 elementEmitter_->EmitCppType().c_str(), name.c_str());
305 sb.Append(prefix + TAB + TAB)
306 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
307 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
308 sb.Append(prefix + TAB).Append("}\n");
309 sb.Append(prefix).Append("}\n");
310 } else {
311 std::string elementName = StringHelper::Format("it%d", innerLevel++);
312 sb.Append(prefix).AppendFormat("for (const auto& %s : %s) {\n", elementName.c_str(), name.c_str());
313 elementEmitter_->EmitCppWriteVar(parcelName, elementName, sb, prefix + TAB, innerLevel);
314 sb.Append(prefix).Append("}\n");
315 }
316 }
317
EmitCppReadVar(const std::string & name,StringBuilder & sb,const std::string & prefix,TypeMode mode,unsigned int innerLevel) const318 void HdiArrayTypeEmitter::EmitCppReadVar(const std::string &name, StringBuilder &sb, const std::string &prefix,
319 TypeMode mode, unsigned int innerLevel) const
320 {
321 std::string parcelName = (mode == TypeMode::PARAM_IN) ? dataParcelName_ : replyParcelName_;
322 if ((mode == TypeMode::PARAM_IN) || (innerLevel > 0)) {
323 sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().c_str(), name.c_str());
324 }
325
326 if ((elementEmitter_->GetTypeKind() != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
327 sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
328 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
329 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
330 sb.Append(prefix).Append("}\n");
331 return;
332 }
333
334 sb.Append(prefix).AppendFormat("uint32_t %sSize = 0;\n", name.c_str());
335 sb.Append(prefix).AppendFormat("if (!%s.ReadUint32(%sSize)) {\n", parcelName.c_str(), name.c_str());
336 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
337 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
338 sb.Append(prefix).Append("}\n\n");
339 sb.Append(prefix).AppendFormat("%s(%sSize, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
340 CHECK_VALUE_RETURN_MACRO, name.c_str(), MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCppType().c_str());
341 sb.Append(prefix).AppendFormat("%s.clear();\n", name.c_str());
342 sb.Append(prefix).AppendFormat("%s.reserve(%sSize);\n", name.c_str(), name.c_str());
343 sb.Append(prefix).AppendFormat(
344 "for (uint32_t i%d = 0; i%d < %sSize; ++i%d) {\n", innerLevel, innerLevel, name.c_str(), innerLevel);
345 std::string valueName = StringHelper::Format("value%d", innerLevel++);
346 elementEmitter_->EmitCppReadVar(valueName, sb, prefix + TAB, mode, innerLevel);
347 sb.Append(prefix + TAB).AppendFormat("%s.push_back(%s);\n", name.c_str(), valueName.c_str());
348 sb.Append(prefix).Append("}\n");
349 }
350
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const351 void HdiArrayTypeEmitter::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
352 {
353 std::string lenName = StringHelper::Format("%sLen", name.c_str());
354 TypeKind elemType = elementEmitter_->GetTypeKind();
355 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
356 sb.Append(prefix).AppendFormat("if (!WritePodArray(data, %s, sizeof(%s), %s)) {\n", name.c_str(),
357 elementEmitter_->EmitCType().c_str(), lenName.c_str());
358 sb.Append(prefix + TAB)
359 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
360 sb.Append(prefix + TAB).Append("return false;\n");
361 sb.Append(prefix).Append("}\n");
362 return;
363 } else if (elemType == TypeKind::TYPE_STRING) {
364 sb.Append(prefix).AppendFormat("if (!WriteStringArray(data, %s, %s)) {\n", name.c_str(), lenName.c_str());
365 sb.Append(prefix + TAB)
366 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
367 sb.Append(prefix + TAB).Append("return false;\n");
368 sb.Append(prefix).Append("}\n");
369 return;
370 }
371
372 sb.Append(prefix).AppendFormat("if (%s > %s / sizeof(%s) || !HdfSbufWriteUint32(data, %s)) {\n", lenName.c_str(),
373 MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCType().c_str(), lenName.c_str());
374 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", lenName.c_str());
375 sb.Append(prefix + TAB).Append("return false;\n");
376 sb.Append(prefix).Append("}\n\n");
377
378 sb.Append(prefix).AppendFormat("if ((%s == NULL && %s != 0) || (%s != NULL && %s == 0)) {\n",
379 name.c_str(), lenName.c_str(), name.c_str(), lenName.c_str());
380 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: %s is invalid\", __func__);\n", name.c_str());
381 sb.Append(prefix + TAB).Append("return false;\n");
382 sb.Append(prefix).Append("}\n\n");
383
384 if (Options::GetInstance().DoGenerateKernelCode()) {
385 sb.Append(prefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
386 } else {
387 sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
388 }
389
390 std::string elementName = StringHelper::Format("(%s)[i]", name.c_str());
391 elementEmitter_->EmitCMarshalling(elementName, sb, prefix + TAB);
392 sb.Append(prefix).Append("}\n");
393 }
394
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const395 void HdiArrayTypeEmitter::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel,
396 StringBuilder &sb, const std::string &prefix, std::vector<std::string> &freeObjStatements) const
397 {
398 std::string lenName = StringHelper::Format("%sLen", name.c_str());
399 TypeKind elemType = elementEmitter_->GetTypeKind();
400 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
401 sb.Append(prefix).AppendFormat("if (!ReadPodArray(data, (void**)&%s, sizeof(%s), &%s)) {\n", name.c_str(),
402 elementEmitter_->EmitCType().c_str(), lenName.c_str());
403 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
404 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
405 sb.Append(prefix).Append("}\n");
406 return;
407 } else if (elemType == TypeKind::TYPE_STRING) {
408 sb.Append(prefix).AppendFormat("if (!ReadStringArray(data, &%s, &%s)) {\n", name.c_str(), lenName.c_str());
409 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
410 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
411 sb.Append(prefix).Append("}\n");
412 return;
413 }
414
415 EmitCElementUnMarshallingReadLen(lenName, gotoLabel, sb, prefix);
416 sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.c_str());
417 std::string newPrefix = prefix + TAB;
418
419 sb.Append(newPrefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * %s);\n", name.c_str(),
420 elementEmitter_->EmitCType().c_str(), elementEmitter_->EmitCType().c_str(), lenName.c_str());
421 sb.Append(newPrefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
422 sb.Append(newPrefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
423 sb.Append(newPrefix).Append("}\n");
424 freeObjStatements.push_back(StringHelper::Format("OsalMemFree(%s);\n", name.c_str()));
425
426 if (Options::GetInstance().DoGenerateKernelCode()) {
427 sb.Append(newPrefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
428 } else {
429 sb.Append(newPrefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
430 }
431
432 if (elemType == TypeKind::TYPE_STRING) {
433 EmitCStringElementUnMarshalling(name, gotoLabel, sb, newPrefix + TAB, freeObjStatements);
434 } else if (elemType == TypeKind::TYPE_STRUCT) {
435 std::string element = StringHelper::Format("&%s[i]", name.c_str());
436 elementEmitter_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + TAB, freeObjStatements);
437 } else {
438 std::string element = StringHelper::Format("%s[i]", name.c_str());
439 elementEmitter_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + TAB, freeObjStatements);
440 }
441 sb.Append(newPrefix).Append("}\n");
442 sb.Append(prefix).Append("}\n");
443 freeObjStatements.pop_back();
444 }
445
EmitCElementUnMarshallingReadLen(const std::string & lenName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const446 void HdiArrayTypeEmitter::EmitCElementUnMarshallingReadLen(const std::string &lenName, const std::string &gotoLabel,
447 StringBuilder &sb, const std::string &prefix) const
448 {
449 sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(data, &%s)) {\n", lenName.c_str());
450 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", lenName.c_str());
451 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
452 sb.Append(prefix).Append("}\n");
453
454 sb.Append(prefix).AppendFormat("if (%s > %s / sizeof(%s)) {\n", lenName.c_str(), MAX_BUFF_SIZE_MACRO,
455 elementEmitter_->EmitCType().c_str());
456 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: %s is invalid data\", __func__);\n", lenName.c_str());
457 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
458 sb.Append(prefix).Append("}\n");
459 }
460
EmitCStringElementUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & newPrefix,std::vector<std::string> & freeObjStatements) const461 void HdiArrayTypeEmitter::EmitCStringElementUnMarshalling(const std::string &name, const std::string &gotoLabel,
462 StringBuilder &sb, const std::string &newPrefix, std::vector<std::string> &freeObjStatements) const
463 {
464 std::string element = StringHelper::Format("%sElement", name.c_str());
465 elementEmitter_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix, freeObjStatements);
466 if (Options::GetInstance().DoGenerateKernelCode()) {
467 sb.Append(newPrefix).AppendFormat(
468 "%s[i] = (char*)OsalMemCalloc(strlen(%s) + 1);\n", name.c_str(), element.c_str());
469 sb.Append(newPrefix).AppendFormat("if (%s[i] == NULL) {\n", name.c_str());
470 sb.Append(newPrefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
471 sb.Append(newPrefix).Append("}\n\n");
472 sb.Append(newPrefix).AppendFormat(
473 "if (strcpy_s((%s)[i], (strlen(%s) + 1), %s) != EOK) {\n", name.c_str(), element.c_str(), element.c_str());
474 sb.Append(newPrefix + TAB)
475 .AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", element.c_str());
476 sb.Append(newPrefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
477 sb.Append(newPrefix).Append("}\n");
478 } else {
479 sb.Append(newPrefix).Append(TAB).AppendFormat("%s[i] = strdup(%s);\n", name.c_str(), element.c_str());
480 }
481 }
482
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const483 void HdiArrayTypeEmitter::EmitCppMarshalling(const std::string &parcelName, const std::string &name,
484 StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
485 {
486 if ((elementEmitter_->GetTypeKind() != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
487 sb.Append(prefix).AppendFormat("if (!WritePodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
488 sb.Append(prefix + TAB)
489 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
490 sb.Append(prefix + TAB).Append("return false;\n");
491 sb.Append(prefix).Append("}\n");
492 return;
493 }
494
495 sb.Append(prefix).AppendFormat("if (!%s.WriteUint32(%s.size())) {\n", parcelName.c_str(), name.c_str());
496 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed write %s.size\", __func__);\n", name.c_str());
497 sb.Append(prefix + TAB).Append("return false;\n");
498 sb.Append(prefix).Append("}\n");
499 std::string elementName = StringHelper::Format("it%d", innerLevel++);
500 sb.Append(prefix).AppendFormat("for (const auto& %s : %s) {\n", elementName.c_str(), name.c_str());
501 elementEmitter_->EmitCppMarshalling(parcelName, elementName, sb, prefix + TAB, innerLevel);
502 sb.Append(prefix).Append("}\n");
503 }
504
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const505 void HdiArrayTypeEmitter::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name,
506 StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
507 {
508 size_t index = name.find('.');
509 std::string memberName = (index == std::string::npos) ? name : StringHelper::SubStr(name, index + 1);
510 std::string sizeName = StringHelper::Format("%sSize", memberName.c_str());
511 if (innerLevel > 0) {
512 sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().c_str(), memberName.c_str());
513 }
514
515 TypeKind elemType = elementEmitter_->GetTypeKind();
516 if ((elemType != TypeKind::TYPE_BOOLEAN) && elementEmitter_->IsPod()) {
517 sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
518 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
519 sb.Append(prefix + TAB).Append("return false;\n");
520 sb.Append(prefix).Append("}\n");
521 return;
522 }
523
524 sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", sizeName.c_str());
525 sb.Append(prefix).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), sizeName.c_str());
526 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
527 sb.Append(prefix + TAB).Append("return false;\n");
528 sb.Append(prefix).Append("}\n\n");
529 sb.Append(prefix).AppendFormat("%s(%s, >, %s / sizeof(%s), false);\n", CHECK_VALUE_RETURN_MACRO, sizeName.c_str(),
530 MAX_BUFF_SIZE_MACRO, elementEmitter_->EmitCppType().c_str());
531 sb.Append(prefix).AppendFormat("%s.clear();\n", name.c_str());
532 sb.Append(prefix).AppendFormat("%s.reserve(%s);\n", name.c_str(), sizeName.c_str());
533 sb.Append(prefix).AppendFormat(
534 "for (uint32_t i%d = 0; i%d < %s; ++i%d) {\n", innerLevel, innerLevel, sizeName.c_str(), innerLevel);
535 std::string valueName = StringHelper::Format("value%d", innerLevel++);
536 if (elemType == TypeKind::TYPE_STRUCT) {
537 sb.Append(prefix + TAB).AppendFormat("%s %s;\n", elementEmitter_->EmitCppType().c_str(), valueName.c_str());
538 }
539 elementEmitter_->EmitCppUnMarshalling(parcelName, valueName, sb, prefix + TAB, innerLevel);
540 sb.Append(prefix + TAB).AppendFormat("%s.push_back(%s);\n", name.c_str(), valueName.c_str());
541
542 sb.Append(prefix).Append("}\n");
543 }
544
EmitMemoryRecycle(const std::string & name,bool ownership,StringBuilder & sb,const std::string & prefix) const545 void HdiArrayTypeEmitter::EmitMemoryRecycle(
546 const std::string &name, bool ownership, StringBuilder &sb, const std::string &prefix) const
547 {
548 std::string varName = name;
549 sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", varName.c_str());
550 auto elementTypeNeedFree = [this]() -> bool {
551 if (elementEmitter_->IsPod()) {
552 return false;
553 }
554
555 TypeKind elemType = elementEmitter_->GetTypeKind();
556 if ((elemType == TypeKind::TYPE_STRUCT) || (elemType == TypeKind::TYPE_STRING) ||
557 (elemType == TypeKind::TYPE_NATIVE_BUFFER)) {
558 return true;
559 }
560 return false;
561 };
562 if (elementTypeNeedFree()) {
563 if (Options::GetInstance().DoGenerateKernelCode()) {
564 sb.Append(prefix + TAB).AppendFormat("for (i = 0; i < %sLen; i++) {\n", name.c_str());
565 } else {
566 sb.Append(prefix + TAB).AppendFormat("for (uint32_t i = 0; i < %sLen; i++) {\n", name.c_str());
567 }
568
569 std::string elementName = StringHelper::Format("%s[i]", varName.c_str());
570 elementEmitter_->EmitMemoryRecycle(elementName, false, sb, prefix + TAB + TAB);
571 sb.Append(prefix + TAB).Append("}\n");
572 }
573
574 sb.Append(prefix + TAB).AppendFormat("OsalMemFree(%s);\n", varName.c_str());
575 if (!ownership) {
576 sb.Append(prefix + TAB).AppendFormat("%s = NULL;\n", varName.c_str());
577 }
578 sb.Append(prefix).Append("}\n");
579 }
580
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,TypeMode mode) const581 void HdiArrayTypeEmitter::EmitJavaWriteVar(const std::string &parcelName, const std::string &name,
582 StringBuilder &sb, const std::string &prefix, TypeMode mode) const
583 {
584 if (mode == TypeMode::PARAM_OUT) {
585 sb.Append(prefix).AppendFormat("if (%s == null) {\n", name.c_str());
586 sb.Append(prefix + TAB).AppendFormat("%s.writeInt(-1);\n", parcelName.c_str());
587 sb.Append(prefix).Append("} else {\n");
588 sb.Append(prefix + TAB).AppendFormat("%s.writeInt(%s.length);\n", parcelName.c_str(), name.c_str());
589 sb.Append(prefix).Append("}\n");
590 return;
591 }
592 sb.Append(prefix).AppendFormat("if (%s == null) {\n", name.c_str());
593 sb.Append(prefix + TAB).AppendFormat("%s.writeInt(-1);\n", parcelName.c_str());
594 sb.Append(prefix).Append("} else {\n");
595 EmitJavaWriteArrayVar(parcelName, name, sb, prefix + TAB);
596 sb.Append(prefix).Append("}\n");
597 }
598
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const599 void HdiArrayTypeEmitter::EmitJavaReadVar(
600 const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
601 {
602 switch (elementEmitter_->GetTypeKind()) {
603 case TypeKind::TYPE_BOOLEAN:
604 case TypeKind::TYPE_BYTE:
605 case TypeKind::TYPE_SHORT:
606 case TypeKind::TYPE_INT:
607 case TypeKind::TYPE_LONG:
608 case TypeKind::TYPE_FLOAT:
609 case TypeKind::TYPE_DOUBLE:
610 case TypeKind::TYPE_STRING:
611 sb.Append(prefix).AppendFormat("%s.read%sArray(%s);\n",
612 StringHelper::FirstToUpper(elementEmitter_->GetTypeName()).c_str(),
613 parcelName.c_str(), name.c_str());
614 break;
615 case TypeKind::TYPE_FILEDESCRIPTOR:
616 sb.Append(prefix).AppendFormat("%s.readIntArray(%s);\n", parcelName.c_str(), name.c_str());
617 break;
618 case TypeKind::TYPE_SEQUENCEABLE:
619 sb.Append(prefix).AppendFormat("%s.readSequenceableArray(%s);\n", parcelName.c_str(), name.c_str());
620 break;
621 default:
622 break;
623 }
624 }
625
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const626 void HdiArrayTypeEmitter::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
627 StringBuilder &sb, const std::string &prefix) const
628 {
629 switch (elementEmitter_->GetTypeKind()) {
630 case TypeKind::TYPE_BOOLEAN:
631 case TypeKind::TYPE_BYTE:
632 case TypeKind::TYPE_SHORT:
633 case TypeKind::TYPE_INT:
634 case TypeKind::TYPE_LONG:
635 case TypeKind::TYPE_FLOAT:
636 case TypeKind::TYPE_DOUBLE:
637 case TypeKind::TYPE_STRING:
638 sb.Append(prefix).AppendFormat("%s[] %s = %s.read%sArray();\n",
639 StringHelper::FirstToUpper(elementEmitter_->GetTypeName()).c_str(),
640 elementEmitter_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
641 break;
642 case TypeKind::TYPE_FILEDESCRIPTOR:
643 sb.Append(prefix).AppendFormat("%s[] %s = %s.readIntArray();\n",
644 elementEmitter_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
645 break;
646 case TypeKind::TYPE_SEQUENCEABLE:
647 sb.Append(prefix).AppendFormat("int size = %s.readInt();\n", parcelName.c_str());
648 sb.Append(prefix).AppendFormat("%s %s = new %s[size];\n",
649 elementEmitter_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(),
650 elementEmitter_->EmitJavaType(TypeMode::NO_MODE).c_str());
651 sb.Append(prefix).AppendFormat("for (int i = 0; i < size; ++i) {\n");
652 elementEmitter_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + TAB);
653 sb.Append(prefix + TAB).AppendFormat("%s[i] = value;\n", name.c_str());
654 sb.Append(prefix).Append("}\n");
655 break;
656 default:
657 break;
658 }
659 }
660
EmitJavaWriteArrayVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const661 void HdiArrayTypeEmitter::EmitJavaWriteArrayVar(
662 const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
663 {
664 switch (elementEmitter_->GetTypeKind()) {
665 case TypeKind::TYPE_BOOLEAN:
666 case TypeKind::TYPE_BYTE:
667 case TypeKind::TYPE_SHORT:
668 case TypeKind::TYPE_INT:
669 case TypeKind::TYPE_LONG:
670 case TypeKind::TYPE_FLOAT:
671 case TypeKind::TYPE_DOUBLE:
672 case TypeKind::TYPE_STRING:
673 sb.Append(prefix).AppendFormat("%s.write%sArray(%s);\n",
674 StringHelper::FirstToUpper(elementEmitter_->GetTypeName()).c_str(), parcelName.c_str(), name.c_str());
675 break;
676 case TypeKind::TYPE_FILEDESCRIPTOR:
677 sb.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.c_str(), name.c_str());
678 break;
679 case TypeKind::TYPE_SEQUENCEABLE:
680 sb.Append(prefix).AppendFormat("%s.writeSequenceableArray(%s);\n", parcelName.c_str(), name.c_str());
681 break;
682 default:
683 break;
684 }
685 }
686
EmitCMallocVar(const std::string & name,const std::string & lenName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const687 void HdiArrayTypeEmitter::EmitCMallocVar(const std::string &name, const std::string &lenName,
688 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
689 {
690 sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * (%s));\n", name.c_str(),
691 elementEmitter_->EmitCType().c_str(), elementEmitter_->EmitCType().c_str(), lenName.c_str());
692 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
693 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", name.c_str());
694 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", errorCodeName_.c_str());
695 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
696 sb.Append(prefix).Append("}\n");
697 }
698
EmitCWriteMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const699 void HdiArrayTypeEmitter::EmitCWriteMethods(
700 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
701 {
702 elementEmitter_->EmitCWriteMethods(methods, prefix, methodPrefix, isDecl);
703 if (elementEmitter_->GetTypeKind() == TypeKind::TYPE_STRING) {
704 EmitCWriteStrArrayMethods(methods, prefix, methodPrefix, isDecl);
705 return;
706 } else if (!elementEmitter_->IsPod()) {
707 return;
708 }
709 StringBuilder sb;
710 std::string methodName = StringHelper::Format("%sWritePodArray", methodPrefix.c_str());
711 if (isDecl) {
712 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, const void *data, uint32_t elementSize, "
713 "uint32_t count);\n", methodName.c_str());
714 } else {
715 sb.Append("\n");
716 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, const void *data, uint32_t elementSize, "
717 "uint32_t count)\n", methodName.c_str());
718 sb.Append(prefix).Append("{\n");
719 sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUint32(parcel, count)) {\n");
720 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array size\", __func__);\n");
721 sb.Append(prefix + TAB + TAB).Append("return false;\n");
722 sb.Append(prefix + TAB).Append("}\n\n");
723
724 sb.Append(prefix + TAB).Append("if (data == NULL && count == 0) {\n");
725 sb.Append(prefix + TAB + TAB).Append("return true;\n");
726 sb.Append(prefix + TAB).Append("}\n\n");
727
728 if (Options::GetInstance().DoGenerateKernelCode()) {
729 sb.Append(prefix + TAB).Append("if (!HdfSbufWriteBuffer(");
730 sb.Append("parcel, (const void *)data, elementSize * count)) {\n");
731 } else {
732 sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUnpadBuffer(");
733 sb.Append("parcel, (const uint8_t *)data, elementSize * count)) {\n");
734 }
735
736 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array\", __func__);\n");
737 sb.Append(prefix + TAB + TAB).Append("return false;\n");
738 sb.Append(prefix + TAB).Append("}\n\n");
739
740 sb.Append(prefix + TAB).Append("return true;\n");
741 sb.Append(prefix).Append("}\n");
742 }
743 methods.emplace(methodName, sb.ToString());
744 }
745
EmitCReadMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const746 void HdiArrayTypeEmitter::EmitCReadMethods(
747 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
748 {
749 elementEmitter_->EmitCReadMethods(methods, prefix, methodPrefix, isDecl);
750 if (elementEmitter_->GetTypeKind() == TypeKind::TYPE_STRING) {
751 EmitCReadStrArrayMethods(methods, prefix, methodPrefix, isDecl);
752 return;
753 } else if (!elementEmitter_->IsPod()) {
754 return;
755 }
756 StringBuilder sb;
757 std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
758 if (isDecl) {
759 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, void *data, uint32_t elementSize, uint32_t *count);\n",
760 methodName.c_str());
761 } else {
762 sb.Append("\n");
763 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, void *data, uint32_t elementSize, uint32_t *count)\n",
764 methodName.c_str());
765 EmitCReadMethodsBody(sb, prefix);
766 }
767 methods.emplace(methodName, sb.ToString());
768 }
769
EmitCReadMethodsBody(StringBuilder & sb,const std::string & prefix) const770 void HdiArrayTypeEmitter::EmitCReadMethodsBody(StringBuilder &sb, const std::string &prefix) const
771 {
772 sb.Append(prefix).Append("{\n");
773 if (Options::GetInstance().DoGenerateKernelCode()) {
774 sb.Append(prefix + TAB).Append("void *dataPtr = NULL;\n");
775 sb.Append(prefix + TAB).Append("uint32_t dataLen = 0;\n");
776 }
777 sb.Append(prefix + TAB).Append("uint32_t elementCount = 0;\n");
778 sb.Append(prefix + TAB).Append("if (!HdfSbufReadUint32(parcel, &elementCount)) {\n");
779 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read array size\", __func__);\n");
780 sb.Append(prefix + TAB + TAB).Append("return false;\n");
781 sb.Append(prefix + TAB).Append("}\n\n");
782
783 sb.Append(prefix + TAB).AppendFormat("if (elementCount > %s / elementSize) {\n", MAX_BUFF_SIZE_MACRO);
784 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid elementCount\", __func__);\n");
785 sb.Append(prefix + TAB + TAB).Append("return false;\n");
786 sb.Append(prefix + TAB).Append("}\n\n");
787
788 sb.Append(prefix + TAB).Append("if (elementCount == 0) {\n");
789 sb.Append(prefix + TAB + TAB).Append("goto FINISHED;\n");
790 sb.Append(prefix + TAB).Append("}\n\n");
791
792 if (Options::GetInstance().DoGenerateKernelCode()) {
793 sb.Append(prefix + TAB).Append("if (!HdfSbufReadBuffer(parcel, (const void **)&dataPtr, &dataLen)) {\n");
794 } else {
795 sb.Append(prefix + TAB).Append("const void * dataPtr = HdfSbufReadUnpadBuffer(parcel, "
796 "elementSize * elementCount);\n");
797 sb.Append(prefix + TAB).Append("if (dataPtr == NULL) {\n");
798 }
799
800 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read array\", __func__);\n");
801 sb.Append(prefix + TAB + TAB).Append("return false;\n");
802 sb.Append(prefix + TAB).Append("}\n\n");
803
804 sb.Append(prefix + TAB).Append("if (memcpy_s(data, elementSize * elementCount, dataPtr, "
805 "elementSize * elementCount) != EOK) {\n");
806 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to copy array data\", __func__);\n");
807 sb.Append(prefix + TAB + TAB).Append("return false;\n");
808 sb.Append(prefix + TAB).Append("}\n\n");
809
810 sb.Append("FINISHED:\n");
811 sb.Append(prefix + TAB).Append("*count = elementCount;\n");
812 sb.Append(prefix + TAB).Append("return true;\n");
813 sb.Append(prefix).Append("}\n");
814 }
815
EmitCStubReadMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const816 void HdiArrayTypeEmitter::EmitCStubReadMethods(
817 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
818 {
819 elementEmitter_->EmitCStubReadMethods(methods, prefix, methodPrefix, isDecl);
820 if (elementEmitter_->GetTypeKind() == TypeKind::TYPE_STRING) {
821 EmitCStubReadStrArrayMethods(methods, prefix, methodPrefix, isDecl);
822 return;
823 } else if (!elementEmitter_->IsPod()) {
824 return;
825 }
826 StringBuilder sb;
827 std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
828 if (isDecl) {
829 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, void **data, uint32_t elementSize, uint32_t *count);\n",
830 methodName.c_str());
831 } else {
832 sb.Append("\n");
833 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, void **data, uint32_t elementSize, uint32_t *count)\n",
834 methodName.c_str());
835 sb.Append(prefix).Append("{\n");
836 EmitCStubReadMethodBody(sb, prefix + TAB);
837 sb.Append(prefix).Append("}\n");
838 }
839 methods.emplace(methodName, sb.ToString());
840 }
841
EmitCStubReadMethodBody(StringBuilder & sb,const std::string & prefix) const842 void HdiArrayTypeEmitter::EmitCStubReadMethodBody(StringBuilder &sb, const std::string &prefix) const
843 {
844 sb.Append(prefix).Append("const void * dataPtr = NULL;\n");
845 if (Options::GetInstance().DoGenerateKernelCode()) {
846 sb.Append(prefix).Append("uint32_t dataLen = 0;\n");
847 }
848 sb.Append(prefix).Append("void *memPtr = NULL;\n");
849 sb.Append(prefix).Append("uint32_t elementCount = 0;\n");
850 sb.Append(prefix).Append("if (count == NULL || data == NULL || elementSize == 0) {\n");
851 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid param\", __func__);\n");
852 sb.Append(prefix + TAB).Append("return false;\n");
853 sb.Append(prefix).Append("}\n\n");
854 sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &elementCount)) {\n");
855 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read element count\", __func__);\n");
856 sb.Append(prefix + TAB).Append("return false;\n");
857 sb.Append(prefix).Append("}\n\n");
858
859 sb.Append(prefix).AppendFormat("if (elementCount > %s / elementSize) {\n", MAX_BUFF_SIZE_MACRO);
860 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid elementCount\", __func__);\n");
861 sb.Append(prefix + TAB).Append("return false;\n");
862 sb.Append(prefix).Append("}\n\n");
863
864 sb.Append(prefix).Append("if (elementCount == 0) {\n");
865 sb.Append(prefix + TAB).Append("*count = elementCount;\n");
866 sb.Append(prefix + TAB).Append("return true;\n");
867 sb.Append(prefix).Append("}\n\n");
868 if (Options::GetInstance().DoGenerateKernelCode()) {
869 sb.Append(prefix).Append("if (!HdfSbufReadBuffer(parcel, (const void **)&dataPtr, &dataLen)) {\n");
870 } else {
871 sb.Append(prefix).Append("dataPtr = HdfSbufReadUnpadBuffer(parcel, elementSize * elementCount);\n");
872 sb.Append(prefix).Append("if (dataPtr == NULL) {\n");
873 }
874 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
875 sb.Append(prefix + TAB).Append("return false;\n");
876 sb.Append(prefix).Append("}\n\n");
877 sb.Append(prefix).Append("memPtr = OsalMemCalloc(elementSize * elementCount);\n");
878 sb.Append(prefix).Append("if (memPtr == NULL) {\n");
879 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc buffer\", __func__);\n");
880 sb.Append(prefix + TAB).Append("return false;\n");
881 sb.Append(prefix).Append("}\n\n");
882 sb.Append(prefix).Append(
883 "if (memcpy_s(memPtr, elementSize * elementCount, dataPtr, elementSize * elementCount) != EOK) {\n");
884 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy buffer\", __func__);\n");
885 sb.Append(prefix + TAB).Append("OsalMemFree(memPtr);\n");
886 sb.Append(prefix + TAB).Append("return false;\n");
887 sb.Append(prefix).Append("}\n\n");
888 sb.Append(prefix).Append("*data = memPtr;\n");
889 sb.Append(prefix).Append("*count = elementCount;\n");
890 sb.Append(prefix).Append("return true;\n");
891 }
892
EmitCWriteStrArrayMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const893 void HdiArrayTypeEmitter::EmitCWriteStrArrayMethods(
894 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
895 {
896 StringBuilder sb;
897 std::string methodName = StringHelper::Format("%sWriteStringArray", methodPrefix.c_str());
898 if (isDecl) {
899 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, char **data, uint32_t count);\n", methodName.c_str());
900 } else {
901 sb.Append("\n");
902 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, char **data, uint32_t count)\n", methodName.c_str());
903 sb.Append(prefix).Append("{\n");
904 sb.Append(prefix + TAB).Append("uint32_t i = 0;\n");
905 sb.Append(prefix + TAB).Append("if (parcel == NULL) {\n");
906 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
907 sb.Append(prefix + TAB + TAB).Append("return false;\n");
908 sb.Append(prefix + TAB).Append("}\n\n");
909 sb.Append(prefix + TAB).AppendFormat("if (count > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
910 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid count\", __func__);\n");
911 sb.Append(prefix + TAB + TAB).Append("return false;\n");
912 sb.Append(prefix + TAB).Append("}\n\n");
913 sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUint32(parcel, count)) {\n");
914 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write count of array\", __func__);\n");
915 sb.Append(prefix + TAB + TAB).Append("return false;\n");
916 sb.Append(prefix + TAB).Append("}\n\n");
917 sb.Append(prefix + TAB).Append("if (count == 0) {\n");
918 sb.Append(prefix + TAB + TAB).Append("return true;\n");
919 sb.Append(prefix + TAB).Append("}\n\n");
920 sb.Append(prefix + TAB).Append("if (data == NULL) {\n");
921 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid array object\", __func__);\n");
922 sb.Append(prefix + TAB + TAB).Append("return false;\n");
923 sb.Append(prefix + TAB).Append("}\n\n");
924 sb.Append(prefix + TAB).Append("for (i = 0; i < count; i++) {\n");
925 sb.Append(prefix + TAB + TAB).Append("if (!HdfSbufWriteString(parcel, data[i])) {\n");
926 sb.Append(prefix + TAB + TAB + TAB)
927 .Append("HDF_LOGE(\"%{public}s: failed to write element of array\", __func__);\n");
928 sb.Append(prefix + TAB + TAB + TAB).Append("return false;\n");
929 sb.Append(prefix + TAB + TAB).Append("}\n");
930 sb.Append(prefix + TAB).Append("}\n\n");
931 sb.Append(prefix + TAB).Append("return true;\n");
932 sb.Append(prefix).Append("}\n");
933 }
934 methods.emplace(methodName, sb.ToString());
935 }
936
EmitCReadStrArrayMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const937 void HdiArrayTypeEmitter::EmitCReadStrArrayMethods(
938 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
939 {
940 StringBuilder sb;
941 std::string methodName = StringHelper::Format("%sReadStringArray", methodPrefix.c_str());
942 if (isDecl) {
943 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, char **data, uint32_t *count);\n", methodName.c_str());
944 } else {
945 sb.Append("\n");
946 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, char **data, uint32_t *count)\n", methodName.c_str());
947 sb.Append(prefix).Append("{\n");
948 EmitCReadStrArrayMethodBody(sb, prefix + TAB);
949 sb.Append(prefix).Append("}\n");
950 }
951 methods.emplace(methodName, sb.ToString());
952 }
953
EmitCReadStrArrayMethodBody(StringBuilder & sb,const std::string & prefix) const954 void HdiArrayTypeEmitter::EmitCReadStrArrayMethodBody(StringBuilder &sb, const std::string &prefix) const
955 {
956 sb.Append(prefix).Append("uint32_t i = 0;\n");
957 sb.Append(prefix).Append("uint32_t dataCount = 0;\n");
958 EmitCCheckParamOfReadStringArray(sb, prefix);
959 sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &dataCount)) {\n");
960 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read count of array\", __func__);\n");
961 sb.Append(prefix + TAB).Append("return false;\n");
962 sb.Append(prefix).Append("}\n\n");
963 sb.Append(prefix).AppendFormat("if (dataCount > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
964 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid dataCount\", __func__);\n");
965 sb.Append(prefix + TAB).Append("return false;\n");
966 sb.Append(prefix).Append("}\n\n");
967 sb.Append(prefix).Append("if (dataCount == 0) {\n");
968 sb.Append(prefix + TAB).Append("*count = dataCount;\n");
969 sb.Append(prefix + TAB).Append("return true;\n");
970 sb.Append(prefix).Append("}\n\n");
971 sb.Append(prefix).Append("for (i = 0; i < dataCount; i++) {\n");
972 sb.Append(prefix + TAB).Append("char *elementStr = NULL;\n");
973 sb.Append(prefix + TAB).Append("uint32_t strLen = 0;\n");
974 sb.Append(prefix + TAB).Append("const char *str = HdfSbufReadString(parcel);\n");
975 sb.Append(prefix + TAB).Append("if (str == NULL) {\n");
976 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read string\", __func__);\n");
977 sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
978 sb.Append(prefix + TAB).Append("}\n");
979 sb.Append(prefix + TAB).Append("strLen = strlen(str);\n");
980 sb.Append(prefix + TAB).Append("elementStr = (char *)OsalMemCalloc(strLen + 1);\n");
981 sb.Append(prefix + TAB).Append("if (elementStr == NULL) {\n");
982 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc element of array\", __func__);\n");
983 sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
984 sb.Append(prefix + TAB).Append("}\n");
985 sb.Append(prefix + TAB).Append("if (strcpy_s(elementStr, strLen + 1, str) != EOK) {\n");
986 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed copy element of array\", __func__);\n");
987 sb.Append(prefix + TAB + TAB).Append("OsalMemFree(elementStr);\n");
988 sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
989 sb.Append(prefix + TAB).Append("}\n");
990 sb.Append(prefix + TAB).Append("data[i] = elementStr;\n");
991 sb.Append(prefix).Append("}\n\n");
992 sb.Append(prefix).Append("*count = dataCount;\n");
993 sb.Append(prefix).Append("return true;\n\n");
994 sb.Append("ERROR:\n");
995 sb.Append(prefix).Append("for (i = 0; i < dataCount; ++i) {\n");
996 sb.Append(prefix + TAB).Append("if (data[i] != NULL) {\n");
997 sb.Append(prefix + TAB + TAB).Append("OsalMemFree(data[i]);\n");
998 sb.Append(prefix + TAB + TAB).Append("data[i] = NULL;\n");
999 sb.Append(prefix + TAB).Append("}\n");
1000 sb.Append(prefix).Append("}\n");
1001 sb.Append(prefix).Append("*count = 0;\n");
1002 sb.Append(prefix).Append("return false;\n");
1003 }
1004
EmitCCheckParamOfReadStringArray(StringBuilder & sb,const std::string & prefix) const1005 void HdiArrayTypeEmitter::EmitCCheckParamOfReadStringArray(StringBuilder &sb, const std::string &prefix) const
1006 {
1007 sb.Append(prefix).Append("if (parcel == NULL) {\n");
1008 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
1009 sb.Append(prefix + TAB).Append("return false;\n");
1010 sb.Append(prefix).Append("}\n\n");
1011 sb.Append(prefix).Append("if (data == NULL || count == NULL) {\n");
1012 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid array object\", __func__);\n");
1013 sb.Append(prefix + TAB).Append("return false;\n");
1014 sb.Append(prefix).Append("}\n\n");
1015 }
1016
EmitCStubReadStrArrayMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1017 void HdiArrayTypeEmitter::EmitCStubReadStrArrayMethods(
1018 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1019 {
1020 StringBuilder sb;
1021 std::string methodName = StringHelper::Format("%sReadStringArray", methodPrefix.c_str());
1022 if (isDecl) {
1023 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, char ***data, uint32_t *count);\n",
1024 methodName.c_str());
1025 } else {
1026 sb.Append("\n");
1027 sb.AppendFormat("static bool %s(struct HdfSBuf *parcel, char ***data, uint32_t *count)\n", methodName.c_str());
1028 sb.Append(prefix).Append("{\n");
1029 EmitCStubReadStrArrayMethodBody(sb, prefix + TAB);
1030 sb.Append(prefix).Append("}\n");
1031 }
1032 methods.emplace(methodName, sb.ToString());
1033 }
1034
EmitCStubReadStrArrayMethodBody(StringBuilder & sb,const std::string & prefix) const1035 void HdiArrayTypeEmitter::EmitCStubReadStrArrayMethodBody(StringBuilder &sb, const std::string &prefix) const
1036 {
1037 sb.Append(prefix).Append("uint32_t i = 0;\n");
1038 sb.Append(prefix).Append("char **dataPtr = NULL;\n");
1039 sb.Append(prefix).Append("uint32_t dataCount = 0;\n");
1040 EmitCCheckParamOfReadStringArray(sb, prefix);
1041 sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &dataCount)) {\n");
1042 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read count of array\", __func__);\n");
1043 sb.Append(prefix + TAB).Append("return false;\n");
1044 sb.Append(prefix).Append("}\n\n");
1045 sb.Append(prefix).AppendFormat("if (dataCount > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
1046 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid dataCount\", __func__);\n");
1047 sb.Append(prefix + TAB).Append("return false;\n");
1048 sb.Append(prefix).Append("}\n\n");
1049 sb.Append(prefix).Append("if (dataCount == 0) {\n");
1050 sb.Append(prefix + TAB).Append("*count = dataCount;\n");
1051 sb.Append(prefix + TAB).Append("return true;\n");
1052 sb.Append(prefix).Append("}\n\n");
1053 sb.Append(prefix).Append("dataPtr = (char **)OsalMemCalloc(sizeof(char *) * dataCount);\n");
1054 sb.Append(prefix).Append("if (dataPtr == NULL) {\n");
1055 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc array\", __func__);\n");
1056 sb.Append(prefix + TAB).Append("return false;\n");
1057 sb.Append(prefix).Append("}\n\n");
1058 sb.Append(prefix).Append("for (i = 0; i < dataCount; i++) {\n");
1059 sb.Append(prefix + TAB).Append("char *elementStr = NULL;\n");
1060 sb.Append(prefix + TAB).Append("uint32_t strLen = 0;\n");
1061 sb.Append(prefix + TAB).Append("const char *str = HdfSbufReadString(parcel);\n");
1062 sb.Append(prefix + TAB).Append("if (str == NULL) {\n");
1063 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc array\", __func__);\n");
1064 sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1065 sb.Append(prefix + TAB).Append("}\n\n");
1066 sb.Append(prefix + TAB).Append("strLen = strlen(str);\n");
1067 sb.Append(prefix + TAB).Append("elementStr = (char *)OsalMemCalloc(strLen + 1);\n");
1068 sb.Append(prefix + TAB).Append("if (elementStr == NULL) {\n");
1069 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc element of array\", __func__);\n");
1070 sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1071 sb.Append(prefix + TAB).Append("}\n\n");
1072 sb.Append(prefix + TAB).Append("if (strcpy_s(elementStr, strLen + 1, str) != EOK) {\n");
1073 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed copy element of array\", __func__);\n");
1074 sb.Append(prefix + TAB + TAB).Append("OsalMemFree(elementStr);\n");
1075 sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1076 sb.Append(prefix + TAB).Append("}\n");
1077 sb.Append(prefix + TAB).Append("dataPtr[i] = elementStr;\n");
1078 sb.Append(prefix).Append("}\n\n");
1079 sb.Append(prefix).Append("*count = dataCount;\n");
1080 sb.Append(prefix).Append("*data = dataPtr;\n");
1081 sb.Append(prefix).Append("return true;\n\n");
1082 EmitCStubReadStrArrayFree(sb, prefix);
1083 }
1084
EmitCStubReadStrArrayFree(StringBuilder & sb,const std::string & prefix) const1085 void HdiArrayTypeEmitter::EmitCStubReadStrArrayFree(StringBuilder &sb, const std::string &prefix) const
1086 {
1087 sb.Append("ERROR:\n");
1088 sb.Append(prefix).Append("if (dataPtr != NULL) {\n");
1089 sb.Append(prefix + TAB).Append("for (i = 0; i < dataCount; i++) {\n");
1090 sb.Append(prefix + TAB + TAB).Append("if (dataPtr[i] != NULL) {\n");
1091 sb.Append(prefix + TAB + TAB + TAB).Append("OsalMemFree(dataPtr[i]);\n");
1092 sb.Append(prefix + TAB + TAB + TAB).Append("dataPtr[i] = NULL;\n");
1093 sb.Append(prefix + TAB + TAB).Append("}\n");
1094 sb.Append(prefix + TAB).Append("}\n");
1095 sb.Append(prefix + TAB).Append("OsalMemFree(dataPtr);\n");
1096 sb.Append(prefix).Append("}\n\n");
1097 sb.Append(prefix).Append("*count = 0;\n");
1098 sb.Append(prefix).Append("return false;\n");
1099 }
1100
EmitCppWriteMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1101 void HdiArrayTypeEmitter::EmitCppWriteMethods(
1102 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1103 {
1104 elementEmitter_->EmitCppWriteMethods(methods, prefix, methodPrefix, isDecl);
1105 if (!elementEmitter_->IsPod()) {
1106 return;
1107 }
1108 StringBuilder sb;
1109 std::string methodName = StringHelper::Format("%sWritePodArray", methodPrefix.c_str());
1110 if (isDecl) {
1111 sb.Append("template<typename ElementType>\n");
1112 sb.AppendFormat("static bool %s(MessageParcel &parcel, const std::vector<ElementType> &data);\n",
1113 methodName.c_str());
1114 } else {
1115 sb.Append("\n").Append("template<typename ElementType>\n");
1116 sb.AppendFormat("static bool %s(MessageParcel &parcel, const std::vector<ElementType> &data)\n",
1117 methodName.c_str());
1118 sb.Append(prefix).Append("{\n");
1119 sb.Append(prefix + TAB).Append("if (!parcel.WriteUint32(data.size())) {\n");
1120 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write data size\", __func__);\n");
1121 sb.Append(prefix + TAB + TAB).Append("return false;\n");
1122 sb.Append(prefix + TAB).Append("}\n");
1123
1124 sb.Append(prefix + TAB).Append("if (data.empty()) {\n");
1125 sb.Append(prefix + TAB + TAB).Append("return true;\n");
1126 sb.Append(prefix + TAB).Append("}\n");
1127
1128 sb.Append(prefix + TAB).Append("if (!parcel.WriteUnpadBuffer(");
1129 sb.Append("(const void*)data.data(), sizeof(ElementType) * data.size())) {\n");
1130 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array\", __func__);\n");
1131 sb.Append(prefix + TAB + TAB).Append("return false;\n");
1132 sb.Append(prefix + TAB).Append("}\n");
1133
1134 sb.Append(prefix + TAB).Append("return true;\n");
1135 sb.Append(prefix).Append("}\n");
1136 }
1137 methods.emplace(methodName, sb.ToString());
1138 }
1139
EmitCppReadMethods(UtilMethodMap & methods,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1140 void HdiArrayTypeEmitter::EmitCppReadMethods(
1141 UtilMethodMap &methods, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1142 {
1143 elementEmitter_->EmitCppReadMethods(methods, prefix, methodPrefix, isDecl);
1144 if (!elementEmitter_->IsPod()) {
1145 return;
1146 }
1147 StringBuilder sb;
1148 std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
1149 if (isDecl) {
1150 sb.Append("template<typename ElementType>\n");
1151 sb.AppendFormat("static bool %s(MessageParcel &parcel, std::vector<ElementType> &data);\n",
1152 methodName.c_str());
1153 } else {
1154 sb.Append("\n").Append("template<typename ElementType>\n");
1155 sb.AppendFormat("static bool %s(MessageParcel &parcel, std::vector<ElementType> &data)\n", methodName.c_str());
1156 sb.Append(prefix).Append("{\n");
1157 sb.Append(prefix + TAB).Append("data.clear();\n");
1158 sb.Append(prefix + TAB).Append("uint32_t size = 0;\n");
1159 sb.Append(prefix + TAB).Append("if (!parcel.ReadUint32(size)) {\n");
1160 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
1161 sb.Append(prefix + TAB + TAB).Append("return false;\n");
1162 sb.Append(prefix + TAB).Append("}\n\n");
1163
1164 sb.Append(prefix + TAB).Append("if (size == 0) {\n");
1165 sb.Append(prefix + TAB + TAB).Append("return true;\n");
1166 sb.Append(prefix + TAB).Append("}\n");
1167
1168 sb.Append(prefix + TAB).Append("const ElementType *dataPtr = reinterpret_cast<const ElementType*>(");
1169 sb.Append("parcel.ReadUnpadBuffer(sizeof(ElementType) * size));\n");
1170 sb.Append(prefix + TAB).Append("if (dataPtr == nullptr) {\n");
1171 sb.Append(prefix + TAB + TAB).Append("HDF_LOGI(\"%{public}s: failed to read data\", __func__);\n");
1172 sb.Append(prefix + TAB + TAB).Append("return false;\n");
1173 sb.Append(prefix + TAB).Append("}\n");
1174
1175 sb.Append(prefix + TAB).Append("data.assign(dataPtr, dataPtr + size);\n");
1176 sb.Append(prefix + TAB).Append("return true;\n");
1177 sb.Append(prefix).Append("}\n");
1178 }
1179 methods.emplace(methodName, sb.ToString());
1180 }
1181
GetTypeKind()1182 TypeKind HdiListTypeEmitter::GetTypeKind()
1183 {
1184 return TypeKind::TYPE_LIST;
1185 }
1186
EmitJavaType(TypeMode mode,bool isInnerType) const1187 std::string HdiListTypeEmitter::EmitJavaType(TypeMode mode, bool isInnerType) const
1188 {
1189 return StringHelper::Format("List<%s>", elementEmitter_->EmitJavaType(mode, true).c_str());
1190 }
1191
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,TypeMode mode) const1192 void HdiListTypeEmitter::EmitJavaWriteVar(const std::string &parcelName, const std::string &name,
1193 StringBuilder &sb, const std::string &prefix, TypeMode mode) const
1194 {
1195 sb.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.c_str(), name.c_str());
1196 sb.Append(prefix).AppendFormat(
1197 "for (%s element : %s) {\n", elementEmitter_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str());
1198 elementEmitter_->EmitJavaWriteVar(parcelName, "element", sb, prefix + TAB);
1199 sb.Append(prefix).Append("}\n");
1200 }
1201
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const1202 void HdiListTypeEmitter::EmitJavaReadVar(
1203 const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
1204 {
1205 sb.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(), parcelName.c_str());
1206 sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1207
1208 elementEmitter_->EmitJavaReadInnerVar(parcelName, "value", false, sb, prefix + TAB);
1209 sb.Append(prefix + TAB).AppendFormat("%s.add(value);\n", name.c_str());
1210 sb.Append(prefix).Append("}\n");
1211 }
1212
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const1213 void HdiListTypeEmitter::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
1214 StringBuilder &sb, const std::string &prefix) const
1215 {
1216 sb.Append(prefix).AppendFormat("%s %s = new Array%s();\n", EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(),
1217 EmitJavaType(TypeMode::NO_MODE).c_str());
1218 sb.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(), parcelName.c_str());
1219 sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1220 elementEmitter_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + TAB);
1221 sb.Append(prefix + TAB).AppendFormat("%s.add(value);\n", name.c_str());
1222 sb.Append(prefix).Append("}\n");
1223 }
1224 } // namespace Idl
1225 } // namespace OHOS