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