• 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 
ToString()19 String ASTArrayType::ToString()
20 {
21     return String::Format("%s[]", elementType_->ToString().string());
22 }
23 
GetTypeKind()24 TypeKind ASTArrayType::GetTypeKind()
25 {
26     return TypeKind::TYPE_ARRAY;
27 }
28 
EmitCType(TypeMode mode) const29 String ASTArrayType::EmitCType(TypeMode mode) const
30 {
31     switch (mode) {
32         case TypeMode::NO_MODE:
33             return String::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).string());
34         case TypeMode::PARAM_IN: {
35             if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING) {
36                 return String::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).string());
37             }
38             return String::Format("const %s*", elementType_->EmitCType(TypeMode::NO_MODE).string());
39         }
40         case TypeMode::PARAM_OUT:
41             return String::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).string());
42         case TypeMode::LOCAL_VAR:
43             return String::Format("%s*", elementType_->EmitCType(TypeMode::NO_MODE).string());
44         default:
45             return "unknow type";
46     }
47 }
48 
EmitCppType(TypeMode mode) const49 String ASTArrayType::EmitCppType(TypeMode mode) const
50 {
51     switch (mode) {
52         case TypeMode::NO_MODE:
53             return String::Format("std::vector<%s>", elementType_->EmitCppType(TypeMode::NO_MODE).string());
54         case TypeMode::PARAM_IN:
55             return String::Format("const std::vector<%s>&", elementType_->EmitCppType(TypeMode::NO_MODE).string());
56         case TypeMode::PARAM_OUT:
57             return String::Format("std::vector<%s>&", elementType_->EmitCppType(TypeMode::NO_MODE).string());
58         case TypeMode::LOCAL_VAR:
59             return String::Format("std::vector<%s>", elementType_->EmitCppType(TypeMode::NO_MODE).string());
60         default:
61             return "unknow type";
62     }
63 }
64 
EmitJavaType(TypeMode mode,bool isInnerType) const65 String ASTArrayType::EmitJavaType(TypeMode mode, bool isInnerType) const
66 {
67     return String::Format("%s[]", elementType_->EmitJavaType(TypeMode::NO_MODE, false).string());
68 }
69 
EmitCWriteVar(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const70 void ASTArrayType::EmitCWriteVar(const String& parcelName, const String& name, const String& ecName,
71     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
72 {
73     String lenName = String::Format("%sLen", name.string());
74     sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint32(%s, %s)) {\n",
75         parcelName.string(), lenName.string());
76     sb.Append(prefix + g_tab).AppendFormat(
77         "HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string());
78     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
79     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
80     sb.Append(prefix).Append("}\n");
81 
82     if (Options::GetInstance().DoGenerateKernelCode()) {
83         sb.Append(prefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.string());
84     } else {
85         sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.string());
86     }
87 
88     String elementName = "";
89     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT
90         || elementType_->GetTypeKind() == TypeKind::TYPE_UNION) {
91         elementName = String::Format("&%s[i]", name.string());
92     } else {
93         elementName = String::Format("%s[i]", name.string());
94     }
95 
96     elementType_->EmitCWriteVar(parcelName, elementName, ecName, gotoLabel, sb, prefix + g_tab);
97     sb.Append(prefix).Append("}\n");
98 }
99 
EmitCProxyWriteOutVar(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const100 void ASTArrayType::EmitCProxyWriteOutVar(const String& parcelName, const String& name, const String& ecName,
101     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
102 {
103     String lenName = String::Format("*%sLen", name.string());
104     sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint32(%s, %s)) {\n",
105         parcelName.string(), lenName.string());
106     sb.Append(prefix + g_tab).AppendFormat(
107         "HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string());
108     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
109     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
110     sb.Append(prefix).Append("}\n");
111 }
112 
EmitCProxyReadVar(const String & parcelName,const String & name,bool isInnerType,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const113 void ASTArrayType::EmitCProxyReadVar(const String& parcelName, const String& name, bool isInnerType,
114     const String& ecName, const String& gotoLabel, StringBuilder& sb, const String& prefix) const
115 {
116     String lenName = String::Format("%sLen", name.string());
117     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, %s)) {\n",
118         parcelName.string(), lenName.string());
119     sb.Append(prefix + g_tab).AppendFormat(
120         "HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.string());
121     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
122     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
123     sb.Append(prefix).Append("}\n\n");
124 
125     if (Options::GetInstance().DoGenerateKernelCode()) {
126         sb.Append(prefix).AppendFormat("for (i = 0; i < *%s; i++) {\n", lenName.string());
127     } else {
128         sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < *%s; i++) {\n", lenName.string());
129     }
130 
131     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING) {
132         EmitCProxyReadStrElement(parcelName, name, ecName, gotoLabel, sb, prefix);
133     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
134         String element = String::Format("&%s[i]", name.string());
135         elementType_->EmitCProxyReadVar(parcelName, element, true, ecName, gotoLabel, sb, prefix + g_tab);
136     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_UNION) {
137         String element = String::Format("&%s[i]", name.string());
138         String elementCp = String::Format("%sElementCp", name.string());
139         elementType_->EmitCProxyReadVar(parcelName, elementCp, true, ecName, gotoLabel, sb, prefix + g_tab);
140         sb.Append(prefix + g_tab).AppendFormat("(void)memcpy_s(%s, sizeof(%s), %s, sizeof(%s));\n",
141             element.string(), elementType_->EmitCType().string(), elementCp.string(),
142             elementType_->EmitCType().string());
143     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR) {
144         String element = String::Format("%s[i]", name.string());
145         elementType_->EmitCProxyReadVar(parcelName, element, true, ecName, gotoLabel, sb, prefix + g_tab);
146     } else {
147         String element = String::Format("&%s[i]", name.string());
148         elementType_->EmitCProxyReadVar(parcelName, element, true, ecName, gotoLabel, sb, prefix + g_tab);
149     }
150     sb.Append(prefix).Append("}\n");
151 }
152 
EmitCStubReadVar(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const153 void ASTArrayType::EmitCStubReadVar(const String& parcelName, const String& name, const String& ecName,
154     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
155 {
156     String lenName = String::Format("%sLen", name.string());
157     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, &%s)) {\n",
158         parcelName.string(), lenName.string());
159     sb.Append(prefix + g_tab).AppendFormat(
160         "HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.string());
161     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
162     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
163     sb.Append(prefix).Append("}\n\n");
164 
165     sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.string());
166     EmitCMallocVar(name, lenName, false, ecName, gotoLabel, sb, prefix + g_tab);
167     sb.Append("\n");
168 
169     if (Options::GetInstance().DoGenerateKernelCode()) {
170         sb.Append(prefix + g_tab).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.string());
171     } else {
172         sb.Append(prefix + g_tab).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.string());
173     }
174     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING) {
175         EmitCStubReadStrElement(parcelName, name, ecName, gotoLabel, sb, prefix);
176     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
177         String element = String::Format("&%s[i]", name.string());
178         elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, prefix + g_tab + g_tab);
179     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_UNION) {
180         String element = String::Format("%s[i]", name.string());
181         String elementCp = String::Format("%sElementCp", name.string());
182         elementType_->EmitCStubReadVar(parcelName, elementCp, ecName, gotoLabel, sb, prefix + g_tab + g_tab);
183         sb.Append(prefix + g_tab + g_tab).AppendFormat("(void)memcpy_s(&%s, sizeof(%s), %s, sizeof(%s));\n",
184             element.string(), elementType_->EmitCType().string(), elementCp.string(),
185             elementType_->EmitCType().string());
186     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR) {
187         String element = String::Format("%s[i]", name.string());
188         elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, prefix + g_tab + g_tab);
189     } else {
190         String element = String::Format("&%s[i]", name.string());
191         elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, prefix + g_tab + g_tab);
192     }
193     sb.Append(prefix + g_tab).Append("}\n");
194     sb.Append(prefix).Append("}\n");
195 }
196 
EmitCStubReadOutVar(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const197 void ASTArrayType::EmitCStubReadOutVar(const String& parcelName, const String& name, const String& ecName,
198     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
199 {
200     String lenName = String::Format("%sLen", name.string());
201     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(%s, &%s)) {\n",
202         parcelName.string(), lenName.string());
203     sb.Append(prefix + g_tab).AppendFormat(
204         "HDF_LOGE(\"%%{public}s: read %s size failed!\", __func__);\n", name.string());
205     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
206     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
207     sb.Append(prefix).Append("}\n\n");
208 
209     sb.Append(prefix).AppendFormat("%s(%s, >, %s / sizeof(%s), %s, HDF_ERR_INVALID_PARAM, %s);\n",
210         CHECK_VALUE_RET_GOTO_MACRO, lenName.string(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCType().string(),
211         ecName.string(), gotoLabel.string());
212 
213     sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.string());
214     EmitCMallocVar(name, lenName, false, ecName, gotoLabel, sb, prefix + g_tab);
215     sb.Append(prefix).Append("}\n");
216 }
217 
218 
EmitCppWriteVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,unsigned int innerLevel) const219 void ASTArrayType::EmitCppWriteVar(const String& parcelName, const String& name, StringBuilder& sb,
220     const String& prefix, unsigned int innerLevel) const
221 {
222     sb.Append(prefix).AppendFormat("if (!%s.WriteUint32(%s.size())) {\n", parcelName.string(), name.string());
223     sb.Append(prefix + g_tab).AppendFormat(
224         "HDF_LOGE(\"%%{public}s: write %s.size() failed!\", __func__);\n", name.string());
225     sb.Append(prefix + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
226     sb.Append(prefix).Append("}\n");
227     String elementName = String::Format("it%d", innerLevel++);
228     sb.Append(prefix).AppendFormat("for (auto %s : %s) {\n", elementName.string(), name.string());
229 
230     elementType_->EmitCppWriteVar(parcelName, elementName, sb, prefix + g_tab, innerLevel);
231     sb.Append(prefix).Append("}\n");
232 }
233 
EmitCppReadVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,bool initVariable,unsigned int innerLevel) const234 void ASTArrayType::EmitCppReadVar(const String& parcelName, const String& name, StringBuilder& sb,
235     const String& prefix, bool initVariable, unsigned int innerLevel) const
236 {
237     if (initVariable) {
238         sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().string(), name.string());
239     }
240 
241     sb.Append(prefix).AppendFormat("uint32_t %sSize = 0;\n", name.string());
242     sb.Append(prefix).AppendFormat("if (!%s.ReadUint32(%sSize)) {\n", parcelName.string(), name.string());
243     sb.Append(prefix + g_tab).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
244     sb.Append(prefix + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
245     sb.Append(prefix).Append("}\n\n");
246 
247     sb.Append(prefix).AppendFormat("%s(%sSize, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
248         CHECK_VALUE_RETURN_MACRO, name.string(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCppType().string());
249     sb.Append(prefix).AppendFormat("for (uint32_t i%d = 0; i%d < %sSize; ++i%d) {\n",
250         innerLevel, innerLevel, name.string(), innerLevel);
251 
252     String valueName = String::Format("value%d", innerLevel++);
253     elementType_->EmitCppReadVar(parcelName, valueName, sb, prefix + g_tab, true, innerLevel);
254     sb.Append(prefix + g_tab).AppendFormat("%s.push_back(%s);\n", name.string(), valueName.string());
255     sb.Append(prefix).Append("}\n");
256 }
257 
EmitCMarshalling(const String & name,StringBuilder & sb,const String & prefix) const258 void ASTArrayType::EmitCMarshalling(const String& name, StringBuilder& sb, const String& prefix) const
259 {
260     sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint32(data, %sLen)) {\n", name.string());
261     sb.Append(prefix + g_tab).AppendFormat(
262         "HDF_LOGE(\"%%{public}s: write %sLen failed!\", __func__);\n", name.string());
263     sb.Append(prefix + g_tab).Append("return false;\n");
264     sb.Append(prefix).Append("}\n");
265 
266     if (Options::GetInstance().DoGenerateKernelCode()) {
267         sb.Append(prefix).AppendFormat("for (i = 0; i < %sLen; i++) {\n", name.string());
268     } else {
269         sb.Append(prefix).AppendFormat("for (uint32_t i = 0; i < %sLen; i++) {\n", name.string());
270     }
271 
272     String elementName = String::Format("(%s)[i]", name.string());
273     elementType_->EmitCMarshalling(elementName, sb, prefix + g_tab);
274     sb.Append(prefix).Append("}\n");
275 }
276 
EmitCUnMarshalling(const String & name,const String & gotoLabel,StringBuilder & sb,const String & prefix,std::vector<String> & freeObjStatements) const277 void ASTArrayType::EmitCUnMarshalling(const String& name, const String& gotoLabel, StringBuilder& sb,
278     const String& prefix, std::vector<String>& freeObjStatements) const
279 {
280     String lenName = String::Format("%sLen", name.string());
281     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint32(data, &%s)) {\n", lenName.string());
282     sb.Append(prefix + g_tab).AppendFormat(
283         "HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", lenName.string());
284     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
285     sb.Append(prefix).Append("}\n");
286 
287     sb.Append(prefix).AppendFormat("if (%s > %s / sizeof(%s)) {\n", lenName.string(), MAX_BUFF_SIZE_MACRO,
288         elementType_->EmitCType().string());
289     sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %s is invalid data\", __func__);\n",
290         lenName.string());
291     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
292     sb.Append(prefix).Append("}\n");
293 
294     sb.Append(prefix).AppendFormat("if (%s > 0) {\n", lenName.string());
295     String newPrefix = prefix + g_tab;
296 
297     sb.Append(newPrefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * %s);\n",
298         name.string(), elementType_->EmitCType().string(), elementType_->EmitCType().string(), lenName.string());
299     sb.Append(newPrefix).AppendFormat("if (%s == NULL) {\n", name.string());
300     sb.Append(newPrefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
301     sb.Append(newPrefix).Append("}\n");
302     freeObjStatements.push_back(String::Format("OsalMemFree(%s);\n", name.string()));
303 
304     if (Options::GetInstance().DoGenerateKernelCode()) {
305         sb.Append(newPrefix).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.string());
306     } else {
307         sb.Append(newPrefix).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.string());
308     }
309 
310     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING) {
311         EmitCStringElementUnMarshalling(name, gotoLabel, sb, newPrefix, freeObjStatements);
312     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
313         String element = String::Format("&%s[i]", name.string());
314         elementType_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + g_tab, freeObjStatements);
315     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_UNION) {
316         String element = String::Format("%s[i]", name.string());
317         String elementCp = String::Format("%sElementCp", name.string());
318         elementType_->EmitCUnMarshalling(elementCp, gotoLabel, sb, newPrefix + g_tab, freeObjStatements);
319         sb.Append(newPrefix + g_tab).AppendFormat("(void)memcpy_s(&%s, sizeof(%s), %s, sizeof(%s));\n",
320             element.string(), elementType_->EmitCType().string(), elementCp.string(),
321             elementType_->EmitCType().string());
322     } else {
323         String element = String::Format("%s[i]", name.string());
324         elementType_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + g_tab, freeObjStatements);
325     }
326     sb.Append(newPrefix).Append("}\n");
327     sb.Append(prefix).Append("}\n");
328     freeObjStatements.pop_back();
329 }
330 
EmitCStringElementUnMarshalling(const String & name,const String & gotoLabel,StringBuilder & sb,const String & newPrefix,std::vector<String> & freeObjStatements) const331 void ASTArrayType::EmitCStringElementUnMarshalling(const String& name, const String& gotoLabel, StringBuilder& sb,
332     const String& newPrefix, std::vector<String>& freeObjStatements) const
333 {
334     String element = String::Format("%sElement", name.string());
335     elementType_->EmitCUnMarshalling(element, gotoLabel, sb, newPrefix + g_tab, freeObjStatements);
336     if (Options::GetInstance().DoGenerateKernelCode()) {
337         sb.Append(newPrefix).AppendFormat("%s[i] = (char*)OsalMemCalloc(strlen(%s) + 1);\n",
338             name.string(), element.string());
339         sb.Append(newPrefix).AppendFormat("if (%s[i] == NULL) {\n", name.string());
340         sb.Append(newPrefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
341         sb.Append(newPrefix).Append("}\n\n");
342 
343         sb.Append(newPrefix).AppendFormat("if (strcpy_s((%s)[i], (strlen(%s) + 1), %s) != HDF_SUCCESS) {\n",
344             name.string(), element.string(), element.string());
345         sb.Append(newPrefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
346             element.string());
347         sb.Append(newPrefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
348         sb.Append(newPrefix).Append("}\n");
349     } else {
350         sb.Append(newPrefix).Append(g_tab).AppendFormat("%s[i] = strdup(%s);\n",
351             name.string(), element.string());
352     }
353 }
354 
EmitCppMarshalling(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,unsigned int innerLevel) const355 void ASTArrayType::EmitCppMarshalling(const String& parcelName, const String& name, StringBuilder& sb,
356     const String& prefix, unsigned int innerLevel) const
357 {
358     sb.Append(prefix).AppendFormat("if (!%s.WriteUint32(%s.size())) {\n", parcelName.string(), name.string());
359     sb.Append(prefix + g_tab).AppendFormat(
360         "HDF_LOGE(\"%%{public}s: write %s.size failed!\", __func__);\n", name.string());
361     sb.Append(prefix + g_tab).Append("return false;\n");
362     sb.Append(prefix).Append("}\n");
363     String elementName = String::Format("it%d", innerLevel++);
364     sb.Append(prefix).AppendFormat("for (auto %s : %s) {\n", elementName.string(), name.string());
365 
366     elementType_->EmitCppMarshalling(parcelName, elementName, sb, prefix + g_tab, innerLevel);
367     sb.Append(prefix).Append("}\n");
368 }
369 
EmitCppUnMarshalling(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,bool emitType,unsigned int innerLevel) const370 void ASTArrayType::EmitCppUnMarshalling(const String& parcelName, const String& name, StringBuilder& sb,
371     const String& prefix, bool emitType, unsigned int innerLevel) const
372 {
373     int index = name.IndexOf('.', 0);
374     String memberName = name.Substring(index + 1);
375     String sizeName = String::Format("%sSize", memberName.string());
376     if (emitType) {
377         sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().string(), memberName.string());
378     }
379 
380     sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", sizeName.string());
381     sb.Append(prefix).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.string(), sizeName.string());
382     sb.Append(prefix + g_tab).Append("HDF_LOGE(\"%{public}s: failed to read size\", __func__);\n");
383     sb.Append(prefix + g_tab).Append("return false;\n");
384     sb.Append(prefix).Append("}\n\n");
385 
386     sb.Append(prefix).AppendFormat("%s(%s, >, %s / sizeof(%s), false);\n",
387         CHECK_VALUE_RETURN_MACRO, sizeName.string(), MAX_BUFF_SIZE_MACRO, elementType_->EmitCppType().string());
388     sb.Append(prefix).AppendFormat("for (uint32_t i%d = 0; i%d < %s; ++i%d) {\n",
389         innerLevel, innerLevel, sizeName.string(), innerLevel);
390 
391     String valueName = String::Format("value%d", innerLevel++);
392     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
393         sb.Append(prefix + g_tab).AppendFormat("%s %s;\n",
394             elementType_->EmitCppType().string(), valueName.string());
395         elementType_->EmitCppUnMarshalling(parcelName, valueName, sb, prefix + g_tab, true, innerLevel);
396         sb.Append(prefix + g_tab).AppendFormat("%s.push_back(%s);\n", name.string(), valueName.string());
397     } else if (elementType_->GetTypeKind() == TypeKind::TYPE_UNION) {
398         sb.Append(prefix + g_tab).AppendFormat("%s %s;\n",
399             elementType_->EmitCppType().string(), valueName.string());
400         String cpName = String::Format("%sCp", valueName.string());
401         elementType_->EmitCppUnMarshalling(parcelName, cpName, sb, prefix + g_tab, true, innerLevel);
402         sb.Append(prefix + g_tab).AppendFormat("(void)memcpy_s(&%s, sizeof(%s), %s, sizeof(%s));\n",
403             valueName.string(), elementType_->EmitCppType().string(), cpName.string(),
404             elementType_->EmitCppType().string());
405         sb.Append(prefix + g_tab).AppendFormat("%s.push_back(%s);\n", name.string(), valueName.string());
406     } else {
407         elementType_->EmitCppUnMarshalling(parcelName, valueName, sb, prefix + g_tab, true, innerLevel);
408         sb.Append(prefix + g_tab).AppendFormat("%s.push_back(%s);\n", name.string(), valueName.string());
409     }
410     sb.Append(prefix).Append("}\n");
411 }
412 
EmitMemoryRecycle(const String & name,bool isClient,bool ownership,StringBuilder & sb,const String & prefix) const413 void ASTArrayType::EmitMemoryRecycle(const String& name, bool isClient, bool ownership, StringBuilder& sb,
414     const String& prefix) const
415 {
416     String varName = name;
417     String lenName = isClient ? String::Format("*%sLen", name.string()) : String::Format("%sLen", name.string());
418 
419     sb.Append(prefix).AppendFormat("if (%s > 0 && %s != NULL) {\n", lenName.string(), varName.string());
420     if (elementType_->GetTypeKind() == TypeKind::TYPE_STRING || elementType_->GetTypeKind() == TypeKind::TYPE_STRUCT) {
421         if (Options::GetInstance().DoGenerateKernelCode()) {
422             sb.Append(prefix + g_tab).AppendFormat("for (i = 0; i < %s; i++) {\n", lenName.string());
423         } else {
424             sb.Append(prefix + g_tab).AppendFormat("for (uint32_t i = 0; i < %s; i++) {\n", lenName.string());
425         }
426 
427         String elementName = String::Format("%s[i]", varName.string());
428         elementType_->EmitMemoryRecycle(elementName, false, false, sb, prefix + g_tab + g_tab);
429         sb.Append(prefix + g_tab).Append("}\n");
430     }
431 
432     sb.Append(prefix + g_tab).AppendFormat("OsalMemFree(%s);\n", varName.string());
433     if (isClient) {
434         sb.Append(prefix + g_tab).AppendFormat("%s = NULL;\n", varName.string());
435     }
436 
437     sb.Append(prefix).Append("}\n");
438 }
439 
EmitJavaWriteVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix) const440 void ASTArrayType::EmitJavaWriteVar(const String& parcelName, const String& name, StringBuilder& sb,
441     const String& prefix) const
442 {
443     sb.Append(prefix).AppendFormat("if (%s == null) {\n", name.string());
444     sb.Append(prefix + g_tab).AppendFormat("%s.writeInt(-1);\n", parcelName.string());
445     sb.Append(prefix).Append("} else { \n");
446     EmitJavaWriteArrayVar(parcelName, name, sb, prefix + g_tab);
447     sb.Append(prefix).Append("}\n");
448 }
449 
EmitJavaReadVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix) const450 void ASTArrayType::EmitJavaReadVar(const String& parcelName, const String& name, StringBuilder& sb,
451     const String& prefix) const
452 {
453     switch (elementType_->GetTypeKind()) {
454         case TypeKind::TYPE_BOOLEAN:
455             sb.Append(prefix).AppendFormat("%s.readBooleanArray(%s);\n", parcelName.string(), name.string());
456             break;
457         case TypeKind::TYPE_BYTE:
458             sb.Append(prefix).AppendFormat("%s.readByteArray(%s);\n", parcelName.string(), name.string());
459             break;
460         case TypeKind::TYPE_SHORT:
461             sb.Append(prefix).AppendFormat("%s.readShortArray(%s);\n", parcelName.string(), name.string());
462             break;
463         case TypeKind::TYPE_INT:
464         case TypeKind::TYPE_FILEDESCRIPTOR:
465             sb.Append(prefix).AppendFormat("%s.readIntArray(%s);\n", parcelName.string(), name.string());
466             break;
467         case TypeKind::TYPE_LONG:
468             sb.Append(prefix).AppendFormat("%s.readLongArray(%s);\n", parcelName.string(), name.string());
469             break;
470         case TypeKind::TYPE_FLOAT:
471             sb.Append(prefix).AppendFormat("%s.readFloatArray(%s);\n", parcelName.string(), name.string());
472             break;
473         case TypeKind::TYPE_DOUBLE:
474             sb.Append(prefix).AppendFormat("%s.readDoubleArray(%s);\n", parcelName.string(), name.string());
475             break;
476         case TypeKind::TYPE_STRING:
477             sb.Append(prefix).AppendFormat("%s.readStringArray(%s);\n", parcelName.string(), name.string());
478             break;
479         case TypeKind::TYPE_SEQUENCEABLE:
480             sb.Append(prefix).AppendFormat("%s.readSequenceableArray(%s);\n", parcelName.string(), name.string());
481             break;
482         default:
483             break;
484     }
485 }
486 
EmitJavaReadInnerVar(const String & parcelName,const String & name,bool isInner,StringBuilder & sb,const String & prefix) const487 void ASTArrayType::EmitJavaReadInnerVar(const String& parcelName, const String& name, bool isInner,
488     StringBuilder& sb, const String& prefix) const
489 {
490     switch (elementType_->GetTypeKind()) {
491         case TypeKind::TYPE_BOOLEAN:
492             sb.Append(prefix).AppendFormat("%s[] %s = %s.readBooleanArray();\n",
493                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
494             break;
495         case TypeKind::TYPE_BYTE:
496             sb.Append(prefix).AppendFormat("%s[] %s = %s.readByteArray();\n",
497                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
498             break;
499         case TypeKind::TYPE_SHORT:
500             sb.Append(prefix).AppendFormat("%s[] %s = %s.readShortArray();\n",
501                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
502             break;
503         case TypeKind::TYPE_INT:
504         case TypeKind::TYPE_FILEDESCRIPTOR:
505             sb.Append(prefix).AppendFormat("%s[] %s = %s.readIntArray();\n",
506                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
507             break;
508         case TypeKind::TYPE_LONG:
509             sb.Append(prefix).AppendFormat("%s[] %s = %s.readLongArray();\n",
510                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
511             break;
512         case TypeKind::TYPE_FLOAT:
513             sb.Append(prefix).AppendFormat("%s[] %s = %s.readFloatArray();\n",
514                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
515             break;
516         case TypeKind::TYPE_DOUBLE:
517             sb.Append(prefix).AppendFormat("%s[] %s = %s.readDoubleArray();\n",
518                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
519             break;
520         case TypeKind::TYPE_STRING:
521             sb.Append(prefix).AppendFormat("%s[] %s = %s.readStringArray();\n",
522                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(), parcelName.string());
523             break;
524         case TypeKind::TYPE_SEQUENCEABLE:
525             sb.Append(prefix).AppendFormat("int size = %s.readInt();\n", parcelName.string());
526             sb.Append(prefix).AppendFormat("%s %s = new %s[size];\n",
527                 elementType_->EmitJavaType(TypeMode::NO_MODE).string(), name.string(),
528                 elementType_->EmitJavaType(TypeMode::NO_MODE).string());
529             sb.Append(prefix).AppendFormat("for (int i = 0; i < size; ++i) {\n");
530             elementType_->EmitJavaReadInnerVar(parcelName, "value", true, sb, prefix + g_tab);
531             sb.Append(prefix + g_tab).AppendFormat("%s[i] = value;\n", name.string());
532             sb.Append(prefix).Append("}\n");
533             break;
534         default:
535             break;
536     }
537 }
538 
EmitJavaWriteArrayVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix) const539 void ASTArrayType::EmitJavaWriteArrayVar(const String& parcelName, const String& name, StringBuilder& sb,
540     const String& prefix) const
541 {
542     switch (elementType_->GetTypeKind()) {
543         case TypeKind::TYPE_BOOLEAN:
544             sb.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.string(), name.string());
545             break;
546         case TypeKind::TYPE_BYTE:
547             sb.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n", parcelName.string(), name.string());
548             break;
549         case TypeKind::TYPE_SHORT:
550             sb.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.string(), name.string());
551             break;
552         case TypeKind::TYPE_INT:
553         case TypeKind::TYPE_FILEDESCRIPTOR:
554             sb.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.string(), name.string());
555             break;
556         case TypeKind::TYPE_LONG:
557             sb.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.string(), name.string());
558             break;
559         case TypeKind::TYPE_FLOAT:
560             sb.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.string(), name.string());
561             break;
562         case TypeKind::TYPE_DOUBLE:
563             sb.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.string(), name.string());
564             break;
565         case TypeKind::TYPE_STRING:
566             sb.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.string(), name.string());
567             break;
568         case TypeKind::TYPE_SEQUENCEABLE:
569             sb.Append(prefix).AppendFormat("%s.writeSequenceableArray(%s);\n", parcelName.string(), name.string());
570             break;
571         default:
572             break;
573     }
574 }
575 
EmitCMallocVar(const String & name,const String & lenName,bool isClient,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const576 void ASTArrayType::EmitCMallocVar(const String& name, const String& lenName, bool isClient, const String& ecName,
577     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
578 {
579     String varName = isClient ? String::Format("*%s", name.string()) : name;
580     String lenVarName = isClient ? String::Format("*%s", lenName.string()) : lenName;
581 
582     sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s) * (%s));\n", varName.string(),
583         elementType_->EmitCType().string(), elementType_->EmitCType().string(), lenVarName.string());
584     sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", varName.string());
585     sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n",
586         varName.string());
587     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", ecName.string());
588     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
589     sb.Append(prefix).Append("}\n");
590 }
591 
EmitCProxyReadStrElement(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const592 void ASTArrayType::EmitCProxyReadStrElement(const String& parcelName, const String& name, const String& ecName,
593     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
594 {
595     String cpName = String::Format("%sCp", name.string());
596         elementType_->EmitCProxyReadVar(parcelName, cpName, true, ecName, gotoLabel, sb, prefix + g_tab);
597     sb.Append("\n");
598     if (Options::GetInstance().DoGenerateKernelCode()) {
599         sb.Append(prefix + g_tab).AppendFormat("%s[i] = (char*)OsalMemCalloc(strlen(%s) + 1);\n",
600             name.string(), cpName.string());
601         sb.Append(prefix + g_tab).AppendFormat("if (%s[i] == NULL) {\n", name.string());
602         sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s[i] failed\", __func__);\n",
603             name.string());
604         sb.Append(prefix + g_tab + g_tab).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", ecName.string());
605         sb.Append(prefix + g_tab + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
606         sb.Append(prefix + g_tab).Append("}\n\n");
607         sb.Append(prefix + g_tab).AppendFormat("if (strcpy_s(%s[i], (strlen(%s) + 1), %s) != HDF_SUCCESS) {\n",
608             name.string(), cpName.string(), cpName.string());
609         sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
610             cpName.string());
611         sb.Append(prefix + g_tab + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
612         sb.Append(prefix + g_tab + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
613         sb.Append(prefix + g_tab).Append("}\n");
614     } else {
615         sb.Append(prefix + g_tab).AppendFormat("%s[i] = strdup(%sCp);\n",
616             name.string(), name.string());
617     }
618 }
619 
EmitCStubReadStrElement(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const620 void ASTArrayType::EmitCStubReadStrElement(const String& parcelName, const String& name, const String& ecName,
621     const String& gotoLabel, StringBuilder& sb, const String& prefix) const
622 {
623     String element = String::Format("%sCp", name.string());
624     String newPrefix = prefix + g_tab + g_tab;
625     elementType_->EmitCStubReadVar(parcelName, element, ecName, gotoLabel, sb, newPrefix);
626     sb.Append("\n");
627     if (Options::GetInstance().DoGenerateKernelCode()) {
628         sb.Append(newPrefix).AppendFormat("%s[i] = (char*)OsalMemCalloc(strlen(%s) + 1);\n",
629             name.string(), element.string());
630         sb.Append(newPrefix).AppendFormat("if (%s[i] == NULL) {\n", name.string());
631         sb.Append(newPrefix + g_tab).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", ecName.string());
632         sb.Append(newPrefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
633         sb.Append(newPrefix).Append("}\n\n");
634 
635         sb.Append(newPrefix).AppendFormat("if (strcpy_s(%s[i], (strlen(%s) + 1), %s) != HDF_SUCCESS) {\n",
636             name.string(), element.string(), element.string());
637         sb.Append(newPrefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
638             element.string());
639         sb.Append(newPrefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
640         sb.Append(newPrefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
641         sb.Append(newPrefix).Append("}\n");
642     } else {
643         sb.Append(newPrefix).AppendFormat("%s[i] = strdup(%sCp);\n", name.string(), name.string());
644     }
645 }
646 } // namespace HDI
647 } // namespace OHOS