1 /*
2 * Copyright (c) 2024 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 "hdi_enum_type_emitter.h"
17
18 namespace OHOS {
19 namespace Idl {
SetBaseTypeName(const std::string & name)20 void HdiEnumTypeEmitter::SetBaseTypeName(const std::string &name)
21 {
22 baseTypeName_ = name;
23 }
24
GetTypeKind()25 TypeKind HdiEnumTypeEmitter::GetTypeKind()
26 {
27 return TypeKind::TYPE_ENUM;
28 }
29
EmitCType(TypeMode mode) const30 std::string HdiEnumTypeEmitter::EmitCType(TypeMode mode) const
31 {
32 switch (mode) {
33 case TypeMode::NO_MODE:
34 return StringHelper::Format("enum %s", name_.c_str());
35 case TypeMode::PARAM_IN:
36 return StringHelper::Format("enum %s", name_.c_str());
37 case TypeMode::PARAM_OUT:
38 return StringHelper::Format("enum %s*", name_.c_str());
39 case TypeMode::LOCAL_VAR:
40 return StringHelper::Format("enum %s", name_.c_str());
41 default:
42 return "unknown type";
43 }
44 }
45
EmitCppType(TypeMode mode) const46 std::string HdiEnumTypeEmitter::EmitCppType(TypeMode mode) const
47 {
48 switch (mode) {
49 case TypeMode::NO_MODE:
50 case TypeMode::PARAM_IN:
51 case TypeMode::LOCAL_VAR:
52 return StringHelper::Format("%s", typeName_.c_str());
53 case TypeMode::PARAM_OUT:
54 return StringHelper::Format("%s&", typeName_.c_str());
55 default:
56 return "unknown type";
57 }
58 }
59
EmitJavaType(TypeMode mode,bool isInnerType) const60 std::string HdiEnumTypeEmitter::EmitJavaType(TypeMode mode, bool isInnerType) const
61 {
62 // currently, Java does not support the enum type.
63 return "/";
64 }
65
EmitCTypeDecl() const66 std::string HdiEnumTypeEmitter::EmitCTypeDecl() const
67 {
68 StringBuilder sb;
69 sb.AppendFormat("enum %s {\n", name_.c_str());
70
71 for (auto it : members_) {
72 if (it->GetValue().empty()) {
73 sb.Append(TAB).AppendFormat("%s,\n", it->GetValueName().c_str());
74 } else {
75 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetValueName().c_str(), it->GetValue().c_str());
76 }
77 }
78
79 sb.Append("};");
80 return sb.ToString();
81 }
82
EmitCppTypeDecl() const83 std::string HdiEnumTypeEmitter::EmitCppTypeDecl() const
84 {
85 StringBuilder sb;
86 if (baseTypeName_.empty()) {
87 sb.AppendFormat("enum %s {\n", name_.c_str());
88 } else {
89 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseTypeName_.c_str());
90 }
91
92 for (auto it : members_) {
93 if (it->GetValue().empty()) {
94 sb.Append(TAB).AppendFormat("%s,\n", it->GetValueName().c_str());
95 } else {
96 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetValueName().c_str(), it->GetValue().c_str());
97 }
98 }
99
100 sb.Append("};");
101 return sb.ToString();
102 }
103
EmitCWriteVar(TypeMode mode,const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const104 void HdiEnumTypeEmitter::EmitCWriteVar(TypeMode mode, const std::string &name,
105 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
106 {
107 std::string parcelName = (mode == TypeMode::PARAM_IN) ? dataParcelName_ : replyParcelName_;
108 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(%s, (uint64_t)%s)) {\n", parcelName.c_str(), name.c_str());
109 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
110 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
111 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
112 sb.Append(prefix).Append("}\n");
113 }
114
EmitCProxyReadVar(const std::string & name,bool isInnerType,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const115 void HdiEnumTypeEmitter::EmitCProxyReadVar(const std::string &name, bool isInnerType, const std::string &gotoLabel,
116 StringBuilder &sb, const std::string &prefix) const
117 {
118 std::string tmpVarName = "enumTmp";
119 sb.Append(prefix).Append("{\n");
120 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
121 sb.Append(prefix + TAB)
122 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", replyParcelName_.c_str(), tmpVarName.c_str());
123 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
124 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
125 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
126 sb.Append(prefix + TAB).Append("}\n\n");
127 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", name.c_str());
128 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: invlid parameter %s\", __func__);\n",
129 name.c_str());
130 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
131 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
132 sb.Append(prefix + TAB).Append("}\n\n");
133 sb.Append(prefix + TAB).AppendFormat("*%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
134 sb.Append(prefix).Append("}\n");
135 }
136
EmitCStubReadVar(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const137 void HdiEnumTypeEmitter::EmitCStubReadVar(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
138 const std::string &prefix) const
139 {
140 std::string tmpVarName = "enumTmp";
141 sb.Append(prefix).Append("{\n");
142 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
143 sb.Append(prefix + TAB)
144 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", dataParcelName_.c_str(), tmpVarName.c_str());
145 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
146 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", errorCodeName_.c_str());
147 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
148 sb.Append(prefix + TAB).Append("}\n");
149 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
150 sb.Append(prefix).Append("}\n");
151 }
152
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const153 void HdiEnumTypeEmitter::EmitCppWriteVar(const std::string &parcelName, const std::string &name,
154 StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
155 {
156 sb.Append(prefix).AppendFormat("if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(),
157 name.c_str());
158 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
159 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
160 sb.Append(prefix).Append("}\n");
161 }
162
EmitCppReadVar(const std::string & name,StringBuilder & sb,const std::string & prefix,TypeMode mode,unsigned int innerLevel) const163 void HdiEnumTypeEmitter::EmitCppReadVar(const std::string &name, StringBuilder &sb, const std::string &prefix,
164 TypeMode mode, unsigned int innerLevel) const
165 {
166 std::string tmpVarName = "enumTmp";
167 std::string parcelName = (mode == TypeMode::PARAM_IN) ? dataParcelName_ : replyParcelName_;
168 if ((mode == TypeMode::PARAM_IN) || (innerLevel > 0)) {
169 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
170 EmitCType().c_str());
171 }
172 sb.Append(prefix).Append("{\n");
173 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
174 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
175 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
176 name.c_str());
177 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
178 sb.Append(prefix + TAB).Append("}\n");
179 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
180 tmpVarName.c_str());
181 sb.Append(prefix).Append("}\n");
182 }
183
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const184 void HdiEnumTypeEmitter::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
185 {
186 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(data, (uint64_t)%s)) {\n", name.c_str());
187 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
188 sb.Append(prefix + TAB).Append("return false;\n");
189 sb.Append(prefix).Append("}\n");
190 }
191
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const192 void HdiEnumTypeEmitter::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel,
193 StringBuilder &sb, const std::string &prefix, std::vector<std::string> &freeObjStatements) const
194 {
195 std::string tmpVarName = "enumTmp";
196 sb.Append(prefix).Append("{\n");
197 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
198 sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufReadUint64(data, &%s)) {\n", tmpVarName.c_str());
199 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
200 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
201 sb.Append(prefix + TAB).Append("}\n");
202 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
203 sb.Append(prefix).Append("}\n");
204 }
205
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const206 void HdiEnumTypeEmitter::EmitCppMarshalling(const std::string &parcelName, const std::string &name,
207 StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
208 {
209 sb.Append(prefix).AppendFormat(
210 "if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(), name.c_str());
211 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
212 sb.Append(prefix + TAB).Append("return false;\n");
213 sb.Append(prefix).Append("}\n");
214 }
215
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const216 void HdiEnumTypeEmitter::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name,
217 StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
218 {
219 std::string tmpVarName = "enumTmp";
220 if (innerLevel > 0) {
221 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
222 EmitCType().c_str());
223 }
224 sb.Append(prefix).Append("{\n");
225 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
226 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
227 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
228 name.c_str());
229 sb.Append(prefix + TAB + TAB).Append("return false;\n");
230 sb.Append(prefix + TAB).Append("}\n");
231 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
232 tmpVarName.c_str());
233 sb.Append(prefix).Append("}\n");
234 }
235 } // namespace Idl
236 } // namespace OHOS
237