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