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> ¶m,
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