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 "sa_cpp_client_proxy_code_emitter.h"
17 #include "util/file.h"
18 #include "util/string_helper.h"
19
20 namespace OHOS {
21 namespace Idl {
EmitCode()22 void SaCppClientProxyCodeEmitter::EmitCode()
23 {
24 SaTypeEmitter::circleCount_ = 0;
25 EmitInterfaceProxyHeaderFile();
26 EmitInterfaceProxyCppFile();
27 }
28
EmitInterfaceProxyHeaderFile()29 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyHeaderFile()
30 {
31 std::string filePath =
32 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
33 File file(filePath, File::WRITE);
34 StringBuilder sb;
35
36 EmitLicense(sb);
37 EmitHeadMacro(sb, proxyFullName_);
38
39 sb.Append("\n").Append("#include <iremote_proxy.h>\n");
40 EmitSecurecInclusion(sb);
41 sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).c_str());
42 if (ast_ != nullptr && ast_->GetHasCacheableProxyMethods()) {
43 sb.Append("#include \"api_cache_manager.h\"\n");
44 }
45 sb.Append("\n");
46 EmitInterfaceProxyInHeaderFile(sb);
47 EmitTailMacro(sb, proxyFullName_);
48
49 std::string data = sb.ToString();
50 file.WriteData(data.c_str(), data.size());
51 file.Flush();
52 file.Close();
53 }
54
EmitInterfaceProxyInHeaderFile(StringBuilder & sb)55 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyInHeaderFile(StringBuilder &sb)
56 {
57 EmitBeginNamespace(sb);
58 EmitImportUsingNamespace(sb);
59 sb.AppendFormat("class %s : public IRemoteProxy<%s> {\n", proxyName_.c_str(), interfaceName_.c_str());
60 sb.Append("public:\n");
61 EmitInterfaceProxyConstructor(sb, TAB);
62 sb.Append("\n");
63 EmitInterfaceProxyMethodDecls(sb, TAB);
64 sb.Append("\n");
65 sb.Append("private:\n");
66 EmitInterfaceProxyConstants(sb, TAB);
67 sb.Append("};\n");
68 EmitEndNamespace(sb);
69 }
70
EmitInterfaceProxyRegisterDeathRecipient(StringBuilder & sb,const std::string & prefix) const71 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyRegisterDeathRecipient(StringBuilder &sb,
72 const std::string &prefix) const
73 {
74 sb.Append(prefix).Append("if (remote_) {\n");
75 sb.Append(prefix + TAB).Append("if (!remote->IsProxyObject()) {\n");
76 if (logOn_) {
77 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"remote is not proxy object!\");\n");
78 }
79 sb.Append(prefix + TAB + TAB).Append("return;\n")
80 .Append(prefix + TAB).Append("}\n")
81 .Append(prefix + TAB)
82 .AppendFormat("deathRecipient_ = new (std::nothrow) %s(*this);\n", deathRecipientName_.c_str())
83 .Append(prefix + TAB).Append("if (!deathRecipient_) {\n");
84 if (logOn_) {
85 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"deathRecipient_ is nullptr!\");\n");
86 }
87 sb.Append(prefix + TAB + TAB).Append("return;\n")
88 .Append(prefix + TAB).Append("}\n")
89 .Append(prefix + TAB).Append("if (!remote->AddDeathRecipient(deathRecipient_)) {\n");
90 if (logOn_) {
91 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"AddDeathRecipient failed!\");\n");
92 }
93 sb.Append(prefix + TAB + TAB).Append("return;\n")
94 .Append(prefix + TAB).Append("}\n")
95 .Append(prefix + TAB).Append("remote_ = remote;\n")
96 .Append(prefix).Append("}\n");
97 }
98
EmitInterfaceProxyAddCacheApi(StringBuilder & sb,const std::string & prefix) const99 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyAddCacheApi(StringBuilder &sb, const std::string &prefix) const
100 {
101 sb.Append(prefix).Append("{\n");
102 size_t methodNumber = interface_->GetMethodNumber();
103 for (size_t i = 0; i < methodNumber; i++) {
104 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
105 if (!method->GetCacheable() || method->IsOneWay()) {
106 continue;
107 }
108 std::string overloadname = "";
109 SACppCodeEmitter::CheckMethodOverload(method, i, overloadname);
110 int32_t cacheableTime = method->GetCacheableTime();
111 if (cacheableTime != 0) {
112 sb.Append(prefix).Append("ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(),\n")
113 .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), %d);\n",
114 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str(), cacheableTime);
115 } else {
116 sb.Append(prefix).Append("ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(),\n")
117 .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), 0);\n",
118 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
119 }
120 }
121 sb.Append("\n");
122 EmitInterfaceProxyRegisterDeathRecipient(sb, prefix + TAB);
123 sb.Append(prefix).Append("}\n");
124 }
125
EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder & sb,const std::string & prefix) const126 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder &sb,
127 const std::string &prefix) const
128 {
129 sb.Append(prefix).Append("{\n");
130 sb.Append(prefix + TAB).Append("if (remote_ == nullptr) {\n");
131 sb.Append(prefix + TAB).Append(TAB).Append("return;\n");
132 sb.Append(prefix + TAB).Append("}\n");
133 sb.Append(prefix + TAB).Append("if (deathRecipient_ == nullptr) {\n");
134 sb.Append(prefix + TAB).Append(TAB).Append("return;\n");
135 sb.Append(prefix + TAB).Append("}\n");
136 sb.Append(prefix + TAB).Append("remote_->RemoveDeathRecipient(deathRecipient_);\n");
137 sb.Append(prefix + TAB).Append("remote_ = nullptr;\n");
138 size_t methodNumber = interface_->GetMethodNumber();
139 if (methodNumber > 0) {
140 sb.Append("\n");
141 for (size_t i = 0; i < methodNumber; i++) {
142 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
143 std::string overloadname = "";
144 SACppCodeEmitter::CheckMethodOverload(method, i, overloadname);
145 if (method->GetCacheable() && !method->IsOneWay()) {
146 sb.Append(prefix).Append("ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(),\n")
147 .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s));\n",
148 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
149 }
150 }
151 }
152 sb.Append(prefix).Append("}\n");
153 }
154
EmitInterfaceProxyConstructor(StringBuilder & sb,const std::string & prefix) const155 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder &sb, const std::string &prefix) const
156 {
157 sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.c_str());
158 sb.Append(prefix + TAB).Append("const sptr<IRemoteObject>& remote)\n");
159 sb.Append(prefix + TAB).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.c_str());
160 if (ast_->GetHasCacheableProxyMethods()) {
161 EmitInterfaceProxyAddCacheApi(sb, prefix);
162 } else {
163 sb.Append(prefix).Append("{}\n");
164 }
165 sb.Append("\n");
166 sb.Append(prefix).AppendFormat("virtual ~%s()\n", proxyName_.c_str());
167 if (ast_->GetHasCacheableProxyMethods()) {
168 EmitInterfaceProxyUnRegisterDeathRecipient(sb, prefix);
169 } else {
170 sb.Append(prefix).Append("{}\n");
171 }
172 }
173
EmitInterfaceProxyMethodDecls(StringBuilder & sb,const std::string & prefix) const174 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
175 {
176 size_t methodNumber = interface_->GetMethodNumber();
177 for (size_t i = 0; i < methodNumber; i++) {
178 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
179 EmitInterfaceProxyMethodDecl(method, sb, prefix);
180 if (i != methodNumber - 1) {
181 sb.Append("\n");
182 }
183 }
184 }
185
EmitInterfaceProxyMethodDecl(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const186 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodDecl(AutoPtr<ASTMethod> &method, StringBuilder &sb,
187 const std::string &prefix) const
188 {
189 if (method->IsMacro()) {
190 sb.AppendFormat("#%s %s\n", method->GetMacroType().c_str(), method->GetMacroVal().c_str());
191 }
192 sb.Append(prefix).AppendFormat("ErrCode %s(", method->GetName().c_str());
193 EmitInterfaceMethodParams(method, sb, prefix + TAB);
194 sb.Append(") override;\n");
195 if (method->IsMacro()) {
196 sb.Append("#endif\n");
197 }
198 }
199
EmitInterfaceProxyDeathRecipient(StringBuilder & sb,const std::string & prefix) const200 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyDeathRecipient(StringBuilder &sb, const std::string &prefix) const
201 {
202 sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n", deathRecipientName_.c_str());
203 sb.Append(prefix).Append("public:\n");
204 sb.Append(prefix + TAB).AppendFormat("explicit %s(%s &client) : client_(client) {}\n", deathRecipientName_.c_str(),
205 proxyName_.c_str());
206 sb.Append(prefix + TAB).AppendFormat("~%s() override = default;\n", deathRecipientName_.c_str());
207 sb.Append(prefix + TAB).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
208 sb.Append(prefix + TAB).Append("{\n");
209 sb.Append(prefix + TAB + TAB).Append("client_.OnRemoteDied(remote);\n");
210 sb.Append(prefix + TAB).Append("}\n");
211 sb.Append(prefix).Append("private:\n");
212 sb.Append(prefix + TAB).AppendFormat("%s &client_;\n", proxyName_.c_str());
213 sb.Append(prefix).Append("};\n\n");
214
215 sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)\n");
216 sb.Append(prefix).Append("{\n");
217 sb.Append(prefix + TAB).Append("(void)remoteObject;\n");
218 sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().ClearCache(GetDescriptor());\n");
219 sb.Append(prefix).Append("}\n");
220 sb.Append(prefix).Append("sptr<IRemoteObject> remote_ = nullptr;\n");
221 sb.Append(prefix).Append("sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;\n");
222 }
223
EmitInterfaceProxyConstants(StringBuilder & sb,const std::string & prefix)224 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyConstants(StringBuilder &sb, const std::string &prefix)
225 {
226 if (ast_->GetHasCacheableProxyMethods()) {
227 EmitInterfaceProxyDeathRecipient(sb, prefix);
228 }
229 sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.c_str());
230
231 EmitInterfaceProxyIpcCapacityValues(sb, prefix);
232 }
233
EmitInterfaceProxyIpcCapacityValues(StringBuilder & sb,const std::string & prefix)234 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyIpcCapacityValues(StringBuilder &sb, const std::string &prefix)
235 {
236 size_t methodNumber = interface_->GetMethodNumber();
237 for (size_t i = 0; i < methodNumber; i++) {
238 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
239 if (method->HasIpcInCapacity()) {
240 sb.Append(prefix).AppendFormat("static constexpr size_t CAPACITY_%s_%d = %s << 10;\n",
241 ConstantName(method->GetName()).c_str(), method->GetIpcCode(), method->GetIpcInCapacity().c_str());
242 }
243 }
244 }
245
EmitInterfaceProxyCppFile()246 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyCppFile()
247 {
248 std::string filePath =
249 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
250 File file(filePath, File::WRITE);
251 StringBuilder sb;
252
253 EmitLicense(sb);
254 sb.AppendFormat("#include \"%s.h\"\n", FileName(proxyName_).c_str());
255 if (logOn_) {
256 sb.Append("#include \"hilog/log.h\"\n");
257 }
258 if (hitraceOn_) {
259 sb.Append("#include \"hitrace_meter.h\"\n");
260 }
261 sb.Append("\n");
262 if (logOn_) {
263 sb.Append("using OHOS::HiviewDFX::HiLog;\n\n");
264 }
265 EmitBeginNamespace(sb);
266 EmitImportUsingNamespace(sb);
267 EmitInterfaceProxyMethodImpls(sb, "");
268 EmitEndNamespace(sb);
269
270 std::string data = sb.ToString();
271 file.WriteData(data.c_str(), data.size());
272 file.Flush();
273 file.Close();
274 }
275
EmitInterfaceProxyMethodImpls(StringBuilder & sb,const std::string & prefix) const276 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder &sb, const std::string &prefix) const
277 {
278 size_t methodNumber = interface_->GetMethodNumber();
279 for (size_t i = 0; i < methodNumber; i++) {
280 AutoPtr<ASTMethod> method = interface_->GetMethod(i);
281 std::string overloadname = "";
282 SACppCodeEmitter::CheckMethodOverload(method, i, overloadname);
283 SACppCodeEmitter::SetOverloadName(overloadname);
284 EmitInterfaceProxyMethodImpl(method, sb, prefix);
285 if (i != methodNumber - 1) {
286 sb.Append("\n");
287 }
288 }
289 }
290
EmitInterfaceProxyMethodImpl(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const291 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodImpl(AutoPtr<ASTMethod> &method, StringBuilder &sb,
292 const std::string &prefix) const
293 {
294 if (method->IsMacro()) {
295 sb.AppendFormat("#%s %s\n", method->GetMacroType().c_str(), method->GetMacroVal().c_str());
296 }
297 sb.Append(prefix).AppendFormat("ErrCode %s::%s(", proxyName_.c_str(), method->GetName().c_str());
298 EmitInterfaceMethodParams(method, sb, prefix + TAB);
299 sb.Append(")\n");
300 EmitInterfaceProxyMethodBody(method, sb, prefix);
301 if (method->IsMacro()) {
302 sb.Append("#endif\n");
303 }
304 }
305
EmitInterfaceProxyMethodPreSendRequest(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const306 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodPreSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
307 const std::string &prefix) const
308 {
309 if ((method->GetCacheable()) && (!method->IsOneWay())) {
310 std::string overloadname = SACppCodeEmitter::GetOverloadName();
311 sb.Append(prefix).Append("bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(),\n")
312 .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), data, reply);",
313 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
314 sb.Append("\n");
315 sb.Append(prefix).Append("if (hitCache) {\n");
316 EmitInterfaceProxyMethodErrCode(method, sb, prefix);
317 EmitInterfaceProxyMethodReply(method, sb, prefix);
318 sb.Append(prefix + TAB).Append("return ERR_OK;\n");
319 sb.Append(prefix).Append("}\n\n");
320 }
321 }
322
EmitInterfaceProxyMethodPostSendRequest(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const323 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodPostSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
324 const std::string &prefix) const
325 {
326 std::string overloadname = SACppCodeEmitter::GetOverloadName();
327 sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(),\n")
328 .Append(prefix + TAB + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), data, reply);\n",
329 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
330 }
331
EmitInterfaceSetIpcCapacity(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const332 void SaCppClientProxyCodeEmitter::EmitInterfaceSetIpcCapacity(AutoPtr<ASTMethod> &method, StringBuilder &sb,
333 const std::string &prefix) const
334 {
335 std::string capacity = StringHelper::Format("CAPACITY_%s_%d", ConstantName(method->GetName()).c_str(),
336 method->GetIpcCode());
337 sb.Append(prefix).AppendFormat("if (!data.SetMaxCapacity(%s)) {\n", capacity.c_str());
338 if (logOn_) {
339 sb.Append(prefix + TAB).AppendFormat(
340 "HiLog::Error(LABEL, \"Failed to set maximum capacity to %%zu\", %s);\n",
341 capacity.c_str());
342 }
343 sb.Append(prefix + TAB).Append("return ERR_INVALID_VALUE;\n");
344 sb.Append(prefix).Append("}\n\n");
345 }
346
EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const347 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> &method, StringBuilder &sb,
348 const std::string &prefix) const
349 {
350 sb.Append(prefix).Append("{\n");
351 if (hitraceOn_) {
352 sb.Append(prefix + TAB).AppendFormat("HITRACE_METER_NAME(%s, __PRETTY_FUNCTION__);\n", hitraceTag_.c_str());
353 }
354 sb.Append(prefix + TAB).Append("MessageParcel data;\n");
355 sb.Append(prefix + TAB).Append("MessageParcel reply;\n");
356 std::string option = "MessageOption::TF_SYNC";
357 if (method->IsMessageOption()) {
358 option = method->GetMessageOption();
359 } else if (method->IsOneWay()) {
360 option = "MessageOption::TF_ASYNC";
361 }
362 sb.Append(prefix + TAB).AppendFormat("MessageOption option(%s);\n\n", option.c_str());
363 if (method->HasIpcInCapacity()) {
364 EmitInterfaceSetIpcCapacity(method, sb, prefix + TAB);
365 }
366 sb.Append(prefix + TAB).Append("if (!data.WriteInterfaceToken(GetDescriptor())) {\n");
367 if (logOn_) {
368 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Write interface token failed!\");\n");
369 }
370 sb.Append(prefix + TAB + TAB).Append("return ERR_INVALID_VALUE;\n").Append(prefix + TAB).Append("}\n\n");
371 size_t paramNumber = method->GetParameterNumber();
372 for (size_t i = 0; i < paramNumber; i++) {
373 AutoPtr<ASTParameter> param = method->GetParameter(i);
374 if (param->GetAttribute() & ASTParamAttr::PARAM_IN) {
375 EmitWriteMethodParameter(param, "data.", sb, prefix + TAB);
376 }
377 }
378 if (paramNumber > 0) {
379 sb.Append('\n');
380 }
381 EmitInterfaceProxyMethodPreSendRequest(method, sb, prefix + TAB);
382 sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = Remote();\n");
383 sb.Append(prefix + TAB).Append("if (!remote) {\n");
384 if (logOn_) {
385 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Remote is nullptr!\");\n");
386 }
387 sb.Append(prefix + TAB + TAB).Append("return ERR_INVALID_DATA;\n").Append(prefix + TAB).Append("}\n");
388 std::string overloadname = SACppCodeEmitter::GetOverloadName();
389 sb.Append(prefix + TAB).Append("int32_t result = remote->SendRequest(\n").Append(prefix + TAB + TAB)
390 .AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), data, reply, option);\n",
391 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
392 sb.Append(prefix + TAB).Append("if (FAILED(result)) {\n");
393 if (logOn_) {
394 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Send request failed!\");\n");
395 }
396 sb.Append(prefix + TAB).Append(" return result;\n").Append(prefix + TAB).Append("}\n");
397 EmitInterfaceProxyMethodRetValue(method, sb, prefix);
398 }
399
EmitInterfaceProxyMethodErrCode(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const400 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodErrCode(AutoPtr<ASTMethod> &method, StringBuilder &sb,
401 const std::string &prefix) const
402 {
403 sb.Append(prefix + TAB).Append("ErrCode errCode = reply.ReadInt32();\n");
404 sb.Append(prefix + TAB).Append("if (FAILED(errCode)) {\n");
405 if (logOn_) {
406 std::string overloadname = SACppCodeEmitter::GetOverloadName();
407 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Read result failed, code is: %{public}d.\",\n")
408 .Append(prefix + TAB + TAB + TAB)
409 .AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s));\n",
410 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
411 }
412 sb.Append(prefix + TAB).Append(" return errCode;\n");
413 sb.Append(prefix + TAB).Append("}\n");
414 }
415
EmitInterfaceProxyMethodReply(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const416 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodReply(AutoPtr<ASTMethod> &method, StringBuilder &sb,
417 const std::string &prefix) const
418 {
419 size_t paramNumber = method->GetParameterNumber();
420 for (size_t i = 0; i < paramNumber; i++) {
421 AutoPtr<ASTParameter> param = method->GetParameter(i);
422 TypeKind paramTypeKind = param->GetType()->GetTypeKind();
423 const std::string name = param->GetName();
424 if ((paramTypeKind == TypeKind::TYPE_ARRAY || paramTypeKind == TypeKind::TYPE_LIST ||
425 paramTypeKind == TypeKind::TYPE_SET) && param->GetAttribute() == ASTParamAttr::PARAM_INOUT) {
426 sb.Append(prefix + TAB).AppendFormat("%s.clear();\n", name.c_str());
427 }
428 if (param != nullptr && (param->GetAttribute() & ASTParamAttr::PARAM_OUT)) {
429 EmitReadMethodParameter(param, "reply.", false, sb, prefix + TAB);
430 }
431 }
432 AutoPtr<ASTType> returnType = method->GetReturnType();
433 if (returnType != nullptr && (returnType->GetTypeKind() != TypeKind::TYPE_VOID)) {
434 AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(returnType);
435 if (typeEmitter != nullptr) {
436 typeEmitter->EmitCppReadVar("reply.", "funcResult", sb, prefix + TAB, false);
437 }
438 }
439 }
440
EmitInterfaceProxyMethodRetValue(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const441 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodRetValue(AutoPtr<ASTMethod> &method, StringBuilder &sb,
442 const std::string &prefix) const
443 {
444 if (!method->IsOneWay()) {
445 sb.Append("\n");
446 EmitInterfaceProxyMethodErrCode(method, sb, prefix);
447 sb.Append("\n");
448 if (method->GetCacheable()) {
449 EmitInterfaceProxyMethodPostSendRequest(method, sb, prefix);
450 }
451 EmitInterfaceProxyMethodReply(method, sb, prefix);
452 }
453 sb.Append(prefix + TAB).Append("return ERR_OK;\n");
454 sb.Append(prefix).Append("}\n");
455 }
456
457 } // namespace Idl
458 } // namespace OHOS