1 /*
2 * Copyright (c) 2021-2023 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/cpp_service_stub_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)15 bool CppServiceStubCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
16 {
17 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
18 directory_ = GetFileParentPath(targetDirectory);
19 } else {
20 return false;
21 }
22
23 if (!File::CreateParentDir(directory_)) {
24 Logger::E("CppServiceStubCodeEmitter", "Create '%s' failed!", directory_.c_str());
25 return false;
26 }
27
28 return true;
29 }
30
EmitCode()31 void CppServiceStubCodeEmitter::EmitCode()
32 {
33 if (mode_ == GenMode::IPC) {
34 EmitStubHeaderFile();
35 EmitStubSourceFile();
36 }
37 }
38
EmitStubHeaderFile()39 void CppServiceStubCodeEmitter::EmitStubHeaderFile()
40 {
41 std::string filePath =
42 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(stubName_).c_str()));
43 File file(filePath, File::WRITE);
44 StringBuilder sb;
45
46 EmitLicense(sb);
47 EmitHeadMacro(sb, stubFullName_);
48 sb.Append("\n");
49 EmitStubHeaderInclusions(sb);
50 sb.Append("\n");
51 EmitStubDecl(sb);
52 sb.Append("\n");
53 EmitTailMacro(sb, stubFullName_);
54
55 std::string data = sb.ToString();
56 file.WriteData(data.c_str(), data.size());
57 file.Flush();
58 file.Close();
59 }
60
EmitStubHeaderInclusions(StringBuilder & sb)61 void CppServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb)
62 {
63 HeaderFile::HeaderFileSet headerFiles;
64
65 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
66 if (interface_->GetExtendsInterface() != nullptr) {
67 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE,
68 EmitHeaderNameByInterface(interface_->GetExtendsInterface(), stubName_));
69 }
70 GetHeaderOtherLibInclusions(headerFiles);
71
72 for (const auto &file : headerFiles) {
73 sb.AppendFormat("%s\n", file.ToString().c_str());
74 }
75 }
76
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const77 void CppServiceStubCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
78 {
79 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
80 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
81 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "ipc_object_stub");
82 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
83 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "refbase");
84 }
85
EmitStubDecl(StringBuilder & sb)86 void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder &sb)
87 {
88 EmitBeginNamespace(sb);
89 sb.Append("\n");
90 EmitStubUsingNamespace(sb);
91 sb.AppendFormat("class %s : public IPCObjectStub {\n", stubName_.c_str());
92 EmitStubBody(sb, TAB);
93 sb.Append("};\n");
94 EmitEndNamespace(sb);
95 }
96
EmitStubUsingNamespace(StringBuilder & sb) const97 void CppServiceStubCodeEmitter::EmitStubUsingNamespace(StringBuilder &sb) const
98 {
99 sb.Append("using namespace OHOS;\n");
100 }
101
EmitStubBody(StringBuilder & sb,const std::string & prefix) const102 void CppServiceStubCodeEmitter::EmitStubBody(StringBuilder &sb, const std::string &prefix) const
103 {
104 sb.Append("public:\n");
105 EmitStubConstructorDecl(sb, prefix);
106 sb.Append("\n");
107 EmitStubOnRequestDecl(sb, prefix);
108 sb.Append("\n");
109 EmitStubMethodDecls(sb, prefix);
110 sb.Append("\n");
111 EmitStubPrivateData(sb, prefix);
112 }
113
EmitStubConstructorDecl(StringBuilder & sb,const std::string & prefix) const114 void CppServiceStubCodeEmitter::EmitStubConstructorDecl(StringBuilder &sb, const std::string &prefix) const
115 {
116 sb.Append(prefix).AppendFormat("explicit %s(const sptr<%s> &impl);\n", stubName_.c_str(), interfaceName_.c_str());
117 sb.Append(prefix).AppendFormat("virtual ~%s();\n", stubName_.c_str());
118 }
119
EmitStubOnRequestDecl(StringBuilder & sb,const std::string & prefix) const120 void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder &sb, const std::string &prefix) const
121 {
122 sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, ");
123 sb.Append("MessageOption &option) override;\n");
124 }
125
EmitStubMethodDecls(StringBuilder & sb,const std::string & prefix) const126 void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix) const
127 {
128 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
129 EmitStubStaticMethodDecl(method, sb, prefix);
130 sb.Append("\n");
131 }
132 if (interface_->GetExtendsInterface() == nullptr) {
133 EmitStubStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
134 sb.Append("\n");
135 }
136
137 sb.Append("private:\n");
138 AutoPtr<ASTInterfaceType> interface = interface_;
139 while (interface != nullptr) {
140 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
141 EmitStubMethodDecl(method, sb, prefix);
142 sb.Append("\n");
143 }
144 interface = interface->GetExtendsInterface();
145 }
146 EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix);
147 sb.Append("\n");
148 }
149
EmitStubMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const150 void CppServiceStubCodeEmitter::EmitStubMethodDecl(
151 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
152 {
153 sb.Append(prefix).AppendFormat("int32_t %s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s);\n",
154 stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
155 optionName_.c_str());
156 }
157
EmitStubStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const158 void CppServiceStubCodeEmitter::EmitStubStaticMethodDecl(
159 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
160 {
161 sb.Append(prefix).AppendFormat(
162 "static int32_t %s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl);\n",
163 stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
164 optionName_.c_str(), EmitDefinitionByInterface(interface_, interfaceName_).c_str());
165 }
166
EmitStubPrivateData(StringBuilder & sb,const std::string & prefix) const167 void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const
168 {
169 sb.Append(prefix).AppendFormat("static inline ObjectDelegator<%s, %s> objDelegator_;\n",
170 EmitDefinitionByInterface(interface_, stubName_).c_str(),
171 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
172 sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
173 }
174
EmitStubSourceFile()175 void CppServiceStubCodeEmitter::EmitStubSourceFile()
176 {
177 std::string filePath =
178 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(stubName_).c_str()));
179 File file(filePath, File::WRITE);
180 StringBuilder sb;
181
182 EmitLicense(sb);
183 EmitStubSourceInclusions(sb);
184 sb.Append("\n");
185 EmitLogTagMacro(sb, FileName(stubName_));
186 sb.Append("\n");
187 EmitBeginNamespace(sb);
188 UtilMethodMap utilMethods;
189 GetUtilMethods(utilMethods);
190 EmitUtilMethods(sb, "", utilMethods, true);
191 sb.Append("\n");
192 EmitUtilMethods(sb, "", utilMethods, false);
193 sb.Append("\n");
194 EmitInterfaceGetMethodImpl(sb, "");
195 sb.Append("\n");
196 EmitStubConstructorImpl(sb, "");
197 sb.Append("\n");
198 EmitStubOnRequestMethodImpl(sb, "");
199 sb.Append("\n");
200 EmitStubMethodImpls(sb, "");
201 EmitEndNamespace(sb);
202
203 std::string data = sb.ToString();
204 file.WriteData(data.c_str(), data.size());
205 file.Flush();
206 file.Close();
207 }
208
EmitStubSourceInclusions(StringBuilder & sb)209 void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
210 {
211 HeaderFile::HeaderFileSet headerFiles;
212 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
213 GetSourceOtherLibInclusions(headerFiles);
214 GetSourceOtherFileInclusions(headerFiles);
215
216 for (const auto &file : headerFiles) {
217 sb.AppendFormat("%s\n", file.ToString().c_str());
218 }
219 }
220
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const221 void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
222 {
223 if (!interface_->IsSerializable()) {
224 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
225 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
226 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
227 } else {
228 const AST::TypeStringMap &types = ast_->GetTypes();
229 for (const auto &pair : types) {
230 AutoPtr<ASTType> type = pair.second;
231 if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
232 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
233 break;
234 }
235 }
236 }
237
238 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
239 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
240 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
241 AutoPtr<ASTType> paramType = param->GetType();
242 if (param->GetAttribute() == ParamAttr::PARAM_IN &&
243 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
244 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
245 }
246
247 if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
248 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
249 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
250 }
251 }
252 }
253
254 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
255 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
256 }
257
GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet & headerFiles) const258 void CppServiceStubCodeEmitter::GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const
259 {
260 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
261 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
262 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
263 AutoPtr<ASTType> paramType = param->GetType();
264 if (param->GetAttribute() == ParamAttr::PARAM_IN &&
265 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
266 AutoPtr<ASTInterfaceType> type = dynamic_cast<ASTInterfaceType *>(paramType.Get());
267 std::string FileName = InterfaceToFilePath(paramType->ToString());
268 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName);
269 }
270 }
271 }
272 }
273
EmitInterfaceGetMethodImpl(StringBuilder & sb,const std::string & prefix) const274 void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
275 {
276 if (!interface_->IsSerializable()) {
277 EmitGetMethodImpl(sb, prefix);
278 sb.Append(prefix).Append("\n");
279 EmitGetInstanceMethodImpl(sb, prefix);
280 sb.Append(prefix).Append("\n");
281 }
282 }
283
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const284 void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
285 {
286 sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(bool isStub)\n",
287 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
288 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
289 sb.Append(prefix).Append("{\n");
290 sb.Append(prefix + TAB).AppendFormat("return %s::Get(\"%s\", isStub);\n",
291 EmitDefinitionByInterface(interface_, interfaceName_).c_str(), FileName(implName_).c_str());
292 sb.Append(prefix).Append("}\n");
293 }
294
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const295 void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const
296 {
297 sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
298 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
299 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
300 sb.Append(prefix).Append("{\n");
301
302 sb.Append(prefix + TAB).Append("if (!isStub) {\n");
303 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
304 sb.Append(prefix + TAB).Append("}\n");
305
306 sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
307 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
308 sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
309 sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
310 sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
311 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n");
312 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
313 sb.Append(prefix + TAB).Append("}\n");
314 sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
315 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
316 sb.Append(prefix).Append("}\n");
317 }
318
EmitStubConstructorImpl(StringBuilder & sb,const std::string & prefix) const319 void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const
320 {
321 sb.Append(prefix).AppendFormat("%s::%s(const sptr<%s> &impl)\n",
322 EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(),
323 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
324 sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n",
325 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
326 sb.Append(prefix).Append("{\n");
327 sb.Append(prefix).Append("}\n\n");
328
329 sb.Append(prefix).AppendFormat(
330 "%s::~%s()\n", EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str());
331 sb.Append(prefix).Append("{\n");
332 sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n");
333 sb.Append(prefix).Append("}\n");
334 }
335
EmitStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)336 void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
337 {
338 sb.Append(prefix).AppendFormat(
339 "int32_t %s::OnRemoteRequest(uint32_t code, ", EmitDefinitionByInterface(interface_, stubName_).c_str());
340 sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n");
341 sb.Append(prefix).Append("{\n");
342
343 sb.Append(prefix + TAB).Append("switch (code) {\n");
344 AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
345 sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
346 sb.Append(prefix + TAB + TAB + TAB)
347 .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), getVerMethod->GetName().c_str());
348 AutoPtr<ASTInterfaceType> interface = interface_;
349 while (interface != nullptr) {
350 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
351 sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
352 sb.Append(prefix + TAB + TAB + TAB)
353 .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str());
354 }
355 interface = interface->GetExtendsInterface();
356 }
357
358 sb.Append(prefix + TAB + TAB).Append("default: {\n");
359 sb.Append(prefix + TAB + TAB + TAB)
360 .Append("HDF_LOGE(\"%{public}s: cmd %{public}d is not supported\", __func__, code);\n");
361 sb.Append(prefix + TAB + TAB + TAB).Append("return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
362 sb.Append(prefix + TAB + TAB).Append("}\n");
363 sb.Append(prefix + TAB).Append("}\n");
364 sb.Append("}\n");
365 }
366
EmitStubMethodImpls(StringBuilder & sb,const std::string & prefix) const367 void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const
368 {
369 AutoPtr<ASTInterfaceType> interface = interface_;
370 AutoPtr<ASTInterfaceType> mataInterface = interface_;
371 while (interface != nullptr) {
372 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
373 EmitStubMethodImpl(interface, method, sb, prefix);
374 sb.Append("\n");
375 }
376 interface = interface->GetExtendsInterface();
377 if (interface != nullptr) {
378 mataInterface = interface;
379 }
380 }
381 AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
382 EmitStubMethodImpl(mataInterface, verMethod, sb, prefix);
383 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
384 sb.Append("\n");
385 EmitStubStaticMethodImpl(method, sb, prefix);
386 }
387 if (interface_->GetExtendsInterface() == nullptr) {
388 sb.Append("\n");
389 EmitStubStaticMethodImpl(verMethod, sb, prefix);
390 }
391 }
392
EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const393 void CppServiceStubCodeEmitter::EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,
394 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
395 {
396 sb.Append(prefix).AppendFormat("int32_t %s::%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n",
397 EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
398 dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
399 sb.Append(prefix).Append("{\n");
400 sb.Append(prefix + TAB).AppendFormat("return %s::%s%s_(%s, %s, %s, impl_);\n",
401 EmitDefinitionByInterface(interface, stubName_).c_str(),
402 stubName_.c_str(), method->GetName().c_str(),
403 dataParcelName_.c_str(), replyParcelName_.c_str(),
404 optionName_.c_str());
405 sb.Append("}\n");
406 }
407
EmitStubStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const408 void CppServiceStubCodeEmitter::EmitStubStaticMethodImpl(
409 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
410 {
411 sb.Append(prefix).AppendFormat(
412 "int32_t %s::%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl)\n",
413 EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
414 dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str(),
415 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
416 sb.Append(prefix).Append("{\n");
417
418 // read interface token and check it
419 EmitStubReadInterfaceToken(dataParcelName_, sb, prefix + TAB);
420 sb.Append("\n");
421
422 EmitStubReadMemFlag(method, dataParcelName_, sb, prefix + TAB);
423
424 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
425 AutoPtr<ASTParameter> param = method->GetParameter(i);
426 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
427 EmitReadMethodParameter(param, dataParcelName_, true, sb, prefix + TAB);
428 sb.Append("\n");
429 } else {
430 EmitLocalVariable(param, dataParcelName_, sb, prefix + TAB);
431 sb.Append("\n");
432 }
433 }
434
435 EmitStubCallMethod(method, sb, prefix + TAB);
436 sb.Append("\n");
437
438 if (!method->IsOneWay()) {
439 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
440 AutoPtr<ASTParameter> param = method->GetParameter(i);
441 if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
442 EmitWriteMethodParameter(param, replyParcelName_, sb, prefix + TAB);
443 sb.Append("\n");
444 }
445 }
446 }
447
448 sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
449 sb.Append("}\n");
450 }
451
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const452 void CppServiceStubCodeEmitter::EmitStubCallMethod(
453 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
454 {
455 sb.Append(prefix).Append("if (impl == nullptr) {\n");
456 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: impl is nullptr!\", __func__);\n");
457 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
458 sb.Append(prefix).Append("}\n\n");
459
460 sb.Append(prefix).AppendFormat("int32_t %s = impl->%s(", errorCodeName_.c_str(), method->GetName().c_str());
461 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
462 AutoPtr<ASTParameter> param = method->GetParameter(i);
463 sb.Append(param->GetName());
464 if (i + 1 < method->GetParameterNumber()) {
465 sb.Append(", ");
466 }
467 }
468 sb.Append(");\n");
469
470 sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
471 sb.Append(prefix + TAB)
472 .AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
473 errorCodeName_.c_str());
474 sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
475 sb.Append(prefix).Append("}\n");
476 }
477
EmitStubReadInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const478 void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken(
479 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
480 {
481 sb.Append(prefix).AppendFormat("if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(),
482 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
483 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n");
484 sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
485 sb.Append(prefix).Append("}\n");
486 }
487
EmitStubReadMemFlag(const AutoPtr<ASTMethod> & method,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const488 void CppServiceStubCodeEmitter::EmitStubReadMemFlag(const AutoPtr<ASTMethod> &method,
489 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
490 {
491 if (NeedFlag(method)) {
492 sb.Append(prefix).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
493 sb.Append(prefix).AppendFormat("if (!%s.ReadBool(%s)) {\n", parcelName.c_str(), flagOfSetMemName_.c_str());
494 sb.Append(prefix + TAB)
495 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", flagOfSetMemName_.c_str());
496 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
497 sb.Append(prefix).Append("}\n");
498 }
499 }
500
EmitLocalVariable(const AutoPtr<ASTParameter> & param,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const501 void CppServiceStubCodeEmitter::EmitLocalVariable(const AutoPtr<ASTParameter> ¶m,
502 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
503 {
504 sb.Append(prefix).Append(param->EmitCppLocalVar()).Append("\n");
505 AutoPtr<ASTType> type = param->GetType();
506 if (!type->IsStringType() && !type->IsArrayType() && !type->IsListType()) {
507 return;
508 }
509
510 sb.Append(prefix).AppendFormat("if (%s) {\n", flagOfSetMemName_.c_str());
511 std::string capacityName = "capacity";
512 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", capacityName.c_str());
513 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), capacityName.c_str());
514 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n",
515 capacityName.c_str());
516 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
517 sb.Append(prefix + TAB).Append("}\n");
518
519 if (type->IsStringType()) {
520 sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(char), HDF_ERR_INVALID_PARAM);\n",
521 CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO);
522 } else {
523 AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
524 sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
525 CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO,
526 arrayType->GetElementType()->EmitCppType().c_str());
527 }
528 sb.Append(prefix + TAB).AppendFormat("%s.reserve(%s);\n", param->GetName().c_str(), capacityName.c_str());
529 sb.Append(prefix).Append("}\n");
530 }
531
GetUtilMethods(UtilMethodMap & methods)532 void CppServiceStubCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
533 {
534 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
535 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
536 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
537 AutoPtr<ASTType> paramType = param->GetType();
538 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
539 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
540 } else {
541 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
542 }
543 }
544 }
545 }
546 } // namespace HDI
547 } // namespace OHOS
548