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> ¶m, 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> ¶m, 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> ¶m,
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> ¶m,
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> ¶m,
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