• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "ast/ast_array_type.h"
10 #include "util/options.h"
11 
12 namespace OHOS {
13 namespace HDI {
IsArrayType()14 bool ASTArrayType::IsArrayType()
15 {
16     return true;
17 }
18 
HasInnerType(TypeKind innerTypeKind) const19 bool ASTArrayType::HasInnerType(TypeKind innerTypeKind) const
20 {
21     if (elementType_ == nullptr) {
22         return false;
23     }
24 
25     if (elementType_->GetTypeKind() == innerTypeKind) {
26         return true;
27     }
28     return elementType_->HasInnerType(innerTypeKind);
29 }
30 
ToString() const31 std::string ASTArrayType::ToString() const
32 {
33     return StringHelper::Format("%s[]", elementType_->ToString().c_str());
34 }
35 
GetTypeKind()36 TypeKind ASTArrayType::GetTypeKind()
37 {
38     return TypeKind::TYPE_ARRAY;
39 }
40 
EmitCType(TypeMode mode) const41 std::string ASTArrayType::EmitCType(TypeMode mode) const
42 {
43     switch (mode) {
44         case TypeMode::NO_MODE:
45             return StringHelper::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).c_str());
46         case TypeMode::PARAM_IN: {
47             if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING) {
48                 return StringHelper::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).c_str());
49             }
50             return StringHelper::Format("const %s*", elementType_->EmitCType(TypeMode::NO_MODE).c_str());
51         }
52         case TypeMode::PARAM_OUT:
53             return StringHelper::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).c_str());
54         case TypeMode::LOCAL_VAR:
55             return StringHelper::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).c_str());
56         default:
57             return "unknow type";
58     }
59 }
60 
EmitCppType(TypeMode mode) const61 std::string ASTArrayType::EmitCppType(TypeMode mode) const
62 {
63     switch (mode) {
64         case TypeMode::NO_MODE:
65             return StringHelper::Format("std::vector<%s>", elementType_->EmitCppType(TypeMode::NO_MODE).c_str());
66         case TypeMode::PARAM_IN:
67             return StringHelper::Format("const std::vector<%s>&", elementType_->EmitCppType(TypeMode::NO_MODE).c_str());
68         case TypeMode::PARAM_OUT:
69             return StringHelper::Format("std::vector<%s>&", elementType_->EmitCppType(TypeMode::NO_MODE).c_str());
70         case TypeMode::LOCAL_VAR:
71             return StringHelper::Format("std::vector<%s>", elementType_->EmitCppType(TypeMode::NO_MODE).c_str());
72         default:
73             return "unknow type";
74     }
75 }
76 
EmitJavaType(TypeMode mode,bool isInnerType) const77 std::string ASTArrayType::EmitJavaType(TypeMode mode, bool isInnerType) const
78 {
79     return StringHelper::Format("%s[]", elementType_->EmitJavaType(TypeMode::NO_MODE, false).c_str());
80 }
81 
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const82 void ASTArrayType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
83     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
84 {
85     std::string lenName = StringHelper::Format("%sLen", name.c_str());
86     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
87         sb.Append(prefix).AppendFormat("if (!WritePodArray(%s, %s, sizeof(%s), %s)) {\n", parcelName.c_str(),
88             name.c_str(), elementType_->EmitCType().c_str(), lenName.c_str());
89         sb.Append(prefix + TAB)
90             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
91         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
92         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
93         sb.Append(prefix).Append("}\n");
94         return;
95     } else if (elementType_->IsStringType()) {
96         sb.Append(prefix).AppendFormat(
97             "if (!WriteStringArray(%s, %s, %s)) {\n", parcelName.c_str(), name.c_str(), lenName.c_str());
98         sb.Append(prefix + TAB)
99             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
100         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
101         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
102         sb.Append(prefix).Append("}\n");
103         return;
104     }
105 
106     sb.Append(prefix).AppendFormat("if (%s == NULL || %s == 0) {\n", name.c_str(), lenName.c_str());
107     sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufWriteUint32(%s, 0)) {\n", parcelName.c_str());
108     sb.Append(prefix + TAB + TAB)
109         .AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
110     sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
111     sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
112     sb.Append(prefix + TAB).Append("}\n");
113     sb.Append(prefix).Append("} else {\n");
114     sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufWriteUint32(%s, %s)) {\n", parcelName.c_str(), lenName.c_str());
115     sb.Append(prefix + TAB + TAB)
116         .AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
117     sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
118     sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
119     sb.Append(prefix + TAB).Append("}\n");
120 
121     if (Options::GetInstance().DoGenerateKernelCode()) {
122         sb.Append(prefix + TAB).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
123     } else {
124         sb.Append(prefix + TAB).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
125     }
126 
127     std::string elementName = "";
128     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT || elementType_->GetTypeKind() == TypeKind::TYPE_UNION) {
129         elementName = StringHelper::Format("&%s[i]", name.c_str());
130     } else {
131         elementName = StringHelper::Format("%s[i]", name.c_str());
132     }
133     elementType_->EmitCWriteVar(parcelName, elementName, ecName, gotoLabel, sb, prefix + TAB + TAB);
134     sb.Append(prefix + TAB).Append("}\n");
135     sb.Append(prefix).Append("}\n");
136 }
137 
EmitCProxyWriteOutVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const138 void ASTArrayType::EmitCProxyWriteOutVar(const std::string &parcelName, const std::string &name,
139     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
140 {
141     std::string lenName = StringHelper::Format("*%sLen", name.c_str());
142     sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint32(%s, %s)) {\n", parcelName.c_str(), lenName.c_str());
143     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
144     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
145     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
146     sb.Append(prefix).Append("}\n");
147 }
148 
EmitCProxyReadVar(const std::string & parcelName,const std::string & name,bool isInnerType,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const149 void ASTArrayType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
150     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
151 {
152     std::string lenName = StringHelper::Format("%sLen", name.c_str());
153     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
154         sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, %s, sizeof(%s), %s)) {\n", parcelName.c_str(),
155             name.c_str(), elementType_->EmitCType().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", ecName.c_str());
158         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
159         sb.Append(prefix).Append("}\n");
160         return;
161     } else if (elementType_->IsStringType()) {
162         sb.Append(prefix).AppendFormat(
163             "if (!ReadStringArray(%s, %s, %s)) {\n", parcelName.c_str(), name.c_str(), lenName.c_str());
164         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
165         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
166         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
167         sb.Append(prefix).Append("}\n");
168         return;
169     }
170 
171     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, %s)) {\n", parcelName.c_str(), lenName.c_str());
172     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.c_str());
173     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
174     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
175     sb.Append(prefix).Append("}\n\n");
176 
177     sb.Append(prefix).AppendFormat("%s(*%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
178         CHECK_VALUE_RET_GOTO_MACRO, lenName.c_str(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCType().c_str(),
179         ecName.c_str(), gotoLabel.c_str());
180 
181     if (Options::GetInstance().DoGenerateKernelCode()) {
182         sb.Append(prefix).AppendFormat("for (i = 0; i < *%s; i++) {\n", lenName.c_str());
183     } else {
184         sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < *%s; i++) {\n", lenName.c_str());
185     }
186 
187     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
188         std::string element = StringHelper::Format("&%s[i]", name.c_str());
189         elementType_->EmitCProxyReadVar(parcelName, element, true, ecName, gotoLabel, sb, prefix + TAB);
190     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR) {
191         std::string element = StringHelper::Format("%s[i]", name.c_str());
192         elementType_->EmitCProxyReadVar(parcelName, element, true, ecName, gotoLabel, sb, prefix + TAB);
193     } else {
194         std::string element = StringHelper::Format("&%s[i]", name.c_str());
195         elementType_->EmitCProxyReadVar(parcelName, element, true, ecName, gotoLabel, sb, prefix + TAB);
196     }
197     sb.Append(prefix).Append("}\n");
198 }
199 
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const200 void ASTArrayType::EmitCStubReadVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
201     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
202 {
203     std::string lenName = StringHelper::Format("%sLen", name.c_str());
204     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
205         sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, (void **)&%s, sizeof(%s), &%s)) {\n", parcelName.c_str(),
206             name.c_str(), elementType_->EmitCType().c_str(), lenName.c_str());
207         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
208         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
209         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
210         sb.Append(prefix).Append("}\n");
211         return;
212     } else if (elementType_->IsStringType()) {
213         sb.Append(prefix).AppendFormat(
214             "if (!ReadStringArray(%s, &%s, &%s)) {\n", parcelName.c_str(), name.c_str(), lenName.c_str());
215         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
216         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
217         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
218         sb.Append(prefix).Append("}\n");
219         return;
220     }
221 
222     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, &%s)) {\n", parcelName.c_str(), lenName.c_str());
223     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.c_str());
224     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
225     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
226     sb.Append(prefix).Append("}\n\n");
227     sb.Append(prefix).AppendFormat("%s(%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
228         CHECK_VALUE_RET_GOTO_MACRO, lenName.c_str(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCType().c_str(),
229         ecName.c_str(), gotoLabel.c_str());
230 
231     sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.c_str());
232     EmitCMallocVar(name, lenName, false, ecName, gotoLabel, sb, prefix + TAB);
233     sb.Append("\n");
234 
235     if (Options::GetInstance().DoGenerateKernelCode()) {
236         sb.Append(prefix + TAB).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
237     } else {
238         sb.Append(prefix + TAB).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
239     }
240     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
241         std::string element = StringHelper::Format("&%s[i]", name.c_str());
242         elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, prefix + TAB + TAB);
243     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR) {
244         std::string element = StringHelper::Format("%s[i]", name.c_str());
245         elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, prefix + TAB + TAB);
246     } else {
247         std::string element = StringHelper::Format("&%s[i]", name.c_str());
248         elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, prefix + TAB + TAB);
249     }
250     sb.Append(prefix + TAB).Append("}\n");
251     sb.Append(prefix).Append("}\n");
252 }
253 
EmitCStubReadOutVar(const std::string & buffSizeName,const std::string & memFlagName,const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const254 void ASTArrayType::EmitCStubReadOutVar(const std::string &buffSizeName, const std::string &memFlagName,
255     const std::string &parcelName, const std::string &name, const std::string &ecName, const std::string &gotoLabel,
256     StringBuilder &sb, const std::string &prefix) const
257 {
258     std::string lenName = StringHelper::Format("%sLen", name.c_str());
259 
260     sb.Append(prefix).AppendFormat("if (%s) {\n", memFlagName.c_str());
261     sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufReadUint32(%s, &%s)) {\n", parcelName.c_str(), lenName.c_str());
262     sb.Append(prefix + TAB + TAB)
263         .AppendFormat("HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.c_str());
264     sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
265     sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
266     sb.Append(prefix + TAB).Append("}\n\n");
267     sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
268         CHECK_VALUE_RET_GOTO_MACRO, lenName.c_str(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCType().c_str(),
269         ecName.c_str(), gotoLabel.c_str());
270 
271     sb.Append(prefix + TAB).AppendFormat("if (%s > 0) {\n", lenName.c_str());
272     EmitCMallocVar(name, lenName, false, ecName, gotoLabel, sb, prefix + TAB + TAB);
273     sb.Append(prefix + TAB).Append("}\n");
274     sb.Append(prefix).Append("} else {\n");
275     sb.Append(prefix + TAB).AppendFormat("%s = (%s*)OsalMemCalloc(%s);\n", name.c_str(),
276         elementType_->EmitCType().c_str(), buffSizeName.c_str());
277     sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", name.c_str());
278     sb.Append(prefix + TAB + TAB)
279         .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", name.c_str());
280     sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", ecName.c_str());
281     sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
282     sb.Append(prefix + TAB).Append("}\n");
283 
284     sb.Append(prefix + TAB).AppendFormat("%sLen = (%s / sizeof(%s));\n", name.c_str(),
285         buffSizeName.c_str(), elementType_->EmitCType().c_str());
286     sb.Append(prefix).Append("}\n\n");
287 }
288 
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const289 void ASTArrayType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
290     const std::string &prefix, unsigned int innerLevel) const
291 {
292     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
293         sb.Append(prefix).AppendFormat("if (!WritePodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
294         sb.Append(prefix + TAB)
295             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
296         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
297         sb.Append(prefix).Append("}\n");
298         return;
299     }
300 
301     sb.Append(prefix).AppendFormat("if (!%s.WriteUint32(%s.size())) {\n", parcelName.c_str(), name.c_str());
302     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s size failed!\", __func__);\n", name.c_str());
303     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
304     sb.Append(prefix).Append("}\n");
305 
306     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
307         sb.Append(prefix).AppendFormat("if (!%s.empty()) {\n", name.c_str());
308         sb.Append(prefix + TAB).AppendFormat("if (!%s.WriteUnpadBuffer(", parcelName.c_str());
309         sb.AppendFormat("(const void*)%s.data(), sizeof(%s) * %s.size())) {\n", name.c_str(),
310             elementType_->EmitCppType().c_str(), name.c_str());
311         sb.Append(prefix + TAB + TAB)
312             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
313         sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
314         sb.Append(prefix + TAB).Append("}\n");
315         sb.Append(prefix).Append("}\n");
316     } else {
317         std::string elementName = StringHelper::Format("it%d", innerLevel++);
318         sb.Append(prefix).AppendFormat("for (const auto& %s : %s) {\n", elementName.c_str(), name.c_str());
319         elementType_->EmitCppWriteVar(parcelName, elementName, sb, prefix + TAB, innerLevel);
320         sb.Append(prefix).Append("}\n");
321     }
322 }
323 
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const324 void ASTArrayType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
325     const std::string &prefix, bool initVariable, unsigned int innerLevel) const
326 {
327     if (initVariable) {
328         sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().c_str(), name.c_str());
329     }
330 
331     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
332         sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
333         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
334         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
335         sb.Append(prefix).Append("}\n");
336         return;
337     }
338 
339     sb.Append(prefix).AppendFormat("uint32_t %sSize = 0;\n", name.c_str());
340     sb.Append(prefix).AppendFormat("if (!%s.ReadUint32(%sSize)) {\n", parcelName.c_str(), name.c_str());
341     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
342     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
343     sb.Append(prefix).Append("}\n\n");
344     sb.Append(prefix).AppendFormat("%s(%sSize, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
345         CHECK_VALUE_RETURN_MACRO, name.c_str(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCppType().c_str());
346     sb.Append(prefix).AppendFormat("%s.clear();\n", name.c_str());
347     sb.Append(prefix).AppendFormat("%s.reserve(%sSize);\n", name.c_str(), name.c_str());
348     sb.Append(prefix).AppendFormat(
349         "for (uint32_t i%d = 0; i%d < %sSize; ++i%d) {\n", innerLevel, innerLevel, name.c_str(), innerLevel);
350     std::string valueName = StringHelper::Format("value%d", innerLevel++);
351     elementType_->EmitCppReadVar(parcelName, valueName, sb, prefix + TAB, true, innerLevel);
352     sb.Append(prefix + TAB).AppendFormat("%s.push_back(%s);\n", name.c_str(), valueName.c_str());
353     sb.Append(prefix).Append("}\n");
354 }
355 
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const356 void ASTArrayType::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
357 {
358     std::string lenName = StringHelper::Format("%sLen", name.c_str());
359     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
360         sb.Append(prefix).AppendFormat("if (!WritePodArray(data, %s, sizeof(%s), %s)) {\n", name.c_str(),
361             elementType_->EmitCType().c_str(), lenName.c_str());
362         sb.Append(prefix + TAB)
363             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
364         sb.Append(prefix + TAB).Append("return false;\n");
365         sb.Append(prefix).Append("}\n");
366         return;
367     } else if (elementType_->IsStringType()) {
368         sb.Append(prefix).AppendFormat("if (!WriteStringArray(data, %s, %s)) {\n", name.c_str(), lenName.c_str());
369         sb.Append(prefix + TAB)
370             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
371         sb.Append(prefix + TAB).Append("return false;\n");
372         sb.Append(prefix).Append("}\n");
373         return;
374     }
375 
376     sb.Append(prefix).AppendFormat("if (%s > %s / sizeof(%s) || !HdfSbufWriteUint32(data, %s)) {\n", lenName.c_str(),
377         MAX_BUFF_SIZE_MACRO, elementType_->EmitCType().c_str(), lenName.c_str());
378     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", lenName.c_str());
379     sb.Append(prefix + TAB).Append("return false;\n");
380     sb.Append(prefix).Append("}\n");
381 
382     if (Options::GetInstance().DoGenerateKernelCode()) {
383         sb.Append(prefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
384     } else {
385         sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
386     }
387 
388     std::string elementName = StringHelper::Format("(%s)[i]", name.c_str());
389     elementType_->EmitCMarshalling(elementName, sb, prefix + TAB);
390     sb.Append(prefix).Append("}\n");
391 }
392 
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const393 void ASTArrayType::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
394     const std::string &prefix, std::vector<std::string> &freeObjStatements) const
395 {
396     std::string lenName = StringHelper::Format("%sLen", name.c_str());
397     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
398         sb.Append(prefix).AppendFormat("if (!ReadPodArray(data, (void**)&%s, sizeof(%s), &%s)) {\n", name.c_str(),
399             elementType_->EmitCType().c_str(), lenName.c_str());
400         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
401         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
402         sb.Append(prefix).Append("}\n");
403         return;
404     } else if (elementType_->IsStringType()) {
405         sb.Append(prefix).AppendFormat("if (!ReadStringArray(data, &%s, &%s)) {\n", name.c_str(), lenName.c_str());
406         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
407         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
408         sb.Append(prefix).Append("}\n");
409         return;
410     }
411 
412     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(data, &%s)) {\n", lenName.c_str());
413     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", lenName.c_str());
414     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
415     sb.Append(prefix).Append("}\n");
416 
417     sb.Append(prefix).AppendFormat("if (%s > %s / sizeof(%s)) {\n", lenName.c_str(), MAX_BUFF_SIZE_MACRO,
418         elementType_->EmitCType().c_str());
419     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: %s is invalid data\", __func__);\n", lenName.c_str());
420     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
421     sb.Append(prefix).Append("}\n");
422 
423     sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.c_str());
424     std::string newPrefix = prefix + TAB;
425 
426     sb.Append(newPrefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * %s);\n", name.c_str(),
427         elementType_->EmitCType().c_str(), elementType_->EmitCType().c_str(), lenName.c_str());
428     sb.Append(newPrefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
429     sb.Append(newPrefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
430     sb.Append(newPrefix).Append("}\n");
431     freeObjStatements.push_back(StringHelper::Format("OsalMemFree(%s);\n", name.c_str()));
432 
433     if (Options::GetInstance().DoGenerateKernelCode()) {
434         sb.Append(newPrefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
435     } else {
436         sb.Append(newPrefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
437     }
438 
439     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING) {
440         EmitCStringElementUnMarshalling(name, gotoLabel, sb, newPrefix + TAB, freeObjStatements);
441     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
442         std::string element = StringHelper::Format("&%s[i]", name.c_str());
443         elementType_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + TAB, freeObjStatements);
444     } else {
445         std::string element = StringHelper::Format("%s[i]", name.c_str());
446         elementType_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + TAB, freeObjStatements);
447     }
448     sb.Append(newPrefix).Append("}\n");
449     sb.Append(prefix).Append("}\n");
450     freeObjStatements.pop_back();
451 }
452 
EmitCStringElementUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & newPrefix,std::vector<std::string> & freeObjStatements) const453 void ASTArrayType::EmitCStringElementUnMarshalling(const std::string &name, const std::string &gotoLabel,
454     StringBuilder &sb, const std::string &newPrefix, std::vector<std::string> &freeObjStatements) const
455 {
456     std::string element = StringHelper::Format("%sElement", name.c_str());
457     elementType_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix, freeObjStatements);
458     if (Options::GetInstance().DoGenerateKernelCode()) {
459         sb.Append(newPrefix).AppendFormat(
460             "%s[i] = (char*)OsalMemCalloc(strlen(%s) + 1);\n", name.c_str(), element.c_str());
461         sb.Append(newPrefix).AppendFormat("if (%s[i] == NULL) {\n", name.c_str());
462         sb.Append(newPrefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
463         sb.Append(newPrefix).Append("}\n\n");
464         sb.Append(newPrefix).AppendFormat(
465             "if (strcpy_s((%s)[i], (strlen(%s) + 1), %s) != EOK) {\n", name.c_str(), element.c_str(), element.c_str());
466         sb.Append(newPrefix + TAB)
467             .AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", element.c_str());
468         sb.Append(newPrefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
469         sb.Append(newPrefix).Append("}\n");
470     } else {
471         sb.Append(newPrefix).Append(TAB).AppendFormat("%s[i] = strdup(%s);\n", name.c_str(), element.c_str());
472     }
473 }
474 
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const475 void ASTArrayType::EmitCppMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
476     const std::string &prefix, unsigned int innerLevel) const
477 {
478     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
479         sb.Append(prefix).AppendFormat("if (!WritePodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
480         sb.Append(prefix + TAB)
481             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write %s\", __func__);\n", name.c_str());
482         sb.Append(prefix + TAB).Append("return false;\n");
483         sb.Append(prefix).Append("}\n");
484         return;
485     }
486 
487     sb.Append(prefix).AppendFormat("if (!%s.WriteUint32(%s.size())) {\n", parcelName.c_str(), name.c_str());
488     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed write %s.size\", __func__);\n", name.c_str());
489     sb.Append(prefix + TAB).Append("return false;\n");
490     sb.Append(prefix).Append("}\n");
491     std::string elementName = StringHelper::Format("it%d", innerLevel++);
492     sb.Append(prefix).AppendFormat("for (const auto& %s : %s) {\n", elementName.c_str(), name.c_str());
493     elementType_->EmitCppMarshalling(parcelName, elementName, sb, prefix + TAB, innerLevel);
494     sb.Append(prefix).Append("}\n");
495 }
496 
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool emitType,unsigned int innerLevel) const497 void ASTArrayType::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
498     const std::string &prefix, bool emitType, unsigned int innerLevel) const
499 {
500     size_t index = name.find('.');
501     std::string memberName = (index == std::string::npos) ? name : StringHelper::SubStr(name, index + 1);
502     std::string sizeName = StringHelper::Format("%sSize", memberName.c_str());
503     if (emitType) {
504         sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().c_str(), memberName.c_str());
505     }
506 
507     if (!elementType_->IsBooleanType() && elementType_->IsPod()) {
508         sb.Append(prefix).AppendFormat("if (!ReadPodArray(%s, %s)) {\n", parcelName.c_str(), name.c_str());
509         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", name.c_str());
510         sb.Append(prefix + TAB).Append("return false;\n");
511         sb.Append(prefix).Append("}\n");
512         return;
513     }
514 
515     sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", sizeName.c_str());
516     sb.Append(prefix).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), sizeName.c_str());
517     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
518     sb.Append(prefix + TAB).Append("return false;\n");
519     sb.Append(prefix).Append("}\n\n");
520     sb.Append(prefix).AppendFormat("%s(%s, >, %s / sizeof(%s), false);\n", CHECK_VALUE_RETURN_MACRO, sizeName.c_str(),
521         MAX_BUFF_SIZE_MACRO, elementType_->EmitCppType().c_str());
522     sb.Append(prefix).AppendFormat("%s.clear();\n", name.c_str());
523     sb.Append(prefix).AppendFormat("%s.reserve(%s);\n", name.c_str(), sizeName.c_str());
524     sb.Append(prefix).AppendFormat(
525         "for (uint32_t i%d = 0; i%d < %s; ++i%d) {\n", innerLevel, innerLevel, sizeName.c_str(), innerLevel);
526     std::string valueName = StringHelper::Format("value%d", innerLevel++);
527     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
528         sb.Append(prefix + TAB).AppendFormat("%s %s;\n", elementType_->EmitCppType().c_str(), valueName.c_str());
529     }
530     elementType_->EmitCppUnMarshalling(parcelName, valueName, sb, prefix + TAB, true, innerLevel);
531     sb.Append(prefix + TAB).AppendFormat("%s.push_back(%s);\n", name.c_str(), valueName.c_str());
532 
533     sb.Append(prefix).Append("}\n");
534 }
535 
EmitMemoryRecycle(const std::string & name,bool isClient,bool ownership,StringBuilder & sb,const std::string & prefix) const536 void ASTArrayType::EmitMemoryRecycle(
537     const std::string &name, bool isClient, bool ownership, StringBuilder &sb, const std::string &prefix) const
538 {
539     std::string varName = name;
540     std::string lenName =
541         isClient ? StringHelper::Format("*%sLen", name.c_str()) : StringHelper::Format("%sLen", name.c_str());
542     sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", varName.c_str());
543     auto elementTypeNeedFree = [this]() -> bool {
544         if (elementType_->IsPod()) {
545             return false;
546         }
547 
548         if (elementType_->IsStructType() || elementType_->IsStringType()) {
549             return true;
550         }
551         return false;
552     };
553     if (elementTypeNeedFree()) {
554         if (Options::GetInstance().DoGenerateKernelCode()) {
555             sb.Append(prefix + TAB).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
556         } else {
557             sb.Append(prefix + TAB).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
558         }
559 
560         std::string elementName = StringHelper::Format("%s[i]", varName.c_str());
561         elementType_->EmitMemoryRecycle(elementName, false, false, sb, prefix + TAB + TAB);
562         sb.Append(prefix + TAB).Append("}\n");
563     }
564 
565     sb.Append(prefix + TAB).AppendFormat("OsalMemFree(%s);\n", varName.c_str());
566     if (isClient) {
567         sb.Append(prefix + TAB).AppendFormat("%s = NULL;\n", varName.c_str());
568     }
569     sb.Append(prefix).Append("}\n");
570 }
571 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const572 void ASTArrayType::EmitJavaWriteVar(
573     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
574 {
575     sb.Append(prefix).AppendFormat("if (%s == null) {\n", name.c_str());
576     sb.Append(prefix + TAB).AppendFormat("%s.writeInt(-1);\n", parcelName.c_str());
577     sb.Append(prefix).Append("} else { \n");
578     EmitJavaWriteArrayVar(parcelName, name, sb, prefix + TAB);
579     sb.Append(prefix).Append("}\n");
580 }
581 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const582 void ASTArrayType::EmitJavaReadVar(
583     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
584 {
585     switch (elementType_->GetTypeKind()) {
586         case TypeKind::TYPE_BOOLEAN:
587             sb.Append(prefix).AppendFormat("%s.readBooleanArray(%s);\n", parcelName.c_str(), name.c_str());
588             break;
589         case TypeKind::TYPE_BYTE:
590             sb.Append(prefix).AppendFormat("%s.readByteArray(%s);\n", parcelName.c_str(), name.c_str());
591             break;
592         case TypeKind::TYPE_SHORT:
593             sb.Append(prefix).AppendFormat("%s.readShortArray(%s);\n", parcelName.c_str(), name.c_str());
594             break;
595         case TypeKind::TYPE_INT:
596         case TypeKind::TYPE_FILEDESCRIPTOR:
597             sb.Append(prefix).AppendFormat("%s.readIntArray(%s);\n", parcelName.c_str(), name.c_str());
598             break;
599         case TypeKind::TYPE_LONG:
600             sb.Append(prefix).AppendFormat("%s.readLongArray(%s);\n", parcelName.c_str(), name.c_str());
601             break;
602         case TypeKind::TYPE_FLOAT:
603             sb.Append(prefix).AppendFormat("%s.readFloatArray(%s);\n", parcelName.c_str(), name.c_str());
604             break;
605         case TypeKind::TYPE_DOUBLE:
606             sb.Append(prefix).AppendFormat("%s.readDoubleArray(%s);\n", parcelName.c_str(), name.c_str());
607             break;
608         case TypeKind::TYPE_STRING:
609             sb.Append(prefix).AppendFormat("%s.readStringArray(%s);\n", parcelName.c_str(), name.c_str());
610             break;
611         case TypeKind::TYPE_SEQUENCEABLE:
612             sb.Append(prefix).AppendFormat("%s.readSequenceableArray(%s);\n", parcelName.c_str(), name.c_str());
613             break;
614         default:
615             break;
616     }
617 }
618 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const619 void ASTArrayType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
620     StringBuilder &sb, const std::string &prefix) const
621 {
622     switch (elementType_->GetTypeKind()) {
623         case TypeKind::TYPE_BOOLEAN:
624             sb.Append(prefix).AppendFormat("%s[] %s = %s.readBooleanArray();\n",
625                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
626             break;
627         case TypeKind::TYPE_BYTE:
628             sb.Append(prefix).AppendFormat("%s[] %s = %s.readByteArray();\n",
629                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
630             break;
631         case TypeKind::TYPE_SHORT:
632             sb.Append(prefix).AppendFormat("%s[] %s = %s.readShortArray();\n",
633                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
634             break;
635         case TypeKind::TYPE_INT:
636         case TypeKind::TYPE_FILEDESCRIPTOR:
637             sb.Append(prefix).AppendFormat("%s[] %s = %s.readIntArray();\n",
638                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
639             break;
640         case TypeKind::TYPE_LONG:
641             sb.Append(prefix).AppendFormat("%s[] %s = %s.readLongArray();\n",
642                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
643             break;
644         case TypeKind::TYPE_FLOAT:
645             sb.Append(prefix).AppendFormat("%s[] %s = %s.readFloatArray();\n",
646                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
647             break;
648         case TypeKind::TYPE_DOUBLE:
649             sb.Append(prefix).AppendFormat("%s[] %s = %s.readDoubleArray();\n",
650                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
651             break;
652         case TypeKind::TYPE_STRING:
653             sb.Append(prefix).AppendFormat("%s[] %s = %s.readStringArray();\n",
654                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
655             break;
656         case TypeKind::TYPE_SEQUENCEABLE:
657             sb.Append(prefix).AppendFormat("int size = %s.readInt();\n", parcelName.c_str());
658             sb.Append(prefix).AppendFormat("%s %s = new %s[size];\n",
659                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(),
660                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str());
661             sb.Append(prefix).AppendFormat("for (int i = 0; i < size; ++i) {\n");
662             elementType_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + TAB);
663             sb.Append(prefix + TAB).AppendFormat("%s[i] = value;\n", name.c_str());
664             sb.Append(prefix).Append("}\n");
665             break;
666         default:
667             break;
668     }
669 }
670 
EmitJavaWriteArrayVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const671 void ASTArrayType::EmitJavaWriteArrayVar(
672     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
673 {
674     switch (elementType_->GetTypeKind()) {
675         case TypeKind::TYPE_BOOLEAN:
676             sb.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.c_str(), name.c_str());
677             break;
678         case TypeKind::TYPE_BYTE:
679             sb.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n", parcelName.c_str(), name.c_str());
680             break;
681         case TypeKind::TYPE_SHORT:
682             sb.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.c_str(), name.c_str());
683             break;
684         case TypeKind::TYPE_INT:
685         case TypeKind::TYPE_FILEDESCRIPTOR:
686             sb.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.c_str(), name.c_str());
687             break;
688         case TypeKind::TYPE_LONG:
689             sb.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.c_str(), name.c_str());
690             break;
691         case TypeKind::TYPE_FLOAT:
692             sb.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.c_str(), name.c_str());
693             break;
694         case TypeKind::TYPE_DOUBLE:
695             sb.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.c_str(), name.c_str());
696             break;
697         case TypeKind::TYPE_STRING:
698             sb.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.c_str(), name.c_str());
699             break;
700         case TypeKind::TYPE_SEQUENCEABLE:
701             sb.Append(prefix).AppendFormat("%s.writeSequenceableArray(%s);\n", parcelName.c_str(), name.c_str());
702             break;
703         default:
704             break;
705     }
706 }
707 
EmitCMallocVar(const std::string & name,const std::string & lenName,bool isClient,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const708 void ASTArrayType::EmitCMallocVar(const std::string &name, const std::string &lenName, bool isClient,
709     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
710 {
711     std::string varName = isClient ? StringHelper::Format("*%s", name.c_str()) : name;
712     std::string lenVarName = isClient ? StringHelper::Format("*%s", lenName.c_str()) : lenName;
713     sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * (%s));\n", varName.c_str(),
714         elementType_->EmitCType().c_str(), elementType_->EmitCType().c_str(), lenVarName.c_str());
715     sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", varName.c_str());
716     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", varName.c_str());
717     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", ecName.c_str());
718     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
719     sb.Append(prefix).Append("}\n");
720 }
721 
RegisterWriteMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const722 void ASTArrayType::RegisterWriteMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
723 {
724     elementType_->RegisterWriteMethod(language, mode, methods);
725     if (elementType_->IsPod()) {
726         RegisterWritePodArrayMethod(language, mode, methods);
727     } else if (elementType_->IsStringType()) {
728         RegisterWriteStringArrayMethod(language, mode, methods);
729     }
730 }
731 
RegisterReadMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const732 void ASTArrayType::RegisterReadMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
733 {
734     elementType_->RegisterReadMethod(language, mode, methods);
735     if (elementType_->IsPod()) {
736         RegisterReadPodArrayMethod(language, mode, methods);
737     } else if (elementType_->IsStringType()) {
738         RegisterReadStringArrayMethod(language, mode, methods);
739     }
740 }
741 
RegisterWritePodArrayMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const742 void ASTArrayType::RegisterWritePodArrayMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
743 {
744     using namespace std::placeholders;
745     std::string methodName = "WritePodArray";
746     switch (language) {
747         case Options::Language::C:
748             methods.emplace(methodName, std::bind(&ASTArrayType::EmitCWriteMethods, this, _1, _2, _3, _4));
749             break;
750         case Options::Language::CPP:
751             methods.emplace(methodName, std::bind(&ASTArrayType::EmitCppWriteMethods, this, _1, _2, _3, _4));
752             break;
753         default:
754             break;
755     }
756 }
757 
RegisterWriteStringArrayMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const758 void ASTArrayType::RegisterWriteStringArrayMethod(
759     Options::Language language, SerMode mode, UtilMethodMap &methods) const
760 {
761     using namespace std::placeholders;
762     if (language == Options::Language::C && elementType_->IsStringType()) {
763         methods.emplace("WriteStringArray", std::bind(&ASTArrayType::EmitCWriteStrArrayMethods, this, _1, _2, _3, _4));
764     }
765 }
766 
RegisterReadPodArrayMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const767 void ASTArrayType::RegisterReadPodArrayMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
768 {
769     using namespace std::placeholders;
770     std::string methodName = "ReadPodArray";
771     switch (language) {
772         case Options::Language::C: {
773             auto readMethod = mode == SerMode::PROXY_SER ?
774                 std::bind(&ASTArrayType::EmitCReadMethods, this, _1, _2, _3, _4) :
775                 std::bind(&ASTArrayType::EmitCStubReadMethods, this, _1, _2, _3, _4);
776             methods.emplace(methodName, readMethod);
777             break;
778         }
779         case Options::Language::CPP:
780             methods.emplace(methodName, std::bind(&ASTArrayType::EmitCppReadMethods, this, _1, _2, _3, _4));
781             break;
782         default:
783             break;
784     }
785 }
786 
RegisterReadStringArrayMethod(Options::Language language,SerMode mode,UtilMethodMap & methods) const787 void ASTArrayType::RegisterReadStringArrayMethod(Options::Language language, SerMode mode, UtilMethodMap &methods) const
788 {
789     using namespace std::placeholders;
790     if (language == Options::Language::C && elementType_->IsStringType()) {
791         auto readMethod = mode == SerMode::PROXY_SER ?
792             std::bind(&ASTArrayType::EmitCReadStrArrayMethods, this, _1, _2, _3, _4) :
793             std::bind(&ASTArrayType::EmitCStubReadStrArrayMethods, this, _1, _2, _3, _4);
794         methods.emplace("ReadStringArray", readMethod);
795     }
796 }
797 
EmitCWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const798 void ASTArrayType::EmitCWriteMethods(
799     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
800 {
801     std::string methodName = StringHelper::Format("%sWritePodArray", methodPrefix.c_str());
802     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
803     sb.Append("struct HdfSBuf *parcel, const void *data, uint32_t elementSize, uint32_t count)");
804     if (isDecl) {
805         sb.Append(";\n");
806         return;
807     } else {
808         sb.Append("\n");
809     }
810 
811     sb.Append(prefix).Append("{\n");
812     sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUint32(parcel, count)) {\n");
813     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array size\", __func__);\n");
814     sb.Append(prefix + TAB + TAB).Append("return false;\n");
815     sb.Append(prefix + TAB).Append("}\n\n");
816 
817     sb.Append(prefix + TAB).Append("if (data == NULL && count == 0) {\n");
818     sb.Append(prefix + TAB + TAB).Append("return true;\n");
819     sb.Append(prefix + TAB).Append("}\n\n");
820 
821     if (Options::GetInstance().DoGenerateKernelCode()) {
822         sb.Append(prefix + TAB).Append("if (!HdfSbufWriteBuffer(");
823         sb.Append("parcel, (const void *)data, elementSize * count)) {\n");
824     } else {
825         sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUnpadBuffer(");
826         sb.Append("parcel, (const uint8_t *)data, elementSize * count)) {\n");
827     }
828 
829     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array\", __func__);\n");
830     sb.Append(prefix + TAB + TAB).Append("return false;\n");
831     sb.Append(prefix + TAB).Append("}\n\n");
832 
833     sb.Append(prefix + TAB).Append("return true;\n");
834     sb.Append(prefix).Append("}\n");
835 }
836 
EmitCReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const837 void ASTArrayType::EmitCReadMethods(
838     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
839 {
840     std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
841     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
842     sb.Append("struct HdfSBuf *parcel, void *data, uint32_t elementSize, uint32_t *count)");
843     if (isDecl) {
844         sb.Append(";\n");
845         return;
846     } else {
847         sb.Append("\n");
848     }
849 
850     sb.Append(prefix).Append("{\n");
851     if (Options::GetInstance().DoGenerateKernelCode()) {
852         sb.Append(prefix + TAB).Append("void *dataPtr = NULL;\n");
853         sb.Append(prefix + TAB).Append("uint32_t dataLen = 0;\n");
854     }
855     sb.Append(prefix + TAB).Append("uint32_t elementCount = 0;\n");
856     sb.Append(prefix + TAB).Append("if (!HdfSbufReadUint32(parcel, &elementCount)) {\n");
857     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read array size\", __func__);\n");
858     sb.Append(prefix + TAB + TAB).Append("return false;\n");
859     sb.Append(prefix + TAB).Append("}\n\n");
860 
861     sb.Append(prefix + TAB).AppendFormat("if (elementCount > %s / elementSize) {\n", MAX_BUFF_SIZE_MACRO);
862     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid elementCount\", __func__);\n");
863     sb.Append(prefix + TAB + TAB).Append("return false;\n");
864     sb.Append(prefix + TAB).Append("}\n\n");
865 
866     sb.Append(prefix + TAB).Append("if (elementCount == 0) {\n");
867     sb.Append(prefix + TAB + TAB).Append("goto FINISHED;\n");
868     sb.Append(prefix + TAB).Append("}\n\n");
869 
870     if (Options::GetInstance().DoGenerateKernelCode()) {
871         sb.Append(prefix + TAB).Append("if (!HdfSbufReadBuffer(parcel, (const void **)&dataPtr, &dataLen)) {\n");
872     } else {
873         sb.Append(prefix + TAB)
874             .Append("const void * dataPtr = HdfSbufReadUnpadBuffer(parcel, elementSize * elementCount);\n");
875         sb.Append(prefix + TAB).Append("if (dataPtr == NULL) {\n");
876     }
877 
878     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read array\", __func__);\n");
879     sb.Append(prefix + TAB + TAB).Append("return false;\n");
880     sb.Append(prefix + TAB).Append("}\n\n");
881 
882     sb.Append(prefix + TAB).Append("if (memcpy_s(");
883     sb.Append("data, elementSize * elementCount, dataPtr, elementSize * elementCount) != EOK) {\n");
884     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to copy array data\", __func__);\n");
885     sb.Append(prefix + TAB + TAB).Append("return false;\n");
886     sb.Append(prefix + TAB).Append("}\n\n");
887 
888     sb.Append("FINISHED:\n");
889     sb.Append(prefix + TAB).Append("*count = elementCount;\n");
890     sb.Append(prefix + TAB).Append("return true;\n");
891     sb.Append(prefix).Append("}\n");
892 }
893 
EmitCStubReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const894 void ASTArrayType::EmitCStubReadMethods(
895     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
896 {
897     std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
898     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
899     sb.Append("struct HdfSBuf *parcel, void **data, uint32_t elementSize, uint32_t *count)");
900     if (isDecl) {
901         sb.Append(";\n");
902         return;
903     } else {
904         sb.Append("\n");
905     }
906     sb.Append(prefix).Append("{\n");
907     EmitCStubReadMethodBody(sb, prefix + TAB);
908     sb.Append(prefix).Append("}\n");
909 }
910 
EmitCStubReadMethodBody(StringBuilder & sb,const std::string & prefix) const911 void ASTArrayType::EmitCStubReadMethodBody(StringBuilder &sb, const std::string &prefix) const
912 {
913     sb.Append(prefix).Append("const void * dataPtr = NULL;\n");
914     if (Options::GetInstance().DoGenerateKernelCode()) {
915         sb.Append(prefix).Append("uint32_t dataLen = 0;\n");
916     }
917     sb.Append(prefix).Append("void *memPtr = NULL;\n");
918     sb.Append(prefix).Append("uint32_t elementCount = 0;\n");
919     sb.Append(prefix).Append("if (count == NULL || data == NULL || elementSize == 0) {\n");
920     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid param\", __func__);\n");
921     sb.Append(prefix + TAB).Append("return false;\n");
922     sb.Append(prefix).Append("}\n\n");
923     sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &elementCount)) {\n");
924     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read element count\", __func__);\n");
925     sb.Append(prefix + TAB).Append("return false;\n");
926     sb.Append(prefix).Append("}\n\n");
927 
928     sb.Append(prefix).AppendFormat("if (elementCount > %s / elementSize) {\n", MAX_BUFF_SIZE_MACRO);
929     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid elementCount\", __func__);\n");
930     sb.Append(prefix + TAB).Append("return false;\n");
931     sb.Append(prefix).Append("}\n\n");
932 
933     sb.Append(prefix).Append("if (elementCount == 0) {\n");
934     sb.Append(prefix + TAB).Append("*count = elementCount;\n");
935     sb.Append(prefix + TAB).Append("return true;\n");
936     sb.Append(prefix).Append("}\n\n");
937     if (Options::GetInstance().DoGenerateKernelCode()) {
938         sb.Append(prefix).Append("if (!HdfSbufReadBuffer(parcel, (const void **)&dataPtr, &dataLen)) {\n");
939     } else {
940         sb.Append(prefix).Append("dataPtr = HdfSbufReadUnpadBuffer(parcel, elementSize * elementCount);\n");
941         sb.Append(prefix).Append("if (dataPtr == NULL) {\n");
942     }
943     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
944     sb.Append(prefix + TAB).Append("return false;\n");
945     sb.Append(prefix).Append("}\n\n");
946     sb.Append(prefix).Append("memPtr = OsalMemCalloc(elementSize * elementCount);\n");
947     sb.Append(prefix).Append("if (memPtr == NULL) {\n");
948     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc buffer\", __func__);\n");
949     sb.Append(prefix + TAB).Append("return false;\n");
950     sb.Append(prefix).Append("}\n\n");
951     sb.Append(prefix).Append(
952         "if (memcpy_s(memPtr, elementSize * elementCount, dataPtr, elementSize * elementCount) != EOK) {\n");
953     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy buffer\", __func__);\n");
954     sb.Append(prefix + TAB).Append("OsalMemFree(memPtr);\n");
955     sb.Append(prefix + TAB).Append("return false;\n");
956     sb.Append(prefix).Append("}\n\n");
957     sb.Append(prefix).Append("*data = memPtr;\n");
958     sb.Append(prefix).Append("*count = elementCount;\n");
959     sb.Append(prefix).Append("return true;\n");
960 }
961 
EmitCWriteStrArrayMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const962 void ASTArrayType::EmitCWriteStrArrayMethods(
963     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
964 {
965     std::string methodName = StringHelper::Format("%sWriteStringArray", methodPrefix.c_str());
966     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
967     sb.Append("struct HdfSBuf *parcel, char **data, uint32_t count)");
968     if (isDecl) {
969         sb.Append(";\n");
970         return;
971     } else {
972         sb.Append("\n");
973     }
974     sb.Append(prefix).Append("{\n");
975     sb.Append(prefix + TAB).Append("uint32_t i = 0;\n");
976     sb.Append(prefix + TAB).Append("if (parcel == NULL) {\n");
977     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
978     sb.Append(prefix + TAB + TAB).Append("return false;\n");
979     sb.Append(prefix + TAB).Append("}\n\n");
980     sb.Append(prefix + TAB).AppendFormat("if (count > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
981     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid count\", __func__);\n");
982     sb.Append(prefix + TAB + TAB).Append("return false;\n");
983     sb.Append(prefix + TAB).Append("}\n\n");
984     sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUint32(parcel, count)) {\n");
985     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write count of array\", __func__);\n");
986     sb.Append(prefix + TAB + TAB).Append("return false;\n");
987     sb.Append(prefix + TAB).Append("}\n\n");
988     sb.Append(prefix + TAB).Append("if (count == 0) {\n");
989     sb.Append(prefix + TAB + TAB).Append("return true;\n");
990     sb.Append(prefix + TAB).Append("}\n\n");
991     sb.Append(prefix + TAB).Append("if (data == NULL) {\n");
992     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid array object\", __func__);\n");
993     sb.Append(prefix + TAB + TAB).Append("return false;\n");
994     sb.Append(prefix + TAB).Append("}\n\n");
995     sb.Append(prefix + TAB).Append("for (i = 0; i < count; i++) {\n");
996     sb.Append(prefix + TAB + TAB).Append("if (!HdfSbufWriteString(parcel, data[i])) {\n");
997     sb.Append(prefix + TAB + TAB + TAB)
998         .Append("HDF_LOGE(\"%{public}s: failed to write element of array\", __func__);\n");
999     sb.Append(prefix + TAB + TAB + TAB).Append("return false;\n");
1000     sb.Append(prefix + TAB + TAB).Append("}\n");
1001     sb.Append(prefix + TAB).Append("}\n\n");
1002     sb.Append(prefix + TAB).Append("return true;\n");
1003     sb.Append(prefix).Append("}\n");
1004 }
1005 
EmitCReadStrArrayMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1006 void ASTArrayType::EmitCReadStrArrayMethods(
1007     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1008 {
1009     std::string methodName = StringHelper::Format("%sReadStringArray", methodPrefix.c_str());
1010     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
1011     sb.Append("struct HdfSBuf *parcel, char **data, uint32_t *count)");
1012     if (isDecl) {
1013         sb.Append(";\n");
1014         return;
1015     } else {
1016         sb.Append("\n");
1017     }
1018     sb.Append(prefix).Append("{\n");
1019     EmitCReadStrArrayMethodBody(sb, prefix + TAB);
1020     sb.Append(prefix).Append("}\n");
1021 }
1022 
EmitCReadStrArrayMethodBody(StringBuilder & sb,const std::string & prefix) const1023 void ASTArrayType::EmitCReadStrArrayMethodBody(StringBuilder &sb, const std::string &prefix) const
1024 {
1025     sb.Append(prefix).Append("uint32_t i = 0;\n");
1026     sb.Append(prefix).Append("uint32_t dataCount = 0;\n");
1027     EmitCCheckParamOfReadStringArray(sb, prefix);
1028     sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &dataCount)) {\n");
1029     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read count of array\", __func__);\n");
1030     sb.Append(prefix + TAB).Append("return false;\n");
1031     sb.Append(prefix).Append("}\n\n");
1032     sb.Append(prefix).AppendFormat("if (dataCount > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
1033     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid dataCount\", __func__);\n");
1034     sb.Append(prefix + TAB).Append("return false;\n");
1035     sb.Append(prefix).Append("}\n\n");
1036     sb.Append(prefix).Append("if (dataCount == 0) {\n");
1037     sb.Append(prefix + TAB).Append("*count = dataCount;\n");
1038     sb.Append(prefix + TAB).Append("return true;\n");
1039     sb.Append(prefix).Append("}\n\n");
1040     sb.Append(prefix).Append("for (i = 0; i < dataCount; i++) {\n");
1041     sb.Append(prefix + TAB).Append("char *elementStr = NULL;\n");
1042     sb.Append(prefix + TAB).Append("uint32_t strLen = 0;\n");
1043     sb.Append(prefix + TAB).Append("const char *str = HdfSbufReadString(parcel);\n");
1044     sb.Append(prefix + TAB).Append("if (str == NULL) {\n");
1045     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read string\", __func__);\n");
1046     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1047     sb.Append(prefix + TAB).Append("}\n");
1048     sb.Append(prefix + TAB).Append("strLen = strlen(str);\n");
1049     sb.Append(prefix + TAB).Append("elementStr = (char *)OsalMemCalloc(strLen + 1);\n");
1050     sb.Append(prefix + TAB).Append("if (elementStr == NULL) {\n");
1051     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc element of array\", __func__);\n");
1052     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1053     sb.Append(prefix + TAB).Append("}\n");
1054     sb.Append(prefix + TAB).Append("if (strcpy_s(elementStr, strLen + 1, str) != EOK) {\n");
1055     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed copy element of array\", __func__);\n");
1056     sb.Append(prefix + TAB + TAB).Append("OsalMemFree(elementStr);\n");
1057     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1058     sb.Append(prefix + TAB).Append("}\n");
1059     sb.Append(prefix + TAB).Append("data[i] = elementStr;\n");
1060     sb.Append(prefix).Append("}\n\n");
1061     sb.Append(prefix).Append("*count = dataCount;\n");
1062     sb.Append(prefix).Append("return true;\n\n");
1063     sb.Append("ERROR:\n");
1064     sb.Append(prefix).Append("for (i = 0; i < dataCount; ++i) {\n");
1065     sb.Append(prefix + TAB).Append("if (data[i] != NULL) {\n");
1066     sb.Append(prefix + TAB + TAB).Append("OsalMemFree(data[i]);\n");
1067     sb.Append(prefix + TAB + TAB).Append("data[i] = NULL;\n");
1068     sb.Append(prefix + TAB).Append("}\n");
1069     sb.Append(prefix).Append("}\n");
1070     sb.Append(prefix).Append("*count = 0;\n");
1071     sb.Append(prefix).Append("return false;\n");
1072 }
1073 
EmitCCheckParamOfReadStringArray(StringBuilder & sb,const std::string & prefix) const1074 void ASTArrayType::EmitCCheckParamOfReadStringArray(StringBuilder &sb, const std::string &prefix) const
1075 {
1076     sb.Append(prefix).Append("if (parcel == NULL) {\n");
1077     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
1078     sb.Append(prefix + TAB).Append("return false;\n");
1079     sb.Append(prefix).Append("}\n\n");
1080     sb.Append(prefix).Append("if (data == NULL || count == NULL) {\n");
1081     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid array object\", __func__);\n");
1082     sb.Append(prefix + TAB).Append("return false;\n");
1083     sb.Append(prefix).Append("}\n\n");
1084 }
1085 
EmitCStubReadStrArrayMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1086 void ASTArrayType::EmitCStubReadStrArrayMethods(
1087     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1088 {
1089     std::string methodName = StringHelper::Format("%sReadStringArray", methodPrefix.c_str());
1090     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
1091     sb.Append("struct HdfSBuf *parcel, char ***data, uint32_t *count)");
1092     if (isDecl) {
1093         sb.Append(";\n");
1094         return;
1095     } else {
1096         sb.Append("\n");
1097     }
1098     sb.Append(prefix).Append("{\n");
1099     EmitCStubReadStrArrayMethodBody(sb, prefix + TAB);
1100     sb.Append(prefix).Append("}\n");
1101 }
1102 
EmitCStubReadStrArrayMethodBody(StringBuilder & sb,const std::string & prefix) const1103 void ASTArrayType::EmitCStubReadStrArrayMethodBody(StringBuilder &sb, const std::string &prefix) const
1104 {
1105     sb.Append(prefix).Append("uint32_t i = 0;\n");
1106     sb.Append(prefix).Append("char **dataPtr = NULL;\n");
1107     sb.Append(prefix).Append("uint32_t dataCount = 0;\n");
1108     EmitCCheckParamOfReadStringArray(sb, prefix);
1109     sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &dataCount)) {\n");
1110     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read count of array\", __func__);\n");
1111     sb.Append(prefix + TAB).Append("return false;\n");
1112     sb.Append(prefix).Append("}\n\n");
1113     sb.Append(prefix).AppendFormat("if (dataCount > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
1114     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid dataCount\", __func__);\n");
1115     sb.Append(prefix + TAB).Append("return false;\n");
1116     sb.Append(prefix).Append("}\n\n");
1117     sb.Append(prefix).Append("if (dataCount == 0) {\n");
1118     sb.Append(prefix + TAB).Append("*count = dataCount;\n");
1119     sb.Append(prefix + TAB).Append("return true;\n");
1120     sb.Append(prefix).Append("}\n\n");
1121     sb.Append(prefix).Append("dataPtr = (char **)OsalMemCalloc(sizeof(char *) * dataCount);\n");
1122     sb.Append(prefix).Append("if (dataPtr == NULL) {\n");
1123     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc array\", __func__);\n");
1124     sb.Append(prefix + TAB).Append("return false;\n");
1125     sb.Append(prefix).Append("}\n\n");
1126     sb.Append(prefix).Append("for (i = 0; i < dataCount; i++) {\n");
1127     sb.Append(prefix + TAB).Append("char *elementStr = NULL;\n");
1128     sb.Append(prefix + TAB).Append("uint32_t strLen = 0;\n");
1129     sb.Append(prefix + TAB).Append("const char *str = HdfSbufReadString(parcel);\n");
1130     sb.Append(prefix + TAB).Append("if (str == NULL) {\n");
1131     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc array\", __func__);\n");
1132     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1133     sb.Append(prefix + TAB).Append("}\n\n");
1134     sb.Append(prefix + TAB).Append("strLen = strlen(str);\n");
1135     sb.Append(prefix + TAB).Append("elementStr = (char *)OsalMemCalloc(strLen + 1);\n");
1136     sb.Append(prefix + TAB).Append("if (elementStr == NULL) {\n");
1137     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc element of array\", __func__);\n");
1138     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1139     sb.Append(prefix + TAB).Append("}\n\n");
1140     sb.Append(prefix + TAB).Append("if (strcpy_s(elementStr, strLen + 1, str) != EOK) {\n");
1141     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed copy element of array\", __func__);\n");
1142     sb.Append(prefix + TAB + TAB).Append("OsalMemFree(elementStr);\n");
1143     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1144     sb.Append(prefix + TAB).Append("}\n");
1145     sb.Append(prefix + TAB).Append("dataPtr[i] = elementStr;\n");
1146     sb.Append(prefix).Append("}\n\n");
1147     sb.Append(prefix).Append("*count = dataCount;\n");
1148     sb.Append(prefix).Append("*data = dataPtr;\n");
1149     sb.Append(prefix).Append("return true;\n\n");
1150     EmitCStubReadStrArrayFree(sb, prefix);
1151 }
1152 
EmitCStubReadStrArrayFree(StringBuilder & sb,const std::string & prefix) const1153 void ASTArrayType::EmitCStubReadStrArrayFree(StringBuilder &sb, const std::string &prefix) const
1154 {
1155     sb.Append("ERROR:\n");
1156     sb.Append(prefix).Append("if (dataPtr != NULL) {\n");
1157     sb.Append(prefix + TAB).Append("for (i = 0; i < dataCount; i++) {\n");
1158     sb.Append(prefix + TAB + TAB).Append("if (dataPtr[i] != NULL) {\n");
1159     sb.Append(prefix + TAB + TAB + TAB).Append("OsalMemFree(dataPtr[i]);\n");
1160     sb.Append(prefix + TAB + TAB + TAB).Append("dataPtr[i] = NULL;\n");
1161     sb.Append(prefix + TAB + TAB).Append("}\n");
1162     sb.Append(prefix + TAB).Append("}\n");
1163     sb.Append(prefix + TAB).Append("OsalMemFree(dataPtr);\n");
1164     sb.Append(prefix).Append("}\n\n");
1165     sb.Append(prefix).Append("*count = 0;\n");
1166     sb.Append(prefix).Append("return false;\n");
1167 }
1168 
EmitCppWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1169 void ASTArrayType::EmitCppWriteMethods(
1170     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1171 {
1172     std::string methodName = StringHelper::Format("%sWritePodArray", methodPrefix.c_str());
1173     sb.Append(prefix).AppendFormat("template<typename ElementType>\n");
1174     sb.Append(prefix).AppendFormat(
1175         "static bool %s(MessageParcel &parcel, const std::vector<ElementType> &data)", methodName.c_str());
1176     if (isDecl) {
1177         sb.Append(";\n");
1178         return;
1179     } else {
1180         sb.Append("\n");
1181     }
1182 
1183     sb.Append(prefix).Append("{\n");
1184     sb.Append(prefix + TAB).Append("if (!parcel.WriteUint32(data.size())) {\n");
1185     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write data size\", __func__);\n");
1186     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1187     sb.Append(prefix + TAB).Append("}\n");
1188 
1189     sb.Append(prefix + TAB).Append("if (data.empty()) {\n");
1190     sb.Append(prefix + TAB + TAB).Append("return true;\n");
1191     sb.Append(prefix + TAB).Append("}\n");
1192 
1193     sb.Append(prefix + TAB).Append("if (!parcel.WriteUnpadBuffer(");
1194     sb.Append("(const void*)data.data(), sizeof(ElementType) * data.size())) {\n");
1195     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array\", __func__);\n");
1196     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1197     sb.Append(prefix + TAB).Append("}\n");
1198 
1199     sb.Append(prefix + TAB).Append("return true;\n");
1200     sb.Append(prefix).Append("}\n");
1201 }
1202 
EmitCppReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1203 void ASTArrayType::EmitCppReadMethods(
1204     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1205 {
1206     std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
1207     sb.Append(prefix).AppendFormat("template<typename ElementType>\n");
1208     sb.Append(prefix).AppendFormat(
1209         "static bool %s(MessageParcel &parcel, std::vector<ElementType> &data)", methodName.c_str());
1210     if (isDecl) {
1211         sb.Append(";\n");
1212         return;
1213     } else {
1214         sb.Append("\n");
1215     }
1216 
1217     sb.Append(prefix).Append("{\n");
1218     sb.Append(prefix + TAB).Append("data.clear();\n");
1219     sb.Append(prefix + TAB).Append("uint32_t size = 0;\n");
1220     sb.Append(prefix + TAB).Append("if (!parcel.ReadUint32(size)) {\n");
1221     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
1222     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1223     sb.Append(prefix + TAB).Append("}\n\n");
1224 
1225     sb.Append(prefix + TAB).Append("if (size == 0) {\n");
1226     sb.Append(prefix + TAB + TAB).Append("return true;\n");
1227     sb.Append(prefix + TAB).Append("}\n");
1228 
1229     sb.Append(prefix + TAB).Append("const ElementType *dataPtr = reinterpret_cast<const ElementType*>(");
1230     sb.Append("parcel.ReadUnpadBuffer(sizeof(ElementType) * size));\n");
1231     sb.Append(prefix + TAB).Append("if (dataPtr == nullptr) {\n");
1232     sb.Append(prefix + TAB + TAB).Append("HDF_LOGI(\"%{public}s: failed to read data\", __func__);\n");
1233     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1234     sb.Append(prefix + TAB).Append("}\n");
1235 
1236     sb.Append(prefix + TAB).Append("data.assign(dataPtr, dataPtr + size);\n");
1237     sb.Append(prefix + TAB).Append("return true;\n");
1238     sb.Append(prefix).Append("}\n");
1239 }
1240 
IsArrayType()1241 bool ASTListType::IsArrayType()
1242 {
1243     return false;
1244 }
1245 
IsListType()1246 bool ASTListType::IsListType()
1247 {
1248     return true;
1249 }
1250 
ToString() const1251 std::string ASTListType::ToString() const
1252 {
1253     return StringHelper::Format("List<%s>", elementType_->ToString().c_str());
1254 }
1255 
GetTypeKind()1256 TypeKind ASTListType::GetTypeKind()
1257 {
1258     return TypeKind::TYPE_LIST;
1259 }
1260 
EmitJavaType(TypeMode mode,bool isInnerType) const1261 std::string ASTListType::EmitJavaType(TypeMode mode, bool isInnerType) const
1262 {
1263     return StringHelper::Format("List<%s>", elementType_->EmitJavaType(mode, true).c_str());
1264 }
1265 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const1266 void ASTListType::EmitJavaWriteVar(
1267     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
1268 {
1269     sb.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.c_str(), name.c_str());
1270     sb.Append(prefix).AppendFormat(
1271         "for (%s element : %s) {\n", elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str());
1272     elementType_->EmitJavaWriteVar(parcelName, "element", sb, prefix + TAB);
1273     sb.Append(prefix).Append("}\n");
1274 }
1275 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const1276 void ASTListType::EmitJavaReadVar(
1277     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
1278 {
1279     sb.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(), parcelName.c_str());
1280     sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1281 
1282     elementType_->EmitJavaReadInnerVar(parcelName, "value", false, sb, prefix + TAB);
1283     sb.Append(prefix + TAB).AppendFormat("%s.add(value);\n", name.c_str());
1284     sb.Append(prefix).Append("}\n");
1285 }
1286 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const1287 void ASTListType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
1288     StringBuilder &sb, const std::string &prefix) const
1289 {
1290     sb.Append(prefix).AppendFormat("%s %s = new Array%s();\n", EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(),
1291         EmitJavaType(TypeMode::NO_MODE).c_str());
1292     sb.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(), parcelName.c_str());
1293     sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1294     elementType_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + TAB);
1295     sb.Append(prefix + TAB).AppendFormat("%s.add(value);\n", name.c_str());
1296     sb.Append(prefix).Append("}\n");
1297 }
1298 } // namespace HDI
1299 } // namespace OHOS