1 /*
2 * Copyright (c) 2022-2023 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 <sstream>
17 #include "securec.h"
18 #include "util/file.h"
19 #include "codegen/cpp_code_emitter.h"
20
21 namespace OHOS {
22 namespace Idl {
EmitInterface()23 void CppCodeEmitter::EmitInterface()
24 {
25 EmitInterfaceHeaderFile();
26 }
27
EmitInterfaceHeaderFile()28 void CppCodeEmitter::EmitInterfaceHeaderFile()
29 {
30 String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string());
31 File file(filePath, File::WRITE);
32
33 StringBuilder sb;
34
35 EmitLicense(sb);
36 sb.Append("\n");
37 EmitHeadMacro(sb, interfaceFullName_);
38 sb.Append("\n");
39 EmitInterfaceInclusions(sb);
40 sb.Append("\n");
41 if (EmitInterfaceUsings(sb)) {
42 sb.Append("\n");
43 }
44 EmitInterfaceDefinition(sb);
45 EmitTailMacro(sb, interfaceFullName_);
46
47 String data = sb.ToString();
48 file.WriteData(data.string(), data.GetLength());
49 file.Flush();
50 file.Close();
51 }
52
EmitInterfaceInclusions(StringBuilder & sb)53 void CppCodeEmitter::EmitInterfaceInclusions(StringBuilder& sb)
54 {
55 EmitInterfaceStdlibInclusions(sb);
56 EmitInterfaceDBinderInclusions(sb);
57 EmitInterfaceSelfDefinedTypeInclusions(sb);
58 }
59
EmitInterfaceStdlibInclusions(StringBuilder & sb)60 void CppCodeEmitter::EmitInterfaceStdlibInclusions(StringBuilder& sb)
61 {
62 bool includeString = false;
63 bool includeList = false;
64 bool includeMap = false;
65 bool includeNum = false;
66 if (metaComponent_ == nullptr) {
67 return;
68 }
69 for (int i = 0; i < metaComponent_->typeNumber_; i++) {
70 MetaType* mt = metaComponent_->types_[i];
71 switch (mt->kind_) {
72 case TypeKind::Byte: {
73 if (!includeNum) {
74 sb.Append("#include <cstdint>\n");
75 includeNum = true;
76 }
77 break;
78 }
79 case TypeKind::String: {
80 if (!includeString) {
81 sb.Append("#include <string_ex.h>\n");
82 includeString = true;
83 }
84 break;
85 }
86 case TypeKind::Array:
87 case TypeKind::List: {
88 if (!includeList) {
89 sb.Append("#include <vector>\n");
90 includeList = true;
91 }
92 break;
93 }
94 case TypeKind::Map: {
95 if (!includeMap) {
96 sb.Append("#include <unordered_map>\n");
97 includeMap = true;
98 }
99 break;
100 }
101 default:
102 break;
103 }
104 }
105 }
106
EmitInterfaceDBinderInclusions(StringBuilder & sb)107 void CppCodeEmitter::EmitInterfaceDBinderInclusions(StringBuilder& sb)
108 {
109 sb.Append("#include <iremote_broker.h>\n");
110 if (logOn_) {
111 sb.Append("#include \"hilog/log.h\"\n");
112 }
113 }
114
GetFilePath(const String & fpnp)115 String CppCodeEmitter::GetFilePath(const String& fpnp)
116 {
117 int pos = fpnp.IndexOf("..");
118 if (pos == -1) {
119 return String();
120 }
121 String res = fpnp.Substring(0, pos + 1);
122 return res;
123 }
124
GetFilePathNoPoint(const String & fpnp)125 String CppCodeEmitter::GetFilePathNoPoint(const String& fpnp)
126 {
127 int pos = fpnp.IndexOf("..");
128 if (pos == -1) {
129 return String();
130 }
131 String res = fpnp.Substring(0, pos);
132 return res;
133 }
134
GetNamespace(const String & fpnp)135 String CppCodeEmitter::GetNamespace(const String& fpnp)
136 {
137 int pos = fpnp.IndexOf("..");
138 if (pos == -1) {
139 return fpnp;
140 }
141 String res = fpnp.Substring(pos + 2);
142 return res;
143 }
144
EmitInterfaceSelfDefinedTypeInclusions(StringBuilder & sb)145 void CppCodeEmitter::EmitInterfaceSelfDefinedTypeInclusions(StringBuilder& sb)
146 {
147 for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
148 MetaSequenceable* mp = metaComponent_->sequenceables_[i];
149 if (mp == nullptr) {
150 continue;
151 }
152 String filePath = GetFilePathNoPoint(String(mp->namespace_));
153 String fileName;
154 String sequenceName = mp->name_;
155 filePath.IsEmpty() ? fileName = FileName(sequenceName) : fileName = FileName(filePath);
156 sb.Append("#include ").AppendFormat("\"%s.h\"\n", fileName.string());
157 }
158
159 for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
160 MetaInterface* mi = metaComponent_->interfaces_[i];
161 if (mi->external_) {
162 String filePath = GetFilePath(String(mi->namespace_));
163 String fileName = FileName(filePath + mi->name_);
164 sb.Append("#include ").AppendFormat("\"%s.h\"\n", fileName.string());
165 }
166 }
167 }
168
EmitInterfaceUsings(StringBuilder & sb)169 bool CppCodeEmitter::EmitInterfaceUsings(StringBuilder& sb)
170 {
171 bool ret = false;
172 for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
173 MetaSequenceable* mp = metaComponent_->sequenceables_[i];
174 String np = GetNamespace(String(mp->namespace_));
175 if (np.IsEmpty()) {
176 continue;
177 }
178 String fullName = CppFullName(np + mp->name_);
179 sb.Append("using ").AppendFormat("%s;\n", fullName.string());
180 ret = true;
181 }
182
183 for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
184 MetaInterface* mi = metaComponent_->interfaces_[i];
185 if (mi->external_) {
186 String np = GetNamespace(String(mi->namespace_));
187 if (np.IsEmpty()) {
188 continue;
189 }
190 String fullName = CppFullName(np + mi->name_);
191 sb.Append("using ").AppendFormat("%s;\n", fullName.string());
192 ret = true;
193 }
194 }
195 return ret;
196 }
197
EmitInterfaceDefinition(StringBuilder & sb)198 void CppCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb)
199 {
200 EmitBeginNamespace(sb);
201 sb.AppendFormat("class %s : public IRemoteBroker {\n", metaInterface_->name_);
202 sb.Append("public:\n");
203 EmitInterfaceBody(sb, TAB);
204 EmitInterfaceMemberVariables(sb, TAB);
205 sb.Append("};\n");
206 EmitEndNamespace(sb);
207 }
208
EmitInterfaceBody(StringBuilder & sb,const String & prefix)209 void CppCodeEmitter::EmitInterfaceBody(StringBuilder& sb, const String& prefix)
210 {
211 String nameWithoutPath = GetNamespace(interfaceFullName_);
212 sb.Append(TAB).AppendFormat("DECLARE_INTERFACE_DESCRIPTOR(u\"%s\");\n", nameWithoutPath.string());
213 sb.Append("\n");
214 EmitInterfaceMethods(sb, TAB);
215 }
216
EmitInterfaceMethods(StringBuilder & sb,const String & prefix)217 void CppCodeEmitter::EmitInterfaceMethods(StringBuilder& sb, const String& prefix)
218 {
219 if (metaInterface_->methodNumber_ > 0) {
220 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
221 MetaMethod* mm = metaInterface_->methods_[i];
222 EmitInterfaceMethod(mm, sb, prefix);
223 if (i != metaInterface_->methodNumber_ - 1) {
224 sb.Append("\n");
225 }
226 }
227 }
228 }
229
EmitInterfaceMethod(MetaMethod * mm,StringBuilder & sb,const String & prefix)230 void CppCodeEmitter::EmitInterfaceMethod(MetaMethod* mm, StringBuilder& sb, const String& prefix)
231 {
232 MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
233 if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
234 sb.Append(prefix).AppendFormat("virtual ErrCode %s() = 0;\n", mm->name_);
235 } else {
236 sb.Append(prefix).AppendFormat("virtual ErrCode %s(\n", mm->name_);
237 for (int i = 0; i < mm->parameterNumber_; i++) {
238 MetaParameter* mp = mm->parameters_[i];
239 EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
240 if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
241 sb.Append(",\n");
242 }
243 }
244 if (returnType->kind_ != TypeKind::Void) {
245 EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
246 }
247 sb.Append(") = 0;\n");
248 }
249 }
250
EmitInterfaceMethodParameter(MetaParameter * mp,StringBuilder & sb,const String & prefix)251 void CppCodeEmitter::EmitInterfaceMethodParameter(MetaParameter* mp, StringBuilder& sb, const String& prefix)
252 {
253 sb.Append(prefix);
254
255 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
256 const std::string name = mp->name_;
257 sb.AppendFormat("%s %s", EmitType(mt, mp->attributes_, false).string(), name.c_str());
258 }
259
EmitInterfaceMethodReturn(MetaType * mt,StringBuilder & sb,const String & prefix)260 void CppCodeEmitter::EmitInterfaceMethodReturn(MetaType* mt, StringBuilder& sb, const String& prefix)
261 {
262 sb.Append(prefix).AppendFormat("%s result", EmitType(mt, ATTR_OUT, false).string());
263 }
264
EmitInterfaceMemberVariables(StringBuilder & sb,const String & prefix)265 void CppCodeEmitter::EmitInterfaceMemberVariables(StringBuilder& sb, const String& prefix)
266 {
267 sb.Append("protected:\n");
268 if (!domainId_.IsNull() && !logTag_.IsNull()) {
269 sb.Append(prefix).AppendFormat(
270 "static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, %s, \"%s\"};\n",
271 domainId_.string(), logTag_.string());
272 }
273 sb.Append(prefix).Append("const int VECTOR_MAX_SIZE = 102400;\n");
274 sb.Append(prefix).Append("const int LIST_MAX_SIZE = 102400;\n");
275 sb.Append(prefix).Append("const int MAP_MAX_SIZE = 102400;\n");
276 }
277
EmitInterfaceProxy()278 void CppCodeEmitter::EmitInterfaceProxy()
279 {
280 EmitInterfaceProxyHeaderFile();
281 EmitInterfaceProxyCppFile();
282 }
283
EmitInterfaceProxyHeaderFile()284 void CppCodeEmitter::EmitInterfaceProxyHeaderFile()
285 {
286 String filePath = String::Format("%s/%s.h", directory_.string(), FileName(proxyName_).string());
287 File file(filePath, File::WRITE);
288
289 StringBuilder sb;
290
291 EmitLicense(sb);
292 sb.Append("\n");
293 EmitHeadMacro(sb, proxyFullName_);
294 sb.Append("\n");
295 sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string());
296 sb.Append("#include <iremote_proxy.h>\n");
297 if (metaComponent_->hasCacheableProxyMethods_ == true) {
298 sb.Append("#include \"api_cache_manager.h\"\n");
299 }
300 sb.Append("\n");
301 EmitInterfaceProxyInHeaderFile(sb);
302 EmitTailMacro(sb, proxyFullName_);
303
304 String data = sb.ToString();
305 file.WriteData(data.string(), data.GetLength());
306 file.Flush();
307 file.Close();
308 }
309
EmitInterfaceProxyInHeaderFile(StringBuilder & sb)310 void CppCodeEmitter::EmitInterfaceProxyInHeaderFile(StringBuilder& sb)
311 {
312 EmitBeginNamespace(sb);
313 sb.AppendFormat("class %s : public IRemoteProxy<%s> {\n", proxyName_.string(), interfaceName_.string());
314 sb.Append("public:\n");
315 EmitInterfaceProxyConstructor(sb, TAB);
316 sb.Append("\n");
317 EmitInterfaceProxyMethodDecls(sb, TAB);
318 sb.Append("\n");
319 sb.Append("private:\n");
320 EmitInterfaceProxyConstants(sb, TAB);
321 sb.Append("};\n");
322 EmitEndNamespace(sb);
323 }
324
EmitInterfaceProxyRegisterDeathRecipient(StringBuilder & sb,const String & prefix)325 void CppCodeEmitter::EmitInterfaceProxyRegisterDeathRecipient(StringBuilder& sb, const String& prefix)
326 {
327 sb.Append(prefix).Append("if (remote != nullptr) {\n");
328 sb.Append(prefix + TAB).Append("if (!remote->IsProxyObject()) {\n");
329 if (logOn_) {
330 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"remote is not proxy object!\");\n");
331 }
332 sb.Append(prefix + TAB + TAB).Append("return;\n");
333 sb.Append(prefix + TAB).Append("}\n");
334 sb.Append(prefix + TAB).AppendFormat("deathRecipient_ = new (std::nothrow) %s(*this);\n",
335 deathRecipientName_.string());
336 sb.Append(prefix + TAB).Append("if (deathRecipient_ == nullptr) {\n");
337 if (logOn_) {
338 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"deathRecipient_ is nullptr!\");\n");
339 }
340 sb.Append(prefix + TAB + TAB).Append("return;\n");
341 sb.Append(prefix + TAB).Append("}\n");
342 sb.Append(prefix + TAB).Append("if (!remote->AddDeathRecipient(deathRecipient_)) {\n");
343 if (logOn_) {
344 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"AddDeathRecipient failed!\");\n");
345 }
346 sb.Append(prefix + TAB + TAB).Append("return;\n");
347 sb.Append(prefix + TAB).Append("}\n");
348 sb.Append(prefix + TAB).Append("remote_ = remote;\n");
349 sb.Append(prefix).Append("}\n");
350 }
351
EmitInterfaceProxyAddCacheAbleAPI(StringBuilder & sb,const String & prefix)352 void CppCodeEmitter::EmitInterfaceProxyAddCacheAbleAPI(StringBuilder& sb, const String& prefix)
353 {
354 sb.Append("\n");
355 if (metaComponent_->hasCacheableProxyMethods_ == false) {
356 return;
357 }
358 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
359 MetaMethod* mm = metaInterface_->methods_[i];
360 if (mm->cacheable_ == false) {
361 continue;
362 }
363 if (mm->cacheabletime_ != 0) {
364 sb.Append(prefix + TAB).AppendFormat(
365 "ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_%s, %d000);\n",
366 ConstantName(mm->name_).string(), mm->cacheabletime_);
367 } else {
368 sb.Append(prefix + TAB).AppendFormat(
369 "ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_%s, 0);\n",
370 ConstantName(mm->name_).string());
371 }
372 }
373 sb.Append("\n");
374 EmitInterfaceProxyRegisterDeathRecipient(sb, prefix + TAB);
375 }
376
EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder & sb,const String & prefix)377 void CppCodeEmitter::EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder& sb, const String& prefix)
378 {
379 sb.Append(prefix).Append("if (remote_ == nullptr) {\n");
380 sb.Append(prefix).Append(TAB).Append("return;\n");
381 sb.Append(prefix).Append("}\n");
382 sb.Append(prefix).Append("if (deathRecipient_ == nullptr) {\n");
383 sb.Append(prefix).Append(TAB).Append("return;\n");
384 sb.Append(prefix).Append("}\n");
385 sb.Append(prefix).Append("remote_->RemoveDeathRecipient(deathRecipient_);\n");
386 sb.Append(prefix).Append("remote_ = nullptr;\n");
387 if (metaInterface_->methodNumber_ > 0) {
388 sb.Append("\n");
389 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
390 MetaMethod* mm = metaInterface_->methods_[i];
391 if (mm->cacheable_) {
392 sb.Append(prefix).AppendFormat(
393 "ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_%s);\n",
394 ConstantName(mm->name_).string());
395 }
396 }
397 }
398 }
399
EmitInterfaceProxyConstructor(StringBuilder & sb,const String & prefix)400 void CppCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder& sb, const String& prefix)
401 {
402 sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.string());
403 sb.Append(prefix + TAB).Append("const sptr<IRemoteObject>& remote)\n");
404 sb.Append(prefix + TAB).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.string());
405 sb.Append(prefix).Append("{");
406 EmitInterfaceProxyAddCacheAbleAPI(sb, prefix);
407 sb.Append(prefix).Append("}\n\n");
408 sb.Append(prefix).AppendFormat("virtual ~%s()\n", proxyName_.string());
409 sb.Append(prefix).Append("{\n");
410 if (metaComponent_->hasCacheableProxyMethods_) {
411 EmitInterfaceProxyUnRegisterDeathRecipient(sb, prefix + TAB);
412 }
413 sb.Append(prefix).Append("}\n");
414 }
415
EmitInterfaceProxyMethodDecls(StringBuilder & sb,const String & prefix)416 void CppCodeEmitter::EmitInterfaceProxyMethodDecls(StringBuilder& sb, const String& prefix)
417 {
418 if (metaInterface_->methodNumber_ > 0) {
419 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
420 MetaMethod* mm = metaInterface_->methods_[i];
421 EmitInterfaceProxyMethodDecl(mm, sb, prefix);
422 if (i != metaInterface_->methodNumber_ - 1) {
423 sb.Append("\n");
424 }
425 }
426 }
427 }
428
EmitInterfaceProxyMethodDecl(MetaMethod * mm,StringBuilder & sb,const String & prefix)429 void CppCodeEmitter::EmitInterfaceProxyMethodDecl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
430 {
431 MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
432 if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
433 sb.Append(prefix).AppendFormat("ErrCode %s() override;\n", mm->name_);
434 } else {
435 sb.Append(prefix).AppendFormat("ErrCode %s(\n", mm->name_);
436 for (int i = 0; i < mm->parameterNumber_; i++) {
437 MetaParameter* mp = mm->parameters_[i];
438 EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
439 if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
440 sb.Append(",\n");
441 }
442 }
443 if (returnType->kind_ != TypeKind::Void) {
444 EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
445 }
446 sb.Append(") override;\n");
447 }
448 }
449
EmitInterfaceProxyDeathRecipient(StringBuilder & sb,const String & prefix)450 void CppCodeEmitter::EmitInterfaceProxyDeathRecipient(StringBuilder& sb, const String& prefix)
451 {
452 sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n", deathRecipientName_.string());
453 sb.Append(prefix).Append("public:\n");
454 sb.Append(prefix + TAB).AppendFormat("explicit %s(%s &client) : client_(client) {}\n", deathRecipientName_.string(),
455 proxyName_.string());
456 sb.Append(prefix + TAB).AppendFormat("~%s() override = default;\n", deathRecipientName_.string());
457 sb.Append(prefix + TAB).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
458 sb.Append(prefix + TAB).Append("{\n");
459 sb.Append(prefix + TAB + TAB).Append("client_.OnRemoteDied(remote);\n");
460 sb.Append(prefix + TAB).Append("}\n");
461 sb.Append(prefix).Append("private:\n");
462 sb.Append(prefix + TAB).AppendFormat("%s &client_;\n", proxyName_.string());
463 sb.Append(prefix).Append("};\n\n");
464
465 sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)\n");
466 sb.Append(prefix).Append("{\n");
467 sb.Append(prefix + TAB).Append("(void)remoteObject;\n");
468 sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().ClearCache(GetDescriptor());\n");
469 sb.Append(prefix).Append("}\n");
470 sb.Append(prefix).Append("sptr<IRemoteObject> remote_ = nullptr;\n");
471 sb.Append(prefix).Append("sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;\n");
472 }
473
EmitInterfaceProxyConstants(StringBuilder & sb,const String & prefix)474 void CppCodeEmitter::EmitInterfaceProxyConstants(StringBuilder& sb, const String& prefix)
475 {
476 if (metaComponent_->hasCacheableProxyMethods_) {
477 EmitInterfaceProxyDeathRecipient(sb, prefix);
478 }
479 EmitInterfaceMethodCommands(sb, prefix);
480 sb.Append("\n");
481 sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.string());
482 }
483
EmitInterfaceProxyCppFile()484 void CppCodeEmitter::EmitInterfaceProxyCppFile()
485 {
486 String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(proxyName_).string());
487 File file(filePath, File::WRITE);
488
489 StringBuilder sb;
490
491 EmitLicense(sb);
492 sb.Append("\n");
493 sb.AppendFormat("#include \"%s.h\"\n", FileName(proxyName_).string());
494 if (logOn_) {
495 sb.Append("#include \"hilog/log.h\"\n");
496 }
497 if (hitraceOn_) {
498 sb.Append("#include \"hitrace_meter.h\"\n");
499 }
500 sb.Append("\n");
501 if (logOn_) {
502 sb.Append("using OHOS::HiviewDFX::HiLog;\n\n");
503 }
504 EmitBeginNamespace(sb);
505 EmitInterfaceProxyMethodImpls(sb, "");
506 EmitEndNamespace(sb);
507
508 String data = sb.ToString();
509 file.WriteData(data.string(), data.GetLength());
510 file.Flush();
511 file.Close();
512 }
513
EmitInterfaceProxyMethodImpls(StringBuilder & sb,const String & prefix)514 void CppCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder& sb, const String& prefix)
515 {
516 if (metaInterface_->methodNumber_ > 0) {
517 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
518 MetaMethod* mm = metaInterface_->methods_[i];
519 EmitInterfaceProxyMethodImpl(mm, sb, prefix);
520 if (i != metaInterface_->methodNumber_ - 1) {
521 sb.Append("\n");
522 }
523 }
524 }
525 }
526
EmitInterfaceProxyMethodImpl(MetaMethod * mm,StringBuilder & sb,const String & prefix)527 void CppCodeEmitter::EmitInterfaceProxyMethodImpl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
528 {
529 MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
530 if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
531 sb.Append(prefix).AppendFormat("ErrCode %s::%s()\n", proxyName_.string(), mm->name_);
532 } else {
533 sb.Append(prefix).AppendFormat("ErrCode %s::%s(\n", proxyName_.string(), mm->name_);
534 for (int i = 0; i < mm->parameterNumber_; i++) {
535 MetaParameter* mp = mm->parameters_[i];
536 EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
537 if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
538 sb.Append(",\n");
539 }
540 }
541 if (returnType->kind_ != TypeKind::Void) {
542 EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
543 }
544 sb.Append(")\n");
545 }
546 EmitInterfaceProxyMethodBody(mm, sb, prefix);
547 }
548
EmitInterfaceProxyMethodPreSendRequest(MetaMethod * mm,StringBuilder & sb,const String & prefix)549 void CppCodeEmitter::EmitInterfaceProxyMethodPreSendRequest(MetaMethod* mm, StringBuilder& sb, const String& prefix)
550 {
551 if ((mm->cacheable_ == true) && ((mm->properties_ & METHOD_PROPERTY_ONEWAY) == 0)) {
552 sb.Append("\n");
553 sb.Append(prefix + TAB).AppendFormat(
554 "bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_%s, data, reply);",
555 ConstantName(mm->name_).string());
556 sb.Append("\n");
557 sb.Append(prefix + TAB).Append("if (hitCache == true) {\n");
558 EmitInterfaceProxyMethodErrCode(sb, prefix + TAB);
559 EmitInterfaceProxyMethodReply(mm, sb, prefix + TAB);
560 sb.Append(prefix + TAB + TAB).Append("return ERR_OK;\n");
561 sb.Append(prefix + TAB).Append("}\n\n");
562 }
563 }
564
EmitInterfaceProxyMethodPostSendRequest(MetaMethod * mm,StringBuilder & sb,const String & prefix)565 void CppCodeEmitter::EmitInterfaceProxyMethodPostSendRequest(MetaMethod* mm, StringBuilder& sb, const String& prefix)
566 {
567 sb.Append(prefix + TAB).AppendFormat(
568 "ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_%s, data, reply);\n",
569 ConstantName(mm->name_).string());
570 }
571
EmitInterfaceProxyMethodBody(MetaMethod * mm,StringBuilder & sb,const String & prefix)572 void CppCodeEmitter::EmitInterfaceProxyMethodBody(MetaMethod* mm, StringBuilder& sb, const String& prefix)
573 {
574 sb.Append(prefix).Append("{\n");
575 if (hitraceOn_) {
576 sb.Append(prefix + TAB).AppendFormat("HITRACE_METER_NAME(%s, __PRETTY_FUNCTION__);\n",
577 hitraceTag_.string());
578 }
579 sb.Append(prefix + TAB).Append("MessageParcel data;\n");
580 sb.Append(prefix + TAB).Append("MessageParcel reply;\n");
581 sb.Append(prefix + TAB).AppendFormat("MessageOption option(%s);\n",
582 (mm->properties_ & METHOD_PROPERTY_ONEWAY) != 0 ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC");
583 sb.Append("\n");
584 sb.Append(prefix + TAB).Append("if (!data.WriteInterfaceToken(GetDescriptor())) {\n");
585 if (logOn_) {
586 sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Write interface token failed!\");\n");
587 }
588 sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_VALUE;\n");
589 sb.Append(prefix + TAB).Append("}\n");
590 sb.Append("\n");
591
592 for (int i = 0; i < mm->parameterNumber_; i++) {
593 MetaParameter* mp = mm->parameters_[i];
594 if ((mp->attributes_ & ATTR_IN) != 0) {
595 EmitWriteMethodParameter(mp, "data.", sb, prefix + TAB);
596 }
597 }
598 EmitInterfaceProxyMethodPreSendRequest(mm, sb, prefix);
599 sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = Remote();\n");
600 sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
601 if (logOn_) {
602 sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Remote is nullptr!\");\n");
603 }
604 sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_DATA;\n");
605 sb.Append(prefix + TAB).Append("}\n\n");
606 sb.Append(prefix + TAB).AppendFormat("int32_t result = remote->SendRequest(COMMAND_%s, data, reply, option);\n",
607 ConstantName(mm->name_).string());
608 sb.Append(prefix + TAB).Append("if (FAILED(result)) {\n");
609 if (logOn_) {
610 sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Send request failed!\");\n");
611 }
612 sb.Append(prefix + TAB).Append(" return result;\n");
613 sb.Append(prefix + TAB).Append("}\n");
614 EmitInterfaceProxyMethodRetValue(mm, sb, prefix);
615 sb.Append(prefix).Append("}\n");
616 }
617
EmitInterfaceProxyMethodErrCode(StringBuilder & sb,const String & prefix)618 void CppCodeEmitter::EmitInterfaceProxyMethodErrCode(StringBuilder& sb, const String& prefix)
619 {
620 sb.Append(prefix + TAB).Append("ErrCode errCode = reply.ReadInt32();\n");
621 sb.Append(prefix + TAB).Append("if (FAILED(errCode)) {\n");
622 if (logOn_) {
623 sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Read Int32 failed!\");\n");
624 }
625 sb.Append(prefix + TAB).Append(" return errCode;\n");
626 sb.Append(prefix + TAB).Append("}\n");
627 }
628
EmitInterfaceProxyMethodReply(MetaMethod * mm,StringBuilder & sb,const String & prefix)629 void CppCodeEmitter::EmitInterfaceProxyMethodReply(MetaMethod* mm, StringBuilder& sb, const String& prefix)
630 {
631 for (int i = 0; i < mm->parameterNumber_; i++) {
632 MetaParameter* mp = mm->parameters_[i];
633 if ((mp->attributes_ & ATTR_OUT) != 0) {
634 EmitReadMethodParameter(mp, "reply.", sb, prefix + TAB);
635 }
636 }
637 MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
638 if (returnType->kind_ != TypeKind::Void) {
639 EmitReadVariable("reply.", "result", returnType, sb, prefix + TAB, false);
640 }
641 }
642
EmitInterfaceProxyMethodRetValue(MetaMethod * mm,StringBuilder & sb,const String & prefix)643 void CppCodeEmitter::EmitInterfaceProxyMethodRetValue(MetaMethod* mm, StringBuilder& sb, const String& prefix)
644 {
645 if ((mm->properties_ & METHOD_PROPERTY_ONEWAY) == 0) {
646 EmitInterfaceProxyMethodErrCode(sb, prefix);
647 sb.Append("\n");
648 if (mm->cacheable_ == true) {
649 EmitInterfaceProxyMethodPostSendRequest(mm, sb, prefix);
650 }
651 EmitInterfaceProxyMethodReply(mm, sb, prefix);
652 }
653 sb.Append(prefix + TAB).Append("return ERR_OK;\n");
654 }
655
EmitWriteMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & sb,const String & prefix)656 void CppCodeEmitter::EmitWriteMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& sb,
657 const String& prefix)
658 {
659 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
660 const std::string name = mp->name_;
661 EmitWriteVariable(parcelName, name, mt, sb, prefix);
662 }
663
EmitReadMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & sb,const String & prefix)664 void CppCodeEmitter::EmitReadMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& sb,
665 const String& prefix)
666 {
667 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
668 const std::string name = mp->name_;
669 EmitReadVariable(parcelName, name, mt, sb, prefix, false);
670 }
671
EmitInterfaceStub()672 void CppCodeEmitter::EmitInterfaceStub()
673 {
674 EmitInterfaceStubHeaderFile();
675 EmitInterfaceStubCppFile();
676 }
677
EmitInterfaceStubHeaderFile()678 void CppCodeEmitter::EmitInterfaceStubHeaderFile()
679 {
680 String filePath = String::Format("%s/%s.h", directory_.string(), FileName(stubName_).string());
681 File file(filePath, File::WRITE);
682
683 StringBuilder sb;
684
685 EmitLicense(sb);
686 sb.Append("\n");
687 EmitHeadMacro(sb, stubFullName_);
688 sb.Append("\n");
689 sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string());
690 sb.Append("#include <iremote_stub.h>\n");
691 sb.Append("\n");
692 EmitInterfaceStubInHeaderFile(sb);
693 EmitTailMacro(sb, stubFullName_);
694
695 String data = sb.ToString();
696 file.WriteData(data.string(), data.GetLength());
697 file.Flush();
698 file.Close();
699 }
700
EmitInterfaceStubInHeaderFile(StringBuilder & sb)701 void CppCodeEmitter::EmitInterfaceStubInHeaderFile(StringBuilder& sb)
702 {
703 EmitBeginNamespace(sb);
704 sb.AppendFormat("class %s : public IRemoteStub<%s> {\n", stubName_.string(), interfaceName_.string());
705 sb.Append("public:\n");
706 EmitInterfaceStubMethodDecls(sb, TAB);
707 sb.Append("\n");
708 sb.Append("private:\n");
709 EmitInterfaceStubConstants(sb, TAB);
710 sb.Append("};\n");
711 EmitEndNamespace(sb);
712 }
713
EmitInterfaceStubMethodDecls(StringBuilder & sb,const String & prefix)714 void CppCodeEmitter::EmitInterfaceStubMethodDecls(StringBuilder& sb, const String& prefix)
715 {
716 sb.Append(prefix).Append("int32_t OnRemoteRequest(\n");
717 sb.Append(prefix + TAB).Append("uint32_t code,\n");
718 sb.Append(prefix + TAB).Append("MessageParcel& data,\n");
719 sb.Append(prefix + TAB).Append("MessageParcel& reply,\n");
720 sb.Append(prefix + TAB).Append("MessageOption& option) override;\n");
721 }
722
EmitInterfaceStubConstants(StringBuilder & sb,const String & prefix)723 void CppCodeEmitter::EmitInterfaceStubConstants(StringBuilder& sb, const String& prefix)
724 {
725 EmitInterfaceMethodCommands(sb, prefix);
726 }
727
EmitInterfaceStubCppFile()728 void CppCodeEmitter::EmitInterfaceStubCppFile()
729 {
730 String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(stubName_).string());
731 File file(filePath, File::WRITE);
732
733 StringBuilder sb;
734
735 EmitLicense(sb);
736 sb.Append("\n");
737 sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string());
738 if (logOn_) {
739 sb.Append("#include \"hilog/log.h\"\n");
740 }
741 if (hitraceOn_) {
742 sb.Append("#include \"hitrace_meter.h\"\n");
743 }
744 sb.Append("\n");
745 if (logOn_) {
746 sb.Append("using OHOS::HiviewDFX::HiLog;\n\n");
747 }
748 EmitBeginNamespace(sb);
749 EmitInterfaceStubMethodImpls(sb, "");
750 EmitEndNamespace(sb);
751
752 String data = sb.ToString();
753 file.WriteData(data.string(), data.GetLength());
754 file.Flush();
755 file.Close();
756 }
757
EmitInterfaceStubMethodImpls(StringBuilder & sb,const String & prefix)758 void CppCodeEmitter::EmitInterfaceStubMethodImpls(StringBuilder& sb, const String& prefix)
759 {
760 sb.Append(prefix).AppendFormat("int32_t %s::OnRemoteRequest(\n", stubName_.string());
761 sb.Append(prefix + TAB).Append("uint32_t code,\n");
762 sb.Append(prefix + TAB).Append("MessageParcel& data,\n");
763 sb.Append(prefix + TAB).Append("MessageParcel& reply,\n");
764 sb.Append(prefix + TAB).Append("MessageOption& option)\n");
765 sb.Append(prefix).Append("{\n");
766 if (hitraceOn_) {
767 sb.Append(prefix + TAB).AppendFormat("HITRACE_METER_NAME(%s, __PRETTY_FUNCTION__);\n",
768 hitraceTag_.string());
769 }
770 sb.Append(prefix + TAB).Append("std::u16string localDescriptor = GetDescriptor();\n");
771 sb.Append(prefix + TAB).Append("std::u16string remoteDescriptor = data.ReadInterfaceToken();\n");
772 sb.Append(prefix + TAB).Append("if (localDescriptor != remoteDescriptor) {\n");
773 sb.Append(prefix + TAB).Append(TAB).Append("return ERR_TRANSACTION_FAILED;\n");
774 sb.Append(prefix + TAB).Append("}\n");
775 sb.Append(prefix + TAB).Append("switch (code) {\n");
776 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
777 MetaMethod* mm = metaInterface_->methods_[i];
778 EmitInterfaceStubMethodImpl(mm, sb, prefix + TAB + TAB);
779 }
780 sb.Append(prefix + TAB).Append(TAB).Append("default:\n");
781 sb.Append(prefix + TAB).Append(TAB).Append(TAB).Append(
782 "return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
783 sb.Append(prefix + TAB).Append("}\n\n");
784 sb.Append(prefix + TAB).Append("return ERR_TRANSACTION_FAILED;\n");
785 sb.Append(prefix).Append("}\n");
786 }
787
EmitInterfaceStubMethodImplReturn(MetaMethod * mm,StringBuilder & sb,const String & prefix,MetaType * returnType)788 void CppCodeEmitter::EmitInterfaceStubMethodImplReturn(MetaMethod* mm,
789 StringBuilder& sb, const String& prefix, MetaType* returnType)
790 {
791 if (returnType->kind_ != TypeKind::Void) {
792 if ((returnType->kind_ == TypeKind::Sequenceable) || (returnType->kind_ == TypeKind::Interface)) {
793 sb.Append(prefix + TAB).AppendFormat("%s result = nullptr;\n",
794 EmitType(returnType, ATTR_IN, true).string());
795 } else {
796 sb.Append(prefix + TAB).AppendFormat("%s result;\n", EmitType(returnType, ATTR_IN, true).string());
797 }
798 }
799 if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
800 sb.Append(prefix + TAB).AppendFormat("ErrCode errCode = %s();\n", mm->name_);
801 } else {
802 sb.Append(prefix + TAB).AppendFormat("ErrCode errCode = %s(", mm->name_);
803 for (int i = 0; i < mm->parameterNumber_; i++) {
804 MetaParameter* mp = mm->parameters_[i];
805 if (mp == nullptr) {
806 continue;
807 }
808 const std::string name = mp->name_;
809 MetaType* mGetType = metaComponent_->types_[mp->typeIndex_];
810 if (mGetType != nullptr && mGetType->kind_ == TypeKind::Sequenceable && !mp->isSequenceableForOut_) {
811 const std::string parameterName = "*" + name;
812 sb.Append(parameterName.c_str());
813 } else {
814 sb.Append(name.c_str());
815 }
816
817 if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
818 sb.Append(", ");
819 }
820 }
821 if (returnType->kind_ != TypeKind::Void) {
822 EmitReturnParameter("result", returnType, sb);
823 }
824 sb.AppendFormat(");\n", mm->name_);
825 }
826 }
827
EmitInterfaceStubMethodImpl(MetaMethod * mm,StringBuilder & sb,const String & prefix)828 void CppCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
829 {
830 sb.Append(prefix).AppendFormat("case COMMAND_%s: {\n", ConstantName(mm->name_).string());
831 for (int i = 0; i < mm->parameterNumber_; i++) {
832 MetaParameter* mp = mm->parameters_[i];
833 if ((mp->attributes_ & ATTR_IN) != 0) {
834 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
835 const std::string name = mp->name_;
836 EmitReadVariable("data.", name, mt, sb, prefix + TAB);
837 } else if ((mp->attributes_ & ATTR_OUT) != 0) {
838 EmitLocalVariable(mp, sb, prefix + TAB);
839 }
840 }
841 MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
842 if (returnType == nullptr) {
843 return;
844 }
845 EmitInterfaceStubMethodImplReturn(mm, sb, prefix, returnType);
846
847 sb.Append(prefix + TAB).Append("if (!reply.WriteInt32(errCode)) {\n");
848 if (logOn_) {
849 sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Write Int32 failed!\");\n");
850 }
851 sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_VALUE;\n");
852 sb.Append(prefix + TAB).Append("}\n");
853 bool hasOutParameter = false;
854 for (int i = 0; i < mm->parameterNumber_; i++) {
855 MetaParameter* mp = mm->parameters_[i];
856 if ((mp->attributes_ & ATTR_OUT) != 0) {
857 hasOutParameter = true;
858 }
859 }
860 if (hasOutParameter || returnType->kind_ != TypeKind::Void) {
861 sb.Append(prefix + TAB).Append("if (SUCCEEDED(errCode)) {\n");
862 for (int i = 0; i < mm->parameterNumber_; i++) {
863 MetaParameter* mp = mm->parameters_[i];
864 if ((mp->attributes_ & ATTR_OUT) != 0) {
865 EmitWriteMethodParameter(mp, "reply.", sb, prefix + TAB + TAB);
866 }
867 }
868 if (returnType->kind_ != TypeKind::Void) {
869 EmitWriteVariable("reply.", "result", returnType, sb, prefix + TAB + TAB);
870 }
871 sb.Append(prefix + TAB).Append("}\n");
872 }
873 sb.Append(prefix + TAB).Append("return ERR_NONE;\n");
874 sb.Append(prefix).Append("}\n");
875 }
876
EmitInterfaceMethodCommands(StringBuilder & sb,const String & prefix)877 void CppCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& sb, const String& prefix)
878 {
879 for (int i = 0; i < metaInterface_->methodNumber_; i++) {
880 MetaMethod* mm = metaInterface_->methods_[i];
881 sb.Append(prefix).AppendFormat("static constexpr int32_t COMMAND_%s = MIN_TRANSACTION_ID + %d;\n",
882 ConstantName(mm->name_).string(), i);
883 }
884 }
885
EmitLicense(StringBuilder & sb)886 void CppCodeEmitter::EmitLicense(StringBuilder& sb)
887 {
888 sb.Append(metaInterface_->license_).Append("\n");
889 }
890
EmitHeadMacro(StringBuilder & sb,const String & fullName)891 void CppCodeEmitter::EmitHeadMacro(StringBuilder& sb, const String& fullName)
892 {
893 String macroName = MacroName(fullName);
894 sb.Append("#ifndef ").Append(macroName).Append("\n");
895 sb.Append("#define ").Append(macroName).Append("\n");
896 }
897
EmitTailMacro(StringBuilder & sb,const String & fullName)898 void CppCodeEmitter::EmitTailMacro(StringBuilder& sb, const String& fullName)
899 {
900 String macroName = MacroName(fullName);
901 sb.Append("#endif // ").Append(macroName).Append("\n\n");
902 }
903
EmitBeginNamespace(StringBuilder & sb)904 void CppCodeEmitter::EmitBeginNamespace(StringBuilder& sb)
905 {
906 String nspace = GetNamespace(metaInterface_->namespace_);
907 int index = nspace.IndexOf('.');
908 while (index != -1) {
909 sb.AppendFormat("namespace %s {\n", nspace.Substring(0, index).string());
910 nspace = nspace.Substring(index + 1);
911 index = nspace.IndexOf('.');
912 }
913 }
914
EmitEndNamespace(StringBuilder & sb)915 void CppCodeEmitter::EmitEndNamespace(StringBuilder& sb)
916 {
917 String nspace = GetNamespace(metaInterface_->namespace_);
918 nspace = nspace.Substring(0, nspace.GetLength() - 1);
919 while (!nspace.IsEmpty()) {
920 int index = nspace.LastIndexOf('.');
921 sb.AppendFormat("} // namespace %s\n", index != -1 ?
922 nspace.Substring(index + 1, nspace.GetLength()).string() : nspace.string());
923 nspace = nspace.Substring(0, index);
924 }
925 }
926
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)927 void CppCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
928 StringBuilder& sb, const String& prefix)
929 {
930 switch (mt->kind_) {
931 case TypeKind::Boolean:
932 sb.Append(prefix).AppendFormat("if (!%sWriteInt32(%s ? 1 : 0)) {\n", parcelName.string(), name.c_str());
933 if (logOn_) {
934 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
935 name.c_str());
936 }
937 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
938 sb.Append(prefix).Append("}\n");
939 break;
940 case TypeKind::Char:
941 case TypeKind::Byte:
942 case TypeKind::Short:
943 case TypeKind::Integer:
944 sb.Append(prefix).AppendFormat("if (!%sWriteInt32(%s)) {\n", parcelName.string(), name.c_str());
945 if (logOn_) {
946 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
947 name.c_str());
948 }
949 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
950 sb.Append(prefix).Append("}\n");
951 break;
952 case TypeKind::Long:
953 sb.Append(prefix).AppendFormat("if (!%sWriteInt64(%s)) {\n", parcelName.string(), name.c_str());
954 if (logOn_) {
955 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
956 name.c_str());
957 }
958 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
959 sb.Append(prefix).Append("}\n");
960 break;
961 default:
962 EmitWriteVariableFloat(parcelName, name, mt, sb, prefix);
963 break;
964 }
965 }
966
EmitWriteVariableFloat(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)967 void CppCodeEmitter::EmitWriteVariableFloat(
968 const String& parcelName, const std::string& name, MetaType* mt, StringBuilder& sb, const String& prefix)
969 {
970 switch (mt->kind_) {
971 case TypeKind::Float:
972 sb.Append(prefix).AppendFormat("if (!%sWriteFloat(%s)) {\n", parcelName.string(), name.c_str());
973 if (logOn_) {
974 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
975 name.c_str());
976 }
977 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
978 sb.Append(prefix).Append("}\n");
979 break;
980 case TypeKind::Double:
981 sb.Append(prefix).AppendFormat("if (!%sWriteDouble(%s)) {\n", parcelName.string(), name.c_str());
982 if (logOn_) {
983 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
984 name.c_str());
985 }
986 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
987 sb.Append(prefix).Append("}\n");
988 break;
989 default:
990 EmitWriteVariableComplex(parcelName, name, mt, sb, prefix);
991 break;
992 }
993 }
994
EmitWriteVariableComplex(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)995 void CppCodeEmitter::EmitWriteVariableComplex(
996 const String& parcelName, const std::string& name, MetaType* mt, StringBuilder& sb, const String& prefix)
997 {
998 switch (mt->kind_) {
999 case TypeKind::Array:
1000 case TypeKind::List: {
1001 sb.Append(prefix).AppendFormat("if (%s.size() > static_cast<size_t>(VECTOR_MAX_SIZE)) {\n", name.c_str());
1002 if (logOn_) {
1003 if (mt != nullptr && mt->kind_ == TypeKind::Array) {
1004 sb.Append(prefix).Append(TAB).Append(
1005 "HiLog::Error(LABEL, \"The vector/array size exceeds the security limit!\");\n");
1006 } else {
1007 sb.Append(prefix).Append(TAB).AppendFormat(
1008 "HiLog::Error(LABEL, \"The list size exceeds the security limit!\");\n");
1009 }
1010 }
1011 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1012 sb.Append(prefix).Append("}\n");
1013 sb.Append(prefix).AppendFormat("%sWriteInt32(%s.size());\n", parcelName.string(), name.c_str());
1014 sb.Append(prefix).AppendFormat("for (auto it = %s.begin(); it != %s.end(); ++it) {\n",
1015 name.c_str(), name.c_str());
1016 if (mt != nullptr) {
1017 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1018 EmitWriteVariable(parcelName, "(*it)", innerType, sb, prefix + TAB);
1019 sb.Append(prefix).Append("}\n");
1020 }
1021 break;
1022 }
1023 case TypeKind::Map: {
1024 sb.Append(prefix).AppendFormat("if (%s.size() > static_cast<size_t>(MAP_MAX_SIZE)) {\n", name.c_str());
1025 if (logOn_) {
1026 sb.Append(prefix).Append(TAB).AppendFormat(
1027 "HiLog::Error(LABEL, \"The map size exceeds the security limit!\");\n");
1028 }
1029 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1030 sb.Append(prefix).Append("}\n");
1031 sb.Append("\n");
1032 sb.Append(prefix).AppendFormat("%sWriteInt32(%s.size());\n", parcelName.string(), name.c_str());
1033 sb.Append(prefix).AppendFormat("for (auto it = %s.begin(); it != %s.end(); ++it) {\n",
1034 name.c_str(), name.c_str());
1035 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1036 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1037 EmitWriteVariable(parcelName, "(it->first)", keyType, sb, prefix + TAB);
1038 EmitWriteVariable(parcelName, "(it->second)", valueType, sb, prefix + TAB);
1039 sb.Append(prefix).Append("}\n");
1040 break;
1041 }
1042 default:
1043 EmitWriteVariableObject(parcelName, name, mt, sb, prefix);
1044 break;
1045 }
1046 }
1047
EmitWriteVariableObject(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)1048 void CppCodeEmitter::EmitWriteVariableObject(
1049 const String& parcelName, const std::string& name, MetaType* mt, StringBuilder& sb, const String& prefix)
1050 {
1051 switch (mt->kind_) {
1052 case TypeKind::String:
1053 sb.Append(prefix).AppendFormat("if (!%sWriteString16(Str8ToStr16(%s))) {\n", parcelName.string(),
1054 name.c_str());
1055 if (logOn_) {
1056 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
1057 name.c_str());
1058 }
1059 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1060 sb.Append(prefix).Append("}\n");
1061 break;
1062 case TypeKind::Sequenceable:
1063 sb.Append(prefix).AppendFormat("if (!%sWriteParcelable(&%s)) {\n", parcelName.string(), name.c_str());
1064 if (logOn_) {
1065 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
1066 name.c_str());
1067 }
1068 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1069 sb.Append(prefix).Append("}\n");
1070 break;
1071 case TypeKind::Interface:
1072 sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
1073 if (logOn_) {
1074 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"%s is nullptr!\");\n", name.c_str());
1075 }
1076 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1077 sb.Append(prefix).Append("}\n");
1078 sb.Append(prefix).AppendFormat(
1079 "if (!%sWriteRemoteObject(%s->AsObject())) {\n", parcelName.string(), name.c_str());
1080 if (logOn_) {
1081 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
1082 name.c_str());
1083 }
1084 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1085 sb.Append(prefix).Append("}\n");
1086 break;
1087 default:
1088 break;
1089 }
1090 }
1091
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1092 void CppCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
1093 StringBuilder& sb, const String& prefix, bool emitType)
1094 {
1095 switch (mt->kind_) {
1096 case TypeKind::Boolean:
1097 if (emitType) {
1098 sb.Append(prefix).AppendFormat("%s %s = %sReadInt32() == 1 ? true : false;\n",
1099 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1100 } else {
1101 sb.Append(prefix).AppendFormat("%s = %sReadInt32() == 1 ? true : false;\n",
1102 name.c_str(), parcelName.string());
1103 }
1104 break;
1105 case TypeKind::Char:
1106 case TypeKind::Byte:
1107 case TypeKind::Short:
1108 if (emitType) {
1109 sb.Append(prefix).AppendFormat("%s %s = (%s)%sReadInt32();\n", EmitType(mt, ATTR_IN, true).string(),
1110 name.c_str(), EmitType(mt, ATTR_IN, true).string(), parcelName.string());
1111 } else {
1112 sb.Append(prefix).AppendFormat("%s = (%s)%sReadInt32();\n", name.c_str(),
1113 EmitType(mt, ATTR_IN, true).string(), parcelName.string());
1114 }
1115 break;
1116 case TypeKind::Integer:
1117 if (emitType) {
1118 sb.Append(prefix).AppendFormat("%s %s = %sReadInt32();\n",
1119 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1120 } else {
1121 sb.Append(prefix).AppendFormat("%s = %sReadInt32();\n", name.c_str(), parcelName.string());
1122 }
1123 break;
1124 case TypeKind::Long:
1125 if (emitType) {
1126 sb.Append(prefix).AppendFormat("%s %s = %sReadInt64();\n",
1127 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1128 } else {
1129 sb.Append(prefix).AppendFormat("%s = %sReadInt64();\n", name.c_str(), parcelName.string());
1130 }
1131 break;
1132 default:
1133 EmitReadVariableFloat(parcelName, name, mt, sb, prefix, emitType);
1134 break;
1135 }
1136 }
1137
EmitReadVariableFloat(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1138 void CppCodeEmitter::EmitReadVariableFloat(const String& parcelName, const std::string& name, MetaType* mt,
1139 StringBuilder& sb, const String& prefix, bool emitType)
1140 {
1141 switch (mt->kind_) {
1142 case TypeKind::Float:
1143 if (emitType) {
1144 sb.Append(prefix).AppendFormat("%s %s = %sReadFloat();\n",
1145 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1146 } else {
1147 sb.Append(prefix).AppendFormat("%s = %sReadFloat();\n", name.c_str(), parcelName.string());
1148 }
1149 break;
1150 case TypeKind::Double:
1151 if (emitType) {
1152 sb.Append(prefix).AppendFormat("%s %s = %sReadDouble();\n",
1153 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1154 } else {
1155 sb.Append(prefix).AppendFormat("%s = %sReadDouble();\n", name.c_str(), parcelName.string());
1156 }
1157 break;
1158 default:
1159 EmitReadVariableComplex(parcelName, name, mt, sb, prefix, emitType);
1160 break;
1161 }
1162 }
1163
EmitReadVariableComplex(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1164 void CppCodeEmitter::EmitReadVariableComplex(const String& parcelName, const std::string& name, MetaType* mt,
1165 StringBuilder& sb, const String& prefix, bool emitType)
1166 {
1167 switch (mt->kind_) {
1168 case TypeKind::String:
1169 if (emitType) {
1170 sb.Append(prefix).AppendFormat("%s %s = Str16ToStr8(%sReadString16());\n",
1171 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1172 } else {
1173 sb.Append(prefix).AppendFormat("%s = Str16ToStr8(%sReadString16());\n",
1174 name.c_str(), parcelName.string());
1175 }
1176 break;
1177 case TypeKind::Map: {
1178 if (emitType) {
1179 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1180 }
1181 sb.Append(prefix).AppendFormat("int32_t %sSize = %sReadInt32();\n", name.c_str(), parcelName.string());
1182 sb.Append(prefix).AppendFormat("for (int32_t i = 0; i < %sSize; ++i) {\n", name.c_str());
1183 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1184 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1185 EmitReadVariable(parcelName, "key", keyType, sb, prefix + TAB);
1186 EmitReadVariable(parcelName, "value", valueType, sb, prefix + TAB);
1187 sb.Append(prefix + TAB).AppendFormat("%s[key] = value;\n", name.c_str());
1188 sb.Append(prefix).Append("}\n");
1189 break;
1190 }
1191 default:
1192 EmitReadVariableList(parcelName, name, mt, sb, prefix, emitType);
1193 break;
1194 }
1195 }
1196
EmitReadVariableList(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1197 void CppCodeEmitter::EmitReadVariableList(const String& parcelName, const std::string& name, MetaType* mt,
1198 StringBuilder& sb, const String& prefix, bool emitType)
1199 {
1200 switch (mt->kind_) {
1201 case TypeKind::Array:
1202 case TypeKind::List: {
1203 if (emitType) {
1204 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1205 }
1206 sb.Append(prefix).AppendFormat("int32_t %sSize = %sReadInt32();\n", name.c_str(), parcelName.string());
1207 sb.Append(prefix).AppendFormat("if (%sSize > static_cast<int32_t>(VECTOR_MAX_SIZE)) {\n", name.c_str());
1208 if (logOn_) {
1209 sb.Append(prefix + TAB)
1210 .Append("HiLog::Error(LABEL, \"The vector/array size exceeds the security limit!\");\n");
1211 }
1212 sb.Append(prefix + TAB).Append("return ERR_INVALID_DATA;\n");
1213 sb.Append(prefix).Append("}\n");
1214 circleCount++;
1215 std::stringstream circleCountStr;
1216 circleCountStr << circleCount;
1217 std::string iStr = "i" + circleCountStr.str();
1218 std::string valueStr = "value" + circleCountStr.str();
1219 sb.Append(prefix).AppendFormat("for (int32_t %s = 0; %s < %sSize; ++%s) {\n",
1220 iStr.c_str(), iStr.c_str(), name.c_str(), iStr.c_str());
1221 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1222 EmitReadVariable(parcelName, valueStr.c_str(), innerType, sb, prefix + TAB);
1223 if (innerType->kind_ == TypeKind::Sequenceable) {
1224 sb.Append(prefix + TAB).AppendFormat("%s.push_back(*%s);\n", name.c_str(), valueStr.c_str());
1225 } else {
1226 sb.Append(prefix + TAB).AppendFormat("%s.push_back(%s);\n", name.c_str(), valueStr.c_str());
1227 }
1228 sb.Append(prefix).Append("}\n");
1229 break;
1230 }
1231 default:
1232 EmitReadVariableObject(parcelName, name, mt, sb, prefix, emitType);
1233 break;
1234 }
1235 }
1236
EmitReadVariableObject(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1237 void CppCodeEmitter::EmitReadVariableObject(const String& parcelName, const std::string& name, MetaType* mt,
1238 StringBuilder& sb, const String& prefix, bool emitType)
1239 {
1240 switch (mt->kind_) {
1241 case TypeKind::Sequenceable: {
1242 MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1243 if (mp == nullptr) {
1244 break;
1245 }
1246 if (emitType) {
1247 readSequenceable_ = true;
1248 sb.Append(prefix).AppendFormat("std::unique_ptr<%s> %s(%sReadParcelable<%s>());\n\n",
1249 EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string(), mp->name_);
1250 sb.Append(prefix).AppendFormat("if (!%s) {\n", name.c_str());
1251 if (logOn_) {
1252 sb.Append(prefix).Append(TAB).AppendFormat(
1253 "HiLog::Error(LABEL, \"Read [%s] failed!\");\n", mp->name_);
1254 }
1255 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1256 sb.Append(prefix).Append("}\n");
1257 } else {
1258 sb.Append(prefix).AppendFormat("std::unique_ptr<%s> info(%sReadParcelable<%s>());\n",
1259 mp->name_, parcelName.string(), mp->name_);
1260 sb.Append(prefix).Append("if (info != nullptr) {\n");
1261 sb.Append(prefix).Append(TAB).AppendFormat("%s = *info;\n", name.c_str());
1262 sb.Append(prefix).Append("}\n\n");
1263 }
1264 break;
1265 }
1266 case TypeKind::Interface: {
1267 MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1268 if (emitType) {
1269 sb.Append(prefix).AppendFormat("%s %s = iface_cast<%s>(%sReadRemoteObject());\n",
1270 EmitType(mt, ATTR_IN, true).string(), name.c_str(), mi->name_, parcelName.string());
1271 sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
1272 if (logOn_) {
1273 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Read [%s] failed!\");\n",
1274 name.c_str());
1275 }
1276 sb.Append(prefix).Append(TAB).AppendFormat("return ERR_INVALID_DATA;\n");
1277 sb.Append(prefix).Append("}\n\n");
1278 } else {
1279 sb.Append(prefix).AppendFormat("%s = iface_cast<%s>(%sReadRemoteObject());\n",
1280 name.c_str(), mi->name_, parcelName.string());
1281 }
1282 break;
1283 }
1284 default:
1285 break;
1286 }
1287 }
1288
EmitLocalVariable(MetaParameter * mp,StringBuilder & sb,const String & prefix)1289 void CppCodeEmitter::EmitLocalVariable(MetaParameter* mp, StringBuilder& sb, const String& prefix)
1290 {
1291 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
1292 const std::string name = mp->name_;
1293 if ((mt->kind_ == TypeKind::Sequenceable) || (mt->kind_ == TypeKind::Interface)) {
1294 createSequenceableForOut_ = true;
1295 mp->isSequenceableForOut_ = true;
1296 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1297 } else {
1298 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1299 }
1300 }
1301
EmitReturnParameter(const String & name,MetaType * mt,StringBuilder & sb)1302 void CppCodeEmitter::EmitReturnParameter(const String& name, MetaType* mt, StringBuilder& sb)
1303 {
1304 switch (mt->kind_) {
1305 case TypeKind::Char:
1306 case TypeKind::Boolean:
1307 case TypeKind::Byte:
1308 case TypeKind::Short:
1309 case TypeKind::Integer:
1310 case TypeKind::Long:
1311 case TypeKind::Float:
1312 case TypeKind::Double:
1313 case TypeKind::String:
1314 case TypeKind::Sequenceable:
1315 case TypeKind::Interface:
1316 case TypeKind::List:
1317 case TypeKind::Map:
1318 case TypeKind::Array:
1319 sb.Append(name);
1320 break;
1321 default:
1322 break;
1323 }
1324 }
1325
EmitType(MetaType * mt,unsigned int attributes,bool isInnerType)1326 String CppCodeEmitter::EmitType(MetaType* mt, unsigned int attributes, bool isInnerType)
1327 {
1328 switch (mt->kind_) {
1329 case TypeKind::Char:
1330 enteredVector_ = false;
1331 if (attributes & ATTR_IN) {
1332 return "zchar";
1333 } else {
1334 return "zchar&";
1335 }
1336 case TypeKind::Boolean:
1337 enteredVector_ = false;
1338 if (attributes & ATTR_IN) {
1339 return "bool";
1340 } else {
1341 return "bool&";
1342 }
1343 case TypeKind::Byte:
1344 enteredVector_ = false;
1345 if (attributes & ATTR_IN) {
1346 return "int8_t";
1347 } else {
1348 return "int8_t&";
1349 }
1350 case TypeKind::Short:
1351 enteredVector_ = false;
1352 if (attributes & ATTR_IN) {
1353 return "short";
1354 } else {
1355 return "short&";
1356 }
1357 case TypeKind::Integer:
1358 enteredVector_ = false;
1359 if (attributes & ATTR_IN) {
1360 return "int32_t";
1361 } else {
1362 return "int32_t&";
1363 }
1364 case TypeKind::Long:
1365 enteredVector_ = false;
1366 if (attributes & ATTR_IN) {
1367 return "long";
1368 } else {
1369 return "long&";
1370 }
1371 default:
1372 return EmitFloatType(mt, attributes, isInnerType);
1373 }
1374 }
1375
1376
EmitFloatType(MetaType * mt,unsigned int attributes,bool isInnerType)1377 String CppCodeEmitter::EmitFloatType(MetaType* mt, unsigned int attributes, bool isInnerType)
1378 {
1379 switch (mt->kind_) {
1380 case TypeKind::Float:
1381 enteredVector_ = false;
1382 if (attributes & ATTR_IN) {
1383 return "float";
1384 } else {
1385 return "float&";
1386 }
1387 case TypeKind::Double:
1388 enteredVector_ = false;
1389 if (attributes & ATTR_IN) {
1390 return "double";
1391 } else {
1392 return "double&";
1393 }
1394 case TypeKind::Void:
1395 enteredVector_ = false;
1396 return "void";
1397 default:
1398 return EmitComplexType(mt, attributes, isInnerType);
1399 }
1400 }
1401
EmitComplexType(MetaType * mt,unsigned int attributes,bool isInnerType)1402 String CppCodeEmitter::EmitComplexType(MetaType* mt, unsigned int attributes, bool isInnerType)
1403 {
1404 switch (mt->kind_) {
1405 case TypeKind::String:
1406 enteredVector_ = false;
1407 if (attributes & ATTR_IN) {
1408 if (!isInnerType) {
1409 return "const std::string&";
1410 } else {
1411 return "std::string";
1412 }
1413 } else {
1414 return "std::string&";
1415 }
1416 case TypeKind::Map: {
1417 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1418 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1419 if (attributes & ATTR_OUT) {
1420 return String::Format("std::unordered_map<%s, %s>&",
1421 EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1422 } else {
1423 if (!isInnerType) {
1424 return String::Format("const std::unordered_map<%s, %s>&",
1425 EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1426 } else {
1427 return String::Format("std::unordered_map<%s, %s>",
1428 EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1429 }
1430 }
1431 break;
1432 }
1433 default:
1434 return EmitListType(mt, attributes, isInnerType);
1435 }
1436 }
1437
EmitListType(MetaType * mt,unsigned int attributes,bool isInnerType)1438 String CppCodeEmitter::EmitListType(MetaType* mt, unsigned int attributes, bool isInnerType)
1439 {
1440 switch (mt->kind_) {
1441 case TypeKind::Array:
1442 case TypeKind::List: {
1443 enteredVector_ = true;
1444 MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1445 if (attributes & ATTR_OUT) {
1446 return String::Format("std::vector<%s>&",
1447 EmitType(elementType, ATTR_IN, true).string());
1448 } else {
1449 if (!isInnerType) {
1450 return String::Format("const std::vector<%s>&",
1451 EmitType(elementType, ATTR_IN, true).string());
1452 } else {
1453 return String::Format("std::vector<%s>",
1454 EmitType(elementType, ATTR_IN, true).string());
1455 }
1456 }
1457 }
1458 default:
1459 return EmitObjectType(mt, attributes, isInnerType);
1460 }
1461 }
1462
EmitObjectType(MetaType * mt,unsigned int attributes,bool isInnerType)1463 String CppCodeEmitter::EmitObjectType(MetaType* mt, unsigned int attributes, bool isInnerType)
1464 {
1465 switch (mt->kind_) {
1466 case TypeKind::Sequenceable: {
1467 MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1468 if (mp == nullptr) {
1469 return "unknown type";
1470 }
1471 if (enteredVector_) {
1472 enteredVector_ = false;
1473 return String::Format("%s", mp->name_);
1474 }
1475 if (readSequenceable_) {
1476 readSequenceable_ = false;
1477 return String::Format("%s", mp->name_);
1478 }
1479 if (createSequenceableForOut_) {
1480 createSequenceableForOut_ = false;
1481 return String::Format("%s", mp->name_);
1482 }
1483 if ((attributes & ATTR_MASK) == (ATTR_IN | ATTR_OUT)) {
1484 return String::Format("%s*", mp->name_);
1485 } else if (attributes & ATTR_IN) {
1486 return String::Format("const %s&", mp->name_);
1487 } else {
1488 return String::Format("%s&", mp->name_);
1489 }
1490 }
1491 case TypeKind::Interface: {
1492 MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1493 if (mi == nullptr) {
1494 return "unknown type";
1495 }
1496 if (attributes & ATTR_IN) {
1497 if (!isInnerType) {
1498 return String::Format("const sptr<%s>&", mi->name_);
1499 } else {
1500 return String::Format("sptr<%s>", mi->name_);
1501 }
1502 } else {
1503 return String::Format("sptr<%s>&", mi->name_);
1504 }
1505 }
1506 default:
1507 return "unknown type";
1508 }
1509 }
1510
CppFullName(const String & name)1511 String CppCodeEmitter::CppFullName(const String& name)
1512 {
1513 if (name.IsEmpty()) {
1514 return name;
1515 }
1516
1517 return name.Replace(".", "::");
1518 }
1519
FileName(const String & name)1520 String CppCodeEmitter::FileName(const String& name)
1521 {
1522 if (name.IsEmpty()) {
1523 return name;
1524 }
1525
1526 StringBuilder sb;
1527
1528 for (int i = 0; i < name.GetLength(); i++) {
1529 char c = name[i];
1530 if (isupper(c) != 0) {
1531 // 2->Index of the last char array.
1532 if (i > 1 && name[i - 1] != '.' && name[i - 2] != '.') {
1533 sb.Append('_');
1534 }
1535 sb.Append(tolower(c));
1536 } else {
1537 sb.Append(c);
1538 }
1539 }
1540
1541 return sb.ToString().Replace('.', '/');
1542 }
1543
MacroName(const String & name)1544 String CppCodeEmitter::MacroName(const String& name)
1545 {
1546 if (name.IsEmpty()) {
1547 return name;
1548 }
1549
1550 String macro = name.Replace('.', '_').ToUpperCase() + "_H";
1551 return macro;
1552 }
1553
ConstantName(const String & name)1554 String CppCodeEmitter::ConstantName(const String& name)
1555 {
1556 if (name.IsEmpty()) {
1557 return name;
1558 }
1559
1560 StringBuilder sb;
1561
1562 for (int i = 0; i < name.GetLength(); i++) {
1563 char c = name[i];
1564 if (isupper(c) != 0) {
1565 if (i > 1) {
1566 sb.Append('_');
1567 }
1568 sb.Append(c);
1569 } else {
1570 sb.Append(toupper(c));
1571 }
1572 }
1573
1574 return sb.ToString();
1575 }
1576
UnderlineAdded(const String & originName)1577 const std::string CppCodeEmitter::UnderlineAdded(const String& originName)
1578 {
1579 std::string underline("_");
1580 return underline + std::string(originName.string());
1581 }
1582 } // namespace Idl
1583 } // namespace OHOS