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