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