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