• 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_service_stub_code_emitter.h"
10 
11 #include "util/file.h"
12 #include "util/logger.h"
13 
14 namespace OHOS {
15 namespace HDI {
ResolveDirectory(const String & targetDirectory)16 bool CServiceStubCodeEmitter::ResolveDirectory(const String& targetDirectory)
17 {
18     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE ||
19         ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
20         directory_ = GetFilePath(targetDirectory);
21     } else {
22         return false;
23     }
24 
25     if (!File::CreateParentDir(directory_)) {
26         Logger::E("CServiceStubCodeEmitter", "Create '%s' failed!", directory_.string());
27         return false;
28     }
29 
30     return true;
31 }
32 
EmitCode()33 void CServiceStubCodeEmitter::EmitCode()
34 {
35     EmitServiceStubHeaderFile();
36     EmitServiceStubSourceFile();
37 }
38 
EmitServiceStubHeaderFile()39 void CServiceStubCodeEmitter::EmitServiceStubHeaderFile()
40 {
41     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(stubName_).string());
42     File file(filePath, File::WRITE);
43     StringBuilder sb;
44 
45     EmitLicense(sb);
46     EmitHeadMacro(sb, stubFullName_);
47     sb.Append("\n");
48     EmitStubHeaderInclusions(sb);
49     sb.Append("\n");
50     EmitHeadExternC(sb);
51     sb.Append("\n");
52     EmitCbServiceStubDef(sb);
53     sb.Append("\n");
54     EmitCbServiceStubMethodsDcl(sb);
55     sb.Append("\n");
56     EmitTailExternC(sb);
57     sb.Append("\n");
58     EmitTailMacro(sb, stubFullName_);
59 
60     String data = sb.ToString();
61     file.WriteData(data.string(), data.GetLength());
62     file.Flush();
63     file.Close();
64 }
65 
EmitStubHeaderInclusions(StringBuilder & sb)66 void CServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder& sb)
67 {
68     HeaderFile::HeaderFileSet headerFiles;
69 
70     headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_)));
71     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf"));
72 
73     if (interface_->IsSerializable()) {
74         headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service"));
75     }
76 
77     for (const auto& file : headerFiles) {
78         sb.AppendFormat("%s\n", file.ToString().string());
79     }
80 }
81 
EmitCbServiceStubDef(StringBuilder & sb)82 void CServiceStubCodeEmitter::EmitCbServiceStubDef(StringBuilder& sb)
83 {
84     sb.AppendFormat("struct %sStub\n", baseName_.string());
85     sb.Append("{\n");
86     sb.Append(g_tab).AppendFormat("struct %s interface;\n", interfaceName_.string());
87 
88     if (interface_->IsSerializable()) {
89         sb.Append(g_tab).Append("struct HdfRemoteService *remote;\n");
90         sb.Append(g_tab).Append("struct HdfRemoteDispatcher dispatcher;\n");
91     } else {
92         sb.Append(g_tab).AppendFormat("int32_t (*OnRemoteRequest)(struct %s *serviceImpl, ",
93             interfaceName_.string());
94         sb.Append("int code, struct HdfSBuf *data, struct HdfSBuf *reply);\n");
95     }
96 
97     sb.Append("};\n");
98 }
99 
EmitCbServiceStubMethodsDcl(StringBuilder & sb)100 void CServiceStubCodeEmitter::EmitCbServiceStubMethodsDcl(StringBuilder& sb)
101 {
102     sb.AppendFormat("bool %sStubConstruct(struct %sStub *stub);\n", baseName_.string(), baseName_.string());
103 
104     if (interface_->IsSerializable()) {
105         sb.AppendFormat("void %sStubRelease(struct %sStub *stub);\n", baseName_.string(), baseName_.string());
106     }
107 }
108 
EmitServiceStubSourceFile()109 void CServiceStubCodeEmitter::EmitServiceStubSourceFile()
110 {
111     String filePath = String::Format("%s/%s.c", directory_.string(), FileName(stubName_).string());
112     File file(filePath, File::WRITE);
113     StringBuilder sb;
114 
115     EmitLicense(sb);
116     EmitStubSourceInclusions(sb);
117     sb.Append("\n");
118     EmitServiceStubMethodImpls(sb, "");
119     sb.Append("\n");
120     EmitStubOnRequestMethodImpl(sb, "");
121     sb.Append("\n");
122     EmitStubGetMethodImpl(sb);
123 
124     if (!isKernelCode_ && interface_->IsSerializable()) {
125         sb.Append("\n");
126         EmitStubReleaseImpl(sb);
127     }
128 
129     String data = sb.ToString();
130     file.WriteData(data.string(), data.GetLength());
131     file.Flush();
132     file.Close();
133 }
134 
EmitStubSourceInclusions(StringBuilder & sb)135 void CServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder& sb)
136 {
137     HeaderFile::HeaderFileSet headerFiles;
138 
139     headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_)));
140     GetSourceOtherLibInclusions(headerFiles);
141 
142     for (const auto& file : headerFiles) {
143         sb.AppendFormat("%s\n", file.ToString().string());
144     }
145 }
146 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)147 void CServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles)
148 {
149     if (!isKernelCode_) {
150         headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec"));
151     } else {
152         const AST::TypeStringMap& types = ast_->GetTypes();
153         for (const auto& pair : types) {
154             AutoPtr<ASTType> type = pair.second;
155             if (type->GetTypeKind() == TypeKind::TYPE_STRING || type->GetTypeKind() == TypeKind::TYPE_UNION) {
156                 headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec"));
157                 break;
158             }
159         }
160     }
161 
162     if (interface_->IsSerializable()) {
163         headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist"));
164     }
165 
166     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base"));
167     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log"));
168     headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem"));
169 }
170 
EmitServiceStubMethodImpls(StringBuilder & sb,const String & prefix)171 void CServiceStubCodeEmitter::EmitServiceStubMethodImpls(StringBuilder& sb, const String& prefix)
172 {
173     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
174         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
175         EmitServiceStubMethodImpl(method, sb, prefix);
176         sb.Append("\n");
177     }
178 
179     EmitStubGetVerMethodImpl(interface_->GetVersionMethod(), sb, prefix);
180     if (!isKernelCode_) {
181         sb.Append("\n");
182         EmitStubAsObjectMethodImpl(sb, prefix);
183     }
184 }
185 
EmitServiceStubMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)186 void CServiceStubCodeEmitter::EmitServiceStubMethodImpl(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
187     const String& prefix)
188 {
189     sb.Append(prefix).AppendFormat(
190         "static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n",
191         method->GetName().string(), interfaceName_.string(), dataParcelName_.string(), replyParcelName_.string());
192     sb.Append(prefix).Append("{\n");
193     sb.Append(prefix + g_tab).AppendFormat("int32_t %s = HDF_FAILURE;\n", errorCodeName_.string());
194 
195     // Local variable definitions must precede all execution statements.
196     EmitInitLoopVar(method, sb, prefix + g_tab);
197 
198     if (method->GetParameterNumber() > 0) {
199         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
200             AutoPtr<ASTParameter> param = method->GetParameter(i);
201             EmitStubLocalVariable(param, sb, prefix + g_tab);
202         }
203 
204         sb.Append("\n");
205         for (int i = 0; i < method->GetParameterNumber(); i++) {
206             AutoPtr<ASTParameter> param = method->GetParameter(i);
207             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
208                 EmitReadStubMethodParameter(param, dataParcelName_, finishedLabelName_, sb, prefix + g_tab);
209                 sb.Append("\n");
210             } else if (param->EmitCStubReadOutVar(dataParcelName_, errorCodeName_, finishedLabelName_, sb,
211                 prefix + g_tab)) {
212                 sb.Append("\n");
213             }
214         }
215     }
216 
217     EmitStubCallMethod(method, finishedLabelName_, sb, prefix + g_tab);
218     sb.Append("\n");
219 
220     for (int i = 0; i < method->GetParameterNumber(); i++) {
221         AutoPtr<ASTParameter> param = method->GetParameter(i);
222         if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
223             param->EmitCWriteVar(replyParcelName_, errorCodeName_, finishedLabelName_, sb, prefix + g_tab);
224             sb.Append("\n");
225         }
226     }
227 
228     EmitErrorHandle(method, finishedLabelName_, false, sb, prefix);
229     sb.Append(prefix + g_tab).AppendFormat("return %s;\n", errorCodeName_.string());
230     sb.Append(prefix).Append("}\n");
231 }
232 
EmitStubLocalVariable(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const String & prefix)233 void CServiceStubCodeEmitter::EmitStubLocalVariable(const AutoPtr<ASTParameter>& param, StringBuilder& sb,
234     const String& prefix)
235 {
236     AutoPtr<ASTType> type = param->GetType();
237     sb.Append(prefix).Append(param->EmitCLocalVar()).Append("\n");
238     if (type->GetTypeKind() == TypeKind::TYPE_ARRAY
239         || type->GetTypeKind() == TypeKind::TYPE_LIST
240         || (type->GetTypeKind() == TypeKind::TYPE_STRING && param->GetAttribute() == ParamAttr::PARAM_OUT)) {
241         sb.Append(prefix).AppendFormat("uint32_t %sLen = 0;\n", param->GetName().string());
242     }
243 }
244 
EmitReadStubMethodParameter(const AutoPtr<ASTParameter> & param,const String & parcelName,const String & gotoLabel,StringBuilder & sb,const String & prefix)245 void CServiceStubCodeEmitter::EmitReadStubMethodParameter(const AutoPtr<ASTParameter>& param,
246     const String& parcelName, const String& gotoLabel, StringBuilder& sb, const String& prefix)
247 {
248     AutoPtr<ASTType> type = param->GetType();
249 
250     if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
251         EmitReadCStringStubMethodParameter(param, parcelName, gotoLabel, sb, prefix, type);
252     } else if (type->GetTypeKind() == TypeKind::TYPE_INTERFACE) {
253         type->EmitCStubReadVar(parcelName, param->GetName(), errorCodeName_, gotoLabel, sb, prefix);
254     } else if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
255         sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().string(),
256             type->EmitCType(TypeMode::NO_MODE).string(), type->EmitCType(TypeMode::NO_MODE).string());
257         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().string());
258         sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n",
259             param->GetName().string());
260         sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", errorCodeName_.string());
261         sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", finishedLabelName_);
262         sb.Append(prefix).Append("}\n");
263         type->EmitCStubReadVar(parcelName, param->GetName(), errorCodeName_, gotoLabel, sb, prefix);
264     } else if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
265         String cpName = String::Format("%sCp", param->GetName().string());
266         type->EmitCStubReadVar(parcelName, cpName, errorCodeName_, gotoLabel, sb, prefix);
267         sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().string(),
268             type->EmitCType(TypeMode::NO_MODE).string(), type->EmitCType(TypeMode::NO_MODE).string());
269         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().string());
270         sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n",
271             param->GetName().string());
272         sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", errorCodeName_.string());
273         sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", finishedLabelName_);
274         sb.Append(prefix).Append("}\n");
275         sb.Append(prefix).AppendFormat("(void)memcpy_s(%s, sizeof(%s), %s, sizeof(%s));\n", param->GetName().string(),
276             type->EmitCType(TypeMode::NO_MODE).string(), cpName.string(), type->EmitCType(TypeMode::NO_MODE).string());
277     } else if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
278         type->EmitCStubReadVar(parcelName, param->GetName(), errorCodeName_, gotoLabel, sb, prefix);
279     } else if (type->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR) {
280         type->EmitCStubReadVar(parcelName, param->GetName(), errorCodeName_, gotoLabel, sb, prefix);
281     } else {
282         String name = String::Format("&%s", param->GetName().string());
283         type->EmitCStubReadVar(parcelName, name, errorCodeName_, gotoLabel, sb, prefix);
284     }
285 }
286 
EmitReadCStringStubMethodParameter(const AutoPtr<ASTParameter> & param,const String & parcelName,const String & gotoLabel,StringBuilder & sb,const String & prefix,AutoPtr<ASTType> & type)287 void CServiceStubCodeEmitter::EmitReadCStringStubMethodParameter(const AutoPtr<ASTParameter>& param,
288     const String& parcelName, const String& gotoLabel, StringBuilder& sb, const String& prefix,
289     AutoPtr<ASTType>& type)
290 {
291     String cloneName = String::Format("%sCp", param->GetName().string());
292     type->EmitCStubReadVar(parcelName, cloneName, errorCodeName_, gotoLabel, sb, prefix);
293     if (isKernelCode_) {
294         sb.Append("\n");
295         sb.Append(prefix).AppendFormat("%s = (char*)OsalMemCalloc(strlen(%s) + 1);\n",
296             param->GetName().string(), cloneName.string());
297         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().string());
298         sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", errorCodeName_.string());
299         sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n",
300             param->GetName().string());
301         sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
302         sb.Append(prefix).Append("}\n\n");
303         sb.Append(prefix).AppendFormat("if (strcpy_s(%s, (strlen(%s) + 1), %s) != HDF_SUCCESS) {\n",
304             param->GetName().string(), cloneName.string(), cloneName.string());
305         sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
306             param->GetName().string());
307         sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.string());
308         sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
309         sb.Append(prefix).Append("}\n");
310     } else {
311         sb.Append(prefix).AppendFormat("%s = strdup(%s);\n", param->GetName().string(), cloneName.string());
312     }
313 }
314 
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,const String & gotoLabel,StringBuilder & sb,const String & prefix)315 void CServiceStubCodeEmitter::EmitStubCallMethod(const AutoPtr<ASTMethod>& method, const String& gotoLabel,
316     StringBuilder& sb, const String& prefix)
317 {
318     sb.Append(prefix).Append("if (serviceImpl == NULL) {\n");
319     sb.Append(prefix + g_tab).Append("HDF_LOGE(\"%{public}s: invalid serviceImpl object\", __func__);\n");
320     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_OBJECT;\n", errorCodeName_.string());
321     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
322     sb.Append(prefix).Append("}\n\n");
323 
324     sb.Append(prefix).AppendFormat("if (serviceImpl->%s == NULL) {\n", method->GetName().string());
325     sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: invalid interface function %s \", __func__);\n",
326         method->GetName().string());
327     sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_NOT_SUPPORT;\n", errorCodeName_.string());
328     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
329     sb.Append(prefix).Append("}\n\n");
330 
331     if (method->GetParameterNumber() == 0) {
332         sb.Append(prefix).AppendFormat("%s = serviceImpl->%s(serviceImpl);\n", errorCodeName_.string(),
333             method->GetName().string());
334     } else {
335         sb.Append(prefix).AppendFormat("%s = serviceImpl->%s(serviceImpl, ", errorCodeName_.string(),
336             method->GetName().string());
337         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
338             AutoPtr<ASTParameter> param = method->GetParameter(i);
339             EmitCallParameter(sb, param->GetType(), param->GetAttribute(), param->GetName());
340             if (i + 1 < method->GetParameterNumber()) {
341                 sb.Append(", ");
342             }
343         }
344         sb.AppendFormat(");\n", method->GetName().string());
345     }
346 
347     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.string());
348     sb.Append(prefix + g_tab).AppendFormat(
349         "HDF_LOGE(\"%%{public}s: call %s function failed!\", __func__);\n", method->GetName().string());
350     sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
351     sb.Append(prefix).Append("}\n");
352 }
353 
EmitCallParameter(StringBuilder & sb,const AutoPtr<ASTType> & type,ParamAttr attribute,const String & name)354 void CServiceStubCodeEmitter::EmitCallParameter(StringBuilder& sb, const AutoPtr<ASTType>& type, ParamAttr attribute,
355     const String& name)
356 {
357     if (attribute == ParamAttr::PARAM_OUT) {
358         if (type->GetTypeKind() == TypeKind::TYPE_STRING
359             || type->GetTypeKind() == TypeKind::TYPE_ARRAY
360             || type->GetTypeKind() == TypeKind::TYPE_LIST
361             || type->GetTypeKind() == TypeKind::TYPE_STRUCT
362             || type->GetTypeKind() == TypeKind::TYPE_UNION) {
363             sb.AppendFormat("%s", name.string());
364         } else {
365             sb.AppendFormat("&%s", name.string());
366         }
367 
368         if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
369             sb.AppendFormat(", %sLen", name.string());
370         } else if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
371             sb.AppendFormat(", &%sLen", name.string());
372         }
373     } else {
374         sb.AppendFormat("%s", name.string());
375         if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
376             sb.AppendFormat(", %sLen", name.string());
377         }
378     }
379 }
380 
EmitStubGetVerMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const String & prefix)381 void CServiceStubCodeEmitter::EmitStubGetVerMethodImpl(const AutoPtr<ASTMethod>& method, StringBuilder& sb,
382     const String& prefix)
383 {
384     sb.Append(prefix).AppendFormat(
385         "static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n",
386         method->GetName().string(), interfaceName_.string(), dataParcelName_.string(), replyParcelName_.string());
387     sb.Append(prefix).Append("{\n");
388     sb.Append(prefix + g_tab).AppendFormat("int32_t %s = HDF_SUCCESS;\n", errorCodeName_.string());
389 
390     AutoPtr<ASTType> type = new ASTUintType();
391     type->EmitCWriteVar(replyParcelName_, majorVerName_, errorCodeName_, finishedLabelName_, sb, prefix + g_tab);
392     sb.Append("\n");
393     type->EmitCWriteVar(replyParcelName_, minorVerName_, errorCodeName_, finishedLabelName_, sb, prefix + g_tab);
394     sb.Append("\n");
395 
396     sb.Append(finishedLabelName_).Append(":\n");
397     sb.Append(prefix + g_tab).AppendFormat("return %s;\n", errorCodeName_.string());
398     sb.Append(prefix).Append("}\n");
399 }
400 
EmitStubAsObjectMethodImpl(StringBuilder & sb,const String & prefix)401 void CServiceStubCodeEmitter::EmitStubAsObjectMethodImpl(StringBuilder& sb, const String& prefix)
402 {
403     String objName = "self";
404     sb.Append(prefix).AppendFormat("static struct HdfRemoteService *%sStubAsObject(struct %s *%s)\n",
405         baseName_.string(), interfaceName_.string(), objName.string());
406     sb.Append(prefix).Append("{\n");
407 
408     if (interface_->IsSerializable()) {
409         sb.Append(prefix + g_tab).AppendFormat("if (%s == NULL) {\n", objName.string());
410         sb.Append(prefix + g_tab + g_tab).Append("return NULL;\n");
411         sb.Append(prefix + g_tab).Append("}\n");
412 
413         sb.Append(prefix + g_tab).AppendFormat("struct %sStub *stub = CONTAINER_OF(%s, struct %sStub, interface);\n",
414             baseName_.string(), objName.string(), baseName_.string());
415         sb.Append(prefix + g_tab).Append("return stub->remote;\n");
416     } else {
417         sb.Append(prefix + g_tab).Append("return NULL;\n");
418     }
419 
420     sb.Append(prefix).Append("}\n");
421 }
422 
EmitStubOnRequestMethodImpl(StringBuilder & sb,const String & prefix)423 void CServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix)
424 {
425     String remoteName = "remote";
426     String implName = "serviceImpl";
427     String codeName = "code";
428     String funcName = String::Format("%sOnRemoteRquest", baseName_.string());
429     if (interface_->IsSerializable()) {
430         sb.Append(prefix).AppendFormat("static int32_t %s(struct HdfRemoteService *%s, ",
431             funcName.string(), remoteName.string());
432     } else {
433         sb.Append(prefix).AppendFormat("static int32_t %s(struct %s *%s, ",
434             funcName.string(), interfaceName_.string(), implName.string());
435     }
436     sb.AppendFormat("int %s, struct HdfSBuf *data, struct HdfSBuf *reply)\n", codeName.string());
437     sb.Append(prefix).Append("{\n");
438 
439     if (interface_->IsSerializable()) {
440         sb.Append(prefix + g_tab).AppendFormat("struct %s *%s = (struct %s*)%s;\n",
441             interfaceName_.string(), implName.string(), interfaceName_.string(), remoteName.string());
442 
443         sb.Append(prefix + g_tab).AppendFormat(
444             "if (!HdfRemoteServiceCheckInterfaceToken(%s->AsObject(%s), data)) {\n",
445             implName.string(), implName.string());
446         sb.Append(prefix + g_tab + g_tab).Append(
447             "HDF_LOGE(\"%{public}s: interface token check failed\", __func__);\n");
448         sb.Append(prefix + g_tab + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
449         sb.Append(prefix + g_tab).Append("}\n\n");
450     }
451 
452     sb.Append(prefix + g_tab).AppendFormat("switch (%s) {\n", codeName.string());
453     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
454         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
455         sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(method).string());
456         sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return SerStub%s(%s, data, reply);\n",
457             method->GetName().string(), implName.string());
458     }
459 
460     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
461     sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).string());
462     sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return SerStub%s(%s, data, reply);\n",
463         getVerMethod->GetName().string(), implName.string());
464 
465     sb.Append(prefix + g_tab + g_tab).Append("default: {\n");
466     sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat(
467         "HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.string());
468     sb.Append(prefix + g_tab + g_tab + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
469     sb.Append(prefix + g_tab + g_tab).Append("}\n");
470     sb.Append(prefix + g_tab).Append("}\n");
471     sb.Append("}\n");
472 }
473 
EmitStubGetMethodImpl(StringBuilder & sb)474 void CServiceStubCodeEmitter::EmitStubGetMethodImpl(StringBuilder& sb)
475 {
476     String stubTypeName = String::Format("%sStub", baseName_.string());
477     String objName = "stub";
478     String funcName = String::Format("%sOnRemoteRquest", baseName_.string());
479 
480     sb.AppendFormat("bool %sConstruct(struct %s *%s)\n", stubTypeName.string(), stubTypeName.string(),
481         objName.string());
482     sb.Append("{\n");
483     sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string());
484     sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: stub is null!\", __func__);\n");
485     sb.Append(g_tab).Append(g_tab).Append("return false;\n");
486     sb.Append(g_tab).Append("}\n\n");
487 
488     if (interface_->IsSerializable()) {
489         sb.Append(g_tab).AppendFormat("%s->dispatcher.Dispatch = %s;\n", objName.string(), funcName.string());
490         sb.Append(g_tab).AppendFormat(
491             "%s->remote = HdfRemoteServiceObtain((struct HdfObject*)%s, &(%s->dispatcher));\n",
492             objName.string(), objName.string(), objName.string());
493         sb.Append(g_tab).AppendFormat("if (%s->remote == NULL) {\n", objName.string());
494         sb.Append(g_tab).Append(g_tab).AppendFormat(
495             "HDF_LOGE(\"%%{public}s: %s->remote is null\", __func__);\n", objName.string());
496         sb.Append(g_tab).Append(g_tab).Append("return false;\n");
497         sb.Append(g_tab).Append("}\n\n");
498 
499         sb.Append(g_tab).AppendFormat("if (!HdfRemoteServiceSetInterfaceDesc(%s->remote, %s)) {\n", objName.string(),
500             EmitDescMacroName().string());
501         sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: ");
502         sb.Append("failed to set remote service interface descriptor\", __func__);\n");
503         sb.Append(g_tab).Append(g_tab).AppendFormat("%sRelease(%s);\n", stubTypeName.string(), objName.string());
504         sb.Append(g_tab).Append(g_tab).Append("return false;\n");
505         sb.Append(g_tab).Append("}\n\n");
506     } else {
507         sb.Append(g_tab).AppendFormat("%s->OnRemoteRequest = %s;\n", objName.string(), funcName.string());
508     }
509 
510     if (!isKernelCode_) {
511         sb.Append(g_tab).AppendFormat("%s->interface.AsObject = %sAsObject;\n", objName.string(),
512             stubTypeName.string());
513     }
514     sb.Append(g_tab).Append("return true;\n");
515     sb.Append("}\n");
516 }
517 
EmitStubReleaseImpl(StringBuilder & sb)518 void CServiceStubCodeEmitter::EmitStubReleaseImpl(StringBuilder& sb)
519 {
520     String objName = "stub";
521     String stubTypeName = String::Format("%sStub", baseName_.string());
522     sb.AppendFormat("void %sRelease(struct %s *%s)\n", stubTypeName.string(), stubTypeName.string(), objName.string());
523     sb.Append("{\n");
524     sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string());
525     sb.Append(g_tab).Append(g_tab).Append("return;\n");
526     sb.Append(g_tab).Append("}\n\n");
527 
528     sb.Append(g_tab).AppendFormat("HdfRemoteServiceRecycle(%s->remote);\n", objName.string());
529     sb.Append(g_tab).AppendFormat("%s->remote = NULL;\n", objName.string());
530     sb.Append("}");
531 }
532 } // namespace HDI
533 } // namespace OHOS