• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "codegen/cpp_code_emitter.h"
17 
18 #include "securec.h"
19 #include "util/file.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     for (int i = 0; i < metaComponent_->typeNumber_; i++) {
67         MetaType* mt = metaComponent_->types_[i];
68         switch (mt->kind_) {
69             case TypeKind::Byte: {
70                 if (!includeNum) {
71                     sb.Append("#include <cstdint>\n");
72                     includeNum = true;
73                 }
74                 break;
75             }
76             case TypeKind::String: {
77                 if (!includeString) {
78                     sb.Append("#include <string_ex.h>\n");
79                     includeString = true;
80                 }
81                 break;
82             }
83             case TypeKind::Array:
84             case TypeKind::List: {
85                 if (!includeList) {
86                     sb.Append("#include <vector>\n");
87                     includeList = true;
88                 }
89                 break;
90             }
91             case TypeKind::Map: {
92                 if (!includeMap) {
93                     sb.Append("#include <unordered_map>\n");
94                     includeMap = true;
95                 }
96                 break;
97             }
98             default:
99                 break;
100         }
101     }
102 }
103 
EmitInterfaceDBinderInclusions(StringBuilder & sb)104 void CppCodeEmitter::EmitInterfaceDBinderInclusions(StringBuilder& sb)
105 {
106     sb.Append("#include <iremote_broker.h>\n");
107 }
108 
GetFilePath(const String & fpnp)109 String CppCodeEmitter::GetFilePath(const String& fpnp)
110 {
111     int pos = fpnp.IndexOf("..");
112     if (pos == -1) {
113         return String();
114     }
115     String res = fpnp.Substring(0, pos + 1);
116     return res;
117 }
118 
GetNamespace(const String & fpnp)119 String CppCodeEmitter::GetNamespace(const String& fpnp)
120 {
121     int pos = fpnp.IndexOf("..");
122     if (pos == -1) {
123         return fpnp;
124     }
125     String res = fpnp.Substring(pos + 2);
126     return res;
127 }
128 
EmitInterfaceSelfDefinedTypeInclusions(StringBuilder & sb)129 void CppCodeEmitter::EmitInterfaceSelfDefinedTypeInclusions(StringBuilder& sb)
130 {
131     for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
132         MetaSequenceable* mp = metaComponent_->sequenceables_[i];
133         String filePath = GetFilePath(String(mp->namespace_));
134         String fileName = FileName(filePath + mp->name_);
135         sb.Append("#include ").AppendFormat("\"%s.h\"\n", fileName.string());
136     }
137 
138     for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
139         MetaInterface* mi = metaComponent_->interfaces_[i];
140         if (mi->external_) {
141             String filePath = GetFilePath(String(mi->namespace_));
142             String fileName = FileName(filePath + mi->name_);
143             sb.Append("#include ").AppendFormat("\"%s.h\"\n", fileName.string());
144         }
145     }
146 }
147 
EmitInterfaceUsings(StringBuilder & sb)148 bool CppCodeEmitter::EmitInterfaceUsings(StringBuilder& sb)
149 {
150     bool ret = false;
151     for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
152         MetaSequenceable* mp = metaComponent_->sequenceables_[i];
153         String np = GetNamespace(String(mp->namespace_));
154         if (np.IsEmpty()) {
155             continue;
156         }
157         String fullName = CppFullName(np + mp->name_);
158         sb.Append("using ").AppendFormat("%s;\n", fullName.string());
159         ret = true;
160     }
161 
162     for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
163         MetaInterface* mi = metaComponent_->interfaces_[i];
164         if (mi->external_) {
165             String np = GetNamespace(String(mi->namespace_));
166             if (np.IsEmpty()) {
167                 continue;
168             }
169             String fullName = CppFullName(np + mi->name_);
170             sb.Append("using ").AppendFormat("%s;\n", fullName.string());
171             ret = true;
172         }
173     }
174     return ret;
175 }
176 
EmitInterfaceDefinition(StringBuilder & sb)177 void CppCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb)
178 {
179     EmitBeginNamespace(sb);
180     sb.AppendFormat("class %s : public IRemoteBroker {\n", metaInterface_->name_);
181     sb.Append("public:\n");
182     EmitInterfaceBody(sb, TAB);
183     sb.Append("};\n");
184     EmitEndNamespace(sb);
185 }
186 
EmitInterfaceBody(StringBuilder & sb,const String & prefix)187 void CppCodeEmitter::EmitInterfaceBody(StringBuilder& sb, const String& prefix)
188 {
189     String nameWithoutPath = GetNamespace(interfaceFullName_);
190     sb.Append(TAB).AppendFormat("DECLARE_INTERFACE_DESCRIPTOR(u\"%s\");\n", nameWithoutPath.string());
191     sb.Append("\n");
192     EmitInterfaceMethods(sb, TAB);
193 }
194 
EmitInterfaceMethods(StringBuilder & sb,const String & prefix)195 void CppCodeEmitter::EmitInterfaceMethods(StringBuilder& sb, const String& prefix)
196 {
197     if (metaInterface_->methodNumber_ > 0) {
198         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
199             MetaMethod* mm = metaInterface_->methods_[i];
200             EmitInterfaceMethod(mm, sb, prefix);
201             if (i != metaInterface_->methodNumber_ - 1) {
202                 sb.Append("\n");
203             }
204         }
205     }
206 }
207 
EmitInterfaceMethod(MetaMethod * mm,StringBuilder & sb,const String & prefix)208 void CppCodeEmitter::EmitInterfaceMethod(MetaMethod* mm, StringBuilder& sb, const String& prefix)
209 {
210     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
211     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
212         sb.Append(prefix).AppendFormat("virtual ErrCode %s() = 0;\n", mm->name_);
213     } else {
214         sb.Append(prefix).AppendFormat("virtual ErrCode %s(\n", mm->name_);
215         for (int i = 0; i < mm->parameterNumber_; i++) {
216             MetaParameter* mp = mm->parameters_[i];
217             EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
218             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
219                 sb.Append(",\n");
220             }
221         }
222         if (returnType->kind_ != TypeKind::Void) {
223             EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
224         }
225         sb.Append(") = 0;\n");
226     }
227 }
228 
EmitInterfaceMethodParameter(MetaParameter * mp,StringBuilder & sb,const String & prefix)229 void CppCodeEmitter::EmitInterfaceMethodParameter(MetaParameter* mp, StringBuilder& sb, const String& prefix)
230 {
231     if ((mp->attributes_ & ATTR_MASK) == (ATTR_IN | ATTR_OUT)) {
232         sb.Append(prefix).Append("/* [in, out] */ ");
233     } else if (mp->attributes_ & ATTR_IN) {
234         sb.Append(prefix).Append("/* [in] */ ");
235     } else {
236         sb.Append(prefix).Append("/* [out] */ ");
237     }
238 
239     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
240     const std::string name = UnderlineAdded(mp->name_);
241     sb.AppendFormat("%s %s", EmitType(mt, mp->attributes_, false).string(), name.c_str());
242 }
243 
EmitInterfaceMethodReturn(MetaType * mt,StringBuilder & sb,const String & prefix)244 void CppCodeEmitter::EmitInterfaceMethodReturn(MetaType* mt, StringBuilder& sb, const String& prefix)
245 {
246     sb.Append(prefix).AppendFormat("/* [out] */ %s result", EmitType(mt, ATTR_OUT, false).string());
247 }
248 
EmitInterfaceProxy()249 void CppCodeEmitter::EmitInterfaceProxy()
250 {
251     EmitInterfaceProxyHeaderFile();
252     EmitInterfaceProxyCppFile();
253 }
254 
EmitInterfaceProxyHeaderFile()255 void CppCodeEmitter::EmitInterfaceProxyHeaderFile()
256 {
257     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(proxyName_).string());
258     File file(filePath, File::WRITE);
259 
260     StringBuilder sb;
261 
262     EmitLicense(sb);
263     sb.Append("\n");
264     EmitHeadMacro(sb, proxyFullName_);
265     sb.Append("\n");
266     sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string());
267     sb.Append("#include <iremote_proxy.h>\n");
268     sb.Append("\n");
269     EmitInterfaceProxyInHeaderFile(sb);
270     EmitTailMacro(sb, proxyFullName_);
271 
272     String data = sb.ToString();
273     file.WriteData(data.string(), data.GetLength());
274     file.Flush();
275     file.Close();
276 }
277 
EmitInterfaceProxyInHeaderFile(StringBuilder & sb)278 void CppCodeEmitter::EmitInterfaceProxyInHeaderFile(StringBuilder& sb)
279 {
280     EmitBeginNamespace(sb);
281     sb.AppendFormat("class %s : public IRemoteProxy<%s> {\n", proxyName_.string(), interfaceName_.string());
282     sb.Append("public:\n");
283     EmitInterfaceProxyConstructor(sb, TAB);
284     sb.Append("\n");
285     EmitInterfaceProxyMethodDecls(sb, TAB);
286     sb.Append("\n");
287     sb.Append("private:\n");
288     EmitInterfaceProxyConstants(sb, TAB);
289     sb.Append("};\n");
290     EmitEndNamespace(sb);
291 }
292 
EmitInterfaceProxyConstructor(StringBuilder & sb,const String & prefix)293 void CppCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder& sb, const String& prefix)
294 {
295     sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.string());
296     sb.Append(prefix + TAB).Append("/* [in] */ const sptr<IRemoteObject>& remote)\n");
297     sb.Append(prefix + TAB).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.string());
298     sb.Append(prefix).Append("{}\n");
299     sb.Append("\n");
300     sb.Append(prefix).AppendFormat("virtual ~%s()\n", proxyName_.string());
301     sb.Append(prefix).Append("{}\n");
302 }
303 
EmitInterfaceProxyMethodDecls(StringBuilder & sb,const String & prefix)304 void CppCodeEmitter::EmitInterfaceProxyMethodDecls(StringBuilder& sb, const String& prefix)
305 {
306     if (metaInterface_->methodNumber_ > 0) {
307         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
308             MetaMethod* mm = metaInterface_->methods_[i];
309             EmitInterfaceProxyMethodDecl(mm, sb, prefix);
310             if (i != metaInterface_->methodNumber_ - 1) {
311                 sb.Append("\n");
312             }
313         }
314     }
315 }
316 
EmitInterfaceProxyMethodDecl(MetaMethod * mm,StringBuilder & sb,const String & prefix)317 void CppCodeEmitter::EmitInterfaceProxyMethodDecl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
318 {
319     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
320     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
321         sb.Append(prefix).AppendFormat("ErrCode %s() override;\n", mm->name_);
322     } else {
323         sb.Append(prefix).AppendFormat("ErrCode %s(\n", mm->name_);
324         for (int i = 0; i < mm->parameterNumber_; i++) {
325             MetaParameter* mp = mm->parameters_[i];
326             EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
327             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
328                 sb.Append(",\n");
329             }
330         }
331         if (returnType->kind_ != TypeKind::Void) {
332             EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
333         }
334         sb.Append(") override;\n");
335     }
336 }
337 
EmitInterfaceProxyConstants(StringBuilder & sb,const String & prefix)338 void CppCodeEmitter::EmitInterfaceProxyConstants(StringBuilder& sb, const String& prefix)
339 {
340     EmitInterfaceMethodCommands(sb, prefix);
341     sb.Append("\n");
342     sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.string());
343 }
344 
EmitInterfaceProxyCppFile()345 void CppCodeEmitter::EmitInterfaceProxyCppFile()
346 {
347     String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(proxyName_).string());
348     File file(filePath, File::WRITE);
349 
350     StringBuilder sb;
351 
352     EmitLicense(sb);
353     sb.Append("\n");
354     sb.AppendFormat("#include \"%s.h\"\n", FileName(proxyName_).string());
355     sb.Append("\n");
356     EmitBeginNamespace(sb);
357     EmitInterfaceProxyMethodImpls(sb, "");
358     EmitEndNamespace(sb);
359 
360     String data = sb.ToString();
361     file.WriteData(data.string(), data.GetLength());
362     file.Flush();
363     file.Close();
364 }
365 
EmitInterfaceProxyMethodImpls(StringBuilder & sb,const String & prefix)366 void CppCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder& sb, const String& prefix)
367 {
368     if (metaInterface_->methodNumber_ > 0) {
369         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
370             MetaMethod* mm = metaInterface_->methods_[i];
371             EmitInterfaceProxyMethodImpl(mm, sb, prefix);
372             if (i != metaInterface_->methodNumber_ - 1) {
373                 sb.Append("\n");
374             }
375         }
376     }
377 }
378 
EmitInterfaceProxyMethodImpl(MetaMethod * mm,StringBuilder & sb,const String & prefix)379 void CppCodeEmitter::EmitInterfaceProxyMethodImpl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
380 {
381     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
382     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
383         sb.Append(prefix).AppendFormat("ErrCode %s::%s()\n", proxyName_.string(), mm->name_);
384     } else {
385         sb.Append(prefix).AppendFormat("ErrCode %s::%s(\n", proxyName_.string(), mm->name_);
386         for (int i = 0; i < mm->parameterNumber_; i++) {
387             MetaParameter* mp = mm->parameters_[i];
388             EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
389             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
390                 sb.Append(",\n");
391             }
392         }
393         if (returnType->kind_ != TypeKind::Void) {
394             EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
395         }
396         sb.Append(")\n");
397     }
398     EmitInterfaceProxyMethodBody(mm, sb, prefix);
399 }
400 
EmitInterfaceProxyMethodBody(MetaMethod * mm,StringBuilder & sb,const String & prefix)401 void CppCodeEmitter::EmitInterfaceProxyMethodBody(MetaMethod* mm, StringBuilder& sb, const String& prefix)
402 {
403     sb.Append(prefix).Append("{\n");
404     sb.Append(prefix + TAB).Append("MessageParcel data;\n");
405     sb.Append(prefix + TAB).Append("MessageParcel reply;\n");
406     sb.Append(prefix + TAB).AppendFormat("MessageOption option(%s);\n",
407         (mm->properties_ & METHOD_PROPERTY_ONEWAY) != 0 ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC");
408     sb.Append("\n");
409     sb.Append(prefix + TAB).Append("if (!data.WriteInterfaceToken(GetDescriptor())) {\n");
410     sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_VALUE;\n");
411     sb.Append(prefix + TAB).Append("}\n");
412     sb.Append("\n");
413 
414     for (int i = 0; i < mm->parameterNumber_; i++) {
415         MetaParameter* mp = mm->parameters_[i];
416         if ((mp->attributes_ & ATTR_IN) != 0) {
417             EmitWriteMethodParameter(mp, "data.", sb, prefix + TAB);
418         }
419     }
420     sb.Append("\n");
421     sb.Append(prefix + TAB).AppendFormat("int32_t st = Remote()->SendRequest(COMMAND_%s, data, reply, option);\n",
422         ConstantName(mm->name_).string());
423     sb.Append(prefix + TAB).Append("if (st != ERR_NONE) {\n");
424     sb.Append(prefix + TAB).Append("    return st;\n");
425     sb.Append(prefix + TAB).Append("}\n");
426     if ((mm->properties_ & METHOD_PROPERTY_ONEWAY) == 0) {
427         sb.Append("\n");
428         sb.Append(prefix + TAB).Append("ErrCode ec = reply.ReadInt32();\n");
429         sb.Append(prefix + TAB).Append("if (FAILED(ec)) {\n");
430         sb.Append(prefix + TAB).Append("    return ec;\n");
431         sb.Append(prefix + TAB).Append("}\n");
432         sb.Append("\n");
433         for (int i = 0; i < mm->parameterNumber_; i++) {
434             MetaParameter* mp = mm->parameters_[i];
435             if ((mp->attributes_ & ATTR_OUT) != 0) {
436                 EmitReadMethodParameter(mp, "reply.", sb, prefix + TAB);
437             }
438         }
439         MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
440         if (returnType->kind_ != TypeKind::Void) {
441             EmitReadVariable("reply.", "result", returnType, sb, prefix + TAB, false);
442         }
443     }
444     sb.Append(prefix + TAB).Append("return ERR_OK;\n");
445     sb.Append(prefix).Append("}\n");
446 }
447 
EmitWriteMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & sb,const String & prefix)448 void CppCodeEmitter::EmitWriteMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& sb,
449     const String& prefix)
450 {
451     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
452     const std::string name = UnderlineAdded(mp->name_);
453     EmitWriteVariable(parcelName, name, mt, sb, prefix);
454 }
455 
EmitReadMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & sb,const String & prefix)456 void CppCodeEmitter::EmitReadMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& sb,
457     const String& prefix)
458 {
459     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
460     const std::string name = UnderlineAdded(mp->name_);
461     EmitReadVariable(parcelName, name, mt, sb, prefix, false);
462 }
463 
EmitInterfaceStub()464 void CppCodeEmitter::EmitInterfaceStub()
465 {
466     EmitInterfaceStubHeaderFile();
467     EmitInterfaceStubCppFile();
468 }
469 
EmitInterfaceStubHeaderFile()470 void CppCodeEmitter::EmitInterfaceStubHeaderFile()
471 {
472     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(stubName_).string());
473     File file(filePath, File::WRITE);
474 
475     StringBuilder sb;
476 
477     EmitLicense(sb);
478     sb.Append("\n");
479     EmitHeadMacro(sb, stubFullName_);
480     sb.Append("\n");
481     sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string());
482     sb.Append("#include <iremote_stub.h>\n");
483     sb.Append("\n");
484     EmitInterfaceStubInHeaderFile(sb);
485     EmitTailMacro(sb, stubFullName_);
486 
487     String data = sb.ToString();
488     file.WriteData(data.string(), data.GetLength());
489     file.Flush();
490     file.Close();
491 }
492 
EmitInterfaceStubInHeaderFile(StringBuilder & sb)493 void CppCodeEmitter::EmitInterfaceStubInHeaderFile(StringBuilder& sb)
494 {
495     EmitBeginNamespace(sb);
496     sb.AppendFormat("class %s : public IRemoteStub<%s> {\n", stubName_.string(), interfaceName_.string());
497     sb.Append("public:\n");
498     EmitInterfaceStubMethodDecls(sb, TAB);
499     sb.Append("\n");
500     sb.Append("private:\n");
501     EmitInterfaceStubConstants(sb, TAB);
502     sb.Append("};\n");
503     EmitEndNamespace(sb);
504 }
505 
EmitInterfaceStubMethodDecls(StringBuilder & sb,const String & prefix)506 void CppCodeEmitter::EmitInterfaceStubMethodDecls(StringBuilder& sb, const String& prefix)
507 {
508     sb.Append(prefix).Append("int OnRemoteRequest(\n");
509     sb.Append(prefix + TAB).Append("/* [in] */ uint32_t code,\n");
510     sb.Append(prefix + TAB).Append("/* [in] */ MessageParcel& data,\n");
511     sb.Append(prefix + TAB).Append("/* [out] */ MessageParcel& reply,\n");
512     sb.Append(prefix + TAB).Append("/* [in] */ MessageOption& option) override;\n");
513 }
514 
EmitInterfaceStubConstants(StringBuilder & sb,const String & prefix)515 void CppCodeEmitter::EmitInterfaceStubConstants(StringBuilder& sb, const String& prefix)
516 {
517     EmitInterfaceMethodCommands(sb, prefix);
518 }
519 
EmitInterfaceStubCppFile()520 void CppCodeEmitter::EmitInterfaceStubCppFile()
521 {
522     String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(stubName_).string());
523     File file(filePath, File::WRITE);
524 
525     StringBuilder sb;
526 
527     EmitLicense(sb);
528     sb.Append("\n");
529     sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string());
530     sb.Append("\n");
531     EmitBeginNamespace(sb);
532     EmitInterfaceStubMethodImpls(sb, "");
533     EmitEndNamespace(sb);
534 
535     String data = sb.ToString();
536     file.WriteData(data.string(), data.GetLength());
537     file.Flush();
538     file.Close();
539 }
540 
EmitInterfaceStubMethodImpls(StringBuilder & sb,const String & prefix)541 void CppCodeEmitter::EmitInterfaceStubMethodImpls(StringBuilder& sb, const String& prefix)
542 {
543     sb.Append(prefix).AppendFormat("int %s::OnRemoteRequest(\n", stubName_.string());
544     sb.Append(prefix + TAB).Append("/* [in] */ uint32_t code,\n");
545     sb.Append(prefix + TAB).Append("/* [in] */ MessageParcel& data,\n");
546     sb.Append(prefix + TAB).Append("/* [out] */ MessageParcel& reply,\n");
547     sb.Append(prefix + TAB).Append("/* [in] */ MessageOption& option)\n");
548     sb.Append(prefix).Append("{\n");
549     sb.Append(prefix + TAB).Append("std::u16string localDescriptor = GetDescriptor();\n");
550     sb.Append(prefix + TAB).Append("std::u16string remoteDescriptor = data.ReadInterfaceToken();\n");
551     sb.Append(prefix + TAB).Append("if (localDescriptor != remoteDescriptor) {\n");
552     sb.Append(prefix + TAB).Append(TAB).Append("return ERR_TRANSACTION_FAILED;\n");
553     sb.Append(prefix + TAB).Append("}\n");
554     sb.Append(prefix + TAB).Append("switch (code) {\n");
555     for (int i = 0; i < metaInterface_->methodNumber_; i++) {
556         MetaMethod* mm = metaInterface_->methods_[i];
557         EmitInterfaceStubMethodImpl(mm, sb, prefix + TAB + TAB);
558     }
559     sb.Append(prefix + TAB).Append(TAB).Append("default:\n");
560     sb.Append(prefix + TAB).Append(TAB).Append(TAB).Append(
561         "return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
562     sb.Append(prefix + TAB).Append("}\n\n");
563     sb.Append(prefix + TAB).Append("return ERR_TRANSACTION_FAILED;\n");
564     sb.Append(prefix).Append("}\n");
565 }
566 
EmitInterfaceStubMethodImpl(MetaMethod * mm,StringBuilder & sb,const String & prefix)567 void CppCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
568 {
569     sb.Append(prefix).AppendFormat("case COMMAND_%s: {\n", ConstantName(mm->name_).string());
570     for (int i = 0; i < mm->parameterNumber_; i++) {
571         MetaParameter* mp = mm->parameters_[i];
572         if ((mp->attributes_ & ATTR_IN) != 0) {
573             MetaType* mt = metaComponent_->types_[mp->typeIndex_];
574             const std::string name = UnderlineAdded(mp->name_);
575             EmitReadVariable("data.", name, mt, sb, prefix + TAB);
576         } else if ((mp->attributes_ & ATTR_OUT) != 0) {
577             EmitLocalVariable(mp, sb, prefix + TAB);
578         }
579     }
580     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
581     if (returnType->kind_ != TypeKind::Void) {
582         if ((returnType->kind_ == TypeKind::Sequenceable) || (returnType->kind_ == TypeKind::Interface)) {
583             sb.Append(prefix + TAB).AppendFormat("%s result = nullptr;\n",
584                 EmitType(returnType, ATTR_IN, true).string());
585         } else {
586             sb.Append(prefix + TAB).AppendFormat("%s result;\n", EmitType(returnType, ATTR_IN, true).string());
587         }
588     }
589     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
590         sb.Append(prefix + TAB).AppendFormat("ErrCode ec = %s();\n", mm->name_);
591     } else {
592         sb.Append(prefix + TAB).AppendFormat("ErrCode ec = %s(", mm->name_);
593         for (int i = 0; i < mm->parameterNumber_; i++) {
594             MetaParameter* mp = mm->parameters_[i];
595             const std::string name = UnderlineAdded(mp->name_);
596             sb.Append(name.c_str());
597             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
598                 sb.Append(", ");
599             }
600         }
601         if (returnType->kind_ != TypeKind::Void) {
602             EmitReturnParameter("result", returnType, sb);
603         }
604         sb.AppendFormat(");\n", mm->name_);
605     }
606     sb.Append(prefix + TAB).Append("reply.WriteInt32(ec);\n");
607     bool hasOutParameter = false;
608     for (int i = 0; i < mm->parameterNumber_; i++) {
609         MetaParameter* mp = mm->parameters_[i];
610         if ((mp->attributes_ & ATTR_OUT) != 0) {
611             hasOutParameter = true;
612         }
613     }
614     if (hasOutParameter || returnType->kind_ != TypeKind::Void) {
615         sb.Append(prefix + TAB).Append("if (SUCCEEDED(ec)) {\n");
616         for (int i = 0; i < mm->parameterNumber_; i++) {
617             MetaParameter* mp = mm->parameters_[i];
618             if ((mp->attributes_ & ATTR_OUT) != 0) {
619                 EmitWriteMethodParameter(mp, "reply.", sb, prefix + TAB + TAB);
620             }
621         }
622         if (returnType->kind_ != TypeKind::Void) {
623             EmitWriteVariable("reply.", "result", returnType, sb, prefix + TAB + TAB);
624         }
625         sb.Append(prefix + TAB).Append("}\n");
626     }
627     sb.Append(prefix + TAB).Append("return ERR_NONE;\n");
628     sb.Append(prefix).Append("}\n");
629 }
630 
EmitInterfaceMethodCommands(StringBuilder & sb,const String & prefix)631 void CppCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& sb, const String& prefix)
632 {
633     for (int i = 0; i < metaInterface_->methodNumber_; i++) {
634         MetaMethod* mm = metaInterface_->methods_[i];
635         sb.Append(prefix).AppendFormat("static constexpr int COMMAND_%s = MIN_TRANSACTION_ID + %d;\n",
636             ConstantName(mm->name_).string(), i);
637     }
638 }
639 
EmitLicense(StringBuilder & sb)640 void CppCodeEmitter::EmitLicense(StringBuilder& sb)
641 {
642     sb.Append(metaInterface_->license_).Append("\n");
643 }
644 
EmitHeadMacro(StringBuilder & sb,const String & fullName)645 void CppCodeEmitter::EmitHeadMacro(StringBuilder& sb, const String& fullName)
646 {
647     String macroName = MacroName(fullName);
648     sb.Append("#ifndef ").Append(macroName).Append("\n");
649     sb.Append("#define ").Append(macroName).Append("\n");
650 }
651 
EmitTailMacro(StringBuilder & sb,const String & fullName)652 void CppCodeEmitter::EmitTailMacro(StringBuilder& sb, const String& fullName)
653 {
654     String macroName = MacroName(fullName);
655     sb.Append("#endif // ").Append(macroName).Append("\n\n");
656 }
657 
EmitBeginNamespace(StringBuilder & sb)658 void CppCodeEmitter::EmitBeginNamespace(StringBuilder& sb)
659 {
660     String nspace = GetNamespace(metaInterface_->namespace_);
661     int index = nspace.IndexOf('.');
662     while (index != -1) {
663         sb.AppendFormat("namespace %s {\n", nspace.Substring(0, index).string());
664         nspace = nspace.Substring(index + 1);
665         index = nspace.IndexOf('.');
666     }
667 }
668 
EmitEndNamespace(StringBuilder & sb)669 void CppCodeEmitter::EmitEndNamespace(StringBuilder& sb)
670 {
671     String nspace = GetNamespace(metaInterface_->namespace_);
672     nspace = nspace.Substring(0, nspace.GetLength() - 1);
673     while (!nspace.IsEmpty()) {
674         int index = nspace.LastIndexOf('.');
675         sb.AppendFormat("} // namespace %s\n", index != -1 ?
676             nspace.Substring(index + 1, nspace.GetLength()).string() : nspace.string());
677         nspace = nspace.Substring(0, index);
678     }
679 }
680 
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)681 void CppCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
682     StringBuilder& sb, const String& prefix)
683 {
684     switch (mt->kind_) {
685         case TypeKind::Boolean:
686             sb.Append(prefix).AppendFormat("%sWriteInt32(%s ? 1 : 0);\n", parcelName.string(), name.c_str());
687             break;
688         case TypeKind::Char:
689         case TypeKind::Byte:
690         case TypeKind::Short:
691         case TypeKind::Integer:
692             sb.Append(prefix).AppendFormat("%sWriteInt32(%s);\n", parcelName.string(), name.c_str());
693             break;
694         case TypeKind::Long:
695             sb.Append(prefix).AppendFormat("%sWriteInt64(%s);\n", parcelName.string(), name.c_str());
696             break;
697         case TypeKind::Float:
698             sb.Append(prefix).AppendFormat("%sWriteFloat(%s);\n", parcelName.string(), name.c_str());
699             break;
700         case TypeKind::Double:
701             sb.Append(prefix).AppendFormat("%sWriteDouble(%s);\n", parcelName.string(), name.c_str());
702             break;
703         case TypeKind::String:
704             sb.Append(prefix).AppendFormat("%sWriteString16(Str8ToStr16(%s));\n", parcelName.string(), name.c_str());
705             break;
706         case TypeKind::Sequenceable:
707             sb.Append(prefix).AppendFormat("%sWriteParcelable(%s);\n", parcelName.string(), name.c_str());
708             break;
709         case TypeKind::Interface:
710             sb.Append(prefix).AppendFormat("%sWriteRemoteObject(%s->AsObject());\n", parcelName.string(), name.c_str());
711             break;
712         case TypeKind::Array:
713         case TypeKind::List: {
714             sb.Append(prefix).AppendFormat("%sWriteInt32(%s.size());\n", parcelName.string(), name.c_str());
715             sb.Append(prefix).AppendFormat("for (auto it = %s.begin(); it != %s.end(); ++it) {\n",
716                 name.c_str(), name.c_str());
717             MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
718             EmitWriteVariable(parcelName, "(*it)", innerType, sb, prefix + TAB);
719             sb.Append(prefix).Append("}\n");
720             break;
721         }
722         case TypeKind::Map: {
723             sb.Append(prefix).AppendFormat("%sWriteInt32(%s.size());\n", parcelName.string(), name.c_str());
724             sb.Append(prefix).AppendFormat("for (auto it = %s.begin(); it != %s.end(); ++it) {\n",
725                 name.c_str(), name.c_str());
726             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
727             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
728             EmitWriteVariable(parcelName, "(it->first)", keyType, sb, prefix + TAB);
729             EmitWriteVariable(parcelName, "(it->second)", valueType, sb, prefix + TAB);
730             sb.Append(prefix).Append("}\n");
731             break;
732         }
733         default:
734             break;
735     }
736 }
737 
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)738 void CppCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
739     StringBuilder& sb, const String& prefix, bool emitType)
740 {
741     switch (mt->kind_) {
742         case TypeKind::Boolean:
743             if (emitType) {
744                 sb.Append(prefix).AppendFormat("%s %s = %sReadInt32() == 1 ? true : false;\n",
745                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
746             } else {
747                 sb.Append(prefix).AppendFormat("%s = %sReadInt32() == 1 ? true : false;\n",
748                     name.c_str(), parcelName.string());
749             }
750             break;
751         case TypeKind::Char:
752         case TypeKind::Byte:
753         case TypeKind::Short:
754             if (emitType) {
755                 sb.Append(prefix).AppendFormat("%s %s = (%s)%sReadInt32();\n", EmitType(mt, ATTR_IN, true).string(),
756                     name.c_str(), EmitType(mt, ATTR_IN, true).string(), parcelName.string());
757             } else {
758                 sb.Append(prefix).AppendFormat("%s = (%s)%sReadInt32();\n", name.c_str(),
759                     EmitType(mt, ATTR_IN, true).string(), parcelName.string());
760             }
761             break;
762         case TypeKind::Integer:
763             if (emitType) {
764                 sb.Append(prefix).AppendFormat("%s %s = %sReadInt32();\n",
765                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
766             } else {
767                 sb.Append(prefix).AppendFormat("%s = %sReadInt32();\n", name.c_str(), parcelName.string());
768             }
769             break;
770         case TypeKind::Long:
771             if (emitType) {
772                 sb.Append(prefix).AppendFormat("%s %s = %sReadInt64();\n",
773                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
774             } else {
775                 sb.Append(prefix).AppendFormat("%s = %sReadInt64();\n", name.c_str(), parcelName.string());
776             }
777             break;
778         case TypeKind::Float:
779             if (emitType) {
780                 sb.Append(prefix).AppendFormat("%s %s = %sReadFloat();\n",
781                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
782             } else {
783                 sb.Append(prefix).AppendFormat("%s = %sReadFloat();\n", name.c_str(), parcelName.string());
784             }
785             break;
786         case TypeKind::Double:
787             if (emitType) {
788                 sb.Append(prefix).AppendFormat("%s %s = %sReadDouble();\n",
789                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
790             } else {
791                 sb.Append(prefix).AppendFormat("%s = %sReadDouble();\n", name.c_str(), parcelName.string());
792             }
793             break;
794         case TypeKind::String:
795             if (emitType) {
796                 sb.Append(prefix).AppendFormat("%s %s = Str16ToStr8(%sReadString16());\n",
797                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
798             } else {
799                 sb.Append(prefix).AppendFormat("%s = Str16ToStr8(%sReadString16());\n",
800                     name.c_str(), parcelName.string());
801             }
802             break;
803         case TypeKind::Sequenceable: {
804             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
805             if (emitType) {
806                 sb.Append(prefix).AppendFormat("%s %s = %sReadParcelable<%s>();\n",
807                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string(), mp->name_);
808             } else {
809                 sb.Append(prefix).AppendFormat("%s = %sReadParcelable<%s>();\n",
810                     name.c_str(), parcelName.string(), mp->name_);
811             }
812             break;
813         }
814         case TypeKind::Interface: {
815             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
816             if (emitType) {
817                 sb.Append(prefix).AppendFormat("%s %s = iface_cast<%s>(%sReadRemoteObject());\n",
818                     EmitType(mt, ATTR_IN, true).string(), name.c_str(),  mi->name_, parcelName.string());
819             } else {
820                 sb.Append(prefix).AppendFormat("%s = iface_cast<%s>(%sReadRemoteObject());\n",
821                     name.c_str(),  mi->name_, parcelName.string());
822             }
823             break;
824         }
825         case TypeKind::Array:
826         case TypeKind::List: {
827             if (emitType) {
828                 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
829             }
830             sb.Append(prefix).AppendFormat("int %sSize = %sReadInt32();\n", name.c_str(), parcelName.string());
831             sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
832             MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
833             EmitReadVariable(parcelName, "value", innerType, sb, prefix + TAB);
834             sb.Append(prefix + TAB).AppendFormat("%s.push_back(value);\n", name.c_str());
835             sb.Append(prefix).Append("}\n");
836             break;
837         }
838         case TypeKind::Map: {
839             if (emitType) {
840                 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
841             }
842             sb.Append(prefix).AppendFormat("int %sSize = %sReadInt32();\n", name.c_str(), parcelName.string());
843             sb.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
844             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
845             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
846             EmitReadVariable(parcelName, "key", keyType, sb, prefix + TAB);
847             EmitReadVariable(parcelName, "value", valueType, sb, prefix + TAB);
848             sb.Append(prefix + TAB).AppendFormat("%s[key] = value;\n", name.c_str());
849             sb.Append(prefix).Append("}\n");
850             break;
851         }
852         default:
853             break;
854     }
855 }
856 
EmitLocalVariable(MetaParameter * mp,StringBuilder & sb,const String & prefix)857 void CppCodeEmitter::EmitLocalVariable(MetaParameter* mp, StringBuilder& sb, const String& prefix)
858 {
859     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
860     const std::string name = UnderlineAdded(mp->name_);
861     if ((mt->kind_ == TypeKind::Sequenceable) || (mt->kind_ == TypeKind::Interface)) {
862         sb.Append(prefix).AppendFormat("%s %s = nullptr;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
863     } else {
864         sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
865     }
866 }
867 
EmitReturnParameter(const String & name,MetaType * mt,StringBuilder & sb)868 void CppCodeEmitter::EmitReturnParameter(const String& name, MetaType* mt, StringBuilder& sb)
869 {
870     switch (mt->kind_) {
871         case TypeKind::Char:
872         case TypeKind::Boolean:
873         case TypeKind::Byte:
874         case TypeKind::Short:
875         case TypeKind::Integer:
876         case TypeKind::Long:
877         case TypeKind::Float:
878         case TypeKind::Double:
879         case TypeKind::String:
880         case TypeKind::Sequenceable:
881         case TypeKind::Interface:
882         case TypeKind::List:
883         case TypeKind::Map:
884         case TypeKind::Array:
885             sb.Append(name);
886             break;
887         default:
888             break;
889     }
890 }
891 
EmitType(MetaType * mt,unsigned int attributes,bool isInnerType)892 String CppCodeEmitter::EmitType(MetaType* mt, unsigned int attributes, bool isInnerType)
893 {
894     switch (mt->kind_) {
895         case TypeKind::Char:
896             if (attributes & ATTR_IN) {
897                 return "zchar";
898             } else {
899                 return "zchar&";
900             }
901         case TypeKind::Boolean:
902             if (attributes & ATTR_IN) {
903                 return "bool";
904             } else {
905                 return "bool&";
906             }
907         case TypeKind::Byte:
908             if (attributes & ATTR_IN) {
909                 return "int8_t";
910             } else {
911                 return "int8_t&";
912             }
913         case TypeKind::Short:
914             if (attributes & ATTR_IN) {
915                 return "short";
916             } else {
917                 return "short&";
918             }
919         case TypeKind::Integer:
920             if (attributes & ATTR_IN) {
921                 return "int";
922             } else {
923                 return "int&";
924             }
925         case TypeKind::Long:
926             if (attributes & ATTR_IN) {
927                 return "long";
928             } else {
929                 return "long&";
930             }
931         case TypeKind::Float:
932             if (attributes & ATTR_IN) {
933                 return "float";
934             } else {
935                 return "float&";
936             }
937         case TypeKind::Double:
938             if (attributes & ATTR_IN) {
939                 return "double";
940             } else {
941                 return "double&";
942             }
943         case TypeKind::String:
944             if (attributes & ATTR_IN) {
945                 if (!isInnerType) {
946                     return "const std::string&";
947                 } else {
948                     return "std::string";
949                 }
950             } else {
951                 return "std::string&";
952             }
953         case TypeKind::Void:
954             return "void";
955         case TypeKind::Sequenceable: {
956             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
957             if ((attributes & ATTR_MASK) == (ATTR_IN | ATTR_OUT)) {
958                 return String::Format("%s*", mp->name_);
959             } else if (attributes & ATTR_IN) {
960                 return String::Format("%s*", mp->name_);
961             } else {
962                 return String::Format("%s*", mp->name_);
963             }
964         }
965         case TypeKind::Interface: {
966             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
967             if (attributes & ATTR_IN) {
968                 if (!isInnerType) {
969                     return String::Format("sptr<%s>", mi->name_);
970                 } else {
971                     return String::Format("sptr<%s>", mi->name_);
972                 }
973             } else {
974                 return String::Format("sptr<%s>&", mi->name_);
975             }
976         }
977         case TypeKind::Array:
978         case TypeKind::List: {
979             MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
980             if (attributes & ATTR_OUT) {
981                 return String::Format("std::vector<%s>&",
982                     EmitType(elementType, ATTR_IN, true).string());
983             } else {
984                 if (!isInnerType) {
985                     return String::Format("const std::vector<%s>&",
986                         EmitType(elementType, ATTR_IN, true).string());
987                 } else {
988                     return String::Format("std::vector<%s>",
989                         EmitType(elementType, ATTR_IN, true).string());
990                 }
991             }
992         }
993         case TypeKind::Map: {
994             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
995             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
996             if (attributes & ATTR_OUT) {
997                 return String::Format("std::unordered_map<%s, %s>&",
998                     EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
999             } else {
1000                 if (!isInnerType) {
1001                     return String::Format("const std::unordered_map<%s, %s>&",
1002                         EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1003                 } else {
1004                     return String::Format("std::unordered_map<%s, %s>",
1005                         EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1006                 }
1007             }
1008             break;
1009         }
1010         default:
1011             return "unknown type";
1012     }
1013 }
1014 
CppFullName(const String & name)1015 String CppCodeEmitter::CppFullName(const String& name)
1016 {
1017     if (name.IsEmpty()) {
1018         return name;
1019     }
1020 
1021     return name.Replace(".", "::");
1022 }
1023 
FileName(const String & name)1024 String CppCodeEmitter::FileName(const String& name)
1025 {
1026     if (name.IsEmpty()) {
1027         return name;
1028     }
1029 
1030     StringBuilder sb;
1031 
1032     for (int i = 0; i < name.GetLength(); i++) {
1033         char c = name[i];
1034         if (isupper(c) != 0) {
1035             // 2->Index of the last char array.
1036             if (i > 1 && name[i - 1] != '.' && name[i - 2] != '.') {
1037                 sb.Append('_');
1038             }
1039             sb.Append(tolower(c));
1040         } else {
1041             sb.Append(c);
1042         }
1043     }
1044 
1045     return sb.ToString().Replace('.', '/');
1046 }
1047 
MacroName(const String & name)1048 String CppCodeEmitter::MacroName(const String& name)
1049 {
1050     if (name.IsEmpty()) {
1051         return name;
1052     }
1053 
1054     String macro = name.Replace('.', '_').ToUpperCase() + "_H";
1055     return macro;
1056 }
1057 
ConstantName(const String & name)1058 String CppCodeEmitter::ConstantName(const String& name)
1059 {
1060     if (name.IsEmpty()) {
1061         return name;
1062     }
1063 
1064     StringBuilder sb;
1065 
1066     for (int i = 0; i < name.GetLength(); i++) {
1067         char c = name[i];
1068         if (isupper(c) != 0) {
1069             if (i > 1) {
1070                 sb.Append('_');
1071             }
1072             sb.Append(c);
1073         } else {
1074             sb.Append(toupper(c));
1075         }
1076     }
1077 
1078     return sb.ToString();
1079 }
1080 
UnderlineAdded(const String & originName)1081 const std::string CppCodeEmitter::UnderlineAdded(const String& originName)
1082 {
1083     std::string underline("_");
1084     return underline + std::string(originName.string());
1085 }
1086 } // namespace Idl
1087 } // namespace OHOS
1088