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_client_proxy_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12 #include "util/string_helper.h"
13
14 namespace OHOS {
15 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)16 bool CppClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
17 {
18 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
19 directory_ = GetFileParentPath(targetDirectory);
20 } else {
21 return false;
22 }
23
24 if (!File::CreateParentDir(directory_)) {
25 Logger::E("CppClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
26 return false;
27 }
28
29 return true;
30 }
31
EmitCode()32 void CppClientProxyCodeEmitter::EmitCode()
33 {
34 switch (mode_) {
35 case GenMode::PASSTHROUGH: {
36 if (!interface_->IsSerializable()) {
37 EmitPassthroughProxySourceFile();
38 }
39 break;
40 }
41 case GenMode::IPC: {
42 EmitProxyHeaderFile();
43 EmitProxySourceFile();
44 }
45 default:
46 break;
47 }
48 }
49
EmitProxyHeaderFile()50 void CppClientProxyCodeEmitter::EmitProxyHeaderFile()
51 {
52 std::string filePath =
53 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
54 File file(filePath, File::WRITE);
55 StringBuilder sb;
56
57 EmitLicense(sb);
58 EmitHeadMacro(sb, proxyFullName_);
59 sb.Append("\n");
60 EmitProxyHeaderInclusions(sb);
61 sb.Append("\n");
62 EmitBeginNamespace(sb);
63 sb.Append("\n");
64 EmitProxyDecl(sb, "");
65 sb.Append("\n");
66 EmitEndNamespace(sb);
67 sb.Append("\n");
68 EmitTailMacro(sb, proxyFullName_);
69
70 std::string data = sb.ToString();
71 file.WriteData(data.c_str(), data.size());
72 file.Flush();
73 file.Close();
74 }
75
EmitProxyHeaderInclusions(StringBuilder & sb)76 void CppClientProxyCodeEmitter::EmitProxyHeaderInclusions(StringBuilder &sb)
77 {
78 HeaderFile::HeaderFileSet headerFiles;
79
80 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
81 if (interface_->GetExtendsInterface() != nullptr) {
82 headerFiles.emplace(
83 HeaderFileType::OWN_HEADER_FILE, EmitHeaderNameByInterface(interface_->GetExtendsInterface(), proxyName_));
84 }
85 GetHeaderOtherLibInclusions(headerFiles);
86
87 for (const auto &file : headerFiles) {
88 sb.AppendFormat("%s\n", file.ToString().c_str());
89 }
90 }
91
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const92 void CppClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
93 {
94 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
95 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
96 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "unistd");
97 }
98 }
99
EmitProxyDecl(StringBuilder & sb,const std::string & prefix)100 void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::string &prefix)
101 {
102 (void)prefix;
103 sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(),
104 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
105 sb.Append("public:\n");
106 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
107 EmitProxyDevmgrDeathRecipient(sb, TAB);
108 sb.Append("\n");
109 }
110 EmitProxyConstructor(sb, TAB);
111 sb.Append("\n");
112 EmitProxyMethodDecls(sb, TAB);
113 sb.Append("\n");
114 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
115 EmitProxyPublicMembers(sb, TAB);
116 }
117 sb.Append("private:\n");
118 EmitProxyConstants(sb, TAB);
119 sb.Append("};\n");
120 }
121
EmitProxyDevmgrDeathRecipient(StringBuilder & sb,const std::string & prefix) const122 void CppClientProxyCodeEmitter::EmitProxyDevmgrDeathRecipient(StringBuilder &sb, const std::string &prefix) const
123 {
124 std::string doubleTab = prefix + TAB;
125 sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n",
126 devmgrDeathRecipientName_.c_str());
127 sb.Append(prefix).Append("public:\n");
128 sb.Append(doubleTab).AppendFormat("%s(wptr<%s> proxy) : proxy_(proxy) {} \n", devmgrDeathRecipientName_.c_str(),
129 EmitDefinitionByInterface(interface_, proxyName_).c_str());
130 sb.Append(doubleTab).AppendFormat("~%s() override = default;\n", devmgrDeathRecipientName_.c_str());
131 EmitProxyDevmgrDeathCallBack(sb, doubleTab);
132 sb.Append(prefix).Append("private:\n");
133 sb.Append(doubleTab).AppendFormat("wptr<%s> proxy_;\n",
134 EmitDefinitionByInterface(interface_, proxyName_).c_str());
135 sb.Append(prefix).Append("};\n");
136 }
137
EmitProxyDevmgrDeathCallBack(StringBuilder & sb,const std::string & prefix) const138 void CppClientProxyCodeEmitter::EmitProxyDevmgrDeathCallBack(StringBuilder &sb, const std::string &prefix) const
139 {
140 std::string trebleTab = prefix + TAB;
141 sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
142 sb.Append(prefix).Append("{\n");
143 sb.Append(trebleTab).Append("int32_t result = HDF_FAILURE;\n");
144 sb.Append(trebleTab).Append("const int sleepInterval = 500000;\n");
145 sb.Append(trebleTab).Append("const int waitTimes = 10;\n");
146 sb.Append(trebleTab).Append("int currentTime = waitTimes;\n");
147 sb.Append(trebleTab).Append("do {\n");
148 sb.Append(trebleTab + TAB).Append("usleep(sleepInterval);\n");
149 sb.Append(trebleTab + TAB).Append("auto proxy = proxy_.promote();\n");
150 sb.Append(trebleTab + TAB).Append("if (proxy != nullptr) {\n");
151 sb.Append(trebleTab + TAB + TAB).AppendFormat("result = %s::Reconnect(proxy);\n",
152 EmitDefinitionByInterface(interface_, proxyName_).c_str());
153 sb.Append(trebleTab + TAB).Append("}\n");
154 sb.Append(trebleTab + TAB).Append("--currentTime;\n");
155 sb.Append(trebleTab).Append("} while (result != HDF_SUCCESS && currentTime >0);\n");
156 sb.Append(prefix).Append("}\n");
157 }
158
EmitProxyConstructor(StringBuilder & sb,const std::string & prefix) const159 void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
160 {
161 sb.Append(prefix).AppendFormat("explicit %s(const sptr<IRemoteObject>& remote)", proxyName_.c_str());
162 sb.AppendFormat(
163 " : IProxyBroker<%s>(remote) {\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
164 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
165 sb.Append(prefix + TAB).Append("reconnectRemote_ = nullptr;\n");
166 sb.Append(prefix + TAB).Append("servMgr_ = nullptr;\n");
167 sb.Append(prefix + TAB).Append("deathRecipient_ = nullptr;\n");
168 sb.Append(prefix + TAB).Append("isReconnected_ = false;\n");
169 }
170 sb.Append(prefix).AppendFormat("}\n");
171 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
172 sb.Append(prefix).AppendFormat("virtual ~%s() {\n", proxyName_.c_str());
173 sb.Append(prefix + TAB).AppendFormat("if (servMgr_ != nullptr && deathRecipient_ != nullptr) {\n");
174 sb.Append(prefix + TAB + TAB).AppendFormat("servMgr_->RemoveDeathRecipient(deathRecipient_);\n");
175 sb.Append(prefix + TAB).AppendFormat("}\n");
176 sb.Append(prefix).AppendFormat("}\n");
177 } else {
178 sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", proxyName_.c_str());
179 }
180 }
181
EmitProxyMethodDecls(StringBuilder & sb,const std::string & prefix) const182 void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
183 {
184 EmitProxyIsProxyMethodImpl(sb, prefix);
185 AutoPtr<ASTInterfaceType> interface = interface_;
186 while (interface != nullptr) {
187 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
188 EmitProxyMethodDecl(method, sb, prefix);
189 sb.Append("\n");
190 }
191 interface = interface->GetExtendsInterface();
192 }
193 EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix);
194 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
195 sb.Append("\n");
196 EmitProxyStaticMethodDecl(method, sb, prefix);
197 }
198 if (interface_->GetExtendsInterface() == nullptr) {
199 sb.Append("\n");
200 EmitProxyStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
201 }
202 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
203 sb.Append("\n");
204 EmitProxyReconnectMethodDecl(sb, prefix);
205 sb.Append("\n");
206 EmitProxyGetRemoteMethodDecl(sb, prefix);
207 }
208 }
209
EmitProxyMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const210 void CppClientProxyCodeEmitter::EmitProxyMethodDecl(
211 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
212 {
213 if (method->GetParameterNumber() == 0) {
214 sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
215 } else {
216 StringBuilder paramStr;
217 paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
218
219 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
220 AutoPtr<ASTParameter> param = method->GetParameter(i);
221 EmitProxyMethodParameter(param, paramStr, "");
222 if (i + 1 < method->GetParameterNumber()) {
223 paramStr.Append(", ");
224 }
225 }
226
227 paramStr.Append(") override;");
228
229 sb.Append(SpecificationParam(paramStr, prefix + TAB));
230 sb.Append("\n");
231 }
232 }
233
EmitProxyStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const234 void CppClientProxyCodeEmitter::EmitProxyStaticMethodDecl(
235 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
236 {
237 if (method->GetParameterNumber() == 0) {
238 sb.Append(prefix).AppendFormat(
239 "static int32_t %s_(const sptr<IRemoteObject> remote);\n", method->GetName().c_str());
240 } else {
241 StringBuilder paramStr;
242 paramStr.Append(prefix).AppendFormat("static int32_t %s_(", method->GetName().c_str());
243
244 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
245 AutoPtr<ASTParameter> param = method->GetParameter(i);
246 EmitProxyMethodParameter(param, paramStr, "");
247 paramStr.Append(", ");
248 }
249 paramStr.Append("const sptr<IRemoteObject> remote");
250
251 paramStr.Append(");");
252
253 sb.Append(SpecificationParam(paramStr, prefix + TAB));
254 sb.Append("\n");
255 }
256 }
257
EmitProxyReconnectMethodDecl(StringBuilder & sb,const std::string & prefix) const258 void CppClientProxyCodeEmitter::EmitProxyReconnectMethodDecl(StringBuilder &sb, const std::string &prefix) const
259 {
260 sb.Append(prefix).AppendFormat("static int32_t Reconnect(sptr<%s> proxy);\n",
261 EmitDefinitionByInterface(interface_, proxyName_).c_str());
262 }
263
EmitProxyGetRemoteMethodDecl(StringBuilder & sb,const std::string & prefix) const264 void CppClientProxyCodeEmitter::EmitProxyGetRemoteMethodDecl(StringBuilder &sb, const std::string &prefix) const
265 {
266 sb.Append(prefix).Append("sptr<IRemoteObject> GetCurrentRemote() {\n");
267 sb.Append(prefix + TAB).Append("return isReconnected_ ? reconnectRemote_ : Remote();\n");
268 sb.Append(prefix).Append("}\n");
269 }
270
EmitProxyPublicMembers(StringBuilder & sb,const std::string & prefix) const271 void CppClientProxyCodeEmitter::EmitProxyPublicMembers(StringBuilder &sb, const std::string &prefix) const
272 {
273 sb.Append(prefix).Append("bool isReconnected_;\n");
274 sb.Append(prefix).Append("std::string serviceName_;\n");
275 sb.Append(prefix).AppendFormat("sptr<IRemoteObject> servMgr_;\n", devmgrVersionName_.c_str());
276 sb.Append(prefix).AppendFormat("sptr<%s::%s> deathRecipient_;\n",
277 EmitDefinitionByInterface(interface_, proxyName_).c_str(),
278 devmgrDeathRecipientName_.c_str());
279 sb.Append(prefix).Append("sptr<IRemoteObject> reconnectRemote_;\n");
280 }
281
EmitProxyConstants(StringBuilder & sb,const std::string & prefix) const282 void CppClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const
283 {
284 sb.Append(prefix).AppendFormat(
285 "static inline BrokerDelegator<%s> delegator_;\n", EmitDefinitionByInterface(interface_, proxyName_).c_str());
286 }
287
EmitProxyMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const288 void CppClientProxyCodeEmitter::EmitProxyMethodParameter(
289 const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const
290 {
291 sb.Append(prefix).Append(param->EmitCppParameter());
292 }
293
EmitPassthroughProxySourceFile()294 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
295 {
296 std::string filePath =
297 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
298 File file(filePath, File::WRITE);
299 StringBuilder sb;
300
301 EmitLicense(sb);
302 EmitPassthroughProxySourceInclusions(sb);
303 sb.Append("\n");
304 EmitLogTagMacro(sb, FileName(proxyName_));
305 sb.Append("\n");
306 EmitBeginNamespace(sb);
307 EmitGetMethodImpl(sb, "");
308 sb.Append("\n");
309 EmitPassthroughGetInstanceMethodImpl(sb, "");
310 EmitEndNamespace(sb);
311
312 std::string data = sb.ToString();
313 file.WriteData(data.c_str(), data.size());
314 file.Flush();
315 file.Close();
316 }
317
EmitPassthroughProxySourceInclusions(StringBuilder & sb)318 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceInclusions(StringBuilder &sb)
319 {
320 HeaderFile::HeaderFileSet headerFiles;
321
322 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
323 if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
324 headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "codecvt");
325 headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "locale");
326 } else {
327 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
328 }
329 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
330 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
331
332 for (const auto &file : headerFiles) {
333 sb.AppendFormat("%s\n", file.ToString().c_str());
334 }
335 }
336
EmitPassthroughGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const337 void CppClientProxyCodeEmitter::EmitPassthroughGetInstanceMethodImpl(StringBuilder &sb,
338 const std::string &prefix) const
339 {
340 sb.Append(prefix).AppendFormat("%s %s::Get(const std::string &serviceName, bool isStub)\n",
341 interface_->EmitCppType().c_str(), interface_->GetName().c_str());
342 sb.Append(prefix).Append("{\n");
343 EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
344 sb.Append(prefix + TAB).Append("return nullptr;\n");
345 sb.Append(prefix).Append("}\n");
346 }
347
EmitProxySourceFile()348 void CppClientProxyCodeEmitter::EmitProxySourceFile()
349 {
350 std::string filePath =
351 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
352 File file(filePath, File::WRITE);
353 StringBuilder sb;
354
355 EmitLicense(sb);
356 EmitProxySourceInclusions(sb);
357 sb.Append("\n");
358 EmitLogTagMacro(sb, FileName(proxyName_));
359 sb.Append("\n");
360 EmitBeginNamespace(sb);
361 sb.Append("\n");
362 UtilMethodMap utilMethods;
363 GetUtilMethods(utilMethods);
364 EmitUtilMethods(sb, "", utilMethods, true);
365 sb.Append("\n");
366 if (interface_->GetExtendsInterface() != nullptr) {
367 EmitProxyCastFromMethodImplTemplate(sb, "");
368 sb.Append("\n");
369 }
370 if (!interface_->IsSerializable()) {
371 EmitGetMethodImpl(sb, "");
372 sb.Append("\n");
373 EmitGetInstanceMethodImpl(sb, "");
374 sb.Append("\n");
375 EmitProxyCppReconnectMethodImpl(sb, "");
376 sb.Append("\n");
377 }
378 EmitProxyCastFromMethodImpls(sb, "");
379 EmitUtilMethods(sb, "", utilMethods, false);
380 EmitProxyMethodImpls(sb, "");
381 sb.Append("\n");
382 EmitEndNamespace(sb);
383
384 std::string data = sb.ToString();
385 file.WriteData(data.c_str(), data.size());
386 file.Flush();
387 file.Close();
388 }
389
EmitProxySourceInclusions(StringBuilder & sb)390 void CppClientProxyCodeEmitter::EmitProxySourceInclusions(StringBuilder &sb)
391 {
392 HeaderFile::HeaderFileSet headerFiles;
393 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(proxyName_));
394 GetSourceOtherLibInclusions(headerFiles);
395 GetSourceOtherFileInclusions(headerFiles);
396
397 for (const auto &file : headerFiles) {
398 sb.AppendFormat("%s\n", file.ToString().c_str());
399 }
400 }
401
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const402 void CppClientProxyCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
403 {
404 if (!interface_->IsSerializable()) {
405 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iservmgr_hdi");
406 }
407 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
408 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
409 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
410 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
411 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
412 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
413
414 const AST::TypeStringMap &types = ast_->GetTypes();
415 for (const auto &pair : types) {
416 AutoPtr<ASTType> type = pair.second;
417 if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
418 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
419 break;
420 }
421 }
422
423 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
424 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
425 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
426 AutoPtr<ASTType> paramType = param->GetType();
427 if (param->GetAttribute() == ParamAttr::PARAM_IN &&
428 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
429 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
430 }
431
432 if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
433 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
434 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
435 }
436 }
437 }
438 }
439
GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet & headerFiles) const440 void CppClientProxyCodeEmitter::GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const
441 {
442 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
443 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
444 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
445 AutoPtr<ASTType> paramType = param->GetType();
446 if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
447 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
448 AutoPtr<ASTInterfaceType> type = dynamic_cast<ASTInterfaceType *>(paramType.Get());
449 std::string FileName = InterfaceToFilePath(paramType->ToString());
450 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName);
451 }
452 }
453 }
454 }
455
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const456 void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
457 {
458 sb.Append(prefix).AppendFormat("%s %s::Get(bool isStub)\n", interface_->EmitCppType().c_str(),
459 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
460 sb.Append(prefix).Append("{\n");
461 sb.Append(prefix + TAB)
462 .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
463 sb.Append(prefix).Append("}\n");
464 }
465
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix)466 void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix)
467 {
468 std::string objName = "proxy";
469 std::string interfaceNamespace = GetNameSpaceByInterface(interface_, interfaceName_);
470 sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
471 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
472 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
473 sb.Append(prefix).Append("{\n");
474 EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
475 sb.Append(prefix + TAB).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
476 sb.Append(prefix + TAB).Append("auto servMgr = IServiceManager::Get();\n");
477 sb.Append(prefix + TAB).Append("if (servMgr == nullptr) {\n");
478 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
479 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
480 sb.Append(prefix + TAB).Append("}\n\n");
481 sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = ");
482 sb.Append("servMgr->GetService(serviceName.c_str());\n");
483 sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
484 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get remote object failed!\", __func__);\n");
485 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
486 sb.Append(prefix + TAB).Append("}\n\n");
487 sb.Append(prefix + TAB).AppendFormat("sptr<%s> %s = new %s(remote);\n",
488 EmitDefinitionByInterface(interface_, proxyName_).c_str(), objName.c_str(),
489 (interfaceNamespace +
490 (StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_) +
491 "Proxy").c_str());
492 sb.Append(prefix + TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str());
493 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n");
494 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
495 sb.Append(prefix + TAB).Append("}\n\n");
496 EmitGetInstanceMethodInitProxyImpl(sb, prefix);
497 }
498
EmitGetInstanceMethodInitProxyImpl(StringBuilder & sb,const std::string & prefix) const499 void CppClientProxyCodeEmitter::EmitGetInstanceMethodInitProxyImpl(StringBuilder &sb, const std::string &prefix) const
500 {
501 std::string objName = "proxy";
502 std::string serMajorName = "serMajorVer";
503 std::string serMinorName = "serMinorVer";
504 sb.Append(prefix + TAB).AppendFormat("%s->servMgr_ = ", objName.c_str());
505 sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(servMgr);\n");
506 sb.Append(prefix + TAB).AppendFormat("%s->deathRecipient_ = new %s::%s(%s);\n", objName.c_str(),
507 EmitDefinitionByInterface(interface_, proxyName_).c_str(),
508 devmgrDeathRecipientName_.c_str(), objName.c_str());
509 sb.Append(prefix + TAB).AppendFormat("%s->servMgr_->AddDeathRecipient(%s->deathRecipient_);\n",
510 objName.c_str(), objName.c_str());
511 sb.Append(prefix + TAB).AppendFormat("%s->isReconnected_ = false;\n", objName.c_str());
512 sb.Append(prefix + TAB).AppendFormat("%s->serviceName_ = serviceName;\n", objName.c_str());
513
514 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
515 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
516 sb.Append(prefix + TAB).AppendFormat("int32_t %s = %s->GetVersion(%s, %s);\n",
517 errorCodeName_.c_str(), objName.c_str(), serMajorName.c_str(), serMinorName.c_str());
518 sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
519 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
520 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
521 sb.Append(prefix + TAB).Append("}\n\n");
522
523 sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
524 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
525 sb.Append("version of service:%u.%u");
526 sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
527 sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
528 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
529 sb.Append(prefix + TAB).Append("}\n\n");
530 sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str());
531 sb.Append(prefix).Append("}\n");
532 }
533
EmitProxyCppReconnectMethodImpl(StringBuilder & sb,const std::string & prefix) const534 void CppClientProxyCodeEmitter::EmitProxyCppReconnectMethodImpl(StringBuilder &sb, const std::string &prefix) const
535 {
536 std::string doubleTab = prefix + TAB;
537 sb.Append(prefix).AppendFormat("int32_t %s::Reconnect(\n",
538 EmitDefinitionByInterface(interface_, proxyName_).c_str());
539 sb.Append(doubleTab).AppendFormat("sptr<%s> proxy) \n",
540 EmitDefinitionByInterface(interface_, proxyName_).c_str());
541 sb.Append(prefix).Append("{\n");
542 sb.Append(doubleTab).Append("if (proxy == nullptr) {\n");
543 sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : input proxy is null\");\n");
544 sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
545 sb.Append(doubleTab).Append("}\n");
546 sb.Append(doubleTab).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
547 sb.Append(doubleTab).Append("proxy->isReconnected_ = false;\n");
548 sb.Append(doubleTab).Append("auto iServMgr = IServiceManager::Get();\n");
549 sb.Append(doubleTab).Append("if (iServMgr == nullptr) {\n");
550 sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : iServMgr is null\");\n");
551 sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
552 sb.Append(doubleTab).Append("};\n");
553 sb.Append(doubleTab).Append("proxy->reconnectRemote_ = ");
554 sb.Append("iServMgr->GetService(proxy->serviceName_.c_str());\n");
555 sb.Append(doubleTab).Append("if (proxy->reconnectRemote_ == nullptr) {\n");
556 sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : reconnectRemote_ is null\");\n");
557 sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
558 sb.Append(doubleTab).Append("}\n");
559 sb.Append(doubleTab).Append("proxy->servMgr_ = ");
560 sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(iServMgr);\n");
561 sb.Append(doubleTab).Append("if (proxy->servMgr_ == nullptr) {\n");
562 sb.Append(doubleTab + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
563 sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
564 sb.Append(doubleTab).Append("}\n");
565 sb.Append(doubleTab).Append("proxy->servMgr_->AddDeathRecipient(\n");
566 sb.Append(doubleTab + TAB).AppendFormat("new %s::%s(proxy));\n",
567 EmitDefinitionByInterface(interface_, proxyName_).c_str(), devmgrDeathRecipientName_.c_str());
568 sb.Append(doubleTab).Append("proxy->isReconnected_ = true;\n");
569 sb.Append(doubleTab).Append("return HDF_SUCCESS;\n");
570 sb.Append(prefix).Append("}\n");
571 }
572
EmitProxyPassthroughtLoadImpl(StringBuilder & sb,const std::string & prefix) const573 void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const
574 {
575 sb.Append(prefix).AppendFormat("if (isStub) {\n");
576
577 if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
578 sb.Append(prefix + TAB).Append("std::string desc = ");
579 sb.Append("std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(");
580 sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
581 } else {
582 sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
583 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
584 }
585 sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
586 sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
587 sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
588 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.data());\n");
589 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
590 sb.Append(prefix + TAB).Append("}\n");
591
592 if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
593 sb.Append(prefix + TAB).AppendFormat("return std::shared_ptr<%s>(reinterpret_cast<%s *>(impl));\n",
594 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
595 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
596 } else {
597 sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
598 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
599 }
600 sb.Append(prefix).Append("}\n\n");
601 }
602
EmitProxyMethodImpls(StringBuilder & sb,const std::string & prefix)603 void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix)
604 {
605 AutoPtr<ASTInterfaceType> interface = interface_;
606 AutoPtr<ASTInterfaceType> metaInterface = interface_;
607 while (interface != nullptr) {
608 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
609 EmitProxyMethodImpl(interface, method, sb, prefix);
610 sb.Append("\n");
611 }
612 interface = interface->GetExtendsInterface();
613 if (interface != nullptr) {
614 metaInterface = interface;
615 }
616 }
617 AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
618 EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix);
619 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
620 sb.Append("\n");
621 EmitProxyStaticMethodImpl(method, sb, prefix);
622 }
623 if (interface_->GetExtendsInterface() == nullptr) {
624 sb.Append("\n");
625 EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix);
626 }
627 }
628
EmitProxyIsProxyMethodImpl(StringBuilder & sb,const std::string & prefix) const629 void CppClientProxyCodeEmitter::EmitProxyIsProxyMethodImpl(StringBuilder &sb, const std::string &prefix) const
630 {
631 sb.Append(prefix).Append("inline bool IsProxy() override\n");
632 sb.Append(prefix).Append("{\n");
633 sb.Append(prefix + TAB).Append("return true;\n");
634 sb.Append(prefix).Append("}\n\n");
635 }
636
EmitProxyCastFromMethodImpls(StringBuilder & sb,const std::string & prefix) const637 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpls(StringBuilder &sb, const std::string &prefix) const
638 {
639 AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
640 while (interface != nullptr) {
641 EmitProxyCastFromMethodImpl(interface, sb, prefix);
642 sb.Append(prefix).Append("\n");
643 interface = interface->GetExtendsInterface();
644 }
645 }
646
EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,StringBuilder & sb,const std::string & prefix) const647 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,
648 StringBuilder &sb, const std::string &prefix) const
649 {
650 std::string currentInterface = EmitDefinitionByInterface(interface_, interfaceName_);
651 std::string parentInterface = EmitDefinitionByInterface(interface, interfaceName_);
652
653 sb.Append(prefix).AppendFormat("sptr<%s> %s::CastFrom(const sptr<%s> &parent)\n",
654 currentInterface.c_str(), currentInterface.c_str(), parentInterface.c_str());
655 sb.Append(prefix).Append("{\n");
656 sb.Append(prefix + TAB).AppendFormat("return CastFromTemplate<%s, %s>(parent);\n",
657 currentInterface.c_str(), parentInterface.c_str());
658 sb.Append(prefix).Append("}\n");
659 }
660
EmitProxyCastFromMethodImplTemplate(StringBuilder & sb,const std::string & prefix) const661 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImplTemplate(StringBuilder &sb, const std::string &prefix) const
662 {
663 std::string serMajorName = "serMajorVer";
664 std::string serMinorName = "serMinorVer";
665
666 sb.Append(prefix).Append("template<typename ChildType, typename ParentType>\n");
667 sb.Append(prefix).Append("static sptr<ChildType> CastFromTemplate(const sptr<ParentType> &parent)\n");
668 sb.Append(prefix).Append("{\n");
669 sb.Append(prefix + TAB).Append("if (parent == nullptr) {\n");
670 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:parent is nullptr!\", __func__);\n");
671 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
672 sb.Append(prefix + TAB).Append("}\n\n");
673
674 sb.Append(prefix + TAB).Append("if (!parent->IsProxy()) {\n");
675 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:not proxy, not support castfrom!\", __func__);\n");
676 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
677 sb.Append(prefix + TAB).Append("}\n\n");
678
679 sb.Append(prefix + TAB).AppendFormat("sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<ParentType>(parent);\n");
680 sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
681 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_objcast failed!\", __func__);\n");
682 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
683 sb.Append(prefix + TAB).Append("}\n\n");
684
685 sb.Append(prefix + TAB).AppendFormat("sptr<ChildType> proxy = OHOS::HDI::hdi_facecast<ChildType>(remote);\n");
686 sb.Append(prefix + TAB).Append("if (proxy == nullptr) {\n");
687 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_facecast failed!\", __func__);\n");
688 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
689 sb.Append(prefix + TAB).Append("}\n\n");
690
691 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
692 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
693 sb.Append(prefix + TAB).AppendFormat("int32_t %s = proxy->GetVersion(%s, %s);\n",
694 errorCodeName_.c_str(), serMajorName.c_str(), serMinorName.c_str());
695 sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
696 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
697 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
698 sb.Append(prefix + TAB).Append("}\n\n");
699
700 sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
701 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
702 sb.Append("version of service:%u.%u");
703 sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
704 sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
705 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
706 sb.Append(prefix + TAB).Append("}\n\n");
707
708 sb.Append(prefix + TAB).Append("return proxy;\n");
709 sb.Append(prefix).Append("}\n");
710 }
711
EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)712 void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,
713 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
714 {
715 if (method->GetParameterNumber() == 0) {
716 sb.Append(prefix).AppendFormat(
717 "int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
718 } else {
719 StringBuilder paramStr;
720 paramStr.Append(prefix).AppendFormat(
721 "int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
722 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
723 AutoPtr<ASTParameter> param = method->GetParameter(i);
724 EmitProxyMethodParameter(param, paramStr, "");
725 if (i + 1 < method->GetParameterNumber()) {
726 paramStr.Append(", ");
727 }
728 }
729
730 paramStr.Append(")");
731
732 sb.Append(SpecificationParam(paramStr, prefix + TAB));
733 sb.Append("\n");
734 }
735 EmitProxyMethodBody(interface, method, sb, prefix);
736 }
737
EmitProxyStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)738 void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl(
739 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
740 {
741 if (method->GetParameterNumber() == 0) {
742 sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr<IRemoteObject> remote)\n",
743 EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
744 } else {
745 StringBuilder paramStr;
746 paramStr.Append(prefix).AppendFormat(
747 "int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
748 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
749 AutoPtr<ASTParameter> param = method->GetParameter(i);
750 EmitProxyMethodParameter(param, paramStr, "");
751 paramStr.Append(", ");
752 }
753
754 paramStr.Append("const sptr<IRemoteObject> remote)");
755 sb.Append(SpecificationParam(paramStr, prefix + TAB));
756 sb.Append("\n");
757 }
758 EmitProxyStaticMethodBody(method, sb, prefix);
759 }
760
EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)761 void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,
762 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
763 {
764 sb.Append(prefix).Append("{\n");
765 sb.Append(prefix + TAB).AppendFormat("return %s::%s_(",
766 EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str());
767 if (method->GetParameterNumber() > 0) {
768 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
769 AutoPtr<ASTParameter> param = method->GetParameter(i);
770 sb.Append(param->GetName().c_str());
771 sb.Append(", ");
772 }
773 }
774 if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
775 sb.Append("GetCurrentRemote());\n");
776 } else {
777 sb.Append("Remote());\n");
778 }
779 sb.Append(prefix).Append("}\n");
780 }
781
EmitProxyStaticMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)782 void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody(
783 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
784 {
785 std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC";
786 sb.Append(prefix).Append("{\n");
787 sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", dataParcelName_.c_str());
788 sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", replyParcelName_.c_str());
789 sb.Append(prefix + TAB).AppendFormat("MessageOption %s(%s);\n", optionName_.c_str(), option.c_str());
790 sb.Append("\n");
791
792 // write interface token
793 EmitWriteInterfaceToken(dataParcelName_, sb, prefix + TAB);
794 sb.Append("\n");
795
796 EmitWriteFlagOfNeedSetMem(method, dataParcelName_, sb, prefix + TAB);
797
798 if (method->GetParameterNumber() > 0) {
799 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
800 AutoPtr<ASTParameter> param = method->GetParameter(i);
801 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
802 EmitWriteMethodParameter(param, dataParcelName_, sb, prefix + TAB);
803 sb.Append("\n");
804 }
805 }
806 }
807 sb.Append(prefix + TAB).AppendFormat("if (remote == nullptr) {\n");
808 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid remote object!\", __func__);\n");
809 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
810 sb.Append(prefix + TAB).Append("}\n\n");
811 sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n", errorCodeName_.c_str(),
812 EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
813 sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
814 sb.Append(prefix + TAB + TAB).AppendFormat(
815 "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n", errorCodeName_.c_str());
816 sb.Append(prefix + TAB + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
817 sb.Append(prefix + TAB).Append("}\n");
818
819 if (!method->IsOneWay()) {
820 sb.Append("\n");
821 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
822 AutoPtr<ASTParameter> param = method->GetParameter(i);
823 if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
824 EmitReadMethodParameter(param, replyParcelName_, false, sb, prefix + TAB);
825 sb.Append("\n");
826 }
827 }
828 }
829
830 sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
831 sb.Append(prefix).Append("}\n");
832 }
833
EmitWriteInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const834 void CppClientProxyCodeEmitter::EmitWriteInterfaceToken(
835 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
836 {
837 sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(),
838 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
839 sb.Append(prefix + TAB)
840 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n");
841 sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
842 sb.Append(prefix).Append("}\n");
843 }
844
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const845 void CppClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
846 const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
847 {
848 if (NeedFlag(method)) {
849 sb.Append(prefix).AppendFormat("if (!%s.WriteBool(false)) {\n", dataBufName.c_str());
850 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:failed to write flag of memory setting!\", __func__);\n");
851 sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
852 sb.Append(prefix).Append("}\n\n");
853 }
854 }
855
GetUtilMethods(UtilMethodMap & methods)856 void CppClientProxyCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
857 {
858 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
859 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
860 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
861 AutoPtr<ASTType> paramType = param->GetType();
862 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
863 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
864 } else {
865 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
866 }
867 }
868 }
869 }
870 } // namespace HDI
871 } // namespace OHOS