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