• 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_service_stub_code_emitter.h"
17 
18 #include "util/file.h"
19 #include "util/logger.h"
20 
21 namespace OHOS {
22 namespace Idl {
ResolveDirectory(const std::string & targetDirectory)23 bool CServiceStubCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
24 {
25     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
26         directory_ = GetFileParentPath(targetDirectory);
27     } else {
28         return false;
29     }
30 
31     if (!File::CreateParentDir(directory_)) {
32         Logger::E("CServiceStubCodeEmitter", "Create '%s' failed!", directory_.c_str());
33         return false;
34     }
35 
36     return true;
37 }
38 
EmitCode()39 void CServiceStubCodeEmitter::EmitCode()
40 {
41     switch (mode_) {
42         case GenMode::IPC:
43         case GenMode::KERNEL: {
44             EmitServiceStubHeaderFile();
45             EmitServiceStubSourceFile();
46             break;
47         }
48         default:
49             break;
50     }
51 }
52 
EmitServiceStubHeaderFile()53 void CServiceStubCodeEmitter::EmitServiceStubHeaderFile()
54 {
55     std::string filePath =
56         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(stubName_).c_str()));
57     File file(filePath, File::WRITE);
58     StringBuilder sb;
59 
60     EmitLicense(sb);
61     EmitHeadMacro(sb, stubFullName_);
62     sb.Append("\n");
63     EmitStubHeaderInclusions(sb);
64     sb.Append("\n");
65     EmitHeadExternC(sb);
66     sb.Append("\n");
67     EmitCbServiceStubDef(sb);
68     if (mode_ == GenMode::KERNEL) {
69         sb.Append("\n");
70         EmitCbServiceStubMethodsDcl(sb);
71     }
72     sb.Append("\n");
73     EmitTailExternC(sb);
74     sb.Append("\n");
75     EmitTailMacro(sb, stubFullName_);
76 
77     std::string data = sb.ToString();
78     file.WriteData(data.c_str(), data.size());
79     file.Flush();
80     file.Close();
81 }
82 
EmitStubHeaderInclusions(StringBuilder & sb)83 void CServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb)
84 {
85     HeaderFile::HeaderFileSet headerFiles;
86 
87     headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
88     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
89 
90     if (mode_ != GenMode::KERNEL) {
91         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service");
92     }
93 
94     for (const auto &file : headerFiles) {
95         sb.AppendFormat("%s\n", file.ToString().c_str());
96     }
97 }
98 
EmitCbServiceStubDef(StringBuilder & sb) const99 void CServiceStubCodeEmitter::EmitCbServiceStubDef(StringBuilder &sb) const
100 {
101     sb.AppendFormat("struct %sStub {\n", baseName_.c_str());
102     if (mode_ == GenMode::KERNEL) {
103         sb.Append(TAB).AppendFormat("struct %s interface;\n", interfaceName_.c_str());
104         sb.Append(TAB).AppendFormat("int32_t (*OnRemoteRequest)(struct %s *serviceImpl, ", interfaceName_.c_str());
105         sb.Append("int code, struct HdfSBuf *data, struct HdfSBuf *reply);\n");
106     } else {
107         sb.Append(TAB).Append("struct HdfRemoteService *remote;\n");
108         sb.Append(TAB).AppendFormat("struct %s *interface;\n", interfaceName_.c_str());
109         sb.Append(TAB).Append("struct HdfRemoteDispatcher dispatcher;\n");
110     }
111     sb.Append("};\n");
112 }
113 
EmitCbServiceStubMethodsDcl(StringBuilder & sb) const114 void CServiceStubCodeEmitter::EmitCbServiceStubMethodsDcl(StringBuilder &sb) const
115 {
116     sb.AppendFormat("bool %sStubConstruct(struct %sStub *stub);\n", baseName_.c_str(), baseName_.c_str());
117 }
118 
EmitServiceStubSourceFile()119 void CServiceStubCodeEmitter::EmitServiceStubSourceFile()
120 {
121     std::string filePath =
122         File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(stubName_).c_str()));
123     File file(filePath, File::WRITE);
124     StringBuilder sb;
125 
126     EmitLicense(sb);
127     EmitStubSourceInclusions(sb);
128     sb.Append("\n");
129     EmitLogTagMacro(sb, FileName(stubName_));
130     if (mode_ != GenMode::KERNEL && !interface_->IsSerializable()) {
131         sb.Append("\n");
132         EmitExternalMethodImpl(sb);
133     }
134     sb.Append("\n");
135     EmitUtilMethods(sb, true);
136     sb.Append("\n");
137     EmitUtilMethods(sb, false);
138     EmitServiceStubMethodImpls(sb, "");
139 
140     if (mode_ == GenMode::KERNEL) {
141         sb.Append("\n");
142         EmitKernelStubOnRequestMethodImpl(sb, "");
143         sb.Append("\n");
144         EmitKernelStubConstruct(sb);
145     } else {
146         sb.Append("\n");
147         EmitStubOnRequestMethodImpl(sb, "");
148         if (!interface_->IsSerializable()) {
149             sb.Append("\n");
150             EmitStubRemoteDispatcher(sb);
151         }
152 
153         sb.Append("\n");
154         EmitStubNewInstance(sb);
155         sb.Append("\n");
156         EmitStubReleaseMethod(sb);
157         sb.Append("\n");
158         EmitStubConstructor(sb);
159         sb.Append("\n");
160         EmitStubRegAndUnreg(sb);
161     }
162 
163     std::string data = sb.ToString();
164     file.WriteData(data.c_str(), data.size());
165     file.Flush();
166     file.Close();
167 }
168 
EmitStubSourceInclusions(StringBuilder & sb)169 void CServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
170 {
171     HeaderFile::HeaderFileSet headerFiles;
172 
173     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
174     GetSourceOtherLibInclusions(headerFiles);
175 
176     for (const auto &file : headerFiles) {
177         sb.AppendFormat("%s\n", file.ToString().c_str());
178     }
179 }
180 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const181 void CServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
182 {
183     if (mode_ != GenMode::KERNEL) {
184         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
185         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist");
186         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
187 
188         if (!interface_->IsSerializable()) {
189             headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
190         }
191     } else {
192         const AST::TypeStringMap &types = ast_->GetTypes();
193         for (const auto &pair : types) {
194             AutoPtr<ASTType> type = pair.second;
195             if (type->GetTypeKind() == TypeKind::TYPE_STRING || type->GetTypeKind() == TypeKind::TYPE_UNION) {
196                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
197                 break;
198             }
199         }
200     }
201 
202     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
203     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
204     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
205 }
206 
EmitExternalMethodImpl(StringBuilder & sb)207 void CServiceStubCodeEmitter::EmitExternalMethodImpl(StringBuilder &sb)
208 {
209     EmitGetMethodImpl(sb);
210     sb.Append("\n");
211     EmitGetInstanceMehtodImpl(sb);
212     sb.Append("\n");
213     EmitReleaseMethodImpl(sb);
214     sb.Append("\n");
215     EmitReleaseInstanceMethodImpl(sb);
216 }
217 
EmitGetMethodImpl(StringBuilder & sb) const218 void CServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb) const
219 {
220     sb.AppendFormat("struct %s *%sGet(bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
221     sb.Append("{\n");
222     sb.Append(TAB).AppendFormat(
223         "return %sGetInstance(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
224     sb.Append("}\n");
225 }
226 
EmitGetInstanceMehtodImpl(StringBuilder & sb) const227 void CServiceStubCodeEmitter::EmitGetInstanceMehtodImpl(StringBuilder &sb) const
228 {
229     sb.AppendFormat("struct %s *%sGetInstance(const char *serviceName, bool isStub)\n", interfaceName_.c_str(),
230         interfaceName_.c_str());
231     sb.Append("{\n");
232     sb.Append(TAB).Append("if (!isStub) {\n");
233     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
234     sb.Append(TAB).Append("}\n\n");
235     sb.Append(TAB).AppendFormat("const char *instName = serviceName;\n");
236     sb.Append(TAB).AppendFormat("if (strcmp(serviceName, \"%s\") == 0) {\n", FileName(implName_).c_str());
237     sb.Append(TAB).Append(TAB).Append("instName = \"service\";\n");
238     sb.Append(TAB).Append("}\n");
239     sb.Append(TAB).AppendFormat("return (struct %s *)LoadHdiImpl(%s, instName);\n",
240         interfaceName_.c_str(), EmitDescMacroName().c_str());
241     sb.Append("}\n");
242 }
243 
EmitReleaseMethodImpl(StringBuilder & sb) const244 void CServiceStubCodeEmitter::EmitReleaseMethodImpl(StringBuilder &sb) const
245 {
246     sb.AppendFormat(
247         "void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
248     sb.Append("{\n");
249     sb.Append(TAB).AppendFormat(
250         "%sReleaseInstance(\"%s\", instance, isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
251     sb.Append("}\n");
252 }
253 
EmitReleaseInstanceMethodImpl(StringBuilder & sb) const254 void CServiceStubCodeEmitter::EmitReleaseInstanceMethodImpl(StringBuilder &sb) const
255 {
256     sb.AppendFormat("void %sReleaseInstance(const char *serviceName, struct %s *instance, bool isStub)\n",
257         interfaceName_.c_str(), interfaceName_.c_str());
258     sb.Append("{\n");
259     sb.Append(TAB).Append("if (serviceName == NULL || !isStub || instance == NULL) {\n");
260     sb.Append(TAB).Append(TAB).Append("return;\n");
261     sb.Append(TAB).Append("}\n");
262     sb.Append(TAB).Append("const char *instName = serviceName;\n");
263     sb.Append(TAB).AppendFormat("if (strcmp(serviceName, \"%s\") == 0) {\n", FileName(implName_).c_str());
264     sb.Append(TAB).Append(TAB).Append("instName = \"service\";\n");
265     sb.Append(TAB).Append("}\n");
266     sb.Append(TAB).AppendFormat("UnloadHdiImpl(%s, instName, instance);\n", EmitDescMacroName().c_str());
267     sb.Append("}\n");
268 }
269 
EmitServiceStubMethodImpls(StringBuilder & sb,const std::string & prefix)270 void CServiceStubCodeEmitter::EmitServiceStubMethodImpls(StringBuilder &sb, const std::string &prefix)
271 {
272     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
273         EmitServiceStubMethodImpl(method, sb, prefix);
274         sb.Append("\n");
275     }
276 
277     EmitStubGetVerMethodImpl(interface_->GetVersionMethod(), sb, prefix);
278     if (mode_ != GenMode::KERNEL) {
279         sb.Append("\n");
280         EmitStubAsObjectMethodImpl(sb, prefix);
281     }
282 }
283 
EmitServiceStubMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const284 void CServiceStubCodeEmitter::EmitServiceStubMethodImpl(
285     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
286 {
287     sb.Append(prefix).AppendFormat(
288         "static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n",
289         method->GetName().c_str(), interfaceName_.c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
290         HdiTypeEmitter::replyParcelName_.c_str());
291     sb.Append(prefix).Append("{\n");
292     sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_FAILURE;\n", HdiTypeEmitter::errorCodeName_.c_str());
293     bool readFlag = NeedFlag(method);
294     if (readFlag) {
295         sb.Append(prefix + TAB).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
296     }
297 
298     // Local variable definitions must precede all execution statements.
299     EmitMethodNeedLoopVar(method, true, true, sb, prefix + TAB);
300 
301     if (method->GetParameterNumber() > 0) {
302         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
303             AutoPtr<ASTParameter> param = method->GetParameter(i);
304             EmitStubLocalVariable(param, sb, prefix + TAB);
305         }
306 
307         sb.Append("\n");
308         EmitReadFlagVariable(readFlag, sb, prefix + TAB);
309         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
310             AutoPtr<ASTParameter> param = method->GetParameter(i);
311             if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
312                 EmitReadStubMethodParameter(param, FINISHED_LABEL, sb, prefix + TAB);
313                 sb.Append("\n");
314             } else {
315                 EmitOutVarMemInitialize(param, FINISHED_LABEL, sb, prefix + TAB);
316             }
317         }
318     }
319 
320     EmitStubCallMethod(method, FINISHED_LABEL, sb, prefix + TAB);
321     sb.Append("\n");
322 
323     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
324         AutoPtr<ASTParameter> param = method->GetParameter(i);
325         if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
326             AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
327             if (typeEmitter == nullptr) {
328                 continue;
329             }
330             typeEmitter->EmitCWriteVar(TypeMode::PARAM_OUT, param->GetName(), FINISHED_LABEL, sb, prefix + TAB);
331             sb.Append("\n");
332         }
333     }
334 
335     EmitErrorHandle(method, sb, prefix);
336     sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
337     sb.Append(prefix).Append("}\n");
338 }
339 
EmitErrorHandle(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const340 void CServiceStubCodeEmitter::EmitErrorHandle(const AutoPtr<ASTMethod> &method,
341     StringBuilder &sb, const std::string &prefix) const
342 {
343     sb.Append(prefix).AppendFormat("%s:\n", FINISHED_LABEL);
344     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
345         AutoPtr<ASTParameter> param = method->GetParameter(i);
346         AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
347         if (typeEmitter != nullptr) {
348             typeEmitter->EmitMemoryRecycle(param->GetName(), true, sb, prefix + TAB);
349         }
350     }
351 }
352 
EmitReadFlagVariable(bool readFlag,StringBuilder & sb,const std::string & prefix) const353 void CServiceStubCodeEmitter::EmitReadFlagVariable(bool readFlag, StringBuilder &sb, const std::string &prefix) const
354 {
355     if (!readFlag) {
356         return;
357     }
358 
359     sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint8(%s, (uint8_t *)&%s)) {\n",
360         HdiTypeEmitter::dataParcelName_.c_str(), flagOfSetMemName_.c_str());
361     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: read flag of memory setting failed!\", __func__);\n");
362     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
363     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
364     sb.Append(prefix).Append("}\n\n");
365 }
366 
EmitStubLocalVariable(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const367 void CServiceStubCodeEmitter::EmitStubLocalVariable(
368     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix) const
369 {
370     AutoPtr<ASTType> type = param->GetType();
371     EmitParamLocalVar(param, sb, prefix);
372     if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST ||
373         (type->GetTypeKind() == TypeKind::TYPE_STRING && (param->GetAttribute() == ASTParamAttr::PARAM_OUT))) {
374         sb.Append(prefix).AppendFormat("uint32_t %sLen = 0;\n", param->GetName().c_str());
375     }
376 }
377 
EmitParamLocalVar(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const378 void CServiceStubCodeEmitter::EmitParamLocalVar(const AutoPtr<ASTParameter> &param, StringBuilder &sb,
379     const std::string &prefix) const
380 {
381     AutoPtr<ASTType> type = param->GetType();
382     AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
383     if (typeEmitter == nullptr) {
384         return;
385     }
386     sb.Append(prefix).AppendFormat("%s %s", typeEmitter->EmitCType(TypeMode::LOCAL_VAR).c_str(),
387         param->GetName().c_str());
388     switch (type->GetTypeKind()) {
389         case TypeKind::TYPE_BOOLEAN:
390             sb.Append(" = false");
391             break;
392         case TypeKind::TYPE_BYTE:
393         case TypeKind::TYPE_SHORT:
394         case TypeKind::TYPE_INT:
395         case TypeKind::TYPE_LONG:
396         case TypeKind::TYPE_UCHAR:
397         case TypeKind::TYPE_USHORT:
398         case TypeKind::TYPE_UINT:
399         case TypeKind::TYPE_ULONG:
400         case TypeKind::TYPE_FLOAT:
401         case TypeKind::TYPE_DOUBLE:
402             sb.Append(" = 0");
403             break;
404         case TypeKind::TYPE_STRING:
405         case TypeKind::TYPE_ARRAY:
406         case TypeKind::TYPE_LIST:
407         case TypeKind::TYPE_STRUCT:
408         case TypeKind::TYPE_UNION:
409         case TypeKind::TYPE_INTERFACE:
410         case TypeKind::TYPE_NATIVE_BUFFER:
411             sb.Append(" = NULL");
412             break;
413         case TypeKind::TYPE_FILEDESCRIPTOR:
414             sb.Append(" = -1");
415             break;
416         default:
417             break;
418     }
419     sb.Append(";\n");
420 }
421 
EmitReadStubMethodParameter(const AutoPtr<ASTParameter> & param,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const422 void CServiceStubCodeEmitter::EmitReadStubMethodParameter(const AutoPtr<ASTParameter> &param,
423     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
424 {
425     AutoPtr<ASTType> type = param->GetType();
426     AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
427     if (typeEmitter == nullptr) {
428         return;
429     }
430     if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
431         EmitReadCStringStubMethodParameter(param, gotoLabel, sb, prefix, typeEmitter);
432     } else if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
433         sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().c_str(),
434             typeEmitter->EmitCType().c_str(), typeEmitter->EmitCType().c_str());
435         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
436         sb.Append(prefix + TAB)
437             .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
438         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
439         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
440         sb.Append(prefix).Append("}\n");
441         typeEmitter->EmitCStubReadVar(param->GetName(), gotoLabel, sb, prefix);
442     } else if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
443         std::string cpName = StringHelper::Format("%sCp", param->GetName().c_str());
444         typeEmitter->EmitCStubReadVar(cpName, gotoLabel, sb, prefix);
445         sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().c_str(),
446             typeEmitter->EmitCType().c_str(), typeEmitter->EmitCType().c_str());
447         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
448         sb.Append(prefix + TAB)
449             .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
450         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
451         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
452         sb.Append(prefix).Append("}\n");
453         sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n",
454             param->GetName().c_str(), typeEmitter->EmitCType().c_str(), cpName.c_str(),
455             typeEmitter->EmitCType().c_str());
456         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to memcpy %s\", __func__);\n",
457             param->GetName().c_str());
458         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
459         sb.Append(prefix).Append("}\n");
460     } else if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST ||
461                type->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR ||
462                type->GetTypeKind() == TypeKind::TYPE_NATIVE_BUFFER || type->GetTypeKind() == TypeKind::TYPE_ENUM ||
463                type->GetTypeKind() == TypeKind::TYPE_INTERFACE) {
464         typeEmitter->EmitCStubReadVar(param->GetName(), gotoLabel, sb, prefix);
465     } else {
466         std::string name = StringHelper::Format("&%s", param->GetName().c_str());
467         typeEmitter->EmitCStubReadVar(name, gotoLabel, sb, prefix);
468     }
469 }
470 
EmitReadCStringStubMethodParameter(const AutoPtr<ASTParameter> & param,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,AutoPtr<HdiTypeEmitter> & typeEmitter) const471 void CServiceStubCodeEmitter::EmitReadCStringStubMethodParameter(const AutoPtr<ASTParameter> &param,
472     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix,
473     AutoPtr<HdiTypeEmitter> &typeEmitter) const
474 {
475     std::string cloneName = StringHelper::Format("%sCp", param->GetName().c_str());
476     typeEmitter->EmitCStubReadVar(cloneName, gotoLabel, sb, prefix);
477     if (mode_ == GenMode::KERNEL) {
478         sb.Append("\n");
479         sb.Append(prefix).AppendFormat(
480             "%s = (char*)OsalMemCalloc(strlen(%s) + 1);\n", param->GetName().c_str(), cloneName.c_str());
481         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
482         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
483         sb.Append(prefix + TAB)
484             .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
485         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
486         sb.Append(prefix).Append("}\n\n");
487         sb.Append(prefix).AppendFormat("if (strcpy_s(%s, (strlen(%s) + 1), %s) != HDF_SUCCESS) {\n",
488             param->GetName().c_str(), cloneName.c_str(), cloneName.c_str());
489         sb.Append(prefix + TAB)
490             .AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", param->GetName().c_str());
491         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
492         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
493         sb.Append(prefix).Append("}\n");
494     } else {
495         sb.Append(prefix).AppendFormat("%s = strdup(%s);\n", param->GetName().c_str(), cloneName.c_str());
496     }
497 }
498 
EmitOutVarMemInitialize(const AutoPtr<ASTParameter> & param,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const499 void CServiceStubCodeEmitter::EmitOutVarMemInitialize(const AutoPtr<ASTParameter> &param,
500     const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
501 {
502     AutoPtr<ASTType> type = param->GetType();
503     AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
504     if (typeEmitter == nullptr) {
505         return;
506     }
507     if (type->IsStructType() || type->IsUnionType()) {
508         sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().c_str(),
509             typeEmitter->EmitCType().c_str(), typeEmitter->EmitCType().c_str());
510         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
511         sb.Append(prefix + TAB)
512             .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
513         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
514         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
515         sb.Append(prefix).Append("}\n\n");
516     } else if (type->IsStringType() || type->IsArrayType() || type->IsListType()) {
517         typeEmitter->EmitCStubReadOutVar(flagOfSetMemName_, param->GetName(), gotoLabel, sb, prefix);
518         sb.Append("\n");
519     }
520 }
521 
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const522 void CServiceStubCodeEmitter::EmitStubCallMethod(
523     const AutoPtr<ASTMethod> &method, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
524 {
525     sb.Append(prefix).Append("if (serviceImpl == NULL) {\n");
526     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid serviceImpl object\", __func__);\n");
527     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_OBJECT;\n", HdiTypeEmitter::errorCodeName_.c_str());
528     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
529     sb.Append(prefix).Append("}\n\n");
530 
531     sb.Append(prefix).AppendFormat("if (serviceImpl->%s == NULL) {\n", method->GetName().c_str());
532     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: invalid interface function %s \", __func__);\n",
533         method->GetName().c_str());
534     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_NOT_SUPPORT;\n", HdiTypeEmitter::errorCodeName_.c_str());
535     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
536     sb.Append(prefix).Append("}\n\n");
537 
538     if (method->GetParameterNumber() == 0) {
539         sb.Append(prefix).AppendFormat(
540             "%s = serviceImpl->%s(serviceImpl);\n", HdiTypeEmitter::errorCodeName_.c_str(), method->GetName().c_str());
541     } else {
542         sb.Append(prefix).AppendFormat(
543             "%s = serviceImpl->%s(serviceImpl, ", HdiTypeEmitter::errorCodeName_.c_str(), method->GetName().c_str());
544         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
545             AutoPtr<ASTParameter> param = method->GetParameter(i);
546             EmitCallParameter(sb, param->GetType(), param->GetAttribute(), param->GetName());
547             if (i + 1 < method->GetParameterNumber()) {
548                 sb.Append(", ");
549             }
550         }
551         sb.AppendFormat(");\n", method->GetName().c_str());
552     }
553 
554     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
555     sb.Append(prefix + TAB)
556         .AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
557         HdiTypeEmitter::errorCodeName_.c_str());
558     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
559     sb.Append(prefix).Append("}\n");
560 }
561 
EmitCallParameter(StringBuilder & sb,const AutoPtr<ASTType> & type,ASTParamAttr::ParamAttr attribute,const std::string & name) const562 void CServiceStubCodeEmitter::EmitCallParameter(
563     StringBuilder &sb, const AutoPtr<ASTType> &type, ASTParamAttr::ParamAttr attribute, const std::string &name) const
564 {
565     if (attribute == ASTParamAttr::PARAM_OUT) {
566         if (type->GetTypeKind() == TypeKind::TYPE_STRING || type->GetTypeKind() == TypeKind::TYPE_ARRAY ||
567             type->GetTypeKind() == TypeKind::TYPE_LIST || type->GetTypeKind() == TypeKind::TYPE_STRUCT ||
568             type->GetTypeKind() == TypeKind::TYPE_UNION) {
569             sb.AppendFormat("%s", name.c_str());
570         } else {
571             sb.AppendFormat("&%s", name.c_str());
572         }
573 
574         if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
575             sb.AppendFormat(", %sLen", name.c_str());
576         } else if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
577             sb.AppendFormat(", &%sLen", name.c_str());
578         }
579     }
580     if (attribute == ASTParamAttr::PARAM_IN) {
581         sb.AppendFormat("%s", name.c_str());
582         if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
583             sb.AppendFormat(", %sLen", name.c_str());
584         }
585     }
586 }
587 
EmitStubGetVerMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const588 void CServiceStubCodeEmitter::EmitStubGetVerMethodImpl(
589     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
590 {
591     sb.Append(prefix).AppendFormat(
592         "static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n",
593         method->GetName().c_str(), interfaceName_.c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
594         HdiTypeEmitter::replyParcelName_.c_str());
595     sb.Append(prefix).Append("{\n");
596     sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_SUCCESS;\n", HdiTypeEmitter::errorCodeName_.c_str());
597 
598     AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(new ASTUintType());
599     if (typeEmitter == nullptr) {
600         return;
601     }
602     typeEmitter->EmitCWriteVar(TypeMode::PARAM_OUT, majorVerName_, FINISHED_LABEL, sb, prefix + TAB);
603     sb.Append("\n");
604     typeEmitter->EmitCWriteVar(TypeMode::PARAM_OUT, minorVerName_, FINISHED_LABEL, sb, prefix + TAB);
605     sb.Append("\n");
606 
607     sb.Append(FINISHED_LABEL).Append(":\n");
608     sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
609     sb.Append(prefix).Append("}\n");
610 }
611 
EmitStubAsObjectMethodImpl(StringBuilder & sb,const std::string & prefix) const612 void CServiceStubCodeEmitter::EmitStubAsObjectMethodImpl(StringBuilder &sb, const std::string &prefix) const
613 {
614     std::string objName = "self";
615     sb.Append(prefix).AppendFormat("static struct HdfRemoteService *%sStubAsObject(struct %s *%s)\n", baseName_.c_str(),
616         interfaceName_.c_str(), objName.c_str());
617     sb.Append(prefix).Append("{\n");
618 
619     if (interface_->IsSerializable()) {
620         sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
621         sb.Append(prefix + TAB + TAB).Append("return NULL;\n");
622         sb.Append(prefix + TAB).Append("}\n");
623         sb.Append(prefix + TAB).AppendFormat(
624             "struct %sStub *stub = CONTAINER_OF(%s, struct %sStub, interface);\n", baseName_.c_str(),
625             objName.c_str(), baseName_.c_str());
626         sb.Append(prefix + TAB).Append("return stub->remote;\n");
627     } else {
628         sb.Append(prefix + TAB).Append("return NULL;\n");
629     }
630 
631     sb.Append(prefix).Append("}\n");
632 }
633 
EmitKernelStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)634 void CServiceStubCodeEmitter::EmitKernelStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
635 {
636     std::string implName = "serviceImpl";
637     std::string codeName = "code";
638     std::string funcName = StringHelper::Format("%sOnRemoteRequest", baseName_.c_str());
639     sb.Append(prefix).AppendFormat("static int32_t %s(struct %s *%s, ", funcName.c_str(), interfaceName_.c_str(),
640         implName.c_str());
641     sb.AppendFormat("int %s, struct HdfSBuf *data, struct HdfSBuf *reply)\n", codeName.c_str());
642     sb.Append(prefix).Append("{\n");
643     sb.Append(prefix + TAB).AppendFormat("switch (%s) {\n", codeName.c_str());
644     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
645         sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
646         sb.Append(prefix + TAB + TAB + TAB)
647             .AppendFormat("return SerStub%s(%s, data, reply);\n", method->GetName().c_str(), implName.c_str());
648     }
649 
650     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
651     sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
652     sb.Append(prefix + TAB + TAB + TAB)
653         .AppendFormat("return SerStub%s(%s, data, reply);\n", getVerMethod->GetName().c_str(), implName.c_str());
654 
655     sb.Append(prefix + TAB + TAB).Append("default: {\n");
656     sb.Append(prefix + TAB + TAB + TAB)
657         .AppendFormat("HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.c_str());
658     sb.Append(prefix + TAB + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
659     sb.Append(prefix + TAB + TAB).Append("}\n");
660     sb.Append(prefix + TAB).Append("}\n");
661     sb.Append("}\n");
662 }
663 
EmitKernelStubConstruct(StringBuilder & sb) const664 void CServiceStubCodeEmitter::EmitKernelStubConstruct(StringBuilder &sb) const
665 {
666     std::string stubTypeName = StringHelper::Format("%sStub", baseName_.c_str());
667     std::string objName = "stub";
668     std::string funcName = StringHelper::Format("%sOnRemoteRequest", baseName_.c_str());
669 
670     sb.AppendFormat(
671         "bool %sConstruct(struct %s *%s)\n", stubTypeName.c_str(), stubTypeName.c_str(), objName.c_str());
672     sb.Append("{\n");
673     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
674     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: stub is null!\", __func__);\n");
675     sb.Append(TAB).Append(TAB).Append("return false;\n");
676     sb.Append(TAB).Append("}\n\n");
677     sb.Append(TAB).AppendFormat("%s->OnRemoteRequest = %s;\n", objName.c_str(), funcName.c_str());
678     sb.Append(TAB).Append("return true;\n");
679     sb.Append("}\n");
680 }
681 
EmitStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)682 void CServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
683 {
684     std::string remoteName = "remote";
685     std::string codeName = "code";
686     std::string funcName = StringHelper::Format("%sOnRemoteRequest", baseName_.c_str());
687     sb.Append(prefix).AppendFormat("static int32_t %s(struct HdfRemoteService *%s, ", funcName.c_str(),
688         remoteName.c_str());
689     sb.AppendFormat("int %s, struct HdfSBuf *data, struct HdfSBuf *reply)\n", codeName.c_str());
690     sb.Append(prefix).Append("{\n");
691 
692     sb.Append(prefix + TAB).AppendFormat("struct %s *stub = (struct %s*)%s;\n", stubName_.c_str(),
693         stubName_.c_str(), remoteName.c_str());
694     sb.Append(prefix + TAB).Append("if (stub == NULL || stub->remote == NULL || stub->interface == NULL) {\n");
695     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid stub object\", __func__);\n");
696     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
697     sb.Append(prefix + TAB).Append("}\n");
698 
699     sb.Append(prefix + TAB).AppendFormat("if (!HdfRemoteServiceCheckInterfaceToken(stub->%s, data)) {\n",
700         remoteName.c_str());
701     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: interface token check failed\", __func__);\n");
702     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
703     sb.Append(prefix + TAB).Append("}\n\n");
704 
705     sb.Append(prefix + TAB).AppendFormat("switch (%s) {\n", codeName.c_str());
706     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
707         sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
708         sb.Append(prefix + TAB + TAB + TAB)
709             .AppendFormat("return SerStub%s(stub->interface, data, reply);\n", method->GetName().c_str());
710     }
711 
712     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
713     sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
714     sb.Append(prefix + TAB + TAB + TAB)
715         .AppendFormat("return SerStub%s(stub->interface, data, reply);\n", getVerMethod->GetName().c_str());
716 
717     sb.Append(prefix + TAB + TAB).Append("default: {\n");
718     sb.Append(prefix + TAB + TAB + TAB)
719         .AppendFormat("HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.c_str());
720     sb.Append(prefix + TAB + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
721     sb.Append(prefix + TAB + TAB).Append("}\n");
722     sb.Append(prefix + TAB).Append("}\n");
723     sb.Append("}\n");
724 }
725 
EmitStubRemoteDispatcher(StringBuilder & sb) const726 void CServiceStubCodeEmitter::EmitStubRemoteDispatcher(StringBuilder &sb) const
727 {
728     std::string dispatcherName = StringHelper::Format("g_%sDispatcher", StringHelper::StrToLower(baseName_).c_str());
729     sb.AppendFormat("static struct HdfRemoteDispatcher %s = {\n", dispatcherName.c_str());
730     sb.Append(TAB).AppendFormat(".Dispatch = %sOnRemoteRequest,\n", baseName_.c_str());
731     sb.Append(TAB).Append(".DispatchAsync = NULL,\n");
732     sb.Append("};\n");
733 }
734 
EmitStubNewInstance(StringBuilder & sb) const735 void CServiceStubCodeEmitter::EmitStubNewInstance(StringBuilder &sb) const
736 {
737     std::string dispatcherName = StringHelper::Format("g_%sDispatcher", StringHelper::StrToLower(baseName_).c_str());
738     sb.AppendFormat("static struct HdfRemoteService **%sNewInstance(void *impl)\n", stubName_.c_str());
739     sb.Append("{\n");
740     sb.Append(TAB).Append("if (impl == NULL) {\n");
741     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: impl is null\", __func__);\n");
742     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
743     sb.Append(TAB).Append("}\n\n");
744 
745     sb.Append(TAB).AppendFormat("struct %s *serviceImpl = (struct %s *)impl;\n", interfaceName_.c_str(),
746         interfaceName_.c_str());
747     sb.Append(TAB).AppendFormat("struct %s *stub = OsalMemCalloc(sizeof(struct %s));\n", stubName_.c_str(),
748         stubName_.c_str());
749     sb.Append(TAB).Append("if (stub == NULL) {\n");
750     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc stub object\", __func__);\n");
751     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
752     sb.Append(TAB).Append("}\n");
753 
754     if (interface_->IsSerializable()) {
755         sb.Append(TAB).Append("stub->remote = HdfRemoteServiceObtain((struct HdfObject *)stub, &stub->dispatcher);\n");
756     } else {
757         sb.Append(TAB).AppendFormat("stub->remote = HdfRemoteServiceObtain((struct HdfObject *)stub, &%s);\n",
758             dispatcherName.c_str());
759     }
760 
761     sb.Append(TAB).Append("if (stub->remote == NULL) {\n");
762     sb.Append(TAB).Append(TAB).Append("OsalMemFree(stub);\n");
763     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
764     sb.Append(TAB).Append("}\n");
765     sb.Append(TAB).AppendFormat("(void)HdfRemoteServiceSetInterfaceDesc(stub->remote, %s);\n",
766         EmitDescMacroName().c_str());
767     sb.Append(TAB).AppendFormat("stub->dispatcher.Dispatch = %sOnRemoteRequest;\n", baseName_.c_str());
768     sb.Append(TAB).Append("stub->interface = serviceImpl;\n");
769     sb.Append(TAB).AppendFormat("stub->interface->AsObject = %sStubAsObject;\n", baseName_.c_str());
770     sb.Append(TAB).Append("return &stub->remote;\n");
771     sb.Append("}\n");
772 }
773 
EmitStubReleaseMethod(StringBuilder & sb) const774 void CServiceStubCodeEmitter::EmitStubReleaseMethod(StringBuilder &sb) const
775 {
776     sb.AppendFormat("static void %sRelease(struct HdfRemoteService **remote)\n", stubName_.c_str());
777     sb.Append("{\n");
778     sb.Append(TAB).Append("if (remote == NULL) {\n");
779     sb.Append(TAB).Append(TAB).Append("return;\n");
780     sb.Append(TAB).Append("}\n");
781     sb.Append(TAB).AppendFormat("struct %s *stub = CONTAINER_OF(remote, struct %s, remote);\n",
782         stubName_.c_str(), stubName_.c_str());
783     sb.Append(TAB).Append("HdfRemoteServiceRecycle(stub->remote);\n");
784     sb.Append(TAB).Append("OsalMemFree(stub);\n");
785     sb.Append("}\n");
786 }
787 
EmitStubConstructor(StringBuilder & sb) const788 void CServiceStubCodeEmitter::EmitStubConstructor(StringBuilder &sb) const
789 {
790     std::string constructorName = StringHelper::Format("g_%sConstructor", StringHelper::StrToLower(baseName_).c_str());
791     sb.AppendFormat("__attribute__((unused)) static struct StubConstructor %s = {\n", constructorName.c_str());
792     sb.Append(TAB).AppendFormat(".constructor = %sNewInstance,\n", stubName_.c_str());
793     sb.Append(TAB).AppendFormat(".destructor = %sRelease,\n", stubName_.c_str());
794     sb.Append("};\n");
795 }
796 
EmitStubRegAndUnreg(StringBuilder & sb) const797 void CServiceStubCodeEmitter::EmitStubRegAndUnreg(StringBuilder &sb) const
798 {
799     std::string constructorName = StringHelper::Format("g_%sConstructor", StringHelper::StrToLower(baseName_).c_str());
800     sb.AppendFormat("__attribute__((constructor)) static void %sRegister(void)\n", stubName_.c_str());
801     sb.Append("{\n");
802     sb.Append(TAB).AppendFormat(
803         "HDF_LOGI(\"%%{public}s: register stub constructor of '%%{public}s'\", __func__, %s);\n",
804         EmitDescMacroName().c_str());
805     sb.Append(TAB).AppendFormat("StubConstructorRegister(%s, &%s);\n", EmitDescMacroName().c_str(),
806         constructorName.c_str());
807     sb.Append("}\n");
808 }
809 
EmitUtilMethods(StringBuilder & sb,bool isDecl)810 void CServiceStubCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
811 {
812     UtilMethodMap methods;
813     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
814         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
815             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
816             AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
817             if (typeEmitter == nullptr) {
818                 continue;
819             }
820             if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
821                 typeEmitter->EmitCStubReadMethods(methods, "", "", isDecl);
822             } else {
823                 typeEmitter->EmitCWriteMethods(methods, "", "", isDecl);
824             }
825         }
826     }
827     EmitUtilMethodMap(sb, methods);
828 }
829 } // namespace Idl
830 } // namespace OHOS
831