1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "ast/ast_enum_type.h"
10 #include "util/string_builder.h"
11
12 namespace OHOS {
13 namespace HDI {
SetBaseType(const AutoPtr<ASTType> & baseType)14 void ASTEnumType::SetBaseType(const AutoPtr<ASTType> &baseType)
15 {
16 if (baseType == nullptr) {
17 return;
18 }
19 baseType_ = baseType;
20 }
21
AddMember(const AutoPtr<ASTEnumValue> & member)22 void ASTEnumType::AddMember(const AutoPtr<ASTEnumValue> &member)
23 {
24 members_.push_back(member);
25 }
26
IsEnumType()27 bool ASTEnumType::IsEnumType()
28 {
29 return true;
30 }
31
ToString() const32 std::string ASTEnumType::ToString() const
33 {
34 return "enum " + name_;
35 }
36
Dump(const std::string & prefix)37 std::string ASTEnumType::Dump(const std::string &prefix)
38 {
39 StringBuilder sb;
40 sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
41 if (baseType_ != nullptr) {
42 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseType_->ToString().c_str());
43 } else {
44 sb.AppendFormat("enum %s {\n", name_.c_str());
45 }
46
47 if (members_.size() > 0) {
48 for (auto it : members_) {
49 AutoPtr<ASTExpr> value = it->GetExprValue();
50 if (value == nullptr) {
51 sb.Append(" ").AppendFormat("%s,\n", it->GetName().c_str());
52 } else {
53 sb.Append(" ").AppendFormat("%s = %s,\n", it->GetName().c_str(), value->Dump("").c_str());
54 }
55 }
56 }
57
58 sb.Append(prefix).Append("};\n");
59
60 return sb.ToString();
61 }
62
GetTypeKind()63 TypeKind ASTEnumType::GetTypeKind()
64 {
65 return TypeKind::TYPE_ENUM;
66 }
67
EmitCType(TypeMode mode) const68 std::string ASTEnumType::EmitCType(TypeMode mode) const
69 {
70 switch (mode) {
71 case TypeMode::NO_MODE:
72 return StringHelper::Format("enum %s", name_.c_str());
73 case TypeMode::PARAM_IN:
74 return StringHelper::Format("enum %s", name_.c_str());
75 case TypeMode::PARAM_OUT:
76 return StringHelper::Format("enum %s*", name_.c_str());
77 case TypeMode::LOCAL_VAR:
78 return StringHelper::Format("enum %s", name_.c_str());
79 default:
80 return "unknow type";
81 }
82 }
83
EmitCppType(TypeMode mode) const84 std::string ASTEnumType::EmitCppType(TypeMode mode) const
85 {
86 switch (mode) {
87 case TypeMode::NO_MODE:
88 return StringHelper::Format("%s", name_.c_str());
89 case TypeMode::PARAM_IN:
90 return StringHelper::Format("%s", name_.c_str());
91 case TypeMode::PARAM_OUT:
92 return StringHelper::Format("%s&", name_.c_str());
93 case TypeMode::LOCAL_VAR:
94 return StringHelper::Format("%s", name_.c_str());
95 default:
96 return "unknow type";
97 }
98 }
99
EmitJavaType(TypeMode mode,bool isInnerType) const100 std::string ASTEnumType::EmitJavaType(TypeMode mode, bool isInnerType) const
101 {
102 // currently, Java does not support the enum type.
103 return "/";
104 }
105
EmitCTypeDecl() const106 std::string ASTEnumType::EmitCTypeDecl() const
107 {
108 StringBuilder sb;
109 sb.AppendFormat("enum %s {\n", name_.c_str());
110
111 for (auto it : members_) {
112 if (it->GetExprValue() == nullptr) {
113 sb.Append(TAB).AppendFormat("%s,\n", it->GetName().c_str());
114 } else {
115 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().c_str(), it->GetExprValue()->EmitCode().c_str());
116 }
117 }
118
119 sb.Append("};");
120 return sb.ToString();
121 }
122
EmitCppTypeDecl() const123 std::string ASTEnumType::EmitCppTypeDecl() const
124 {
125 StringBuilder sb;
126 if (baseType_ != nullptr) {
127 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseType_->EmitCppType().c_str());
128 } else {
129 sb.AppendFormat("enum %s {\n", name_.c_str());
130 }
131
132 for (auto it : members_) {
133 if (it->GetExprValue() == nullptr) {
134 sb.Append(TAB).AppendFormat("%s,\n", it->GetName().c_str());
135 } else {
136 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().c_str(), it->GetExprValue()->EmitCode().c_str());
137 }
138 }
139
140 sb.Append("};");
141 return sb.ToString();
142 }
143
EmitJavaTypeDecl() const144 std::string ASTEnumType::EmitJavaTypeDecl() const
145 {
146 StringBuilder sb;
147
148 return sb.ToString();
149 }
150
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const151 void ASTEnumType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
152 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
153 {
154 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(%s, (uint64_t)%s)) {\n", parcelName.c_str(), name.c_str());
155 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
156 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
157 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
158 sb.Append(prefix).Append("}\n");
159 }
160
EmitCProxyReadVar(const std::string & parcelName,const std::string & name,bool isInnerType,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const161 void ASTEnumType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
162 const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
163 {
164 std::string tmpVarName = "enumTmp";
165 sb.Append(prefix).Append("{\n");
166 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
167 sb.Append(prefix + TAB)
168 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
169 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
170 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
171 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
172 sb.Append(prefix + TAB).Append("}\n\n");
173 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", name.c_str());
174 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: invlid parameter %s\", __func__);\n",
175 name.c_str());
176 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
177 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
178 sb.Append(prefix + TAB).Append("}\n\n");
179 sb.Append(prefix + TAB).AppendFormat("*%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
180 sb.Append(prefix).Append("}\n");
181 }
182
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const183 void ASTEnumType::EmitCStubReadVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
184 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
185 {
186 std::string tmpVarName = "enumTmp";
187 sb.Append(prefix).Append("{\n");
188 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
189 sb.Append(prefix + TAB)
190 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
191 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
192 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
193 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
194 sb.Append(prefix + TAB).Append("}\n");
195 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
196 sb.Append(prefix).Append("}\n");
197 }
198
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const199 void ASTEnumType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
200 const std::string &prefix, unsigned int innerLevel) const
201 {
202 sb.Append(prefix).AppendFormat("if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(),
203 name.c_str());
204 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
205 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
206 sb.Append(prefix).Append("}\n");
207 }
208
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const209 void ASTEnumType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
210 const std::string &prefix, bool initVariable, unsigned int innerLevel) const
211 {
212 std::string tmpVarName = "enumTmp";
213 if (initVariable) {
214 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
215 EmitCType().c_str());
216 }
217 sb.Append(prefix).Append("{\n");
218 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
219 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
220 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
221 name.c_str());
222 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
223 sb.Append(prefix + TAB).Append("}\n");
224 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
225 tmpVarName.c_str());
226 sb.Append(prefix).Append("}\n");
227 }
228
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const229 void ASTEnumType::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
230 {
231 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(data, (uint64_t)%s)) {\n", name.c_str());
232 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
233 sb.Append(prefix + TAB).Append("return false;\n");
234 sb.Append(prefix).Append("}\n");
235 }
236
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const237 void ASTEnumType::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
238 const std::string &prefix, std::vector<std::string> &freeObjStatements) const
239 {
240 std::string tmpVarName = "enumTmp";
241 sb.Append(prefix).Append("{\n");
242 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
243 sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufReadUint64(data, &%s)) {\n", tmpVarName.c_str());
244 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
245 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
246 sb.Append(prefix + TAB).Append("}\n");
247 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
248 sb.Append(prefix).Append("}\n");
249 }
250
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const251 void ASTEnumType::EmitCppMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
252 const std::string &prefix, unsigned int innerLevel) const
253 {
254 sb.Append(prefix).AppendFormat(
255 "if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(), name.c_str());
256 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
257 sb.Append(prefix + TAB).Append("return false;\n");
258 sb.Append(prefix).Append("}\n");
259 }
260
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool emitType,unsigned int innerLevel) const261 void ASTEnumType::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
262 const std::string &prefix, bool emitType, unsigned int innerLevel) const
263 {
264 std::string tmpVarName = "enumTmp";
265 if (emitType) {
266 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
267 EmitCType().c_str());
268 }
269 sb.Append(prefix).Append("{\n");
270 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
271 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
272 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
273 name.c_str());
274 sb.Append(prefix + TAB + TAB).Append("return false;\n");
275 sb.Append(prefix + TAB).Append("}\n");
276 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
277 tmpVarName.c_str());
278 sb.Append(prefix).Append("}\n");
279 }
280 } // namespace HDI
281 } // namespace OHOS
282