• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/c_client_proxy_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 CClientProxyCodeEmitter::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("CClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CClientProxyCodeEmitter::EmitCode()
32 {
33     switch (mode_) {
34         case GenMode::PASSTHROUGH: {
35             if (!interface_->IsSerializable()) {
36                 EmitPassthroughProxySourceFile();
37             }
38             break;
39         }
40         case GenMode::IPC:
41         case GenMode::KERNEL: {
42             EmitProxySourceFile();
43             break;
44         }
45         default:
46             break;
47     }
48 }
49 
EmitPassthroughProxySourceFile()50 void CClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
51 {
52     std::string filePath =
53         File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(proxyName_).c_str()));
54     File file(filePath, File::WRITE);
55     StringBuilder sb;
56 
57     EmitLicense(sb);
58     EmitPassthroughProxyInclusions(sb);
59     sb.Append("\n");
60     EmitLogTagMacro(sb, FileName(proxyName_));
61     sb.Append("\n");
62     EmitProxyGetMethodImpl(sb);
63     sb.Append("\n");
64     EmitPassthroughGetInstanceMethod(sb);
65     sb.Append("\n");
66     EmitProxyReleaseMethodImpl(sb);
67     sb.Append("\n");
68     EmitPassthroughReleaseInstanceMethod(sb);
69     std::string data = sb.ToString();
70     file.WriteData(data.c_str(), data.size());
71     file.Flush();
72     file.Close();
73 }
74 
EmitPassthroughProxyInclusions(StringBuilder & sb)75 void CClientProxyCodeEmitter::EmitPassthroughProxyInclusions(StringBuilder &sb)
76 {
77     HeaderFile::HeaderFileSet headerFiles;
78     headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
79     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
80 
81     for (const auto &file : headerFiles) {
82         sb.AppendFormat("%s\n", file.ToString().c_str());
83     }
84 }
85 
EmitPassthroughGetInstanceMethod(StringBuilder & sb) const86 void CClientProxyCodeEmitter::EmitPassthroughGetInstanceMethod(StringBuilder &sb) const
87 {
88     sb.AppendFormat("struct %s *%sGetInstance(const char *serviceName, bool isStub)\n",
89         interfaceName_.c_str(), interfaceName_.c_str());
90     sb.Append("{\n");
91     EmitProxyLoadOrUnLoadHdiImpl("serviceName", true, sb, TAB);
92     sb.Append(TAB).Append("return NULL;\n");
93     sb.Append("}\n");
94 }
95 
EmitPassthroughReleaseInstanceMethod(StringBuilder & sb) const96 void CClientProxyCodeEmitter::EmitPassthroughReleaseInstanceMethod(StringBuilder &sb) const
97 {
98     sb.AppendFormat("void %sReleaseInstance(const char *serviceName, struct %s *instance, bool isStub)\n",
99         interfaceName_.c_str(), interfaceName_.c_str());
100     sb.Append("{\n");
101     sb.Append(TAB).Append("if (instance == NULL) {\n");
102     sb.Append(TAB).Append(TAB).Append("return;\n");
103     sb.Append(TAB).Append("}\n\n");
104     EmitProxyLoadOrUnLoadHdiImpl("serviceName", false, sb, TAB);
105     sb.Append("}\n");
106 }
107 
EmitProxySourceFile()108 void CClientProxyCodeEmitter::EmitProxySourceFile()
109 {
110     std::string filePath =
111         File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(proxyName_).c_str()));
112     File file(filePath, File::WRITE);
113     StringBuilder sb;
114 
115     EmitLicense(sb);
116     EmitProxyInclusions(sb);
117     sb.Append("\n");
118     EmitLogTagMacro(sb, FileName(proxyName_));
119     sb.Append("\n");
120     EmitProxyDefinition(sb);
121     sb.Append("\n");
122     UtilMethodMap utilMethods;
123     GetUtilMethods(utilMethods);
124     EmitUtilMethods(sb, "", utilMethods, true);
125     sb.Append("\n");
126     EmitUtilMethods(sb, "", utilMethods, false);
127     sb.Append("\n");
128     if (mode_ != GenMode::KERNEL) {
129         EmitProxyCallMethodImpl(sb);
130     } else {
131         EmitProxyKernelCallMethodImpl(sb);
132     }
133     sb.Append("\n");
134     EmitProxyMethodImpls(sb);
135     sb.Append("\n");
136     EmitProxyConstruction(sb);
137     sb.Append("\n");
138     EmitProxyExternalMethodImpl(sb);
139 
140     std::string data = sb.ToString();
141     file.WriteData(data.c_str(), data.size());
142     file.Flush();
143     file.Close();
144 }
145 
EmitProxyInclusions(StringBuilder & sb)146 void CClientProxyCodeEmitter::EmitProxyInclusions(StringBuilder &sb)
147 {
148     HeaderFile::HeaderFileSet headerFiles;
149 
150     headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
151     GetHeaderOtherLibInclusions(headerFiles);
152 
153     for (const auto &file : headerFiles) {
154         sb.AppendFormat("%s\n", file.ToString().c_str());
155     }
156 }
157 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const158 void CClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
159 {
160     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
161     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
162     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
163     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
164     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
165 
166     if (mode_ == GenMode::KERNEL) {
167         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_io_service_if");
168     } else {
169         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "servmgr_hdi");
170         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist");
171         if (!interface_->IsSerializable()) {
172             headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
173             headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
174         }
175     }
176 
177     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
178         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
179             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
180             AutoPtr<ASTType> paramType = param->GetType();
181             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
182                 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
183                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
184             }
185         }
186     }
187 }
188 
EmitProxyDefinition(StringBuilder & sb) const189 void CClientProxyCodeEmitter::EmitProxyDefinition(StringBuilder &sb) const
190 {
191     sb.AppendFormat("struct %sProxy {\n", baseName_.c_str());
192     sb.Append(TAB).AppendFormat("struct %s impl;\n", interfaceName_.c_str());
193     if (mode_ == GenMode::KERNEL) {
194         sb.Append(TAB).Append("struct HdfIoService *serv;\n");
195     } else {
196         sb.Append(TAB).Append("struct HdfRemoteService *remote;\n");
197     }
198 
199     sb.Append("};\n");
200 }
201 
EmitProxyCallMethodImpl(StringBuilder & sb) const202 void CClientProxyCodeEmitter::EmitProxyCallMethodImpl(StringBuilder &sb) const
203 {
204     sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n",
205         baseName_.c_str(), interfaceName_.c_str());
206     sb.Append(TAB).Append("struct HdfSBuf *reply, bool isOneWay)\n");
207     sb.Append("{\n");
208 
209     std::string remoteName = "remote";
210     sb.Append(TAB).AppendFormat("struct HdfRemoteService *%s = self->AsObject(self);\n", remoteName.c_str());
211     sb.Append(TAB).AppendFormat("if (%s == NULL ||\n", remoteName.c_str());
212     sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher == NULL ||\n", remoteName.c_str());
213     sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->Dispatch == NULL ||\n", remoteName.c_str());
214     sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->DispatchAsync == NULL) {\n", remoteName.c_str());
215     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n");
216     sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
217     sb.Append(TAB).Append("}\n");
218 
219     sb.Append(TAB).AppendFormat("if (isOneWay) {\n");
220     sb.Append(TAB).Append(TAB).AppendFormat(
221         "return %s->dispatcher->DispatchAsync(%s, id, data, reply);\n", remoteName.c_str(), remoteName.c_str());
222     sb.Append(TAB).AppendFormat("} else {\n");
223     sb.Append(TAB).Append(TAB).AppendFormat(
224         "return %s->dispatcher->Dispatch(%s, id, data, reply);\n", remoteName.c_str(), remoteName.c_str());
225     sb.Append(TAB).AppendFormat("}\n");
226     sb.Append("}\n");
227 }
228 
EmitProxyKernelCallMethodImpl(StringBuilder & sb) const229 void CClientProxyCodeEmitter::EmitProxyKernelCallMethodImpl(StringBuilder &sb) const
230 {
231     sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n",
232         baseName_.c_str(), interfaceName_.c_str());
233     sb.Append(TAB).Append("struct HdfSBuf *reply)\n");
234     sb.Append("{\n");
235 
236     std::string remoteName = "serv";
237     sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n",
238         baseName_.c_str(), baseName_.c_str(), remoteName.c_str());
239     sb.Append(TAB).AppendFormat("struct HdfIoService *%s = proxy->%s;\n", remoteName.c_str(), remoteName.c_str());
240 
241     sb.Append(TAB).AppendFormat("if (%s == NULL ||\n", remoteName.c_str());
242     sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher == NULL ||\n", remoteName.c_str());
243     sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->Dispatch == NULL) {\n", remoteName.c_str());
244     sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n");
245     sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
246     sb.Append(TAB).Append("}\n\n");
247 
248     sb.Append(TAB).AppendFormat("return %s->dispatcher->Dispatch(", remoteName.c_str());
249     sb.AppendFormat("(struct HdfObject *)&(%s->object), id, data, reply);\n", remoteName.c_str());
250     sb.Append("}\n");
251 }
252 
EmitProxyMethodImpls(StringBuilder & sb)253 void CClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb)
254 {
255     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
256         EmitProxyMethodImpl(method, sb);
257         sb.Append("\n");
258     }
259 
260     EmitProxyMethodImpl(interface_->GetVersionMethod(), sb);
261 
262     if (mode_ != GenMode::KERNEL) {
263         sb.Append("\n");
264         EmitProxyAsObjectMethodImpl(sb);
265     }
266 }
267 
EmitProxyMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb)268 void CClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb)
269 {
270     if (method->GetParameterNumber() == 0) {
271         sb.AppendFormat("static int32_t %sProxy%s(struct %s *self)\n", baseName_.c_str(), method->GetName().c_str(),
272             interfaceName_.c_str());
273     } else {
274         StringBuilder paramStr;
275         paramStr.AppendFormat("static int32_t %sProxy%s(", baseName_.c_str(), method->GetName().c_str());
276         paramStr.AppendFormat("struct %s *self, ", interfaceName_.c_str());
277         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
278             AutoPtr<ASTParameter> param = method->GetParameter(i);
279             EmitInterfaceMethodParameter(param, paramStr, "");
280             if (i + 1 < method->GetParameterNumber()) {
281                 paramStr.Append(", ");
282             }
283         }
284 
285         paramStr.Append(")");
286         sb.Append(SpecificationParam(paramStr, TAB));
287         sb.Append("\n");
288     }
289     EmitProxyMethodBody(method, sb, "");
290 }
291 
EmitProxyMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)292 void CClientProxyCodeEmitter::EmitProxyMethodBody(
293     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
294 {
295     sb.Append(prefix).Append("{\n");
296     sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_FAILURE;\n", errorCodeName_.c_str());
297 
298     // Local variable definitions must precede all execution statements.
299     EmitMethodNeedLoopVar(method, true, false, sb, prefix + TAB);
300     sb.Append("\n");
301     EmitCreateBuf(dataParcelName_, replyParcelName_, sb, prefix + TAB);
302     sb.Append("\n");
303     EmitCheckThisPointer(sb, prefix + TAB);
304 
305     if (mode_ != GenMode::KERNEL) {
306         sb.Append("\n");
307         EmitWriteInterfaceToken(dataParcelName_, sb, prefix + TAB);
308     }
309 
310     sb.Append("\n");
311     EmitWriteFlagOfNeedSetMem(method, dataParcelName_, sb, prefix + TAB);
312     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
313         AutoPtr<ASTParameter> param = method->GetParameter(i);
314         if (param->GetAttribute() == ParamAttr::PARAM_IN) {
315             param->EmitCWriteVar(dataParcelName_, errorCodeName_, finishedLabelName_, sb, prefix + TAB);
316             sb.Append("\n");
317         } else if (param->EmitCProxyWriteOutVar(
318             dataParcelName_, errorCodeName_, finishedLabelName_, sb, prefix + TAB)) {
319             sb.Append("\n");
320         }
321     }
322 
323     EmitStubCallMethod(method, sb, prefix + TAB);
324     sb.Append("\n");
325 
326     if (!method->IsOneWay()) {
327         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
328             AutoPtr<ASTParameter> param = method->GetParameter(i);
329             if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
330                 EmitReadProxyMethodParameter(param, replyParcelName_, finishedLabelName_, sb, prefix + TAB);
331                 sb.Append("\n");
332             }
333         }
334     }
335 
336     sb.Append(prefix).AppendFormat("%s:\n", finishedLabelName_);
337     EmitReleaseBuf(dataParcelName_, replyParcelName_, sb, prefix + TAB);
338 
339     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
340     sb.Append("}\n");
341 }
342 
EmitCreateBuf(const std::string & dataBufName,const std::string & replyBufName,StringBuilder & sb,const std::string & prefix) const343 void CClientProxyCodeEmitter::EmitCreateBuf(const std::string &dataBufName,
344     const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const
345 {
346     if (mode_ == GenMode::KERNEL) {
347         sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufObtainDefaultSize();\n", dataBufName.c_str());
348         sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufObtainDefaultSize();\n", replyBufName.c_str());
349     } else {
350         sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufTypedObtain(SBUF_IPC);\n", dataBufName.c_str());
351         sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufTypedObtain(SBUF_IPC);\n", replyBufName.c_str());
352     }
353 
354     sb.Append("\n");
355     sb.Append(prefix).AppendFormat("if (%s == NULL || %s == NULL) {\n", dataBufName.c_str(), replyBufName.c_str());
356     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: HdfSubf malloc failed!\", __func__);\n");
357     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", errorCodeName_.c_str());
358     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabelName_);
359     sb.Append(prefix).Append("}\n");
360 }
361 
EmitCheckThisPointer(StringBuilder & sb,const std::string & prefix) const362 void CClientProxyCodeEmitter::EmitCheckThisPointer(StringBuilder &sb, const std::string &prefix) const
363 {
364     sb.Append(prefix).Append("if (self == NULL) {\n");
365     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid interface object\", __func__);\n");
366     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_OBJECT;\n", errorCodeName_.c_str());
367     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabelName_);
368     sb.Append(prefix).Append("}\n");
369 }
370 
EmitWriteInterfaceToken(const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const371 void CClientProxyCodeEmitter::EmitWriteInterfaceToken(
372     const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
373 {
374     sb.Append(prefix).AppendFormat(
375         "if (!HdfRemoteServiceWriteInterfaceToken(self->AsObject(self), %s)) {\n", dataBufName.c_str());
376     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: write interface token failed!\", __func__);\n");
377     sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
378     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabelName_);
379     sb.Append(prefix).Append("}\n");
380 }
381 
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const382 void CClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
383     const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
384 {
385     if (NeedFlag(method)) {
386         sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint8(%s, 1)) {\n", dataBufName.c_str());
387         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: write flag of memory setting failed!\", __func__);\n");
388         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
389         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabelName_);
390         sb.Append(prefix).Append("}\n\n");
391     }
392 }
393 
EmitReleaseBuf(const std::string & dataBufName,const std::string & replyBufName,StringBuilder & sb,const std::string & prefix) const394 void CClientProxyCodeEmitter::EmitReleaseBuf(const std::string &dataBufName,
395     const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const
396 {
397     sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", dataBufName.c_str());
398     sb.Append(prefix + TAB).AppendFormat("HdfSbufRecycle(%s);\n", dataBufName.c_str());
399     sb.Append(prefix).Append("}\n");
400     sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", replyBufName.c_str());
401     sb.Append(prefix + TAB).AppendFormat("HdfSbufRecycle(%s);\n", replyBufName.c_str());
402     sb.Append(prefix).Append("}\n");
403 }
404 
EmitReadProxyMethodParameter(const AutoPtr<ASTParameter> & param,const std::string & parcelName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const405 void CClientProxyCodeEmitter::EmitReadProxyMethodParameter(const AutoPtr<ASTParameter> &param,
406     const std::string &parcelName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
407 {
408     AutoPtr<ASTType> type = param->GetType();
409     if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
410         std::string cloneName = StringHelper::Format("%sCopy", param->GetName().c_str());
411         type->EmitCProxyReadVar(parcelName, cloneName, false, errorCodeName_, gotoLabel, sb, prefix);
412         sb.Append(prefix).AppendFormat("if (strcpy_s(%s, %sLen, %s) != EOK) {\n", param->GetName().c_str(),
413             param->GetName().c_str(), cloneName.c_str());
414         sb.Append(prefix + TAB)
415             .AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", param->GetName().c_str());
416         sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
417         sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
418         sb.Append(prefix).Append("}\n");
419     } else if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
420         type->EmitCProxyReadVar(parcelName, param->GetName().c_str(), false, errorCodeName_, gotoLabel, sb, prefix);
421     } else if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
422         std::string cpName = StringHelper::Format("%sCp", param->GetName().c_str());
423         type->EmitCProxyReadVar(parcelName, cpName, false, errorCodeName_, gotoLabel, sb, prefix);
424         sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n",
425             param->GetName().c_str(), type->EmitCType().c_str(), cpName.c_str(), type->EmitCType().c_str());
426         sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to memcpy %s\", __func__);\n",
427             param->GetName().c_str());
428         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
429         sb.Append(prefix).Append("}\n");
430     } else {
431         type->EmitCProxyReadVar(parcelName, param->GetName(), false, errorCodeName_, gotoLabel, sb, prefix);
432     }
433 }
434 
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)435 void CClientProxyCodeEmitter::EmitStubCallMethod(
436     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
437 {
438     if (mode_ != GenMode::KERNEL) {
439         sb.Append(prefix).AppendFormat("%s = %sCall(self, %s, %s, %s, %s);\n", errorCodeName_.c_str(),
440             proxyName_.c_str(), EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
441             method->IsOneWay() ? "true" : "false");
442     } else {
443         sb.Append(prefix).AppendFormat("%s = %sCall(self, %s, %s, %s);\n", errorCodeName_.c_str(), proxyName_.c_str(),
444             EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str());
445     }
446     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
447     sb.Append(prefix + TAB).AppendFormat(
448         "HDF_LOGE(\"%%{public}s: call failed! error code is %%{public}d\", __func__, %s);\n", errorCodeName_.c_str());
449     sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabelName_);
450     sb.Append(prefix).Append("}\n");
451 }
452 
EmitProxyAsObjectMethodImpl(StringBuilder & sb) const453 void CClientProxyCodeEmitter::EmitProxyAsObjectMethodImpl(StringBuilder &sb) const
454 {
455     sb.AppendFormat("static struct HdfRemoteService *%sProxyAsObject(struct %s *self)\n", baseName_.c_str(),
456         interfaceName_.c_str());
457     sb.Append("{\n");
458     sb.Append(TAB).Append("if (self == NULL) {\n");
459     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
460     sb.Append(TAB).Append("}\n");
461     sb.Append(TAB).AppendFormat(
462         "struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n", baseName_.c_str(), baseName_.c_str());
463     sb.Append(TAB).Append("return proxy->remote;\n");
464     sb.Append("}\n");
465 }
466 
EmitProxyConstruction(StringBuilder & sb) const467 void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder &sb) const
468 {
469     std::string objName = "impl";
470     sb.AppendFormat(
471         "static void %sProxyConstruct(struct %s *%s)\n", baseName_.c_str(), interfaceName_.c_str(), objName.c_str());
472     sb.Append("{\n");
473 
474     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
475         sb.Append(TAB).AppendFormat("%s->%s = %sProxy%s;\n", objName.c_str(), method->GetName().c_str(),
476             baseName_.c_str(), method->GetName().c_str());
477     }
478 
479     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
480     sb.Append(TAB).AppendFormat("%s->%s = %sProxy%s;\n", objName.c_str(), getVerMethod->GetName().c_str(),
481         baseName_.c_str(), getVerMethod->GetName().c_str());
482 
483     if (mode_ != GenMode::KERNEL) {
484         sb.Append(TAB).AppendFormat("%s->AsObject = %sProxyAsObject;\n", objName.c_str(), baseName_.c_str());
485     }
486 
487     sb.Append("}\n");
488 }
489 
EmitProxyExternalMethodImpl(StringBuilder & sb)490 void CClientProxyCodeEmitter::EmitProxyExternalMethodImpl(StringBuilder &sb)
491 {
492     std::string objName = "client";
493     std::string serMajorName = "serMajorVer";
494     std::string serMinorName = "serMinorVer";
495     std::string remoteName = "remote";
496     std::string serviceName = "serviceName";
497 
498     if (mode_ == GenMode::KERNEL) {
499         remoteName = "serv";
500         EmitKernelProxyGetMethodImpl(sb);
501         sb.Append("\n");
502         EmitKernelProxyGetInstanceMethodImpl(objName, serMajorName, serMinorName, remoteName, serviceName, sb);
503         sb.Append("\n");
504         EmitKernelProxyReleaseMethodImpl(remoteName, "HdfIoServiceRecycle", sb);
505     } else if (interface_->IsSerializable()) {
506         EmitIfaceProxyGetMethodImpl(objName, serMajorName, serMinorName, remoteName, sb);
507         sb.Append("\n");
508 
509         if (interface_->IsCallback()) {
510             EmitCbProxyReleaseMethodImpl(remoteName, "HdfRemoteServiceRecycle", sb);
511         } else {
512             EmitIfaceProxyReleaseMethodImpl(remoteName, "HdfRemoteServiceRecycle", sb);
513         }
514     } else {
515         EmitProxyGetMethodImpl(sb);
516         sb.Append("\n");
517         EmitProxyGetInstanceMethodImpl(objName, serMajorName, serMinorName, remoteName, serviceName, sb);
518         sb.Append("\n");
519         EmitProxyReleaseMethodImpl(sb);
520         sb.Append("\n");
521         EmitProxyReleaseInstanceMethodImpl(serviceName, remoteName, "HdfRemoteServiceRecycle", sb);
522     }
523 }
524 
EmitKernelProxyGetMethodImpl(StringBuilder & sb) const525 void CClientProxyCodeEmitter::EmitKernelProxyGetMethodImpl(StringBuilder &sb) const
526 {
527     sb.AppendFormat("struct %s *%sGet()\n", interfaceName_.c_str(), interfaceName_.c_str());
528     sb.Append("{\n");
529     sb.Append(TAB).AppendFormat("return %sGetInstance(\"%s\");\n", interfaceName_.c_str(),
530         FileName(implName_).c_str());
531     sb.Append("}\n");
532 }
533 
EmitKernelProxyGetInstanceMethodImpl(const std::string & objName,const std::string & serMajorName,const std::string & serMinorName,const std::string & remoteName,const std::string & serviceName,StringBuilder & sb) const534 void CClientProxyCodeEmitter::EmitKernelProxyGetInstanceMethodImpl(const std::string &objName,
535     const std::string &serMajorName, const std::string &serMinorName, const std::string &remoteName,
536     const std::string &serviceName, StringBuilder &sb) const
537 {
538     sb.AppendFormat("struct %s *%sGetInstance(const char* %s)\n", interfaceName_.c_str(), interfaceName_.c_str(),
539         serviceName.c_str());
540     sb.Append("{\n");
541     EmitProxyGetRemoteService(remoteName, serviceName, sb, TAB);
542     sb.Append("\n");
543     EmitProxyCreateProxyObject(objName, remoteName, "HdfIoServiceRecycle", sb, TAB);
544     sb.Append("\n");
545     EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
546     sb.Append("\n");
547     sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
548     sb.Append("}\n");
549 }
550 
EmitKernelProxyReleaseMethodImpl(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb) const551 void CClientProxyCodeEmitter::EmitKernelProxyReleaseMethodImpl(
552     const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const
553 {
554     sb.AppendFormat("void %sRelease(struct %s *instance)\n", interfaceName_.c_str(), interfaceName_.c_str());
555     sb.Append("{\n");
556     sb.Append(TAB).Append("if (instance == NULL) {\n");
557     sb.Append(TAB).Append(TAB).Append("return;\n");
558     sb.Append(TAB).Append("}\n");
559     sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
560         baseName_.c_str(), baseName_.c_str());
561     sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
562     sb.Append(TAB).Append("OsalMemFree(proxy);\n");
563     sb.Append("}\n");
564 }
565 
EmitIfaceProxyGetMethodImpl(const std::string & objName,const std::string & serMajorName,const std::string & serMinorName,const std::string & remoteName,StringBuilder & sb)566 void CClientProxyCodeEmitter::EmitIfaceProxyGetMethodImpl(const std::string &objName, const std::string &serMajorName,
567     const std::string &serMinorName, const std::string &remoteName, StringBuilder &sb)
568 {
569     sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *%s)\n", interfaceName_.c_str(), interfaceName_.c_str(),
570         remoteName.c_str());
571     sb.Append("{\n");
572     sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
573     sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: remote is null\", __func__);\n");
574     sb.Append(TAB).Append(TAB).Append("return NULL;\n");
575     sb.Append(TAB).Append("}\n\n");
576     EmitProxySetInterfaceDesc(remoteName, "HdfRemoteServiceRecycle", sb, TAB);
577     sb.Append("\n");
578     EmitProxyCreateProxyObject(objName, remoteName, "HdfRemoteServiceRecycle", sb, TAB);
579     sb.Append("\n");
580     EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
581     sb.Append("\n");
582     sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
583     sb.Append("}\n");
584 }
585 
EmitIfaceProxyReleaseMethodImpl(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb) const586 void CClientProxyCodeEmitter::EmitIfaceProxyReleaseMethodImpl(
587     const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const
588 {
589     std::string implReleaseMethodName = StringHelper::Format("%sImplRelease", interfaceName_.c_str());
590     sb.AppendFormat("void %s(struct %s *instance) __attribute__((weak));\n", implReleaseMethodName.c_str(),
591         interfaceName_.c_str());
592     sb.AppendFormat("void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(),
593         interfaceName_.c_str());
594     sb.Append("{\n");
595     sb.Append(TAB).Append("if (instance == NULL) {\n");
596     sb.Append(TAB).Append(TAB).Append("return;\n");
597     sb.Append(TAB).Append("}\n");
598 
599     sb.Append(TAB).Append("if (isStub) {\n");
600     sb.Append(TAB).Append(TAB).AppendFormat("if (%s != NULL) {\n", implReleaseMethodName.c_str());
601     sb.Append(TAB).Append(TAB).Append(TAB).AppendFormat("%s(instance);\n", implReleaseMethodName.c_str());
602     sb.Append(TAB).Append(TAB).Append("}\n");
603     sb.Append(TAB).Append(TAB).Append("return;\n");
604     sb.Append(TAB).Append("}\n");
605 
606     sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
607         baseName_.c_str(), baseName_.c_str());
608     sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
609     sb.Append(TAB).Append("OsalMemFree(proxy);\n");
610     sb.Append("}\n");
611 }
612 
EmitCbProxyReleaseMethodImpl(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb) const613 void CClientProxyCodeEmitter::EmitCbProxyReleaseMethodImpl(const std::string &remoteName,
614     const std::string &recycleFuncName, StringBuilder &sb) const
615 {
616     sb.AppendFormat("void %sRelease(struct %s *instance)\n", interfaceName_.c_str(), interfaceName_.c_str());
617     sb.Append("{\n");
618     sb.Append(TAB).Append("if (instance == NULL) {\n");
619     sb.Append(TAB).Append(TAB).Append("return;\n");
620     sb.Append(TAB).Append("}\n\n");
621     sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
622         baseName_.c_str(), baseName_.c_str());
623     sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
624     sb.Append(TAB).Append("OsalMemFree(proxy);\n");
625     sb.Append("}\n");
626 }
627 
EmitProxyGetMethodImpl(StringBuilder & sb) const628 void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder &sb) const
629 {
630     sb.AppendFormat("struct %s *%sGet(bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
631     sb.Append("{\n");
632     sb.Append(TAB).AppendFormat("return %sGetInstance(\"%s\", isStub);\n", interfaceName_.c_str(),
633         FileName(implName_).c_str());
634     sb.Append("}\n");
635 }
636 
EmitProxyGetInstanceMethodImpl(const std::string & objName,const std::string & serMajorName,const std::string & serMinorName,const std::string & remoteName,const std::string & serviceName,StringBuilder & sb) const637 void CClientProxyCodeEmitter::EmitProxyGetInstanceMethodImpl(const std::string &objName,
638     const std::string &serMajorName, const std::string &serMinorName, const std::string &remoteName,
639     const std::string &serviceName, StringBuilder &sb) const
640 {
641     sb.AppendFormat("struct %s *%sGetInstance(const char *%s, bool isStub)\n", interfaceName_.c_str(),
642         interfaceName_.c_str(), serviceName.c_str());
643     sb.Append("{\n");
644     EmitProxyLoadOrUnLoadHdiImpl(serviceName, true, sb, TAB);
645     sb.Append("\n");
646     EmitProxyGetRemoteService(remoteName, serviceName, sb, TAB);
647     sb.Append("\n");
648     EmitProxySetInterfaceDesc(remoteName, "HdfRemoteServiceRecycle", sb, TAB);
649     sb.Append("\n");
650     EmitProxyCreateProxyObject(objName, remoteName, "HdfRemoteServiceRecycle", sb, TAB);
651     sb.Append("\n");
652     EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
653     sb.Append("\n");
654     sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
655     sb.Append("}\n");
656 }
657 
EmitProxyGetRemoteService(const std::string & remoteName,const std::string & serviceName,StringBuilder & sb,const std::string & prefix) const658 void CClientProxyCodeEmitter::EmitProxyGetRemoteService(const std::string &remoteName,
659     const std::string &serviceName, StringBuilder &sb, const std::string &prefix) const
660 {
661     if (mode_ != GenMode::KERNEL) {
662         sb.Append(prefix).Append("struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();\n");
663         sb.Append(prefix).Append("if (serviceMgr == NULL) {\n");
664         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: HDIServiceManager not found!\", __func__);\n");
665         sb.Append(prefix + TAB).Append("return NULL;\n");
666         sb.Append(prefix).Append("}\n\n");
667         sb.Append(prefix).AppendFormat("struct HdfRemoteService *%s = ", remoteName.c_str());
668         sb.AppendFormat("serviceMgr->GetService(serviceMgr, %s);\n", serviceName.c_str());
669         sb.Append(prefix).Append("HDIServiceManagerRelease(serviceMgr);\n");
670         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
671         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to get remote!\", __func__);\n");
672         sb.Append(prefix + TAB).Append("return NULL;\n");
673         sb.Append(prefix).Append("}\n");
674     } else {
675         sb.Append(prefix).AppendFormat("struct HdfIoService *%s = ", remoteName.c_str());
676         sb.AppendFormat("HdfIoServiceBind(%s);\n", serviceName.c_str());
677         sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
678         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to get io service!\", __func__);\n");
679         sb.Append(prefix + TAB).Append("return NULL;\n");
680         sb.Append(prefix).Append("}\n");
681     }
682 }
683 
EmitProxySetInterfaceDesc(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb,const std::string & prefix) const684 void CClientProxyCodeEmitter::EmitProxySetInterfaceDesc(const std::string &remoteName,
685     const std::string &recycleFuncName, StringBuilder &sb, const std::string &prefix) const
686 {
687     sb.Append(prefix).AppendFormat("if (!HdfRemoteServiceSetInterfaceDesc(%s, %s)) {\n", remoteName.c_str(),
688         interface_->EmitDescMacroName().c_str());
689     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: set interface token failed!\", __func__);\n");
690     sb.Append(prefix + TAB).AppendFormat("%s(%s);\n", recycleFuncName.c_str(), remoteName.c_str());
691     sb.Append(prefix + TAB).Append("return NULL;\n");
692     sb.Append(prefix).Append("}\n");
693 }
694 
EmitProxyCreateProxyObject(const std::string & clientObjName,const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb,const std::string & prefix) const695 void CClientProxyCodeEmitter::EmitProxyCreateProxyObject(const std::string &clientObjName,
696     const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb,
697     const std::string &prefix) const
698 {
699     sb.Append(prefix).AppendFormat("struct %sProxy *proxy = (struct %sProxy *)OsalMemCalloc(sizeof(struct %sProxy));\n",
700         baseName_.c_str(), baseName_.c_str(), baseName_.c_str());
701     sb.Append(prefix).Append("if (proxy == NULL) {\n");
702     sb.Append(prefix + TAB)
703         .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.c_str());
704     if (!interface_->IsSerializable()) {
705         sb.Append(prefix + TAB).AppendFormat("%s(%s);\n", recycleFuncName.c_str(), remoteName.c_str());
706     }
707     sb.Append(prefix + TAB).Append("return NULL;\n");
708     sb.Append(prefix).Append("}\n");
709     sb.Append("\n");
710     sb.Append(prefix).AppendFormat("proxy->%s = %s;\n", remoteName.c_str(), remoteName.c_str());
711     sb.Append(prefix).AppendFormat("%sProxyConstruct(&proxy->impl);\n", baseName_.c_str());
712     sb.Append(prefix).AppendFormat("struct %s *%s = &proxy->impl;\n", interfaceName_.c_str(), clientObjName.c_str());
713 }
714 
EmitProxyCheckVersion(const std::string & clientObjName,const std::string & serMajorName,const std::string & serMinorName,StringBuilder & sb,const std::string & prefix) const715 void CClientProxyCodeEmitter::EmitProxyCheckVersion(const std::string &clientObjName, const std::string &serMajorName,
716     const std::string &serMinorName, StringBuilder &sb, const std::string &prefix) const
717 {
718     sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
719     sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
720     sb.Append(prefix).AppendFormat("int32_t %s = %s->GetVersion(%s, &%s, &%s);\n", errorCodeName_.c_str(),
721         clientObjName.c_str(), clientObjName.c_str(), serMajorName.c_str(), serMinorName.c_str());
722     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
723     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: get version failed!\", __func__);\n");
724     if (mode_ == GenMode::KERNEL) {
725         sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
726     } else if (interface_->IsCallback()) {
727         sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
728     } else {
729         sb.Append(prefix + TAB).AppendFormat("%sRelease(false, %s);\n", interfaceName_.c_str(), clientObjName.c_str());
730     }
731 
732     sb.Append(prefix + TAB).Append("return NULL;\n");
733     sb.Append(prefix).Append("}\n\n");
734     sb.Append(prefix).AppendFormat("if (%s != %s) {\n", serMajorName.c_str(), majorVerName_.c_str());
735     sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
736     sb.Append("version of service:%u.%u, version of client:%u.%u\", __func__,\n");
737     sb.Append(prefix + TAB + TAB).AppendFormat("%s, %s, %s, %s);\n", serMajorName.c_str(), serMinorName.c_str(),
738         majorVerName_.c_str(), minorVerName_.c_str());
739     if (mode_ == GenMode::KERNEL) {
740         sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
741     } else if (interface_->IsCallback()) {
742         sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
743     } else {
744         sb.Append(prefix + TAB).AppendFormat("%sRelease(false, %s);\n", interfaceName_.c_str(), clientObjName.c_str());
745     }
746     sb.Append(prefix + TAB).Append("return NULL;\n");
747     sb.Append(prefix).Append("}\n");
748 }
749 
EmitProxyReleaseMethodImpl(StringBuilder & sb) const750 void CClientProxyCodeEmitter::EmitProxyReleaseMethodImpl(StringBuilder &sb) const
751 {
752     sb.AppendFormat(
753         "void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
754     sb.Append("{\n");
755     sb.Append(TAB).AppendFormat(
756         "%sReleaseInstance(\"%s\", instance, isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
757     sb.Append("}\n");
758 }
759 
EmitProxyReleaseInstanceMethodImpl(const std::string & serviceName,const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb)760 void CClientProxyCodeEmitter::EmitProxyReleaseInstanceMethodImpl(const std::string &serviceName,
761     const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb)
762 {
763     sb.AppendFormat("void %sReleaseInstance(const char *%s, struct %s *instance, bool isStub)\n",
764         interfaceName_.c_str(), serviceName.c_str(), interfaceName_.c_str());
765     sb.Append("{\n");
766     sb.Append(TAB).Append("if (instance == NULL) {\n");
767     sb.Append(TAB).Append(TAB).Append("return;\n");
768     sb.Append(TAB).Append("}\n\n");
769     EmitProxyLoadOrUnLoadHdiImpl(serviceName, false, sb, TAB);
770     sb.Append("\n");
771     sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
772         baseName_.c_str(), baseName_.c_str());
773     sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
774     sb.Append(TAB).Append("OsalMemFree(proxy);\n");
775     sb.Append("}\n");
776 }
777 
EmitProxyLoadOrUnLoadHdiImpl(const std::string & serviceName,bool isLoad,StringBuilder & sb,const std::string & prefix) const778 void CClientProxyCodeEmitter::EmitProxyLoadOrUnLoadHdiImpl(const std::string &serviceName, bool isLoad,
779     StringBuilder &sb, const std::string &prefix) const
780 {
781     std::string instName = "instName";
782     sb.Append(prefix).Append("if (isStub) {\n");
783     sb.Append(prefix + TAB).AppendFormat("const char *%s = %s;\n", instName.c_str(), serviceName.c_str());
784     sb.Append(prefix + TAB)
785         .AppendFormat("if (strcmp(%s, \"%s\") == 0) {\n", instName.c_str(), FileName(implName_).c_str());
786     sb.Append(prefix + TAB + TAB).AppendFormat("%s = \"service\";\n", instName.c_str());
787     sb.Append(prefix + TAB).Append("}\n");
788     if (isLoad) {
789         sb.Append(prefix + TAB).AppendFormat("return LoadHdiImpl(%s, %s);\n",
790             interface_->EmitDescMacroName().c_str(), instName.c_str());
791     } else {
792         sb.Append(prefix + TAB).AppendFormat("UnloadHdiImpl(%s, %s, instance);\n",
793             interface_->EmitDescMacroName().c_str(), instName.c_str());
794         sb.Append(prefix + TAB).Append("return;\n");
795     }
796     sb.Append(prefix).Append("}\n");
797 }
798 
GetUtilMethods(UtilMethodMap & methods)799 void CClientProxyCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
800 {
801     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
802         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
803             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
804             AutoPtr<ASTType> paramType = param->GetType();
805             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
806                 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(),
807                     SerMode::PROXY_SER, methods);
808             } else {
809                 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
810             }
811         }
812     }
813 }
814 } // namespace HDI
815 } // namespace OHOS
816