• 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 isClient,bool ownership,StringBuilder & sb,const std::string & prefix) const546 void ASTArrayType::EmitMemoryRecycle(
547     const std::string &name, bool isClient, bool ownership, StringBuilder &sb, const std::string &prefix) const
548 {
549     std::string varName = name;
550     std::string lenName =
551         isClient ? StringHelper::Format("*%sLen", name.c_str()) : StringHelper::Format("%sLen", name.c_str());
552     sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", varName.c_str());
553     auto elementTypeNeedFree = [this]() -> bool {
554         if (elementType_->IsPod()) {
555             return false;
556         }
557 
558         if (elementType_->IsStructType() || elementType_->IsStringType() || elementType_->IsNativeBufferType()) {
559             return true;
560         }
561         return false;
562     };
563     if (elementTypeNeedFree()) {
564         if (Options::GetInstance().DoGenerateKernelCode()) {
565             sb.Append(prefix + TAB).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.c_str());
566         } else {
567             sb.Append(prefix + TAB).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.c_str());
568         }
569 
570         std::string elementName = StringHelper::Format("%s[i]", varName.c_str());
571         elementType_->EmitMemoryRecycle(elementName, false, false, sb, prefix + TAB + TAB);
572         sb.Append(prefix + TAB).Append("}\n");
573     }
574 
575     sb.Append(prefix + TAB).AppendFormat("OsalMemFree(%s);\n", varName.c_str());
576     if (isClient) {
577         sb.Append(prefix + TAB).AppendFormat("%s = NULL;\n", varName.c_str());
578     }
579     sb.Append(prefix).Append("}\n");
580 }
581 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const582 void ASTArrayType::EmitJavaWriteVar(
583     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
584 {
585     sb.Append(prefix).AppendFormat("if (%s == null) {\n", name.c_str());
586     sb.Append(prefix + TAB).AppendFormat("%s.writeInt(-1);\n", parcelName.c_str());
587     sb.Append(prefix).Append("} else { \n");
588     EmitJavaWriteArrayVar(parcelName, name, sb, prefix + TAB);
589     sb.Append(prefix).Append("}\n");
590 }
591 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const592 void ASTArrayType::EmitJavaReadVar(
593     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
594 {
595     switch (elementType_->GetTypeKind()) {
596         case TypeKind::TYPE_BOOLEAN:
597             sb.Append(prefix).AppendFormat("%s.readBooleanArray(%s);\n", parcelName.c_str(), name.c_str());
598             break;
599         case TypeKind::TYPE_BYTE:
600             sb.Append(prefix).AppendFormat("%s.readByteArray(%s);\n", parcelName.c_str(), name.c_str());
601             break;
602         case TypeKind::TYPE_SHORT:
603             sb.Append(prefix).AppendFormat("%s.readShortArray(%s);\n", parcelName.c_str(), name.c_str());
604             break;
605         case TypeKind::TYPE_INT:
606         case TypeKind::TYPE_FILEDESCRIPTOR:
607             sb.Append(prefix).AppendFormat("%s.readIntArray(%s);\n", parcelName.c_str(), name.c_str());
608             break;
609         case TypeKind::TYPE_LONG:
610             sb.Append(prefix).AppendFormat("%s.readLongArray(%s);\n", parcelName.c_str(), name.c_str());
611             break;
612         case TypeKind::TYPE_FLOAT:
613             sb.Append(prefix).AppendFormat("%s.readFloatArray(%s);\n", parcelName.c_str(), name.c_str());
614             break;
615         case TypeKind::TYPE_DOUBLE:
616             sb.Append(prefix).AppendFormat("%s.readDoubleArray(%s);\n", parcelName.c_str(), name.c_str());
617             break;
618         case TypeKind::TYPE_STRING:
619             sb.Append(prefix).AppendFormat("%s.readStringArray(%s);\n", parcelName.c_str(), name.c_str());
620             break;
621         case TypeKind::TYPE_SEQUENCEABLE:
622             sb.Append(prefix).AppendFormat("%s.readSequenceableArray(%s);\n", parcelName.c_str(), name.c_str());
623             break;
624         default:
625             break;
626     }
627 }
628 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const629 void ASTArrayType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
630     StringBuilder &sb, const std::string &prefix) const
631 {
632     switch (elementType_->GetTypeKind()) {
633         case TypeKind::TYPE_BOOLEAN:
634             sb.Append(prefix).AppendFormat("%s[] %s = %s.readBooleanArray();\n",
635                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
636             break;
637         case TypeKind::TYPE_BYTE:
638             sb.Append(prefix).AppendFormat("%s[] %s = %s.readByteArray();\n",
639                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
640             break;
641         case TypeKind::TYPE_SHORT:
642             sb.Append(prefix).AppendFormat("%s[] %s = %s.readShortArray();\n",
643                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
644             break;
645         case TypeKind::TYPE_INT:
646         case TypeKind::TYPE_FILEDESCRIPTOR:
647             sb.Append(prefix).AppendFormat("%s[] %s = %s.readIntArray();\n",
648                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
649             break;
650         case TypeKind::TYPE_LONG:
651             sb.Append(prefix).AppendFormat("%s[] %s = %s.readLongArray();\n",
652                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
653             break;
654         case TypeKind::TYPE_FLOAT:
655             sb.Append(prefix).AppendFormat("%s[] %s = %s.readFloatArray();\n",
656                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
657             break;
658         case TypeKind::TYPE_DOUBLE:
659             sb.Append(prefix).AppendFormat("%s[] %s = %s.readDoubleArray();\n",
660                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
661             break;
662         case TypeKind::TYPE_STRING:
663             sb.Append(prefix).AppendFormat("%s[] %s = %s.readStringArray();\n",
664                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(), parcelName.c_str());
665             break;
666         case TypeKind::TYPE_SEQUENCEABLE:
667             sb.Append(prefix).AppendFormat("int size = %s.readInt();\n", parcelName.c_str());
668             sb.Append(prefix).AppendFormat("%s %s = new %s[size];\n",
669                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(),
670                 elementType_->EmitJavaType(TypeMode::NO_MODE).c_str());
671             sb.Append(prefix).AppendFormat("for (int i = 0; i < size; ++i) {\n");
672             elementType_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + TAB);
673             sb.Append(prefix + TAB).AppendFormat("%s[i] = value;\n", name.c_str());
674             sb.Append(prefix).Append("}\n");
675             break;
676         default:
677             break;
678     }
679 }
680 
EmitJavaWriteArrayVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const681 void ASTArrayType::EmitJavaWriteArrayVar(
682     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
683 {
684     switch (elementType_->GetTypeKind()) {
685         case TypeKind::TYPE_BOOLEAN:
686             sb.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.c_str(), name.c_str());
687             break;
688         case TypeKind::TYPE_BYTE:
689             sb.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n", parcelName.c_str(), name.c_str());
690             break;
691         case TypeKind::TYPE_SHORT:
692             sb.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.c_str(), name.c_str());
693             break;
694         case TypeKind::TYPE_INT:
695         case TypeKind::TYPE_FILEDESCRIPTOR:
696             sb.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.c_str(), name.c_str());
697             break;
698         case TypeKind::TYPE_LONG:
699             sb.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.c_str(), name.c_str());
700             break;
701         case TypeKind::TYPE_FLOAT:
702             sb.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.c_str(), name.c_str());
703             break;
704         case TypeKind::TYPE_DOUBLE:
705             sb.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.c_str(), name.c_str());
706             break;
707         case TypeKind::TYPE_STRING:
708             sb.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.c_str(), name.c_str());
709             break;
710         case TypeKind::TYPE_SEQUENCEABLE:
711             sb.Append(prefix).AppendFormat("%s.writeSequenceableArray(%s);\n", parcelName.c_str(), name.c_str());
712             break;
713         default:
714             break;
715     }
716 }
717 
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) const718 void ASTArrayType::EmitCMallocVar(const std::string &name, const std::string &lenName, bool isClient,
719     const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
720 {
721     std::string varName = isClient ? StringHelper::Format("*%s", name.c_str()) : name;
722     std::string lenVarName = isClient ? StringHelper::Format("*%s", lenName.c_str()) : lenName;
723     sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * (%s));\n", varName.c_str(),
724         elementType_->EmitCType().c_str(), elementType_->EmitCType().c_str(), lenVarName.c_str());
725     sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", varName.c_str());
726     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", varName.c_str());
727     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", ecName.c_str());
728     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
729     sb.Append(prefix).Append("}\n");
730 }
731 
RegisterWriteMethod(Language language,SerMode mode,UtilMethodMap & methods) const732 void ASTArrayType::RegisterWriteMethod(Language language, SerMode mode, UtilMethodMap &methods) const
733 {
734     elementType_->RegisterWriteMethod(language, mode, methods);
735     if (elementType_->IsPod()) {
736         RegisterWritePodArrayMethod(language, mode, methods);
737     } else if (elementType_->IsStringType()) {
738         RegisterWriteStringArrayMethod(language, mode, methods);
739     }
740 }
741 
RegisterReadMethod(Language language,SerMode mode,UtilMethodMap & methods) const742 void ASTArrayType::RegisterReadMethod(Language language, SerMode mode, UtilMethodMap &methods) const
743 {
744     elementType_->RegisterReadMethod(language, mode, methods);
745     if (elementType_->IsPod()) {
746         RegisterReadPodArrayMethod(language, mode, methods);
747     } else if (elementType_->IsStringType()) {
748         RegisterReadStringArrayMethod(language, mode, methods);
749     }
750 }
751 
RegisterWritePodArrayMethod(Language language,SerMode mode,UtilMethodMap & methods) const752 void ASTArrayType::RegisterWritePodArrayMethod(Language language, SerMode mode, UtilMethodMap &methods) const
753 {
754     (void)mode;
755     using namespace std::placeholders;
756     std::string methodName = "WritePodArray";
757     switch (language) {
758         case Language::C:
759             methods.emplace(methodName, std::bind(&ASTArrayType::EmitCWriteMethods, this, _1, _2, _3, _4));
760             break;
761         case Language::CPP:
762             methods.emplace(methodName, std::bind(&ASTArrayType::EmitCppWriteMethods, this, _1, _2, _3, _4));
763             break;
764         default:
765             break;
766     }
767 }
768 
RegisterWriteStringArrayMethod(Language language,SerMode mode,UtilMethodMap & methods) const769 void ASTArrayType::RegisterWriteStringArrayMethod(
770     Language language, SerMode mode, UtilMethodMap &methods) const
771 {
772     (void)mode;
773     using namespace std::placeholders;
774     if (language == Language::C && elementType_->IsStringType()) {
775         methods.emplace("WriteStringArray", std::bind(&ASTArrayType::EmitCWriteStrArrayMethods, this, _1, _2, _3, _4));
776     }
777 }
778 
RegisterReadPodArrayMethod(Language language,SerMode mode,UtilMethodMap & methods) const779 void ASTArrayType::RegisterReadPodArrayMethod(Language language, SerMode mode, UtilMethodMap &methods) const
780 {
781     using namespace std::placeholders;
782     std::string methodName = "ReadPodArray";
783     switch (language) {
784         case Language::C: {
785             auto readMethod = mode == SerMode::PROXY_SER ?
786                 std::bind(&ASTArrayType::EmitCReadMethods, this, _1, _2, _3, _4) :
787                 std::bind(&ASTArrayType::EmitCStubReadMethods, this, _1, _2, _3, _4);
788             methods.emplace(methodName, readMethod);
789             break;
790         }
791         case Language::CPP:
792             methods.emplace(methodName, std::bind(&ASTArrayType::EmitCppReadMethods, this, _1, _2, _3, _4));
793             break;
794         default:
795             break;
796     }
797 }
798 
RegisterReadStringArrayMethod(Language language,SerMode mode,UtilMethodMap & methods) const799 void ASTArrayType::RegisterReadStringArrayMethod(Language language, SerMode mode, UtilMethodMap &methods) const
800 {
801     using namespace std::placeholders;
802     if (language == Language::C && elementType_->IsStringType()) {
803         auto readMethod = mode == SerMode::PROXY_SER ?
804             std::bind(&ASTArrayType::EmitCReadStrArrayMethods, this, _1, _2, _3, _4) :
805             std::bind(&ASTArrayType::EmitCStubReadStrArrayMethods, this, _1, _2, _3, _4);
806         methods.emplace("ReadStringArray", readMethod);
807     }
808 }
809 
EmitCWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const810 void ASTArrayType::EmitCWriteMethods(
811     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
812 {
813     std::string methodName = StringHelper::Format("%sWritePodArray", methodPrefix.c_str());
814     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
815     sb.Append("struct HdfSBuf *parcel, const void *data, uint32_t elementSize, uint32_t count)");
816     if (isDecl) {
817         sb.Append(";\n");
818         return;
819     } else {
820         sb.Append("\n");
821     }
822 
823     sb.Append(prefix).Append("{\n");
824     sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUint32(parcel, count)) {\n");
825     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array size\", __func__);\n");
826     sb.Append(prefix + TAB + TAB).Append("return false;\n");
827     sb.Append(prefix + TAB).Append("}\n\n");
828 
829     sb.Append(prefix + TAB).Append("if (data == NULL && count == 0) {\n");
830     sb.Append(prefix + TAB + TAB).Append("return true;\n");
831     sb.Append(prefix + TAB).Append("}\n\n");
832 
833     if (Options::GetInstance().DoGenerateKernelCode()) {
834         sb.Append(prefix + TAB).Append("if (!HdfSbufWriteBuffer(");
835         sb.Append("parcel, (const void *)data, elementSize * count)) {\n");
836     } else {
837         sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUnpadBuffer(");
838         sb.Append("parcel, (const uint8_t *)data, elementSize * count)) {\n");
839     }
840 
841     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array\", __func__);\n");
842     sb.Append(prefix + TAB + TAB).Append("return false;\n");
843     sb.Append(prefix + TAB).Append("}\n\n");
844 
845     sb.Append(prefix + TAB).Append("return true;\n");
846     sb.Append(prefix).Append("}\n");
847 }
848 
EmitCReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const849 void ASTArrayType::EmitCReadMethods(
850     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
851 {
852     std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
853     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
854     sb.Append("struct HdfSBuf *parcel, void *data, uint32_t elementSize, uint32_t *count)");
855     if (isDecl) {
856         sb.Append(";\n");
857         return;
858     } else {
859         sb.Append("\n");
860     }
861 
862     sb.Append(prefix).Append("{\n");
863     if (Options::GetInstance().DoGenerateKernelCode()) {
864         sb.Append(prefix + TAB).Append("void *dataPtr = NULL;\n");
865         sb.Append(prefix + TAB).Append("uint32_t dataLen = 0;\n");
866     }
867     sb.Append(prefix + TAB).Append("uint32_t elementCount = 0;\n");
868     sb.Append(prefix + TAB).Append("if (!HdfSbufReadUint32(parcel, &elementCount)) {\n");
869     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read array size\", __func__);\n");
870     sb.Append(prefix + TAB + TAB).Append("return false;\n");
871     sb.Append(prefix + TAB).Append("}\n\n");
872 
873     sb.Append(prefix + TAB).AppendFormat("if (elementCount > %s / elementSize) {\n", MAX_BUFF_SIZE_MACRO);
874     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid elementCount\", __func__);\n");
875     sb.Append(prefix + TAB + TAB).Append("return false;\n");
876     sb.Append(prefix + TAB).Append("}\n\n");
877 
878     sb.Append(prefix + TAB).Append("if (elementCount == 0) {\n");
879     sb.Append(prefix + TAB + TAB).Append("goto FINISHED;\n");
880     sb.Append(prefix + TAB).Append("}\n\n");
881 
882     if (Options::GetInstance().DoGenerateKernelCode()) {
883         sb.Append(prefix + TAB).Append("if (!HdfSbufReadBuffer(parcel, (const void **)&dataPtr, &dataLen)) {\n");
884     } else {
885         sb.Append(prefix + TAB)
886             .Append("const void * dataPtr = HdfSbufReadUnpadBuffer(parcel, elementSize * elementCount);\n");
887         sb.Append(prefix + TAB).Append("if (dataPtr == NULL) {\n");
888     }
889 
890     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read array\", __func__);\n");
891     sb.Append(prefix + TAB + TAB).Append("return false;\n");
892     sb.Append(prefix + TAB).Append("}\n\n");
893 
894     sb.Append(prefix + TAB).Append("if (memcpy_s(");
895     sb.Append("data, elementSize * elementCount, dataPtr, elementSize * elementCount) != EOK) {\n");
896     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to copy array data\", __func__);\n");
897     sb.Append(prefix + TAB + TAB).Append("return false;\n");
898     sb.Append(prefix + TAB).Append("}\n\n");
899 
900     sb.Append("FINISHED:\n");
901     sb.Append(prefix + TAB).Append("*count = elementCount;\n");
902     sb.Append(prefix + TAB).Append("return true;\n");
903     sb.Append(prefix).Append("}\n");
904 }
905 
EmitCStubReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const906 void ASTArrayType::EmitCStubReadMethods(
907     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
908 {
909     std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
910     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
911     sb.Append("struct HdfSBuf *parcel, void **data, uint32_t elementSize, uint32_t *count)");
912     if (isDecl) {
913         sb.Append(";\n");
914         return;
915     } else {
916         sb.Append("\n");
917     }
918     sb.Append(prefix).Append("{\n");
919     EmitCStubReadMethodBody(sb, prefix + TAB);
920     sb.Append(prefix).Append("}\n");
921 }
922 
EmitCStubReadMethodBody(StringBuilder & sb,const std::string & prefix) const923 void ASTArrayType::EmitCStubReadMethodBody(StringBuilder &sb, const std::string &prefix) const
924 {
925     sb.Append(prefix).Append("const void * dataPtr = NULL;\n");
926     if (Options::GetInstance().DoGenerateKernelCode()) {
927         sb.Append(prefix).Append("uint32_t dataLen = 0;\n");
928     }
929     sb.Append(prefix).Append("void *memPtr = NULL;\n");
930     sb.Append(prefix).Append("uint32_t elementCount = 0;\n");
931     sb.Append(prefix).Append("if (count == NULL || data == NULL || elementSize == 0) {\n");
932     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid param\", __func__);\n");
933     sb.Append(prefix + TAB).Append("return false;\n");
934     sb.Append(prefix).Append("}\n\n");
935     sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &elementCount)) {\n");
936     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read element count\", __func__);\n");
937     sb.Append(prefix + TAB).Append("return false;\n");
938     sb.Append(prefix).Append("}\n\n");
939 
940     sb.Append(prefix).AppendFormat("if (elementCount > %s / elementSize) {\n", MAX_BUFF_SIZE_MACRO);
941     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid elementCount\", __func__);\n");
942     sb.Append(prefix + TAB).Append("return false;\n");
943     sb.Append(prefix).Append("}\n\n");
944 
945     sb.Append(prefix).Append("if (elementCount == 0) {\n");
946     sb.Append(prefix + TAB).Append("*count = elementCount;\n");
947     sb.Append(prefix + TAB).Append("return true;\n");
948     sb.Append(prefix).Append("}\n\n");
949     if (Options::GetInstance().DoGenerateKernelCode()) {
950         sb.Append(prefix).Append("if (!HdfSbufReadBuffer(parcel, (const void **)&dataPtr, &dataLen)) {\n");
951     } else {
952         sb.Append(prefix).Append("dataPtr = HdfSbufReadUnpadBuffer(parcel, elementSize * elementCount);\n");
953         sb.Append(prefix).Append("if (dataPtr == NULL) {\n");
954     }
955     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
956     sb.Append(prefix + TAB).Append("return false;\n");
957     sb.Append(prefix).Append("}\n\n");
958     sb.Append(prefix).Append("memPtr = OsalMemCalloc(elementSize * elementCount);\n");
959     sb.Append(prefix).Append("if (memPtr == NULL) {\n");
960     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc buffer\", __func__);\n");
961     sb.Append(prefix + TAB).Append("return false;\n");
962     sb.Append(prefix).Append("}\n\n");
963     sb.Append(prefix).Append(
964         "if (memcpy_s(memPtr, elementSize * elementCount, dataPtr, elementSize * elementCount) != EOK) {\n");
965     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy buffer\", __func__);\n");
966     sb.Append(prefix + TAB).Append("OsalMemFree(memPtr);\n");
967     sb.Append(prefix + TAB).Append("return false;\n");
968     sb.Append(prefix).Append("}\n\n");
969     sb.Append(prefix).Append("*data = memPtr;\n");
970     sb.Append(prefix).Append("*count = elementCount;\n");
971     sb.Append(prefix).Append("return true;\n");
972 }
973 
EmitCWriteStrArrayMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const974 void ASTArrayType::EmitCWriteStrArrayMethods(
975     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
976 {
977     std::string methodName = StringHelper::Format("%sWriteStringArray", methodPrefix.c_str());
978     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
979     sb.Append("struct HdfSBuf *parcel, char **data, uint32_t count)");
980     if (isDecl) {
981         sb.Append(";\n");
982         return;
983     } else {
984         sb.Append("\n");
985     }
986     sb.Append(prefix).Append("{\n");
987     sb.Append(prefix + TAB).Append("uint32_t i = 0;\n");
988     sb.Append(prefix + TAB).Append("if (parcel == NULL) {\n");
989     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
990     sb.Append(prefix + TAB + TAB).Append("return false;\n");
991     sb.Append(prefix + TAB).Append("}\n\n");
992     sb.Append(prefix + TAB).AppendFormat("if (count > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
993     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid count\", __func__);\n");
994     sb.Append(prefix + TAB + TAB).Append("return false;\n");
995     sb.Append(prefix + TAB).Append("}\n\n");
996     sb.Append(prefix + TAB).Append("if (!HdfSbufWriteUint32(parcel, count)) {\n");
997     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write count of array\", __func__);\n");
998     sb.Append(prefix + TAB + TAB).Append("return false;\n");
999     sb.Append(prefix + TAB).Append("}\n\n");
1000     sb.Append(prefix + TAB).Append("if (count == 0) {\n");
1001     sb.Append(prefix + TAB + TAB).Append("return true;\n");
1002     sb.Append(prefix + TAB).Append("}\n\n");
1003     sb.Append(prefix + TAB).Append("if (data == NULL) {\n");
1004     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid array object\", __func__);\n");
1005     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1006     sb.Append(prefix + TAB).Append("}\n\n");
1007     sb.Append(prefix + TAB).Append("for (i = 0; i < count; i++) {\n");
1008     sb.Append(prefix + TAB + TAB).Append("if (!HdfSbufWriteString(parcel, data[i])) {\n");
1009     sb.Append(prefix + TAB + TAB + TAB)
1010         .Append("HDF_LOGE(\"%{public}s: failed to write element of array\", __func__);\n");
1011     sb.Append(prefix + TAB + TAB + TAB).Append("return false;\n");
1012     sb.Append(prefix + TAB + TAB).Append("}\n");
1013     sb.Append(prefix + TAB).Append("}\n\n");
1014     sb.Append(prefix + TAB).Append("return true;\n");
1015     sb.Append(prefix).Append("}\n");
1016 }
1017 
EmitCReadStrArrayMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1018 void ASTArrayType::EmitCReadStrArrayMethods(
1019     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1020 {
1021     std::string methodName = StringHelper::Format("%sReadStringArray", methodPrefix.c_str());
1022     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
1023     sb.Append("struct HdfSBuf *parcel, char **data, uint32_t *count)");
1024     if (isDecl) {
1025         sb.Append(";\n");
1026         return;
1027     } else {
1028         sb.Append("\n");
1029     }
1030     sb.Append(prefix).Append("{\n");
1031     EmitCReadStrArrayMethodBody(sb, prefix + TAB);
1032     sb.Append(prefix).Append("}\n");
1033 }
1034 
EmitCReadStrArrayMethodBody(StringBuilder & sb,const std::string & prefix) const1035 void ASTArrayType::EmitCReadStrArrayMethodBody(StringBuilder &sb, const std::string &prefix) const
1036 {
1037     sb.Append(prefix).Append("uint32_t i = 0;\n");
1038     sb.Append(prefix).Append("uint32_t dataCount = 0;\n");
1039     EmitCCheckParamOfReadStringArray(sb, prefix);
1040     sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &dataCount)) {\n");
1041     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read count of array\", __func__);\n");
1042     sb.Append(prefix + TAB).Append("return false;\n");
1043     sb.Append(prefix).Append("}\n\n");
1044     sb.Append(prefix).AppendFormat("if (dataCount > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
1045     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid dataCount\", __func__);\n");
1046     sb.Append(prefix + TAB).Append("return false;\n");
1047     sb.Append(prefix).Append("}\n\n");
1048     sb.Append(prefix).Append("if (dataCount == 0) {\n");
1049     sb.Append(prefix + TAB).Append("*count = dataCount;\n");
1050     sb.Append(prefix + TAB).Append("return true;\n");
1051     sb.Append(prefix).Append("}\n\n");
1052     sb.Append(prefix).Append("for (i = 0; i < dataCount; i++) {\n");
1053     sb.Append(prefix + TAB).Append("char *elementStr = NULL;\n");
1054     sb.Append(prefix + TAB).Append("uint32_t strLen = 0;\n");
1055     sb.Append(prefix + TAB).Append("const char *str = HdfSbufReadString(parcel);\n");
1056     sb.Append(prefix + TAB).Append("if (str == NULL) {\n");
1057     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read string\", __func__);\n");
1058     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1059     sb.Append(prefix + TAB).Append("}\n");
1060     sb.Append(prefix + TAB).Append("strLen = strlen(str);\n");
1061     sb.Append(prefix + TAB).Append("elementStr = (char *)OsalMemCalloc(strLen + 1);\n");
1062     sb.Append(prefix + TAB).Append("if (elementStr == NULL) {\n");
1063     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc element of array\", __func__);\n");
1064     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1065     sb.Append(prefix + TAB).Append("}\n");
1066     sb.Append(prefix + TAB).Append("if (strcpy_s(elementStr, strLen + 1, str) != EOK) {\n");
1067     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed copy element of array\", __func__);\n");
1068     sb.Append(prefix + TAB + TAB).Append("OsalMemFree(elementStr);\n");
1069     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1070     sb.Append(prefix + TAB).Append("}\n");
1071     sb.Append(prefix + TAB).Append("data[i] = elementStr;\n");
1072     sb.Append(prefix).Append("}\n\n");
1073     sb.Append(prefix).Append("*count = dataCount;\n");
1074     sb.Append(prefix).Append("return true;\n\n");
1075     sb.Append("ERROR:\n");
1076     sb.Append(prefix).Append("for (i = 0; i < dataCount; ++i) {\n");
1077     sb.Append(prefix + TAB).Append("if (data[i] != NULL) {\n");
1078     sb.Append(prefix + TAB + TAB).Append("OsalMemFree(data[i]);\n");
1079     sb.Append(prefix + TAB + TAB).Append("data[i] = NULL;\n");
1080     sb.Append(prefix + TAB).Append("}\n");
1081     sb.Append(prefix).Append("}\n");
1082     sb.Append(prefix).Append("*count = 0;\n");
1083     sb.Append(prefix).Append("return false;\n");
1084 }
1085 
EmitCCheckParamOfReadStringArray(StringBuilder & sb,const std::string & prefix) const1086 void ASTArrayType::EmitCCheckParamOfReadStringArray(StringBuilder &sb, const std::string &prefix) const
1087 {
1088     sb.Append(prefix).Append("if (parcel == NULL) {\n");
1089     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
1090     sb.Append(prefix + TAB).Append("return false;\n");
1091     sb.Append(prefix).Append("}\n\n");
1092     sb.Append(prefix).Append("if (data == NULL || count == NULL) {\n");
1093     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid array object\", __func__);\n");
1094     sb.Append(prefix + TAB).Append("return false;\n");
1095     sb.Append(prefix).Append("}\n\n");
1096 }
1097 
EmitCStubReadStrArrayMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1098 void ASTArrayType::EmitCStubReadStrArrayMethods(
1099     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1100 {
1101     std::string methodName = StringHelper::Format("%sReadStringArray", methodPrefix.c_str());
1102     sb.Append(prefix).AppendFormat("static bool %s(", methodName.c_str());
1103     sb.Append("struct HdfSBuf *parcel, char ***data, uint32_t *count)");
1104     if (isDecl) {
1105         sb.Append(";\n");
1106         return;
1107     } else {
1108         sb.Append("\n");
1109     }
1110     sb.Append(prefix).Append("{\n");
1111     EmitCStubReadStrArrayMethodBody(sb, prefix + TAB);
1112     sb.Append(prefix).Append("}\n");
1113 }
1114 
EmitCStubReadStrArrayMethodBody(StringBuilder & sb,const std::string & prefix) const1115 void ASTArrayType::EmitCStubReadStrArrayMethodBody(StringBuilder &sb, const std::string &prefix) const
1116 {
1117     sb.Append(prefix).Append("uint32_t i = 0;\n");
1118     sb.Append(prefix).Append("char **dataPtr = NULL;\n");
1119     sb.Append(prefix).Append("uint32_t dataCount = 0;\n");
1120     EmitCCheckParamOfReadStringArray(sb, prefix);
1121     sb.Append(prefix).Append("if (!HdfSbufReadUint32(parcel, &dataCount)) {\n");
1122     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read count of array\", __func__);\n");
1123     sb.Append(prefix + TAB).Append("return false;\n");
1124     sb.Append(prefix).Append("}\n\n");
1125     sb.Append(prefix).AppendFormat("if (dataCount > %s / sizeof(data[0])) {\n", MAX_BUFF_SIZE_MACRO);
1126     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid dataCount\", __func__);\n");
1127     sb.Append(prefix + TAB).Append("return false;\n");
1128     sb.Append(prefix).Append("}\n\n");
1129     sb.Append(prefix).Append("if (dataCount == 0) {\n");
1130     sb.Append(prefix + TAB).Append("*count = dataCount;\n");
1131     sb.Append(prefix + TAB).Append("return true;\n");
1132     sb.Append(prefix).Append("}\n\n");
1133     sb.Append(prefix).Append("dataPtr = (char **)OsalMemCalloc(sizeof(char *) * dataCount);\n");
1134     sb.Append(prefix).Append("if (dataPtr == NULL) {\n");
1135     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc array\", __func__);\n");
1136     sb.Append(prefix + TAB).Append("return false;\n");
1137     sb.Append(prefix).Append("}\n\n");
1138     sb.Append(prefix).Append("for (i = 0; i < dataCount; i++) {\n");
1139     sb.Append(prefix + TAB).Append("char *elementStr = NULL;\n");
1140     sb.Append(prefix + TAB).Append("uint32_t strLen = 0;\n");
1141     sb.Append(prefix + TAB).Append("const char *str = HdfSbufReadString(parcel);\n");
1142     sb.Append(prefix + TAB).Append("if (str == NULL) {\n");
1143     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc array\", __func__);\n");
1144     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1145     sb.Append(prefix + TAB).Append("}\n\n");
1146     sb.Append(prefix + TAB).Append("strLen = strlen(str);\n");
1147     sb.Append(prefix + TAB).Append("elementStr = (char *)OsalMemCalloc(strLen + 1);\n");
1148     sb.Append(prefix + TAB).Append("if (elementStr == NULL) {\n");
1149     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc element of array\", __func__);\n");
1150     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1151     sb.Append(prefix + TAB).Append("}\n\n");
1152     sb.Append(prefix + TAB).Append("if (strcpy_s(elementStr, strLen + 1, str) != EOK) {\n");
1153     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed copy element of array\", __func__);\n");
1154     sb.Append(prefix + TAB + TAB).Append("OsalMemFree(elementStr);\n");
1155     sb.Append(prefix + TAB + TAB).Append("goto ERROR;\n");
1156     sb.Append(prefix + TAB).Append("}\n");
1157     sb.Append(prefix + TAB).Append("dataPtr[i] = elementStr;\n");
1158     sb.Append(prefix).Append("}\n\n");
1159     sb.Append(prefix).Append("*count = dataCount;\n");
1160     sb.Append(prefix).Append("*data = dataPtr;\n");
1161     sb.Append(prefix).Append("return true;\n\n");
1162     EmitCStubReadStrArrayFree(sb, prefix);
1163 }
1164 
EmitCStubReadStrArrayFree(StringBuilder & sb,const std::string & prefix) const1165 void ASTArrayType::EmitCStubReadStrArrayFree(StringBuilder &sb, const std::string &prefix) const
1166 {
1167     sb.Append("ERROR:\n");
1168     sb.Append(prefix).Append("if (dataPtr != NULL) {\n");
1169     sb.Append(prefix + TAB).Append("for (i = 0; i < dataCount; i++) {\n");
1170     sb.Append(prefix + TAB + TAB).Append("if (dataPtr[i] != NULL) {\n");
1171     sb.Append(prefix + TAB + TAB + TAB).Append("OsalMemFree(dataPtr[i]);\n");
1172     sb.Append(prefix + TAB + TAB + TAB).Append("dataPtr[i] = NULL;\n");
1173     sb.Append(prefix + TAB + TAB).Append("}\n");
1174     sb.Append(prefix + TAB).Append("}\n");
1175     sb.Append(prefix + TAB).Append("OsalMemFree(dataPtr);\n");
1176     sb.Append(prefix).Append("}\n\n");
1177     sb.Append(prefix).Append("*count = 0;\n");
1178     sb.Append(prefix).Append("return false;\n");
1179 }
1180 
EmitCppWriteMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1181 void ASTArrayType::EmitCppWriteMethods(
1182     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1183 {
1184     std::string methodName = StringHelper::Format("%sWritePodArray", methodPrefix.c_str());
1185     sb.Append(prefix).AppendFormat("template<typename ElementType>\n");
1186     sb.Append(prefix).AppendFormat(
1187         "static bool %s(MessageParcel &parcel, const std::vector<ElementType> &data)", methodName.c_str());
1188     if (isDecl) {
1189         sb.Append(";\n");
1190         return;
1191     } else {
1192         sb.Append("\n");
1193     }
1194 
1195     sb.Append(prefix).Append("{\n");
1196     sb.Append(prefix + TAB).Append("if (!parcel.WriteUint32(data.size())) {\n");
1197     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write data size\", __func__);\n");
1198     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1199     sb.Append(prefix + TAB).Append("}\n");
1200 
1201     sb.Append(prefix + TAB).Append("if (data.empty()) {\n");
1202     sb.Append(prefix + TAB + TAB).Append("return true;\n");
1203     sb.Append(prefix + TAB).Append("}\n");
1204 
1205     sb.Append(prefix + TAB).Append("if (!parcel.WriteUnpadBuffer(");
1206     sb.Append("(const void*)data.data(), sizeof(ElementType) * data.size())) {\n");
1207     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to write array\", __func__);\n");
1208     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1209     sb.Append(prefix + TAB).Append("}\n");
1210 
1211     sb.Append(prefix + TAB).Append("return true;\n");
1212     sb.Append(prefix).Append("}\n");
1213 }
1214 
EmitCppReadMethods(StringBuilder & sb,const std::string & prefix,const std::string & methodPrefix,bool isDecl) const1215 void ASTArrayType::EmitCppReadMethods(
1216     StringBuilder &sb, const std::string &prefix, const std::string &methodPrefix, bool isDecl) const
1217 {
1218     std::string methodName = StringHelper::Format("%sReadPodArray", methodPrefix.c_str());
1219     sb.Append(prefix).AppendFormat("template<typename ElementType>\n");
1220     sb.Append(prefix).AppendFormat(
1221         "static bool %s(MessageParcel &parcel, std::vector<ElementType> &data)", methodName.c_str());
1222     if (isDecl) {
1223         sb.Append(";\n");
1224         return;
1225     } else {
1226         sb.Append("\n");
1227     }
1228 
1229     sb.Append(prefix).Append("{\n");
1230     sb.Append(prefix + TAB).Append("data.clear();\n");
1231     sb.Append(prefix + TAB).Append("uint32_t size = 0;\n");
1232     sb.Append(prefix + TAB).Append("if (!parcel.ReadUint32(size)) {\n");
1233     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
1234     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1235     sb.Append(prefix + TAB).Append("}\n\n");
1236 
1237     sb.Append(prefix + TAB).Append("if (size == 0) {\n");
1238     sb.Append(prefix + TAB + TAB).Append("return true;\n");
1239     sb.Append(prefix + TAB).Append("}\n");
1240 
1241     sb.Append(prefix + TAB).Append("const ElementType *dataPtr = reinterpret_cast<const ElementType*>(");
1242     sb.Append("parcel.ReadUnpadBuffer(sizeof(ElementType) * size));\n");
1243     sb.Append(prefix + TAB).Append("if (dataPtr == nullptr) {\n");
1244     sb.Append(prefix + TAB + TAB).Append("HDF_LOGI(\"%{public}s: failed to read data\", __func__);\n");
1245     sb.Append(prefix + TAB + TAB).Append("return false;\n");
1246     sb.Append(prefix + TAB).Append("}\n");
1247 
1248     sb.Append(prefix + TAB).Append("data.assign(dataPtr, dataPtr + size);\n");
1249     sb.Append(prefix + TAB).Append("return true;\n");
1250     sb.Append(prefix).Append("}\n");
1251 }
1252 
IsArrayType()1253 bool ASTListType::IsArrayType()
1254 {
1255     return false;
1256 }
1257 
IsListType()1258 bool ASTListType::IsListType()
1259 {
1260     return true;
1261 }
1262 
ToString() const1263 std::string ASTListType::ToString() const
1264 {
1265     return StringHelper::Format("List<%s>", elementType_->ToString().c_str());
1266 }
1267 
GetTypeKind()1268 TypeKind ASTListType::GetTypeKind()
1269 {
1270     return TypeKind::TYPE_LIST;
1271 }
1272 
EmitJavaType(TypeMode mode,bool isInnerType) const1273 std::string ASTListType::EmitJavaType(TypeMode mode, bool isInnerType) const
1274 {
1275     return StringHelper::Format("List<%s>", elementType_->EmitJavaType(mode, true).c_str());
1276 }
1277 
EmitJavaWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const1278 void ASTListType::EmitJavaWriteVar(
1279     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
1280 {
1281     sb.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.c_str(), name.c_str());
1282     sb.Append(prefix).AppendFormat(
1283         "for (%s element : %s) {\n", elementType_->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str());
1284     elementType_->EmitJavaWriteVar(parcelName, "element", sb, prefix + TAB);
1285     sb.Append(prefix).Append("}\n");
1286 }
1287 
EmitJavaReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix) const1288 void ASTListType::EmitJavaReadVar(
1289     const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
1290 {
1291     sb.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(), parcelName.c_str());
1292     sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1293 
1294     elementType_->EmitJavaReadInnerVar(parcelName, "value", false, sb, prefix + TAB);
1295     sb.Append(prefix + TAB).AppendFormat("%s.add(value);\n", name.c_str());
1296     sb.Append(prefix).Append("}\n");
1297 }
1298 
EmitJavaReadInnerVar(const std::string & parcelName,const std::string & name,bool isInner,StringBuilder & sb,const std::string & prefix) const1299 void ASTListType::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
1300     StringBuilder &sb, const std::string &prefix) const
1301 {
1302     sb.Append(prefix).AppendFormat("%s %s = new Array%s();\n", EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str(),
1303         EmitJavaType(TypeMode::NO_MODE).c_str());
1304     sb.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(), parcelName.c_str());
1305     sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1306     elementType_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + TAB);
1307     sb.Append(prefix + TAB).AppendFormat("%s.add(value);\n", name.c_str());
1308     sb.Append(prefix).Append("}\n");
1309 }
1310 } // namespace HDI
1311 } // namespace OHOS