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