• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "codegen/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 (!Options::GetInstance().DoPassthrough()) {
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     GetHeaderOtherLibInclusions(headerFiles);
67 
68     for (const auto &file : headerFiles) {
69         sb.AppendFormat("%s\n", file.ToString().c_str());
70     }
71 }
72 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)73 void CppServiceStubCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
74 {
75     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
76     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
77     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "ipc_object_stub");
78     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
79     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "refbase");
80 }
81 
EmitStubDecl(StringBuilder & sb)82 void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder &sb)
83 {
84     EmitBeginNamespace(sb);
85     sb.Append("\n");
86     EmitStubUsingNamespace(sb);
87     sb.AppendFormat("class %s : public IPCObjectStub {\n", stubName_.c_str());
88     EmitStubBody(sb, TAB);
89     sb.Append("};\n");
90     EmitEndNamespace(sb);
91 }
92 
EmitStubUsingNamespace(StringBuilder & sb)93 void CppServiceStubCodeEmitter::EmitStubUsingNamespace(StringBuilder &sb)
94 {
95     sb.Append("using namespace OHOS;\n");
96 }
97 
EmitStubBody(StringBuilder & sb,const std::string & prefix)98 void CppServiceStubCodeEmitter::EmitStubBody(StringBuilder &sb, const std::string &prefix)
99 {
100     sb.Append("public:\n");
101     EmitStubConstructorDecl(sb, prefix);
102     sb.Append("\n");
103     EmitStubOnRequestDecl(sb, prefix);
104     sb.Append("\n");
105     EmitStubMethodDecls(sb, prefix);
106     sb.Append("\n");
107     EmitStubPrivateData(sb, prefix);
108 }
109 
EmitStubConstructorDecl(StringBuilder & sb,const std::string & prefix)110 void CppServiceStubCodeEmitter::EmitStubConstructorDecl(StringBuilder &sb, const std::string &prefix)
111 {
112     sb.Append(prefix).AppendFormat("explicit %s(const sptr<%s> &impl);\n", stubName_.c_str(), interfaceName_.c_str());
113     sb.Append(prefix).AppendFormat("virtual ~%s();\n", stubName_.c_str());
114 }
115 
EmitStubOnRequestDecl(StringBuilder & sb,const std::string & prefix)116 void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder &sb, const std::string &prefix)
117 {
118     sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, ");
119     sb.Append("MessageOption &option) override;\n");
120 }
121 
EmitStubMethodDecls(StringBuilder & sb,const std::string & prefix)122 void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix)
123 {
124     sb.Append("private:\n");
125     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
126         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
127         EmitStubMethodDecl(method, sb, prefix);
128         sb.Append("\n");
129     }
130     EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix);
131 }
132 
EmitStubMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)133 void CppServiceStubCodeEmitter::EmitStubMethodDecl(
134     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
135 {
136     sb.Append(prefix).AppendFormat("int32_t %s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s);\n",
137         stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
138         optionName_.c_str());
139 }
140 
EmitStubPrivateData(StringBuilder & sb,const std::string & prefix)141 void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix)
142 {
143     sb.Append("private:\n");
144     sb.Append(prefix).AppendFormat(
145         "static inline ObjectDelegator<%s, %s> objDelegator_;\n", stubName_.c_str(), interfaceName_.c_str());
146     sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", interfaceName_.c_str());
147 }
148 
EmitStubSourceFile()149 void CppServiceStubCodeEmitter::EmitStubSourceFile()
150 {
151     std::string filePath =
152         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(stubName_).c_str()));
153     File file(filePath, File::WRITE);
154     StringBuilder sb;
155 
156     EmitLicense(sb);
157     EmitStubSourceInclusions(sb);
158     sb.Append("\n");
159     EmitLogTagMacro(sb, FileName(stubName_));
160     sb.Append("\n");
161     EmitBeginNamespace(sb);
162     UtilMethodMap utilMethods;
163     GetUtilMethods(utilMethods);
164     EmitUtilMethods(sb, "", utilMethods, true);
165     sb.Append("\n");
166     EmitUtilMethods(sb, "", utilMethods, false);
167     sb.Append("\n");
168     EmitInterfaceGetMethodImpl(sb, "");
169     sb.Append("\n");
170     EmitStubConstructorImpl(sb, "");
171     sb.Append("\n");
172     EmitStubOnRequestMethodImpl(sb, "");
173     sb.Append("\n");
174     EmitStubMethodImpls(sb, "");
175     EmitEndNamespace(sb);
176 
177     std::string data = sb.ToString();
178     file.WriteData(data.c_str(), data.size());
179     file.Flush();
180     file.Close();
181 }
182 
EmitStubSourceInclusions(StringBuilder & sb)183 void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
184 {
185     HeaderFile::HeaderFileSet headerFiles;
186     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
187     GetSourceOtherLibInclusions(headerFiles);
188 
189     for (const auto &file : headerFiles) {
190         sb.AppendFormat("%s\n", file.ToString().c_str());
191     }
192 }
193 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles)194 void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles)
195 {
196     if (!interface_->IsSerializable()) {
197         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
198         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
199         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
200     } else {
201         const AST::TypeStringMap &types = ast_->GetTypes();
202         for (const auto &pair : types) {
203             AutoPtr<ASTType> type = pair.second;
204             if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
205                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
206                 break;
207             }
208         }
209     }
210 
211     for (size_t methodIndex = 0; methodIndex < interface_->GetMethodNumber(); methodIndex++) {
212         AutoPtr<ASTMethod> method = interface_->GetMethod(methodIndex);
213         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
214             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
215             AutoPtr<ASTType> paramType = param->GetType();
216             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
217                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
218                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
219             }
220 
221             if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
222                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
223                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
224             }
225         }
226     }
227 
228     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
229     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
230 }
231 
EmitInterfaceGetMethodImpl(StringBuilder & sb,const std::string & prefix)232 void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix)
233 {
234     if (!interface_->IsSerializable()) {
235         EmitGetMethodImpl(sb, prefix);
236         sb.Append(prefix).Append("\n");
237         EmitGetInstanceMethodImpl(sb, prefix);
238         sb.Append(prefix).Append("\n");
239     }
240 }
241 
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix)242 void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix)
243 {
244     sb.Append(prefix).AppendFormat(
245         "sptr<%s> %s::Get(bool isStub)\n", interface_->GetName().c_str(), interface_->GetName().c_str());
246     sb.Append(prefix).Append("{\n");
247     sb.Append(prefix + TAB)
248         .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
249     sb.Append(prefix).Append("}\n");
250 }
251 
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix)252 void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix)
253 {
254     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
255         interface_->GetName().c_str(), interface_->GetName().c_str());
256     sb.Append(prefix).Append("{\n");
257 
258     sb.Append(prefix + TAB).Append("if (!isStub) {\n");
259     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
260     sb.Append(prefix + TAB).Append("}\n");
261 
262     sb.Append(prefix + TAB)
263         .AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n", interfaceName_.c_str());
264     sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
265     sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
266     sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
267     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n");
268     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
269     sb.Append(prefix + TAB).Append("}\n");
270     sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n", interfaceName_.c_str());
271     sb.Append(prefix).Append("}\n");
272 }
273 
EmitStubConstructorImpl(StringBuilder & sb,const std::string & prefix)274 void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix)
275 {
276     sb.Append(prefix).AppendFormat(
277         "%s::%s(const sptr<%s> &impl)\n", stubName_.c_str(), stubName_.c_str(), interfaceName_.c_str());
278     sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n", interfaceName_.c_str());
279     sb.Append(prefix).Append("{\n");
280     sb.Append(prefix).Append("}\n\n");
281 
282     sb.Append(prefix).AppendFormat("%s::~%s()\n", stubName_.c_str(), stubName_.c_str());
283     sb.Append(prefix).Append("{\n");
284     sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n");
285     sb.Append(prefix).Append("}\n");
286 }
287 
EmitStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)288 void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
289 {
290     sb.Append(prefix).AppendFormat("int32_t %s::OnRemoteRequest(uint32_t code, ", stubName_.c_str());
291     sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n");
292     sb.Append(prefix).Append("{\n");
293 
294     sb.Append(prefix + TAB).Append("switch (code) {\n");
295 
296     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
297         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
298         sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
299         sb.Append(prefix + TAB + TAB + TAB)
300             .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str());
301     }
302 
303     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
304     sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
305     sb.Append(prefix + TAB + TAB + TAB)
306         .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), getVerMethod->GetName().c_str());
307 
308     sb.Append(prefix + TAB + TAB).Append("default: {\n");
309     sb.Append(prefix + TAB + TAB + TAB)
310         .Append("HDF_LOGE(\"%{public}s: cmd %{public}d is not supported\", __func__, code);\n");
311     sb.Append(prefix + TAB + TAB + TAB).Append("return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
312     sb.Append(prefix + TAB + TAB).Append("}\n");
313     sb.Append(prefix + TAB).Append("}\n");
314     sb.Append("}\n");
315 }
316 
EmitStubMethodImpls(StringBuilder & sb,const std::string & prefix)317 void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix)
318 {
319     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
320         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
321         EmitStubMethodImpl(method, sb, prefix);
322         sb.Append("\n");
323     }
324 
325     EmitStubMethodImpl(interface_->GetVersionMethod(), sb, prefix);
326 }
327 
EmitStubMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)328 void CppServiceStubCodeEmitter::EmitStubMethodImpl(
329     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
330 {
331     sb.Append(prefix).AppendFormat("int32_t %s::%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n",
332         stubName_.c_str(), stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(),
333         replyParcelName_.c_str(), optionName_.c_str());
334     sb.Append(prefix).Append("{\n");
335 
336     // read interface token and check it
337     EmitStubReadInterfaceToken(dataParcelName_, sb, prefix + TAB);
338     sb.Append("\n");
339 
340     EmitStubReadMemFlag(method, dataParcelName_, sb, prefix + TAB);
341 
342     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
343         AutoPtr<ASTParameter> param = method->GetParameter(i);
344         if (param->GetAttribute() == ParamAttr::PARAM_IN) {
345             EmitReadMethodParameter(param, dataParcelName_, true, sb, prefix + TAB);
346             sb.Append("\n");
347         } else {
348             EmitLocalVariable(param, dataParcelName_, sb, prefix + TAB);
349             sb.Append("\n");
350         }
351     }
352 
353     EmitStubCallMethod(method, sb, prefix + TAB);
354     sb.Append("\n");
355 
356     if (!method->IsOneWay()) {
357         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
358             AutoPtr<ASTParameter> param = method->GetParameter(i);
359             if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
360                 EmitWriteMethodParameter(param, replyParcelName_, sb, prefix + TAB);
361                 sb.Append("\n");
362             }
363         }
364     }
365 
366     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
367     sb.Append("}\n");
368 }
369 
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)370 void CppServiceStubCodeEmitter::EmitStubCallMethod(
371     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
372 {
373     sb.Append(prefix).AppendFormat("int32_t %s = impl_->%s(", errorCodeName_.c_str(), method->GetName().c_str());
374     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
375         AutoPtr<ASTParameter> param = method->GetParameter(i);
376         sb.Append(param->GetName());
377         if (i + 1 < method->GetParameterNumber()) {
378             sb.Append(", ");
379         }
380     }
381     sb.Append(");\n");
382 
383     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
384     sb.Append(prefix + TAB)
385         .AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%d\", __func__, %s);\n", errorCodeName_.c_str());
386     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
387     sb.Append(prefix).Append("}\n");
388 }
389 
EmitStubReadInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix)390 void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken(
391     const std::string &parcelName, StringBuilder &sb, const std::string &prefix)
392 {
393     sb.Append(prefix).AppendFormat(
394         "if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(), interfaceName_.c_str());
395     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n");
396     sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
397     sb.Append(prefix).Append("}\n");
398 }
399 
EmitStubReadMemFlag(const AutoPtr<ASTMethod> & method,const std::string & parcelName,StringBuilder & sb,const std::string & prefix)400 void CppServiceStubCodeEmitter::EmitStubReadMemFlag(
401     const AutoPtr<ASTMethod> &method, const std::string &parcelName, StringBuilder &sb, const std::string &prefix)
402 {
403     if (NeedFlag(method)) {
404         sb.Append(prefix).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
405         sb.Append(prefix).AppendFormat("if (!%s.ReadBool(%s)) {\n", parcelName.c_str(), flagOfSetMemName_.c_str());
406         sb.Append(prefix + TAB)
407             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", flagOfSetMemName_.c_str());
408         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
409         sb.Append(prefix).Append("}\n");
410     }
411 }
412 
EmitLocalVariable(const AutoPtr<ASTParameter> & param,const std::string & parcelName,StringBuilder & sb,const std::string & prefix)413 void CppServiceStubCodeEmitter::EmitLocalVariable(
414     const AutoPtr<ASTParameter> &param, const std::string &parcelName, StringBuilder &sb, const std::string &prefix)
415 {
416     sb.Append(prefix).Append(param->EmitCppLocalVar()).Append("\n");
417     AutoPtr<ASTType> type = param->GetType();
418     if (!type->IsStringType() && !type->IsArrayType() && !type->IsListType()) {
419         return;
420     }
421 
422     sb.Append(prefix).AppendFormat("if (%s) {\n", flagOfSetMemName_.c_str());
423     std::string capacityName = "capacity";
424     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", capacityName.c_str());
425     sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), capacityName.c_str());
426     sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n",
427         capacityName.c_str());
428     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
429     sb.Append(prefix + TAB).Append("}\n");
430 
431     if (type->IsStringType()) {
432         sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(char), HDF_ERR_INVALID_PARAM);\n",
433             CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO);
434     } else {
435         AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
436         sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
437             CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO,
438             arrayType->GetElementType()->EmitCppType().c_str());
439     }
440     sb.Append(prefix + TAB).AppendFormat("%s.reserve(%s);\n", param->GetName().c_str(), capacityName.c_str());
441     sb.Append(prefix).Append("}\n");
442 }
443 
GetUtilMethods(UtilMethodMap & methods)444 void CppServiceStubCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
445 {
446     for (size_t methodIndex = 0; methodIndex < interface_->GetMethodNumber(); methodIndex++) {
447         AutoPtr<ASTMethod> method = interface_->GetMethod(methodIndex);
448         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
449             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
450             AutoPtr<ASTType> paramType = param->GetType();
451             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
452                 paramType->RegisterReadMethod(Options::GetInstance().GetTargetLanguage(), SerMode::STUB_SER, methods);
453             } else {
454                 paramType->RegisterWriteMethod(Options::GetInstance().GetTargetLanguage(), SerMode::STUB_SER, methods);
455             }
456         }
457     }
458 }
459 } // namespace HDI
460 } // namespace OHOS