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 "codegen/c_custom_types_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12 #include "util/options.h"
13
14 namespace OHOS {
15 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)16 bool CCustomTypesCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
17 {
18 if (ast_->GetASTFileType() != ASTFileType::AST_TYPES) {
19 return false;
20 }
21
22 directory_ = GetFileParentPath(targetDirectory);
23 if (!File::CreateParentDir(directory_)) {
24 Logger::E("CCustomTypesCodeEmitter", "Create '%s' failed!", directory_.c_str());
25 return false;
26 }
27
28 return true;
29 }
30
EmitCode()31 void CCustomTypesCodeEmitter::EmitCode()
32 {
33 switch (mode_) {
34 case GenMode::LOW:
35 case GenMode::PASSTHROUGH: {
36 EmitPassthroughCustomTypesHeaderFile();
37 break;
38 }
39 case GenMode::IPC:
40 case GenMode::KERNEL: {
41 EmitCustomTypesHeaderFile();
42 EmitCustomTypesSourceFile();
43 break;
44 }
45 default:
46 break;
47 }
48 }
49
EmitPassthroughCustomTypesHeaderFile()50 void CCustomTypesCodeEmitter::EmitPassthroughCustomTypesHeaderFile()
51 {
52 std::string filePath =
53 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
54 File file(filePath, File::WRITE);
55 StringBuilder sb;
56
57 EmitLicense(sb);
58 EmitHeadMacro(sb, baseName_);
59 sb.Append("\n");
60 EmitPassthroughHeaderInclusions(sb);
61 sb.Append("\n");
62 EmitHeadExternC(sb);
63 sb.Append("\n");
64 EmitCustomTypeDecls(sb);
65 EmitTailExternC(sb);
66 sb.Append("\n");
67 EmitTailMacro(sb, baseName_);
68
69 std::string data = sb.ToString();
70 file.WriteData(data.c_str(), data.size());
71 file.Flush();
72 file.Close();
73 }
74
EmitPassthroughHeaderInclusions(StringBuilder & sb)75 void CCustomTypesCodeEmitter::EmitPassthroughHeaderInclusions(StringBuilder &sb)
76 {
77 HeaderFile::HeaderFileSet headerFiles;
78 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
79 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
80 GetStdlibInclusions(headerFiles);
81
82 for (const auto &file : headerFiles) {
83 sb.AppendFormat("%s\n", file.ToString().c_str());
84 }
85 }
86
EmitCustomTypesHeaderFile()87 void CCustomTypesCodeEmitter::EmitCustomTypesHeaderFile()
88 {
89 std::string filePath =
90 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
91 File file(filePath, File::WRITE);
92 StringBuilder sb;
93
94 EmitLicense(sb);
95 EmitHeadMacro(sb, baseName_);
96 sb.Append("\n");
97 EmitHeaderInclusions(sb);
98 sb.Append("\n");
99 EmitInterfaceBuffSizeMacro(sb);
100 sb.Append("\n");
101 EmitHeadExternC(sb);
102 sb.Append("\n");
103 EmitForwardDeclaration(sb);
104 sb.Append("\n");
105 EmitCustomTypeDecls(sb);
106 sb.Append("\n");
107 EmitCustomTypeFuncDecl(sb);
108 sb.Append("\n");
109 EmitTailExternC(sb);
110 sb.Append("\n");
111 EmitTailMacro(sb, baseName_);
112
113 std::string data = sb.ToString();
114 file.WriteData(data.c_str(), data.size());
115 file.Flush();
116 file.Close();
117 }
118
EmitHeaderInclusions(StringBuilder & sb)119 void CCustomTypesCodeEmitter::EmitHeaderInclusions(StringBuilder &sb)
120 {
121 HeaderFile::HeaderFileSet headerFiles;
122 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
123 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
124 GetStdlibInclusions(headerFiles);
125
126 for (const auto &file : headerFiles) {
127 sb.AppendFormat("%s\n", file.ToString().c_str());
128 }
129 }
130
EmitForwardDeclaration(StringBuilder & sb) const131 void CCustomTypesCodeEmitter::EmitForwardDeclaration(StringBuilder &sb) const
132 {
133 sb.Append("struct HdfSBuf;\n");
134 }
135
EmitCustomTypeDecls(StringBuilder & sb) const136 void CCustomTypesCodeEmitter::EmitCustomTypeDecls(StringBuilder &sb) const
137 {
138 for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
139 AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
140 EmitCustomTypeDecl(sb, type);
141 if (i + 1 < ast_->GetTypeDefinitionNumber()) {
142 sb.Append("\n");
143 }
144 }
145 }
146
EmitCustomTypeDecl(StringBuilder & sb,const AutoPtr<ASTType> & type) const147 void CCustomTypesCodeEmitter::EmitCustomTypeDecl(StringBuilder &sb, const AutoPtr<ASTType> &type) const
148 {
149 switch (type->GetTypeKind()) {
150 case TypeKind::TYPE_ENUM: {
151 AutoPtr<ASTEnumType> enumType = dynamic_cast<ASTEnumType *>(type.Get());
152 sb.Append(enumType->EmitCTypeDecl()).Append("\n");
153 break;
154 }
155 case TypeKind::TYPE_STRUCT: {
156 AutoPtr<ASTStructType> structType = dynamic_cast<ASTStructType *>(type.Get());
157 sb.Append(structType->EmitCTypeDecl()).Append("\n");
158 break;
159 }
160 case TypeKind::TYPE_UNION: {
161 AutoPtr<ASTUnionType> unionType = dynamic_cast<ASTUnionType *>(type.Get());
162 sb.Append(unionType->EmitCTypeDecl()).Append("\n");
163 break;
164 }
165 default:
166 break;
167 }
168 }
169
EmitCustomTypeFuncDecl(StringBuilder & sb) const170 void CCustomTypesCodeEmitter::EmitCustomTypeFuncDecl(StringBuilder &sb) const
171 {
172 for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
173 AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
174 if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
175 AutoPtr<ASTStructType> structType = dynamic_cast<ASTStructType *>(type.Get());
176 EmitCustomTypeMarshallingDecl(sb, structType);
177 sb.Append("\n");
178 EmitCustomTypeUnmarshallingDecl(sb, structType);
179 sb.Append("\n");
180 EmitCustomTypeFreeDecl(sb, structType);
181 if (i + 1 < ast_->GetTypeDefinitionNumber()) {
182 sb.Append("\n");
183 }
184 }
185 }
186 }
187
EmitCustomTypeMarshallingDecl(StringBuilder & sb,const AutoPtr<ASTStructType> & type) const188 void CCustomTypesCodeEmitter::EmitCustomTypeMarshallingDecl(
189 StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
190 {
191 std::string objName("dataBlock");
192 sb.AppendFormat("bool %sBlockMarshalling(struct HdfSBuf *data, const %s *%s);\n", type->GetName().c_str(),
193 type->EmitCType().c_str(), objName.c_str());
194 }
195
EmitCustomTypeUnmarshallingDecl(StringBuilder & sb,const AutoPtr<ASTStructType> & type) const196 void CCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingDecl(
197 StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
198 {
199 std::string objName("dataBlock");
200 sb.AppendFormat("bool %sBlockUnmarshalling(struct HdfSBuf *data, %s *%s);\n", type->GetName().c_str(),
201 type->EmitCType().c_str(), objName.c_str());
202 }
203
EmitCustomTypeFreeDecl(StringBuilder & sb,const AutoPtr<ASTStructType> & type) const204 void CCustomTypesCodeEmitter::EmitCustomTypeFreeDecl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
205 {
206 std::string objName("dataBlock");
207 sb.AppendFormat(
208 "void %sFree(%s *%s, bool freeSelf);\n", type->GetName().c_str(), type->EmitCType().c_str(), objName.c_str());
209 }
210
EmitCustomTypesSourceFile()211 void CCustomTypesCodeEmitter::EmitCustomTypesSourceFile()
212 {
213 std::string filePath =
214 File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_).c_str()));
215 File file(filePath, File::WRITE);
216 StringBuilder sb;
217
218 EmitLicense(sb);
219 EmitSoucreInclusions(sb);
220 sb.Append("\n");
221 UtilMethodMap utilMethods;
222 GetUtilMethods(utilMethods);
223 EmitUtilMethods(sb, "", utilMethods, true);
224 sb.Append("\n");
225 EmitUtilMethods(sb, "", utilMethods, false);
226 sb.Append("\n");
227 EmitCustomTypeDataProcess(sb);
228
229 std::string data = sb.ToString();
230 file.WriteData(data.c_str(), data.size());
231 file.Flush();
232 file.Close();
233 }
234
EmitSoucreInclusions(StringBuilder & sb)235 void CCustomTypesCodeEmitter::EmitSoucreInclusions(StringBuilder &sb)
236 {
237 HeaderFile::HeaderFileSet headerFiles;
238 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(baseName_));
239 GetSourceOtherLibInclusions(headerFiles);
240
241 for (const auto &file : headerFiles) {
242 sb.AppendFormat("%s\n", file.ToString().c_str());
243 }
244 }
245
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const246 void CCustomTypesCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
247 {
248 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
249 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
250 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
251 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
252 }
253
EmitCustomTypeDataProcess(StringBuilder & sb)254 void CCustomTypesCodeEmitter::EmitCustomTypeDataProcess(StringBuilder &sb)
255 {
256 for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
257 AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
258 if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
259 AutoPtr<ASTStructType> structType = dynamic_cast<ASTStructType *>(type.Get());
260 EmitCustomTypeMarshallingImpl(sb, structType);
261 sb.Append("\n");
262 EmitCustomTypeUnmarshallingImpl(sb, structType);
263 sb.Append("\n");
264 EmitCustomTypeFreeImpl(sb, structType);
265 if (i + 1 < ast_->GetTypeDefinitionNumber()) {
266 sb.Append("\n");
267 }
268 }
269 }
270 }
271
EmitCustomTypeMarshallingImpl(StringBuilder & sb,const AutoPtr<ASTStructType> & type)272 void CCustomTypesCodeEmitter::EmitCustomTypeMarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type)
273 {
274 std::string objName("dataBlock");
275 sb.AppendFormat("bool %sBlockMarshalling(struct HdfSBuf *data, const %s *%s)\n", type->GetName().c_str(),
276 type->EmitCType().c_str(), objName.c_str());
277 sb.Append("{\n");
278 EmitMarshallingVarDecl(type, objName, sb, TAB);
279 EmitParamCheck(objName, sb, TAB);
280 sb.Append("\n");
281 if (type->IsPod()) {
282 if (Options::GetInstance().DoGenerateKernelCode()) {
283 sb.Append(TAB).AppendFormat("if (!HdfSbufWriteBuffer(data, (const void *)%s, sizeof(%s))) {\n",
284 objName.c_str(), type->EmitCType().c_str());
285 } else {
286 sb.Append(TAB).AppendFormat("if (!HdfSbufWriteUnpadBuffer(data, (const uint8_t *)%s, sizeof(%s))) {\n",
287 objName.c_str(), type->EmitCType().c_str());
288 }
289 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to write buffer data\", __func__);\n");
290 sb.Append(TAB).Append(TAB).Append("return false;\n");
291 sb.Append(TAB).Append("}\n");
292 } else {
293 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
294 std::string memberName = type->GetMemberName(i);
295 AutoPtr<ASTType> memberType = type->GetMemberType(i);
296 std::string name = StringHelper::Format("%s->%s", objName.c_str(), memberName.c_str());
297 memberType->EmitCMarshalling(name, sb, TAB);
298 sb.Append("\n");
299 }
300 }
301
302 sb.Append(TAB).Append("return true;\n");
303 sb.Append("}\n");
304 }
305
EmitCustomTypeUnmarshallingImpl(StringBuilder & sb,const AutoPtr<ASTStructType> & type)306 void CCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type)
307 {
308 std::string objName("dataBlock");
309 freeObjStatements_.clear();
310 sb.AppendFormat("bool %sBlockUnmarshalling(struct HdfSBuf *data, %s *%s)\n", type->GetName().c_str(),
311 type->EmitCType().c_str(), objName.c_str());
312 sb.Append("{\n");
313 EmitUnmarshallingVarDecl(type, objName, sb, TAB);
314 EmitParamCheck(objName, sb, TAB);
315 sb.Append("\n");
316 if (type->IsPod()) {
317 EmitPodTypeUnmarshalling(type, objName, sb, TAB);
318 } else {
319 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
320 AutoPtr<ASTType> memberType = type->GetMemberType(i);
321 EmitMemberUnmarshalling(memberType, objName, type->GetMemberName(i), sb, TAB);
322 }
323 }
324 sb.Append(TAB).Append("return true;\n");
325 sb.AppendFormat("%s:\n", errorsLabelName_);
326 EmitCustomTypeMemoryRecycle(type, objName, sb, TAB);
327 sb.Append(TAB).Append("return false;\n");
328 sb.Append("}\n");
329 }
330
EmitMarshallingVarDecl(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const331 void CCustomTypesCodeEmitter::EmitMarshallingVarDecl(const AutoPtr<ASTStructType> &type,
332 const std::string &name, StringBuilder &sb, const std::string &prefix) const
333 {
334 (void)name;
335 if (!Options::GetInstance().DoGenerateKernelCode()) {
336 return;
337 }
338
339 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
340 if (EmitNeedLoopVar(type->GetMemberType(i), true, false)) {
341 sb.Append(prefix).Append("uint32_t i = 0;\n");
342 break;
343 }
344 }
345 }
346
EmitUnmarshallingVarDecl(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const347 void CCustomTypesCodeEmitter::EmitUnmarshallingVarDecl(
348 const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
349 {
350 if (!Options::GetInstance().DoGenerateKernelCode()) {
351 return;
352 }
353
354 if (type->IsPod()) {
355 sb.Append(prefix).AppendFormat("%s *%sPtr = NULL;\n", type->EmitCType().c_str(), name.c_str());
356 sb.Append(prefix).AppendFormat("uint32_t %sLen = 0;\n\n", name.c_str());
357 return;
358 }
359
360 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
361 if (EmitNeedLoopVar(type->GetMemberType(i), true, true)) {
362 sb.Append(prefix).Append("uint32_t i = 0;\n");
363 break;
364 }
365 }
366 }
367
EmitParamCheck(const std::string & name,StringBuilder & sb,const std::string & prefix) const368 void CCustomTypesCodeEmitter::EmitParamCheck(
369 const std::string &name, StringBuilder &sb, const std::string &prefix) const
370 {
371 sb.Append(prefix).Append("if (data == NULL) {\n");
372 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
373 sb.Append(prefix + TAB).Append("return false;\n");
374 sb.Append(prefix).Append("}\n\n");
375 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
376 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid data block\", __func__);\n");
377 sb.Append(prefix + TAB).Append("return false;\n");
378 sb.Append(prefix).Append("}\n");
379 }
380
EmitPodTypeUnmarshalling(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const381 void CCustomTypesCodeEmitter::EmitPodTypeUnmarshalling(
382 const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
383 {
384 std::string objPtrName = StringHelper::Format("%sPtr", name.c_str());
385 if (Options::GetInstance().DoGenerateKernelCode()) {
386 std::string lenName = StringHelper::Format("%sLen", name.c_str());
387 sb.Append(prefix).AppendFormat(
388 "if (!HdfSbufReadBuffer(data, (const void**)&%s, &%s)) {\n", objPtrName.c_str(), lenName.c_str());
389 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
390 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
391 sb.Append(prefix).Append("}\n\n");
392 sb.Append(prefix).AppendFormat(
393 "if (%s == NULL || %s != sizeof(%s)) {\n", objPtrName.c_str(), lenName.c_str(), type->EmitCType().c_str());
394 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid data from reading buffer\", __func__);\n");
395 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
396 sb.Append(prefix).Append("}\n");
397 } else {
398 sb.Append(prefix).AppendFormat("const %s *%s = (const %s *)HdfSbufReadUnpadBuffer(data, sizeof(%s));\n",
399 type->EmitCType().c_str(), objPtrName.c_str(), type->EmitCType().c_str(), type->EmitCType().c_str());
400 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", objPtrName.c_str());
401 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
402 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
403 sb.Append(prefix).Append("}\n\n");
404 }
405
406 sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", name.c_str(),
407 type->EmitCType().c_str(), objPtrName.c_str(), type->EmitCType().c_str());
408 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy data\", __func__);\n");
409 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
410 sb.Append(prefix).Append("}\n\n");
411 }
412
EmitMemberUnmarshalling(const AutoPtr<ASTType> & type,const std::string & name,const std::string & memberName,StringBuilder & sb,const std::string & prefix)413 void CCustomTypesCodeEmitter::EmitMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &name,
414 const std::string &memberName, StringBuilder &sb, const std::string &prefix)
415 {
416 std::string varName = StringHelper::Format("%s->%s", name.c_str(), memberName.c_str());
417 switch (type->GetTypeKind()) {
418 case TypeKind::TYPE_STRING: {
419 EmitStringMemberUnmarshalling(type, memberName, varName, sb, prefix);
420 break;
421 }
422 case TypeKind::TYPE_STRUCT: {
423 std::string paramName = StringHelper::Format("&%s", varName.c_str());
424 type->EmitCUnMarshalling(paramName, errorsLabelName_, sb, prefix, freeObjStatements_);
425 sb.Append("\n");
426 break;
427 }
428 case TypeKind::TYPE_UNION: {
429 std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
430 type->EmitCUnMarshalling(tmpName, errorsLabelName_, sb, prefix, freeObjStatements_);
431 sb.Append(prefix).AppendFormat("if (memcpy_s(&%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", varName.c_str(),
432 type->EmitCType().c_str(), tmpName.c_str(), type->EmitCType().c_str());
433 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy data\", __func__);\n");
434 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
435 sb.Append(prefix).Append("}\n");
436 break;
437 }
438 case TypeKind::TYPE_ARRAY:
439 case TypeKind::TYPE_LIST: {
440 EmitArrayMemberUnmarshalling(type, memberName, varName, sb, prefix);
441 sb.Append("\n");
442 break;
443 }
444 default: {
445 type->EmitCUnMarshalling(varName, errorsLabelName_, sb, prefix, freeObjStatements_);
446 sb.Append("\n");
447 }
448 }
449 }
450
EmitStringMemberUnmarshalling(const AutoPtr<ASTType> & type,const std::string & memberName,const std::string & varName,StringBuilder & sb,const std::string & prefix)451 void CCustomTypesCodeEmitter::EmitStringMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &memberName,
452 const std::string &varName, StringBuilder &sb, const std::string &prefix)
453 {
454 std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
455 sb.Append(prefix).Append("{\n");
456 type->EmitCUnMarshalling(tmpName, errorsLabelName_, sb, prefix + TAB, freeObjStatements_);
457 if (Options::GetInstance().DoGenerateKernelCode()) {
458 sb.Append(prefix + TAB)
459 .AppendFormat("%s = (char*)OsalMemCalloc(strlen(%s) + 1);\n", varName.c_str(), tmpName.c_str());
460 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", varName.c_str());
461 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
462 sb.Append(prefix + TAB).Append("}\n");
463 sb.Append(prefix + TAB).AppendFormat("if (strcpy_s(%s, (strlen(%s) + 1), %s) != EOK) {\n",
464 varName.c_str(), tmpName.c_str(), tmpName.c_str());
465 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
466 sb.Append(prefix + TAB).Append("}\n");
467 } else {
468 sb.Append(prefix + TAB).AppendFormat("%s = strdup(%s);\n", varName.c_str(), tmpName.c_str());
469 }
470
471 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", varName.c_str());
472 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", errorsLabelName_);
473 sb.Append(prefix + TAB).Append("}\n");
474 sb.Append(prefix).Append("}\n");
475 sb.Append("\n");
476 }
477
EmitArrayMemberUnmarshalling(const AutoPtr<ASTType> & type,const std::string & memberName,const std::string & varName,StringBuilder & sb,const std::string & prefix)478 void CCustomTypesCodeEmitter::EmitArrayMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &memberName,
479 const std::string &varName, StringBuilder &sb, const std::string &prefix)
480 {
481 std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
482 AutoPtr<ASTType> elementType = nullptr;
483 if (type->GetTypeKind() == TypeKind::TYPE_ARRAY) {
484 AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
485 elementType = arrayType->GetElementType();
486 } else {
487 AutoPtr<ASTListType> listType = dynamic_cast<ASTListType *>(type.Get());
488 elementType = listType->GetElementType();
489 }
490
491 if (elementType->IsStringType()) {
492 type->EmitCUnMarshalling(varName, errorsLabelName_, sb, prefix, freeObjStatements_);
493 return;
494 }
495
496 sb.Append(prefix).Append("{\n");
497 sb.Append(prefix + TAB).AppendFormat("%s* %s = NULL;\n", elementType->EmitCType().c_str(), tmpName.c_str());
498 sb.Append(prefix + TAB).AppendFormat("uint32_t %sLen = 0;\n", tmpName.c_str());
499 type->EmitCUnMarshalling(tmpName, errorsLabelName_, sb, prefix + TAB, freeObjStatements_);
500 sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", varName.c_str(), tmpName.c_str());
501 sb.Append(prefix + TAB).AppendFormat("%sLen = %sLen;\n", varName.c_str(), tmpName.c_str());
502 sb.Append(prefix).Append("}\n");
503 }
504
EmitCustomTypeFreeImpl(StringBuilder & sb,const AutoPtr<ASTStructType> & type) const505 void CCustomTypesCodeEmitter::EmitCustomTypeFreeImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
506 {
507 std::string objName("dataBlock");
508 sb.AppendFormat(
509 "void %sFree(%s *%s, bool freeSelf)\n", type->GetName().c_str(), type->EmitCType().c_str(), objName.c_str());
510 sb.Append("{\n");
511
512 if (mode_ == GenMode::KERNEL) {
513 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
514 AutoPtr<ASTType> memberType = type->GetMemberType(i);
515 if (EmitNeedLoopVar(memberType, false, true)) {
516 sb.Append(TAB).Append("uint32_t i = 0;\n");
517 break;
518 }
519 }
520 }
521
522 sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
523 sb.Append(TAB).Append(TAB).Append("return;\n");
524 sb.Append(TAB).Append("}\n");
525 sb.Append("\n");
526
527 EmitCustomTypeMemoryRecycle(type, objName, sb, TAB);
528
529 sb.Append(TAB).Append("if (freeSelf) {\n");
530 sb.Append(TAB).Append(TAB).Append("OsalMemFree(dataBlock);\n");
531 sb.Append(TAB).Append("}\n");
532 sb.Append("}\n");
533 }
534
EmitCustomTypeMemoryRecycle(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const535 void CCustomTypesCodeEmitter::EmitCustomTypeMemoryRecycle(
536 const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
537 {
538 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
539 AutoPtr<ASTType> memberType = type->GetMemberType(i);
540 std::string memberName = type->GetMemberName(i);
541 std::string varName = StringHelper::Format("%s->%s", name.c_str(), memberName.c_str());
542 switch (memberType->GetTypeKind()) {
543 case TypeKind::TYPE_STRING:
544 case TypeKind::TYPE_STRUCT:
545 case TypeKind::TYPE_ARRAY:
546 case TypeKind::TYPE_LIST:
547 memberType->EmitMemoryRecycle(varName, false, sb, prefix);
548 sb.Append("\n");
549 break;
550 default:
551 break;
552 }
553 }
554 }
555
GetUtilMethods(UtilMethodMap & methods)556 void CCustomTypesCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
557 {
558 for (const auto &typePair : ast_->GetTypes()) {
559 typePair.second->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::CUSTOM_SER, methods);
560 typePair.second->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::CUSTOM_SER, methods);
561 }
562 }
563 } // namespace HDI
564 } // namespace OHOS