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/cpp_service_stub_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 CppServiceStubCodeEmitter::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("CppServiceStubCodeEmitter", "Create '%s' failed!", directory_.c_str());
25 return false;
26 }
27
28 return true;
29 }
30
EmitCode()31 void CppServiceStubCodeEmitter::EmitCode()
32 {
33 if (mode_ == GenMode::IPC) {
34 EmitStubHeaderFile();
35 EmitStubSourceFile();
36 }
37 }
38
EmitStubHeaderFile()39 void CppServiceStubCodeEmitter::EmitStubHeaderFile()
40 {
41 std::string filePath =
42 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(stubName_).c_str()));
43 File file(filePath, File::WRITE);
44 StringBuilder sb;
45
46 EmitLicense(sb);
47 EmitHeadMacro(sb, stubFullName_);
48 sb.Append("\n");
49 EmitStubHeaderInclusions(sb);
50 sb.Append("\n");
51 EmitStubDecl(sb);
52 sb.Append("\n");
53 EmitTailMacro(sb, stubFullName_);
54
55 std::string data = sb.ToString();
56 file.WriteData(data.c_str(), data.size());
57 file.Flush();
58 file.Close();
59 }
60
EmitStubHeaderInclusions(StringBuilder & sb)61 void CppServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb)
62 {
63 HeaderFile::HeaderFileSet headerFiles;
64
65 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
66 if (interface_->GetExtendsInterface() != nullptr) {
67 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE,
68 EmitHeaderNameByInterface(interface_->GetExtendsInterface(), stubName_));
69 }
70 GetHeaderOtherLibInclusions(headerFiles);
71
72 for (const auto &file : headerFiles) {
73 sb.AppendFormat("%s\n", file.ToString().c_str());
74 }
75 }
76
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const77 void CppServiceStubCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
78 {
79 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
80 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
81 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "ipc_object_stub");
82 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
83 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "refbase");
84 }
85
EmitStubDecl(StringBuilder & sb)86 void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder &sb)
87 {
88 EmitBeginNamespace(sb);
89 sb.Append("\n");
90 EmitStubUsingNamespace(sb);
91 sb.AppendFormat("class %s : public IPCObjectStub {\n", stubName_.c_str());
92 EmitStubBody(sb, TAB);
93 sb.Append("};\n");
94 EmitEndNamespace(sb);
95 }
96
EmitStubUsingNamespace(StringBuilder & sb) const97 void CppServiceStubCodeEmitter::EmitStubUsingNamespace(StringBuilder &sb) const
98 {
99 sb.Append("using namespace OHOS;\n");
100 }
101
EmitStubBody(StringBuilder & sb,const std::string & prefix) const102 void CppServiceStubCodeEmitter::EmitStubBody(StringBuilder &sb, const std::string &prefix) const
103 {
104 sb.Append("public:\n");
105 EmitStubConstructorDecl(sb, prefix);
106 sb.Append("\n");
107 EmitStubOnRequestDecl(sb, prefix);
108 sb.Append("\n");
109 EmitStubMethodDecls(sb, prefix);
110 sb.Append("\n");
111 EmitStubPrivateData(sb, prefix);
112 }
113
EmitStubConstructorDecl(StringBuilder & sb,const std::string & prefix) const114 void CppServiceStubCodeEmitter::EmitStubConstructorDecl(StringBuilder &sb, const std::string &prefix) const
115 {
116 sb.Append(prefix).AppendFormat("explicit %s(const sptr<%s> &impl);\n", stubName_.c_str(), interfaceName_.c_str());
117 sb.Append(prefix).AppendFormat("virtual ~%s();\n", stubName_.c_str());
118 }
119
EmitStubOnRequestDecl(StringBuilder & sb,const std::string & prefix) const120 void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder &sb, const std::string &prefix) const
121 {
122 sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, ");
123 sb.Append("MessageOption &option) override;\n");
124 }
125
EmitStubMethodDecls(StringBuilder & sb,const std::string & prefix) const126 void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix) const
127 {
128 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
129 EmitStubStaticMethodDecl(method, sb, prefix);
130 sb.Append("\n");
131 }
132 if (interface_->GetExtendsInterface() == nullptr) {
133 EmitStubStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
134 sb.Append("\n");
135 }
136
137 sb.Append("private:\n");
138 AutoPtr<ASTInterfaceType> interface = interface_;
139 while (interface != nullptr) {
140 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
141 EmitStubMethodDecl(method, sb, prefix);
142 sb.Append("\n");
143 }
144 interface = interface->GetExtendsInterface();
145 }
146 EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix);
147 sb.Append("\n");
148 }
149
EmitStubMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const150 void CppServiceStubCodeEmitter::EmitStubMethodDecl(
151 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
152 {
153 sb.Append(prefix).AppendFormat("int32_t %s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s);\n",
154 stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
155 optionName_.c_str());
156 }
157
EmitStubStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const158 void CppServiceStubCodeEmitter::EmitStubStaticMethodDecl(
159 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
160 {
161 sb.Append(prefix).AppendFormat(
162 "static int32_t %s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl);\n",
163 stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
164 optionName_.c_str(), EmitDefinitionByInterface(interface_, interfaceName_).c_str());
165 }
166
EmitStubPrivateData(StringBuilder & sb,const std::string & prefix) const167 void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const
168 {
169 sb.Append(prefix).AppendFormat("static inline ObjectDelegator<%s, %s> objDelegator_;\n",
170 EmitDefinitionByInterface(interface_, stubName_).c_str(),
171 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
172 sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
173 }
174
EmitStubSourceFile()175 void CppServiceStubCodeEmitter::EmitStubSourceFile()
176 {
177 std::string filePath =
178 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(stubName_).c_str()));
179 File file(filePath, File::WRITE);
180 StringBuilder sb;
181
182 EmitLicense(sb);
183 EmitStubSourceInclusions(sb);
184 sb.Append("\n");
185 EmitLogTagMacro(sb, FileName(stubName_));
186 sb.Append("\n");
187 EmitBeginNamespace(sb);
188 UtilMethodMap utilMethods;
189 GetUtilMethods(utilMethods);
190 EmitUtilMethods(sb, "", utilMethods, true);
191 sb.Append("\n");
192 EmitUtilMethods(sb, "", utilMethods, false);
193 sb.Append("\n");
194 EmitInterfaceGetMethodImpl(sb, "");
195 sb.Append("\n");
196 EmitStubConstructorImpl(sb, "");
197 sb.Append("\n");
198 EmitStubOnRequestMethodImpl(sb, "");
199 sb.Append("\n");
200 EmitStubMethodImpls(sb, "");
201 EmitEndNamespace(sb);
202
203 std::string data = sb.ToString();
204 file.WriteData(data.c_str(), data.size());
205 file.Flush();
206 file.Close();
207 }
208
EmitStubSourceInclusions(StringBuilder & sb)209 void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
210 {
211 HeaderFile::HeaderFileSet headerFiles;
212 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
213 GetSourceOtherLibInclusions(headerFiles);
214
215 for (const auto &file : headerFiles) {
216 sb.AppendFormat("%s\n", file.ToString().c_str());
217 }
218 }
219
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const220 void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
221 {
222 if (!interface_->IsSerializable()) {
223 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
224 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
225 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
226 } else {
227 const AST::TypeStringMap &types = ast_->GetTypes();
228 for (const auto &pair : types) {
229 AutoPtr<ASTType> type = pair.second;
230 if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
231 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
232 break;
233 }
234 }
235 }
236
237 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
238 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
239 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
240 AutoPtr<ASTType> paramType = param->GetType();
241 if (param->GetAttribute() == ParamAttr::PARAM_IN &&
242 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
243 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
244 }
245
246 if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
247 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
248 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
249 }
250 }
251 }
252
253 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
254 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
255 }
256
EmitInterfaceGetMethodImpl(StringBuilder & sb,const std::string & prefix) const257 void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
258 {
259 if (!interface_->IsSerializable()) {
260 EmitGetMethodImpl(sb, prefix);
261 sb.Append(prefix).Append("\n");
262 EmitGetInstanceMethodImpl(sb, prefix);
263 sb.Append(prefix).Append("\n");
264 }
265 }
266
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const267 void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
268 {
269 sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(bool isStub)\n",
270 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
271 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
272 sb.Append(prefix).Append("{\n");
273 sb.Append(prefix + TAB).AppendFormat("return %s::Get(\"%s\", isStub);\n",
274 EmitDefinitionByInterface(interface_, interfaceName_).c_str(), FileName(implName_).c_str());
275 sb.Append(prefix).Append("}\n");
276 }
277
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const278 void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const
279 {
280 sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
281 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
282 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
283 sb.Append(prefix).Append("{\n");
284
285 sb.Append(prefix + TAB).Append("if (!isStub) {\n");
286 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
287 sb.Append(prefix + TAB).Append("}\n");
288
289 sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
290 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
291 sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
292 sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
293 sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
294 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n");
295 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
296 sb.Append(prefix + TAB).Append("}\n");
297 sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
298 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
299 sb.Append(prefix).Append("}\n");
300 }
301
EmitStubConstructorImpl(StringBuilder & sb,const std::string & prefix) const302 void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const
303 {
304 sb.Append(prefix).AppendFormat("%s::%s(const sptr<%s> &impl)\n",
305 EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(),
306 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
307 sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n",
308 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
309 sb.Append(prefix).Append("{\n");
310 sb.Append(prefix).Append("}\n\n");
311
312 sb.Append(prefix).AppendFormat(
313 "%s::~%s()\n", EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str());
314 sb.Append(prefix).Append("{\n");
315 sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n");
316 sb.Append(prefix).Append("}\n");
317 }
318
EmitStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)319 void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
320 {
321 sb.Append(prefix).AppendFormat(
322 "int32_t %s::OnRemoteRequest(uint32_t code, ", EmitDefinitionByInterface(interface_, stubName_).c_str());
323 sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n");
324 sb.Append(prefix).Append("{\n");
325
326 sb.Append(prefix + TAB).Append("switch (code) {\n");
327 AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
328 sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
329 sb.Append(prefix + TAB + TAB + TAB)
330 .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), getVerMethod->GetName().c_str());
331 AutoPtr<ASTInterfaceType> interface = interface_;
332 while (interface != nullptr) {
333 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
334 sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
335 sb.Append(prefix + TAB + TAB + TAB)
336 .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str());
337 }
338 interface = interface->GetExtendsInterface();
339 }
340
341 sb.Append(prefix + TAB + TAB).Append("default: {\n");
342 sb.Append(prefix + TAB + TAB + TAB)
343 .Append("HDF_LOGE(\"%{public}s: cmd %{public}d is not supported\", __func__, code);\n");
344 sb.Append(prefix + TAB + TAB + TAB).Append("return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
345 sb.Append(prefix + TAB + TAB).Append("}\n");
346 sb.Append(prefix + TAB).Append("}\n");
347 sb.Append("}\n");
348 }
349
EmitStubMethodImpls(StringBuilder & sb,const std::string & prefix) const350 void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const
351 {
352 AutoPtr<ASTInterfaceType> interface = interface_;
353 AutoPtr<ASTInterfaceType> mataInterface = interface_;
354 while (interface != nullptr) {
355 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
356 EmitStubMethodImpl(interface, method, sb, prefix);
357 sb.Append("\n");
358 }
359 interface = interface->GetExtendsInterface();
360 if (interface != nullptr) {
361 mataInterface = interface;
362 }
363 }
364 AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
365 EmitStubMethodImpl(mataInterface, verMethod, sb, prefix);
366 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
367 sb.Append("\n");
368 EmitStubStaticMethodImpl(method, sb, prefix);
369 }
370 if (interface_->GetExtendsInterface() == nullptr) {
371 sb.Append("\n");
372 EmitStubStaticMethodImpl(verMethod, sb, prefix);
373 }
374 }
375
EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const376 void CppServiceStubCodeEmitter::EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,
377 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
378 {
379 sb.Append(prefix).AppendFormat("int32_t %s::%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n",
380 EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
381 dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
382 sb.Append(prefix).Append("{\n");
383 sb.Append(prefix + TAB).AppendFormat("return %s::%s%s_(%s, %s, %s, impl_);\n",
384 EmitDefinitionByInterface(interface, stubName_).c_str(),
385 stubName_.c_str(), method->GetName().c_str(),
386 dataParcelName_.c_str(), replyParcelName_.c_str(),
387 optionName_.c_str());
388 sb.Append("}\n");
389 }
390
EmitStubStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const391 void CppServiceStubCodeEmitter::EmitStubStaticMethodImpl(
392 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
393 {
394 sb.Append(prefix).AppendFormat(
395 "int32_t %s::%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl)\n",
396 EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
397 dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str(),
398 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
399 sb.Append(prefix).Append("{\n");
400
401 // read interface token and check it
402 EmitStubReadInterfaceToken(dataParcelName_, sb, prefix + TAB);
403 sb.Append("\n");
404
405 EmitStubReadMemFlag(method, dataParcelName_, sb, prefix + TAB);
406
407 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
408 AutoPtr<ASTParameter> param = method->GetParameter(i);
409 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
410 EmitReadMethodParameter(param, dataParcelName_, true, sb, prefix + TAB);
411 sb.Append("\n");
412 } else {
413 EmitLocalVariable(param, dataParcelName_, sb, prefix + TAB);
414 sb.Append("\n");
415 }
416 }
417
418 EmitStubCallMethod(method, sb, prefix + TAB);
419 sb.Append("\n");
420
421 if (!method->IsOneWay()) {
422 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
423 AutoPtr<ASTParameter> param = method->GetParameter(i);
424 if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
425 EmitWriteMethodParameter(param, replyParcelName_, sb, prefix + TAB);
426 sb.Append("\n");
427 }
428 }
429 }
430
431 sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
432 sb.Append("}\n");
433 }
434
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const435 void CppServiceStubCodeEmitter::EmitStubCallMethod(
436 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
437 {
438 sb.Append(prefix).Append("if (impl == nullptr) {\n");
439 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: impl is nullptr!\", __func__);\n");
440 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
441 sb.Append(prefix).Append("}\n\n");
442
443 sb.Append(prefix).AppendFormat("int32_t %s = impl->%s(", errorCodeName_.c_str(), method->GetName().c_str());
444 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
445 AutoPtr<ASTParameter> param = method->GetParameter(i);
446 sb.Append(param->GetName());
447 if (i + 1 < method->GetParameterNumber()) {
448 sb.Append(", ");
449 }
450 }
451 sb.Append(");\n");
452
453 sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
454 sb.Append(prefix + TAB)
455 .AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
456 errorCodeName_.c_str());
457 sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
458 sb.Append(prefix).Append("}\n");
459 }
460
EmitStubReadInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const461 void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken(
462 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
463 {
464 sb.Append(prefix).AppendFormat("if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(),
465 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
466 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n");
467 sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
468 sb.Append(prefix).Append("}\n");
469 }
470
EmitStubReadMemFlag(const AutoPtr<ASTMethod> & method,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const471 void CppServiceStubCodeEmitter::EmitStubReadMemFlag(const AutoPtr<ASTMethod> &method,
472 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
473 {
474 if (NeedFlag(method)) {
475 sb.Append(prefix).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
476 sb.Append(prefix).AppendFormat("if (!%s.ReadBool(%s)) {\n", parcelName.c_str(), flagOfSetMemName_.c_str());
477 sb.Append(prefix + TAB)
478 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", flagOfSetMemName_.c_str());
479 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
480 sb.Append(prefix).Append("}\n");
481 }
482 }
483
EmitLocalVariable(const AutoPtr<ASTParameter> & param,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const484 void CppServiceStubCodeEmitter::EmitLocalVariable(const AutoPtr<ASTParameter> ¶m,
485 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
486 {
487 sb.Append(prefix).Append(param->EmitCppLocalVar()).Append("\n");
488 AutoPtr<ASTType> type = param->GetType();
489 if (!type->IsStringType() && !type->IsArrayType() && !type->IsListType()) {
490 return;
491 }
492
493 sb.Append(prefix).AppendFormat("if (%s) {\n", flagOfSetMemName_.c_str());
494 std::string capacityName = "capacity";
495 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", capacityName.c_str());
496 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), capacityName.c_str());
497 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n",
498 capacityName.c_str());
499 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
500 sb.Append(prefix + TAB).Append("}\n");
501
502 if (type->IsStringType()) {
503 sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(char), HDF_ERR_INVALID_PARAM);\n",
504 CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO);
505 } else {
506 AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
507 sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
508 CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO,
509 arrayType->GetElementType()->EmitCppType().c_str());
510 }
511 sb.Append(prefix + TAB).AppendFormat("%s.reserve(%s);\n", param->GetName().c_str(), capacityName.c_str());
512 sb.Append(prefix).Append("}\n");
513 }
514
GetUtilMethods(UtilMethodMap & methods)515 void CppServiceStubCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
516 {
517 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
518 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
519 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
520 AutoPtr<ASTType> paramType = param->GetType();
521 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
522 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
523 } else {
524 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
525 }
526 }
527 }
528 }
529 } // namespace HDI
530 } // namespace OHOS
531