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