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