1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "c_client_proxy_code_emitter.h"
17 #include "util/file.h"
18 #include "util/logger.h"
19
20 namespace OHOS {
21 namespace Idl {
ResolveDirectory(const std::string & targetDirectory)22 bool CClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
23 {
24 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
25 directory_ = GetFileParentPath(targetDirectory);
26 } else {
27 return false;
28 }
29
30 if (!File::CreateParentDir(directory_)) {
31 Logger::E("CClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
32 return false;
33 }
34
35 return true;
36 }
37
EmitCode()38 void CClientProxyCodeEmitter::EmitCode()
39 {
40 switch (mode_) {
41 case GenMode::PASSTHROUGH: {
42 if (!interface_->IsSerializable()) {
43 EmitPassthroughProxySourceFile();
44 }
45 break;
46 }
47 case GenMode::IPC:
48 case GenMode::KERNEL: {
49 EmitProxySourceFile();
50 break;
51 }
52 default:
53 break;
54 }
55 }
56
EmitPassthroughProxySourceFile()57 void CClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
58 {
59 std::string filePath =
60 File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(proxyName_).c_str()));
61 File file(filePath, File::WRITE);
62 StringBuilder sb;
63
64 EmitLicense(sb);
65 EmitPassthroughProxyInclusions(sb);
66 sb.Append("\n");
67 EmitLogTagMacro(sb, FileName(proxyName_));
68 sb.Append("\n");
69 EmitProxyGetMethodImpl(sb);
70 sb.Append("\n");
71 EmitPassthroughGetInstanceMethod(sb);
72 sb.Append("\n");
73 EmitProxyReleaseMethodImpl(sb);
74 sb.Append("\n");
75 EmitPassthroughReleaseInstanceMethod(sb);
76 std::string data = sb.ToString();
77 file.WriteData(data.c_str(), data.size());
78 file.Flush();
79 file.Close();
80 }
81
EmitPassthroughProxyInclusions(StringBuilder & sb)82 void CClientProxyCodeEmitter::EmitPassthroughProxyInclusions(StringBuilder &sb)
83 {
84 HeaderFile::HeaderFileSet headerFiles;
85 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
86 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
87 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
88
89 for (const auto &file : headerFiles) {
90 sb.AppendFormat("%s\n", file.ToString().c_str());
91 }
92 }
93
EmitPassthroughGetInstanceMethod(StringBuilder & sb) const94 void CClientProxyCodeEmitter::EmitPassthroughGetInstanceMethod(StringBuilder &sb) const
95 {
96 sb.AppendFormat("struct %s *%sGetInstance(const char *serviceName, bool isStub)\n",
97 interfaceName_.c_str(), interfaceName_.c_str());
98 sb.Append("{\n");
99 EmitProxyLoadOrUnLoadHdiImpl("serviceName", true, sb, TAB);
100 sb.Append(TAB).Append("return NULL;\n");
101 sb.Append("}\n");
102 }
103
EmitPassthroughReleaseInstanceMethod(StringBuilder & sb) const104 void CClientProxyCodeEmitter::EmitPassthroughReleaseInstanceMethod(StringBuilder &sb) const
105 {
106 sb.AppendFormat("void %sReleaseInstance(const char *serviceName, struct %s *instance, bool isStub)\n",
107 interfaceName_.c_str(), interfaceName_.c_str());
108 sb.Append("{\n");
109 sb.Append(TAB).Append("if (instance == NULL) {\n");
110 sb.Append(TAB).Append(TAB).Append("return;\n");
111 sb.Append(TAB).Append("}\n\n");
112 EmitProxyLoadOrUnLoadHdiImpl("serviceName", false, sb, TAB);
113 sb.Append("}\n");
114 }
115
EmitProxySourceFile()116 void CClientProxyCodeEmitter::EmitProxySourceFile()
117 {
118 std::string filePath =
119 File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(proxyName_).c_str()));
120 File file(filePath, File::WRITE);
121 StringBuilder sb;
122
123 EmitLicense(sb);
124 EmitProxyInclusions(sb);
125 sb.Append("\n");
126 EmitLogTagMacro(sb, FileName(proxyName_));
127 sb.Append("\n");
128 EmitProxyDefinition(sb);
129 sb.Append("\n");
130 EmitUtilMethods(sb, true);
131 sb.Append("\n");
132 EmitUtilMethods(sb, false);
133 sb.Append("\n");
134 if (mode_ != GenMode::KERNEL) {
135 EmitProxyCallMethodImpl(sb);
136 } else {
137 EmitProxyKernelCallMethodImpl(sb);
138 }
139 sb.Append("\n");
140 EmitProxyMethodImpls(sb);
141 sb.Append("\n");
142 EmitProxyConstruction(sb);
143 sb.Append("\n");
144 EmitProxyExternalMethodImpl(sb);
145
146 std::string data = sb.ToString();
147 file.WriteData(data.c_str(), data.size());
148 file.Flush();
149 file.Close();
150 }
151
EmitProxyInclusions(StringBuilder & sb)152 void CClientProxyCodeEmitter::EmitProxyInclusions(StringBuilder &sb)
153 {
154 HeaderFile::HeaderFileSet headerFiles;
155
156 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
157 GetHeaderOtherLibInclusions(headerFiles);
158
159 for (const auto &file : headerFiles) {
160 sb.AppendFormat("%s\n", file.ToString().c_str());
161 }
162 }
163
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const164 void CClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
165 {
166 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
167 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
168 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
169 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
170 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
171
172 if (mode_ == GenMode::KERNEL) {
173 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_io_service_if");
174 } else {
175 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "servmgr_hdi");
176 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist");
177 if (!interface_->IsSerializable()) {
178 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
179 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
180 }
181 }
182
183 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
184 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
185 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
186 AutoPtr<ASTType> paramType = param->GetType();
187 if ((param->GetAttribute() == ASTParamAttr::PARAM_IN) &&
188 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
189 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
190 }
191 }
192 }
193 }
194
EmitProxyDefinition(StringBuilder & sb) const195 void CClientProxyCodeEmitter::EmitProxyDefinition(StringBuilder &sb) const
196 {
197 sb.AppendFormat("struct %sProxy {\n", baseName_.c_str());
198 sb.Append(TAB).AppendFormat("struct %s impl;\n", interfaceName_.c_str());
199 if (mode_ == GenMode::KERNEL) {
200 sb.Append(TAB).Append("struct HdfIoService *serv;\n");
201 } else {
202 sb.Append(TAB).Append("struct HdfRemoteService *remote;\n");
203 }
204
205 sb.Append("};\n");
206 }
207
EmitProxyCallMethodImpl(StringBuilder & sb) const208 void CClientProxyCodeEmitter::EmitProxyCallMethodImpl(StringBuilder &sb) const
209 {
210 sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n",
211 baseName_.c_str(), interfaceName_.c_str());
212 sb.Append(TAB).Append("struct HdfSBuf *reply, bool isOneWay)\n");
213 sb.Append("{\n");
214
215 std::string remoteName = "remote";
216 sb.Append(TAB).AppendFormat("struct HdfRemoteService *%s = self->AsObject(self);\n", remoteName.c_str());
217 sb.Append(TAB).AppendFormat("if (%s == NULL ||\n", remoteName.c_str());
218 sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher == NULL ||\n", remoteName.c_str());
219 sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->Dispatch == NULL ||\n", remoteName.c_str());
220 sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->DispatchAsync == NULL) {\n", remoteName.c_str());
221 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n");
222 sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
223 sb.Append(TAB).Append("}\n");
224
225 sb.Append(TAB).AppendFormat("if (isOneWay) {\n");
226 sb.Append(TAB).Append(TAB).AppendFormat(
227 "return %s->dispatcher->DispatchAsync(%s, id, data, reply);\n", remoteName.c_str(), remoteName.c_str());
228 sb.Append(TAB).AppendFormat("} else {\n");
229 sb.Append(TAB).Append(TAB).AppendFormat(
230 "return %s->dispatcher->Dispatch(%s, id, data, reply);\n", remoteName.c_str(), remoteName.c_str());
231 sb.Append(TAB).AppendFormat("}\n");
232 sb.Append("}\n");
233 }
234
EmitProxyKernelCallMethodImpl(StringBuilder & sb) const235 void CClientProxyCodeEmitter::EmitProxyKernelCallMethodImpl(StringBuilder &sb) const
236 {
237 sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n",
238 baseName_.c_str(), interfaceName_.c_str());
239 sb.Append(TAB).Append("struct HdfSBuf *reply)\n");
240 sb.Append("{\n");
241
242 std::string remoteName = "serv";
243 sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n",
244 baseName_.c_str(), baseName_.c_str(), remoteName.c_str());
245 sb.Append(TAB).AppendFormat("struct HdfIoService *%s = proxy->%s;\n", remoteName.c_str(), remoteName.c_str());
246
247 sb.Append(TAB).AppendFormat("if (%s == NULL ||\n", remoteName.c_str());
248 sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher == NULL ||\n", remoteName.c_str());
249 sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->Dispatch == NULL) {\n", remoteName.c_str());
250 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n");
251 sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
252 sb.Append(TAB).Append("}\n\n");
253
254 sb.Append(TAB).AppendFormat("return %s->dispatcher->Dispatch(", remoteName.c_str());
255 sb.AppendFormat("(struct HdfObject *)&(%s->object), id, data, reply);\n", remoteName.c_str());
256 sb.Append("}\n");
257 }
258
EmitProxyMethodImpls(StringBuilder & sb)259 void CClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb)
260 {
261 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
262 EmitProxyMethodImpl(method, sb);
263 sb.Append("\n");
264 }
265
266 EmitProxyMethodImpl(interface_->GetVersionMethod(), sb);
267
268 if (mode_ != GenMode::KERNEL) {
269 sb.Append("\n");
270 EmitProxyAsObjectMethodImpl(sb);
271 }
272 }
273
EmitProxyMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb)274 void CClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb)
275 {
276 if (method->GetParameterNumber() == 0) {
277 sb.AppendFormat("static int32_t %sProxy%s(struct %s *self)\n", baseName_.c_str(), method->GetName().c_str(),
278 interfaceName_.c_str());
279 } else {
280 StringBuilder paramStr;
281 paramStr.AppendFormat("static int32_t %sProxy%s(", baseName_.c_str(), method->GetName().c_str());
282 paramStr.AppendFormat("struct %s *self, ", interfaceName_.c_str());
283 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
284 AutoPtr<ASTParameter> param = method->GetParameter(i);
285 EmitInterfaceMethodParameter(param, paramStr, "");
286 if (i + 1 < method->GetParameterNumber()) {
287 paramStr.Append(", ");
288 }
289 }
290
291 paramStr.Append(")");
292 sb.Append(SpecificationParam(paramStr, TAB));
293 sb.Append("\n");
294 }
295 EmitProxyMethodBody(method, sb, "");
296 }
297
EmitProxyMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)298 void CClientProxyCodeEmitter::EmitProxyMethodBody(
299 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
300 {
301 sb.Append(prefix).Append("{\n");
302 sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_FAILURE;\n", HdiTypeEmitter::errorCodeName_.c_str());
303
304 // Local variable definitions must precede all execution statements.
305 EmitMethodNeedLoopVar(method, true, false, sb, prefix + TAB);
306 sb.Append("\n");
307 EmitCreateBuf(HdiTypeEmitter::dataParcelName_, HdiTypeEmitter::replyParcelName_, sb, prefix + TAB);
308 sb.Append("\n");
309 EmitCheckThisPointer(sb, prefix + TAB);
310
311 if (mode_ != GenMode::KERNEL) {
312 sb.Append("\n");
313 EmitWriteInterfaceToken(HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
314 }
315
316 sb.Append("\n");
317 EmitWriteFlagOfNeedSetMem(method, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
318 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
319 AutoPtr<ASTParameter> param = method->GetParameter(i);
320 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
321 if (typeEmitter == nullptr) {
322 continue;
323 }
324 if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
325 typeEmitter->EmitCWriteVar(TypeMode::PARAM_IN, param->GetName(), FINISHED_LABEL, sb, prefix + TAB);
326 sb.Append("\n");
327 } else {
328 typeEmitter->EmitCProxyWriteOutVar(param->GetName(), FINISHED_LABEL, sb, prefix + TAB);
329 }
330 }
331
332 EmitStubCallMethod(method, sb, prefix + TAB);
333 sb.Append("\n");
334
335 if (!method->IsOneWay()) {
336 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
337 AutoPtr<ASTParameter> param = method->GetParameter(i);
338 if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
339 EmitReadProxyMethodParameter(param, FINISHED_LABEL, sb, prefix + TAB);
340 sb.Append("\n");
341 }
342 }
343 }
344
345 sb.Append(prefix).AppendFormat("%s:\n", FINISHED_LABEL);
346 EmitReleaseBuf(HdiTypeEmitter::dataParcelName_, HdiTypeEmitter::replyParcelName_, sb, prefix + TAB);
347
348 sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
349 sb.Append("}\n");
350 }
351
EmitCreateBuf(const std::string & dataBufName,const std::string & replyBufName,StringBuilder & sb,const std::string & prefix) const352 void CClientProxyCodeEmitter::EmitCreateBuf(const std::string &dataBufName,
353 const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const
354 {
355 if (mode_ == GenMode::KERNEL) {
356 sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufObtainDefaultSize();\n", dataBufName.c_str());
357 sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufObtainDefaultSize();\n", replyBufName.c_str());
358 } else {
359 sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufTypedObtain(SBUF_IPC);\n", dataBufName.c_str());
360 sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufTypedObtain(SBUF_IPC);\n", replyBufName.c_str());
361 }
362
363 sb.Append("\n");
364 sb.Append(prefix).AppendFormat("if (%s == NULL || %s == NULL) {\n", dataBufName.c_str(), replyBufName.c_str());
365 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: HdfSubf malloc failed!\", __func__);\n");
366 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
367 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
368 sb.Append(prefix).Append("}\n");
369 }
370
EmitCheckThisPointer(StringBuilder & sb,const std::string & prefix) const371 void CClientProxyCodeEmitter::EmitCheckThisPointer(StringBuilder &sb, const std::string &prefix) const
372 {
373 sb.Append(prefix).Append("if (self == NULL) {\n");
374 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid interface object\", __func__);\n");
375 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_OBJECT;\n", HdiTypeEmitter::errorCodeName_.c_str());
376 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
377 sb.Append(prefix).Append("}\n");
378 }
379
EmitWriteInterfaceToken(const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const380 void CClientProxyCodeEmitter::EmitWriteInterfaceToken(
381 const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
382 {
383 sb.Append(prefix).AppendFormat(
384 "if (!HdfRemoteServiceWriteInterfaceToken(self->AsObject(self), %s)) {\n", dataBufName.c_str());
385 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: write interface token failed!\", __func__);\n");
386 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
387 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
388 sb.Append(prefix).Append("}\n");
389 }
390
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const391 void CClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
392 const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
393 {
394 if (NeedFlag(method)) {
395 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint8(%s, 1)) {\n", dataBufName.c_str());
396 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: write flag of memory setting failed!\", __func__);\n");
397 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
398 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
399 sb.Append(prefix).Append("}\n\n");
400 }
401 }
402
EmitReleaseBuf(const std::string & dataBufName,const std::string & replyBufName,StringBuilder & sb,const std::string & prefix) const403 void CClientProxyCodeEmitter::EmitReleaseBuf(const std::string &dataBufName,
404 const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const
405 {
406 sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", dataBufName.c_str());
407 sb.Append(prefix + TAB).AppendFormat("HdfSbufRecycle(%s);\n", dataBufName.c_str());
408 sb.Append(prefix).Append("}\n");
409 sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", replyBufName.c_str());
410 sb.Append(prefix + TAB).AppendFormat("HdfSbufRecycle(%s);\n", replyBufName.c_str());
411 sb.Append(prefix).Append("}\n");
412 }
413
EmitReadProxyMethodParameter(const AutoPtr<ASTParameter> & param,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const414 void CClientProxyCodeEmitter::EmitReadProxyMethodParameter(const AutoPtr<ASTParameter> ¶m,
415 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
416 {
417 AutoPtr<ASTType> type = param->GetType();
418 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
419 if (typeEmitter == nullptr) {
420 return;
421 }
422 std::string name = param->GetName();
423 if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
424 std::string cloneName = StringHelper::Format("%sCopy", name.c_str());
425 typeEmitter->EmitCProxyReadVar(cloneName, false, gotoLabel, sb, prefix);
426 sb.Append(prefix).AppendFormat("if (strcpy_s(%s, %sLen, %s) != EOK) {\n", name.c_str(),
427 name.c_str(), cloneName.c_str());
428 sb.Append(prefix + TAB)
429 .AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
430 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
431 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
432 sb.Append(prefix).Append("}\n");
433 } else if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
434 std::string cpName = StringHelper::Format("%sCp", name.c_str());
435 typeEmitter->EmitCProxyReadVar(cpName, false, gotoLabel, sb, prefix);
436 sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n",
437 name.c_str(), typeEmitter->EmitCType().c_str(), cpName.c_str(), typeEmitter->EmitCType().c_str());
438 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to memcpy %s\", __func__);\n",
439 name.c_str());
440 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
441 sb.Append(prefix).Append("}\n");
442 } else {
443 typeEmitter->EmitCProxyReadVar(name, false, gotoLabel, sb, prefix);
444 }
445 }
446
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)447 void CClientProxyCodeEmitter::EmitStubCallMethod(
448 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
449 {
450 if (mode_ != GenMode::KERNEL) {
451 sb.Append(prefix).AppendFormat("%s = %sCall(self, %s, %s, %s, %s);\n", HdiTypeEmitter::errorCodeName_.c_str(),
452 proxyName_.c_str(), EmitMethodCmdID(method).c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
453 HdiTypeEmitter::replyParcelName_.c_str(),
454 method->IsOneWay() ? "true" : "false");
455 } else {
456 sb.Append(prefix).AppendFormat("%s = %sCall(self, %s, %s, %s);\n", HdiTypeEmitter::errorCodeName_.c_str(),
457 proxyName_.c_str(), EmitMethodCmdID(method).c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
458 HdiTypeEmitter::replyParcelName_.c_str());
459 }
460 sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
461 sb.Append(prefix + TAB).AppendFormat(
462 "HDF_LOGE(\"%%{public}s: call failed! error code is %%{public}d\", __func__, %s);\n",
463 HdiTypeEmitter::errorCodeName_.c_str());
464 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", FINISHED_LABEL);
465 sb.Append(prefix).Append("}\n");
466 }
467
EmitProxyAsObjectMethodImpl(StringBuilder & sb) const468 void CClientProxyCodeEmitter::EmitProxyAsObjectMethodImpl(StringBuilder &sb) const
469 {
470 sb.AppendFormat("static struct HdfRemoteService *%sProxyAsObject(struct %s *self)\n", baseName_.c_str(),
471 interfaceName_.c_str());
472 sb.Append("{\n");
473 sb.Append(TAB).Append("if (self == NULL) {\n");
474 sb.Append(TAB).Append(TAB).Append("return NULL;\n");
475 sb.Append(TAB).Append("}\n");
476 sb.Append(TAB).AppendFormat(
477 "struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n", baseName_.c_str(), baseName_.c_str());
478 sb.Append(TAB).Append("return proxy->remote;\n");
479 sb.Append("}\n");
480 }
481
EmitProxyConstruction(StringBuilder & sb) const482 void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder &sb) const
483 {
484 std::string objName = "impl";
485 sb.AppendFormat(
486 "static void %sProxyConstruct(struct %s *%s)\n", baseName_.c_str(), interfaceName_.c_str(), objName.c_str());
487 sb.Append("{\n");
488
489 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
490 sb.Append(TAB).AppendFormat("%s->%s = %sProxy%s;\n", objName.c_str(), method->GetName().c_str(),
491 baseName_.c_str(), method->GetName().c_str());
492 }
493
494 AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
495 sb.Append(TAB).AppendFormat("%s->%s = %sProxy%s;\n", objName.c_str(), getVerMethod->GetName().c_str(),
496 baseName_.c_str(), getVerMethod->GetName().c_str());
497
498 if (mode_ != GenMode::KERNEL) {
499 sb.Append(TAB).AppendFormat("%s->AsObject = %sProxyAsObject;\n", objName.c_str(), baseName_.c_str());
500 }
501
502 sb.Append("}\n");
503 }
504
EmitProxyExternalMethodImpl(StringBuilder & sb)505 void CClientProxyCodeEmitter::EmitProxyExternalMethodImpl(StringBuilder &sb)
506 {
507 if (mode_ == GenMode::KERNEL) {
508 EmitKernelProxyExternalMethodImpl(sb);
509 } else if (interface_->IsSerializable()) {
510 EmitSerialProxyExternalMethodImpl(sb);
511 } else {
512 EmitProxyExternalMethod(sb);
513 }
514 }
515
EmitKernelProxyExternalMethodImpl(StringBuilder & sb)516 void CClientProxyCodeEmitter::EmitKernelProxyExternalMethodImpl(StringBuilder &sb)
517 {
518 std::string remoteName = "serv";
519
520 EmitKernelProxyGetMethodImpl(sb);
521 sb.Append("\n");
522 EmitKernelProxyGetInstanceMethodImpl(remoteName, sb);
523 sb.Append("\n");
524 EmitKernelProxyReleaseMethodImpl(remoteName, "HdfIoServiceRecycle", sb);
525 }
526
EmitKernelProxyGetMethodImpl(StringBuilder & sb) const527 void CClientProxyCodeEmitter::EmitKernelProxyGetMethodImpl(StringBuilder &sb) const
528 {
529 sb.AppendFormat("struct %s *%sGet()\n", interfaceName_.c_str(), interfaceName_.c_str());
530 sb.Append("{\n");
531 sb.Append(TAB).AppendFormat("return %sGetInstance(\"%s\");\n", interfaceName_.c_str(),
532 FileName(implName_).c_str());
533 sb.Append("}\n");
534 }
535
EmitKernelProxyGetInstanceMethodImpl(const std::string & remoteName,StringBuilder & sb) const536 void CClientProxyCodeEmitter::EmitKernelProxyGetInstanceMethodImpl(const std::string &remoteName,
537 StringBuilder &sb) const
538 {
539 std::string objName = "client";
540 std::string serMajorName = "serMajorVer";
541 std::string serMinorName = "serMinorVer";
542 std::string serviceName = "serviceName";
543
544 sb.AppendFormat("struct %s *%sGetInstance(const char* %s)\n", interfaceName_.c_str(), interfaceName_.c_str(),
545 serviceName.c_str());
546 sb.Append("{\n");
547 EmitProxyGetRemoteService(remoteName, serviceName, sb, TAB);
548 sb.Append("\n");
549 EmitProxyCreateProxyObject(objName, remoteName, "HdfIoServiceRecycle", sb, TAB);
550 sb.Append("\n");
551 EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
552 sb.Append("\n");
553 sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
554 sb.Append("}\n");
555 }
556
EmitKernelProxyReleaseMethodImpl(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb) const557 void CClientProxyCodeEmitter::EmitKernelProxyReleaseMethodImpl(
558 const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const
559 {
560 sb.AppendFormat("void %sRelease(struct %s *instance)\n", interfaceName_.c_str(), interfaceName_.c_str());
561 sb.Append("{\n");
562 sb.Append(TAB).Append("if (instance == NULL) {\n");
563 sb.Append(TAB).Append(TAB).Append("return;\n");
564 sb.Append(TAB).Append("}\n");
565 sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
566 baseName_.c_str(), baseName_.c_str());
567 sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
568 sb.Append(TAB).Append("OsalMemFree(proxy);\n");
569 sb.Append("}\n");
570 }
571
EmitSerialProxyExternalMethodImpl(StringBuilder & sb)572 void CClientProxyCodeEmitter::EmitSerialProxyExternalMethodImpl(StringBuilder &sb)
573 {
574 std::string serMajorName = "serMajorVer";
575 std::string serMinorName = "serMinorVer";
576 std::string remoteName = "remote";
577
578 EmitIfaceProxyGetMethodImpl(serMajorName, serMinorName, remoteName, sb);
579 sb.Append("\n");
580
581 if (interface_->IsCallback()) {
582 EmitCbProxyReleaseMethodImpl(remoteName, "HdfRemoteServiceRecycle", sb);
583 } else {
584 EmitIfaceProxyReleaseMethodImpl(remoteName, "HdfRemoteServiceRecycle", sb);
585 }
586 }
587
EmitIfaceProxyGetMethodImpl(const std::string & serMajorName,const std::string & serMinorName,const std::string & remoteName,StringBuilder & sb)588 void CClientProxyCodeEmitter::EmitIfaceProxyGetMethodImpl(const std::string &serMajorName,
589 const std::string &serMinorName, const std::string &remoteName, StringBuilder &sb)
590 {
591 std::string objName = "client";
592 sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *%s)\n", interfaceName_.c_str(), interfaceName_.c_str(),
593 remoteName.c_str());
594 sb.Append("{\n");
595 sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
596 sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: remote is null\", __func__);\n");
597 sb.Append(TAB).Append(TAB).Append("return NULL;\n");
598 sb.Append(TAB).Append("}\n\n");
599 EmitProxySetInterfaceDesc(remoteName, "HdfRemoteServiceRecycle", sb, TAB);
600 sb.Append("\n");
601 EmitProxyCreateProxyObject(objName, remoteName, "HdfRemoteServiceRecycle", sb, TAB);
602 sb.Append("\n");
603 EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
604 sb.Append("\n");
605 sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
606 sb.Append("}\n");
607 }
608
EmitIfaceProxyReleaseMethodImpl(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb) const609 void CClientProxyCodeEmitter::EmitIfaceProxyReleaseMethodImpl(
610 const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const
611 {
612 std::string implReleaseMethodName = StringHelper::Format("%sImplRelease", interfaceName_.c_str());
613 sb.AppendFormat("void %s(struct %s *instance) __attribute__((weak));\n", implReleaseMethodName.c_str(),
614 interfaceName_.c_str());
615 sb.AppendFormat("void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(),
616 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");
621
622 sb.Append(TAB).Append("if (isStub) {\n");
623 sb.Append(TAB).Append(TAB).AppendFormat("if (%s != NULL) {\n", implReleaseMethodName.c_str());
624 sb.Append(TAB).Append(TAB).Append(TAB).AppendFormat("%s(instance);\n", implReleaseMethodName.c_str());
625 sb.Append(TAB).Append(TAB).Append("}\n");
626 sb.Append(TAB).Append(TAB).Append("return;\n");
627 sb.Append(TAB).Append("}\n");
628
629 sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
630 baseName_.c_str(), baseName_.c_str());
631 sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
632 sb.Append(TAB).Append("OsalMemFree(proxy);\n");
633 sb.Append("}\n");
634 }
635
EmitCbProxyReleaseMethodImpl(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb) const636 void CClientProxyCodeEmitter::EmitCbProxyReleaseMethodImpl(const std::string &remoteName,
637 const std::string &recycleFuncName, StringBuilder &sb) const
638 {
639 sb.AppendFormat("void %sRelease(struct %s *instance)\n", interfaceName_.c_str(), interfaceName_.c_str());
640 sb.Append("{\n");
641 sb.Append(TAB).Append("if (instance == NULL) {\n");
642 sb.Append(TAB).Append(TAB).Append("return;\n");
643 sb.Append(TAB).Append("}\n\n");
644 sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
645 baseName_.c_str(), baseName_.c_str());
646 sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
647 sb.Append(TAB).Append("OsalMemFree(proxy);\n");
648 sb.Append("}\n");
649 }
650
EmitProxyExternalMethod(StringBuilder & sb)651 void CClientProxyCodeEmitter::EmitProxyExternalMethod(StringBuilder &sb)
652 {
653 std::string remoteName = "remote";
654 std::string serviceName = "serviceName";
655
656 EmitProxyGetMethodImpl(sb);
657 sb.Append("\n");
658 EmitProxyGetInstanceMethodImpl(remoteName, serviceName, sb);
659 sb.Append("\n");
660 EmitProxyReleaseMethodImpl(sb);
661 sb.Append("\n");
662 EmitProxyReleaseInstanceMethodImpl(serviceName, remoteName, "HdfRemoteServiceRecycle", sb);
663 }
664
EmitProxyGetMethodImpl(StringBuilder & sb) const665 void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder &sb) const
666 {
667 sb.AppendFormat("struct %s *%sGet(bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
668 sb.Append("{\n");
669 sb.Append(TAB).AppendFormat("return %sGetInstance(\"%s\", isStub);\n", interfaceName_.c_str(),
670 FileName(implName_).c_str());
671 sb.Append("}\n");
672 }
673
EmitProxyGetInstanceMethodImpl(const std::string & remoteName,const std::string & serviceName,StringBuilder & sb) const674 void CClientProxyCodeEmitter::EmitProxyGetInstanceMethodImpl(const std::string &remoteName,
675 const std::string &serviceName, StringBuilder &sb) const
676 {
677 std::string objName = "client";
678 std::string serMajorName = "serMajorVer";
679 std::string serMinorName = "serMinorVer";
680
681 sb.AppendFormat("struct %s *%sGetInstance(const char *%s, bool isStub)\n", interfaceName_.c_str(),
682 interfaceName_.c_str(), serviceName.c_str());
683 sb.Append("{\n");
684 EmitProxyLoadOrUnLoadHdiImpl(serviceName, true, sb, TAB);
685 sb.Append("\n");
686 EmitProxyGetRemoteService(remoteName, serviceName, sb, TAB);
687 sb.Append("\n");
688 EmitProxySetInterfaceDesc(remoteName, "HdfRemoteServiceRecycle", sb, TAB);
689 sb.Append("\n");
690 EmitProxyCreateProxyObject(objName, remoteName, "HdfRemoteServiceRecycle", sb, TAB);
691 sb.Append("\n");
692 EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
693 sb.Append("\n");
694 sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
695 sb.Append("}\n");
696 }
697
EmitProxyGetRemoteService(const std::string & remoteName,const std::string & serviceName,StringBuilder & sb,const std::string & prefix) const698 void CClientProxyCodeEmitter::EmitProxyGetRemoteService(const std::string &remoteName,
699 const std::string &serviceName, StringBuilder &sb, const std::string &prefix) const
700 {
701 if (mode_ != GenMode::KERNEL) {
702 sb.Append(prefix).Append("struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();\n");
703 sb.Append(prefix).Append("if (serviceMgr == NULL) {\n");
704 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: HDIServiceManager not found!\", __func__);\n");
705 sb.Append(prefix + TAB).Append("return NULL;\n");
706 sb.Append(prefix).Append("}\n\n");
707 sb.Append(prefix).AppendFormat("struct HdfRemoteService *%s = ", remoteName.c_str());
708 sb.AppendFormat("serviceMgr->GetService(serviceMgr, %s);\n", serviceName.c_str());
709 sb.Append(prefix).Append("HDIServiceManagerRelease(serviceMgr);\n");
710 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
711 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to get remote!\", __func__);\n");
712 sb.Append(prefix + TAB).Append("return NULL;\n");
713 sb.Append(prefix).Append("}\n");
714 } else {
715 sb.Append(prefix).AppendFormat("struct HdfIoService *%s = ", remoteName.c_str());
716 sb.AppendFormat("HdfIoServiceBind(%s);\n", serviceName.c_str());
717 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
718 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to get io service!\", __func__);\n");
719 sb.Append(prefix + TAB).Append("return NULL;\n");
720 sb.Append(prefix).Append("}\n");
721 }
722 }
723
EmitProxySetInterfaceDesc(const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb,const std::string & prefix) const724 void CClientProxyCodeEmitter::EmitProxySetInterfaceDesc(const std::string &remoteName,
725 const std::string &recycleFuncName, StringBuilder &sb, const std::string &prefix) const
726 {
727 sb.Append(prefix).AppendFormat("if (!HdfRemoteServiceSetInterfaceDesc(%s, %s)) {\n", remoteName.c_str(),
728 EmitDescMacroName().c_str());
729 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: set interface token failed!\", __func__);\n");
730 sb.Append(prefix + TAB).AppendFormat("%s(%s);\n", recycleFuncName.c_str(), remoteName.c_str());
731 sb.Append(prefix + TAB).Append("return NULL;\n");
732 sb.Append(prefix).Append("}\n");
733 }
734
EmitProxyCreateProxyObject(const std::string & clientObjName,const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb,const std::string & prefix) const735 void CClientProxyCodeEmitter::EmitProxyCreateProxyObject(const std::string &clientObjName,
736 const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb,
737 const std::string &prefix) const
738 {
739 sb.Append(prefix).AppendFormat("struct %sProxy *proxy = (struct %sProxy *)OsalMemCalloc(sizeof(struct %sProxy));\n",
740 baseName_.c_str(), baseName_.c_str(), baseName_.c_str());
741 sb.Append(prefix).Append("if (proxy == NULL) {\n");
742 sb.Append(prefix + TAB)
743 .AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.c_str());
744 if (!interface_->IsSerializable()) {
745 sb.Append(prefix + TAB).AppendFormat("%s(%s);\n", recycleFuncName.c_str(), remoteName.c_str());
746 }
747 sb.Append(prefix + TAB).Append("return NULL;\n");
748 sb.Append(prefix).Append("}\n");
749 sb.Append("\n");
750 sb.Append(prefix).AppendFormat("proxy->%s = %s;\n", remoteName.c_str(), remoteName.c_str());
751 sb.Append(prefix).AppendFormat("%sProxyConstruct(&proxy->impl);\n", baseName_.c_str());
752 sb.Append(prefix).AppendFormat("struct %s *%s = &proxy->impl;\n", interfaceName_.c_str(), clientObjName.c_str());
753 }
754
EmitProxyCheckVersion(const std::string & clientObjName,const std::string & serMajorName,const std::string & serMinorName,StringBuilder & sb,const std::string & prefix) const755 void CClientProxyCodeEmitter::EmitProxyCheckVersion(const std::string &clientObjName, const std::string &serMajorName,
756 const std::string &serMinorName, StringBuilder &sb, const std::string &prefix) const
757 {
758 sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
759 sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
760 sb.Append(prefix).AppendFormat("int32_t %s = %s->GetVersion(%s, &%s, &%s);\n",
761 HdiTypeEmitter::errorCodeName_.c_str(), clientObjName.c_str(),
762 clientObjName.c_str(), serMajorName.c_str(), serMinorName.c_str());
763 sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
764 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: get version failed!\", __func__);\n");
765 if (mode_ == GenMode::KERNEL || interface_->IsCallback()) {
766 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
767 } else if (mode_ == GenMode::PASSTHROUGH || loadVersionCheck_) {
768 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s, true);\n", interfaceName_.c_str(), clientObjName.c_str());
769 } else {
770 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s, false);\n", interfaceName_.c_str(), clientObjName.c_str());
771 }
772
773 sb.Append(prefix + TAB).Append("return NULL;\n").Append(prefix).Append("}\n\n");
774 sb.Append(prefix).AppendFormat("if (%s != %s) {\n", serMajorName.c_str(), majorVerName_.c_str());
775 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
776 sb.Append("version of service:%u.%u, version of client:%u.%u\", __func__,\n");
777 sb.Append(prefix + TAB + TAB).AppendFormat("%s, %s, %s, %s);\n", serMajorName.c_str(), serMinorName.c_str(),
778 majorVerName_.c_str(), minorVerName_.c_str());
779 if (mode_ == GenMode::KERNEL || interface_->IsCallback()) {
780 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
781 } else if (mode_ == GenMode::PASSTHROUGH || loadVersionCheck_) {
782 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s, true);\n", interfaceName_.c_str(), clientObjName.c_str());
783 } else {
784 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s, false);\n", interfaceName_.c_str(), clientObjName.c_str());
785 }
786 sb.Append(prefix + TAB).Append("return NULL;\n").Append(prefix).Append("}\n\n");
787 sb.Append(prefix).AppendFormat("if (%s < %s) {\n", serMinorName.c_str(), minorVerName_.c_str());
788 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
789 sb.Append("client minor version(%u) should be less \"\n");
790 sb.Append(prefix + TAB + TAB).Append("\"or equal to server minor version(%u).");
791 sb.AppendFormat("\", __func__, %s, %s);\n", minorVerName_.c_str(), serMinorName.c_str());
792 if (mode_ == GenMode::KERNEL || interface_->IsCallback()) {
793 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
794 } else if (mode_ == GenMode::PASSTHROUGH || loadVersionCheck_) {
795 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s, true);\n", interfaceName_.c_str(), clientObjName.c_str());
796 } else {
797 sb.Append(prefix + TAB).AppendFormat("%sRelease(%s, false);\n", interfaceName_.c_str(), clientObjName.c_str());
798 }
799 sb.Append(prefix + TAB).Append("return NULL;\n").Append(prefix).Append("}\n");
800 }
801
EmitProxyReleaseMethodImpl(StringBuilder & sb) const802 void CClientProxyCodeEmitter::EmitProxyReleaseMethodImpl(StringBuilder &sb) const
803 {
804 sb.AppendFormat(
805 "void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
806 sb.Append("{\n");
807 sb.Append(TAB).AppendFormat(
808 "%sReleaseInstance(\"%s\", instance, isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
809 sb.Append("}\n");
810 }
811
EmitProxyReleaseInstanceMethodImpl(const std::string & serviceName,const std::string & remoteName,const std::string & recycleFuncName,StringBuilder & sb)812 void CClientProxyCodeEmitter::EmitProxyReleaseInstanceMethodImpl(const std::string &serviceName,
813 const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb)
814 {
815 sb.AppendFormat("void %sReleaseInstance(const char *%s, struct %s *instance, bool isStub)\n",
816 interfaceName_.c_str(), serviceName.c_str(), interfaceName_.c_str());
817 sb.Append("{\n");
818 sb.Append(TAB).Append("if (instance == NULL) {\n");
819 sb.Append(TAB).Append(TAB).Append("return;\n");
820 sb.Append(TAB).Append("}\n\n");
821 EmitProxyLoadOrUnLoadHdiImpl(serviceName, false, sb, TAB);
822 sb.Append("\n");
823 sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
824 baseName_.c_str(), baseName_.c_str());
825 sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
826 sb.Append(TAB).Append("OsalMemFree(proxy);\n");
827 sb.Append("}\n");
828 }
829
EmitProxyLoadOrUnLoadHdiImpl(const std::string & serviceName,bool isLoad,StringBuilder & sb,const std::string & prefix) const830 void CClientProxyCodeEmitter::EmitProxyLoadOrUnLoadHdiImpl(const std::string &serviceName, bool isLoad,
831 StringBuilder &sb, const std::string &prefix) const
832 {
833 std::string instName = "instName";
834 sb.Append(prefix).Append("if (isStub) {\n");
835 sb.Append(prefix + TAB).AppendFormat("const char *%s = %s;\n", instName.c_str(), serviceName.c_str());
836 sb.Append(prefix + TAB)
837 .AppendFormat("if (strcmp(%s, \"%s\") == 0) {\n", instName.c_str(), FileName(implName_).c_str());
838 sb.Append(prefix + TAB + TAB).AppendFormat("%s = \"service\";\n", instName.c_str());
839 sb.Append(prefix + TAB).Append("}\n");
840 if (isLoad) {
841 std::string objName = "inst";
842 std::string serMajorName = "serMajorVer";
843 std::string serMinorName = "serMinorVer";
844
845 sb.Append(prefix + TAB).AppendFormat("struct %s *inst = LoadHdiImpl(%s, %s);\n",
846 interfaceName_.c_str(), EmitDescMacroName().c_str(), instName.c_str());
847 sb.Append(prefix + TAB).Append("if (inst == NULL) {\n");
848 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s, failed to load hdi "
849 "impl %%{public}s!\", __func__, %s);\n", EmitDescMacroName().c_str());
850
851 sb.Append(prefix + TAB + TAB).Append("return NULL;\n").Append(prefix + TAB).Append("}\n");
852 sb.Append(prefix + TAB).Append("if (inst->GetVersion == NULL) {\n");
853
854 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: "
855 "GetVersion is not implemented!\", __func__);\n");
856 if (mode_ == GenMode::KERNEL) {
857 sb.Append(prefix + TAB + TAB).AppendFormat("%sRelease(%s);\n", \
858 interfaceName_.c_str(), objName.c_str());
859 } else if (interface_->IsCallback()) {
860 sb.Append(prefix + TAB + TAB).AppendFormat("%sRelease(%s);\n", \
861 interfaceName_.c_str(), objName.c_str());
862 } else if (mode_ == GenMode::PASSTHROUGH || isLoad) {
863 sb.Append(prefix + TAB + TAB).AppendFormat("%sRelease(%s, true);\n", \
864 interfaceName_.c_str(), objName.c_str());
865 } else {
866 sb.Append(prefix + TAB + TAB).AppendFormat("%sRelease(%s, false);\n", \
867 interfaceName_.c_str(), objName.c_str());
868 }
869 sb.Append(prefix + TAB + TAB).Append("return NULL;\n").Append(prefix + TAB).Append("}\n");
870 loadVersionCheck_ = true;
871 EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, prefix + TAB);
872 loadVersionCheck_ = false;
873 sb.Append(prefix + TAB).Append("return inst;\n");
874 } else {
875 sb.Append(prefix + TAB).AppendFormat("UnloadHdiImpl(%s, %s, instance);\n",
876 EmitDescMacroName().c_str(), instName.c_str());
877 sb.Append(prefix + TAB).Append("return;\n");
878 }
879 sb.Append(prefix).Append("}\n");
880 }
881
EmitUtilMethods(StringBuilder & sb,bool isDecl)882 void CClientProxyCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
883 {
884 UtilMethodMap methods;
885 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
886 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
887 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
888 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
889 if (typeEmitter == nullptr) {
890 continue;
891 }
892 if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
893 typeEmitter->EmitCWriteMethods(methods, "", "", isDecl);
894 } else {
895 typeEmitter->EmitCReadMethods(methods, "", "", isDecl);
896 }
897 }
898 }
899 EmitUtilMethodMap(sb, methods);
900 }
901 } // namespace Idl
902 } // namespace OHOS
903