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