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