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