• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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