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
Dump(const std::string & prefix)32 std::string ASTEnumType::Dump(const std::string &prefix)
33 {
34 StringBuilder sb;
35 sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
36 if (baseType_ != nullptr) {
37 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseType_->ToString().c_str());
38 } else {
39 sb.AppendFormat("enum %s {\n", name_.c_str());
40 }
41
42 if (members_.size() > 0) {
43 for (auto it : members_) {
44 AutoPtr<ASTExpr> value = it->GetExprValue();
45 if (value == nullptr) {
46 sb.Append(" ").AppendFormat("%s,\n", it->GetName().c_str());
47 } else {
48 sb.Append(" ").AppendFormat("%s = %s,\n", it->GetName().c_str(), value->Dump("").c_str());
49 }
50 }
51 }
52
53 sb.Append(prefix).Append("};\n");
54
55 return sb.ToString();
56 }
57
GetTypeKind()58 TypeKind ASTEnumType::GetTypeKind()
59 {
60 return TypeKind::TYPE_ENUM;
61 }
62
EmitCType(TypeMode mode) const63 std::string ASTEnumType::EmitCType(TypeMode mode) const
64 {
65 switch (mode) {
66 case TypeMode::NO_MODE:
67 return StringHelper::Format("enum %s", name_.c_str());
68 case TypeMode::PARAM_IN:
69 return StringHelper::Format("enum %s", name_.c_str());
70 case TypeMode::PARAM_OUT:
71 return StringHelper::Format("enum %s*", name_.c_str());
72 case TypeMode::LOCAL_VAR:
73 return StringHelper::Format("enum %s", name_.c_str());
74 default:
75 return "unknow type";
76 }
77 }
78
EmitCppType(TypeMode mode) const79 std::string ASTEnumType::EmitCppType(TypeMode mode) const
80 {
81 switch (mode) {
82 case TypeMode::NO_MODE:
83 return StringHelper::Format("%s", name_.c_str());
84 case TypeMode::PARAM_IN:
85 return StringHelper::Format("%s", name_.c_str());
86 case TypeMode::PARAM_OUT:
87 return StringHelper::Format("%s&", name_.c_str());
88 case TypeMode::LOCAL_VAR:
89 return StringHelper::Format("%s", name_.c_str());
90 default:
91 return "unknow type";
92 }
93 }
94
EmitJavaType(TypeMode mode,bool isInnerType) const95 std::string ASTEnumType::EmitJavaType(TypeMode mode, bool isInnerType) const
96 {
97 // currently, Java does not support the enum type.
98 return "/";
99 }
100
EmitCTypeDecl() const101 std::string ASTEnumType::EmitCTypeDecl() const
102 {
103 StringBuilder sb;
104 sb.AppendFormat("enum %s {\n", name_.c_str());
105
106 for (auto it : members_) {
107 if (it->GetExprValue() == nullptr) {
108 sb.Append(TAB).AppendFormat("%s,\n", it->GetName().c_str());
109 } else {
110 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().c_str(), it->GetExprValue()->EmitCode().c_str());
111 }
112 }
113
114 sb.Append("};");
115 return sb.ToString();
116 }
117
EmitCppTypeDecl() const118 std::string ASTEnumType::EmitCppTypeDecl() const
119 {
120 StringBuilder sb;
121 if (baseType_ != nullptr) {
122 sb.AppendFormat("enum %s : %s {\n", name_.c_str(), baseType_->EmitCppType().c_str());
123 } else {
124 sb.AppendFormat("enum %s {\n", name_.c_str());
125 }
126
127 for (auto it : members_) {
128 if (it->GetExprValue() == nullptr) {
129 sb.Append(TAB).AppendFormat("%s,\n", it->GetName().c_str());
130 } else {
131 sb.Append(TAB).AppendFormat("%s = %s,\n", it->GetName().c_str(), it->GetExprValue()->EmitCode().c_str());
132 }
133 }
134
135 sb.Append("};");
136 return sb.ToString();
137 }
138
EmitJavaTypeDecl() const139 std::string ASTEnumType::EmitJavaTypeDecl() const
140 {
141 StringBuilder sb;
142
143 return sb.ToString();
144 }
145
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const146 void ASTEnumType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
147 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
148 {
149 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(%s, (uint64_t)%s)) {\n", parcelName.c_str(), name.c_str());
150 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
151 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
152 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
153 sb.Append(prefix).Append("}\n");
154 }
155
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) const156 void ASTEnumType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
157 const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
158 {
159 std::string tmpVarName = "enumTmp";
160 sb.Append(prefix).Append("{\n");
161 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
162 sb.Append(prefix + TAB)
163 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
164 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
165 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
166 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
167 sb.Append(prefix + TAB).Append("}\n\n");
168 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", name.c_str());
169 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: invlid parameter %s\", __func__);\n",
170 name.c_str());
171 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
172 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
173 sb.Append(prefix + TAB).Append("}\n\n");
174 sb.Append(prefix + TAB).AppendFormat("*%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
175 sb.Append(prefix).Append("}\n");
176 }
177
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const178 void ASTEnumType::EmitCStubReadVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
179 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
180 {
181 std::string tmpVarName = "enumTmp";
182 sb.Append(prefix).Append("{\n");
183 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
184 sb.Append(prefix + TAB)
185 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
186 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
187 sb.Append(prefix + TAB + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
188 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
189 sb.Append(prefix + TAB).Append("}\n");
190 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
191 sb.Append(prefix).Append("}\n");
192 }
193
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const194 void ASTEnumType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
195 const std::string &prefix, unsigned int innerLevel) const
196 {
197 sb.Append(prefix).AppendFormat("if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(),
198 name.c_str());
199 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
200 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
201 sb.Append(prefix).Append("}\n");
202 }
203
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const204 void ASTEnumType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
205 const std::string &prefix, bool initVariable, unsigned int innerLevel) const
206 {
207 std::string tmpVarName = "enumTmp";
208 if (initVariable) {
209 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
210 EmitCType().c_str());
211 }
212 sb.Append(prefix).Append("{\n");
213 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
214 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
215 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
216 name.c_str());
217 sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
218 sb.Append(prefix + TAB).Append("}\n");
219 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
220 tmpVarName.c_str());
221 sb.Append(prefix).Append("}\n");
222 }
223
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const224 void ASTEnumType::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
225 {
226 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(data, (uint64_t)%s)) {\n", name.c_str());
227 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
228 sb.Append(prefix + TAB).Append("return false;\n");
229 sb.Append(prefix).Append("}\n");
230 }
231
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const232 void ASTEnumType::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
233 const std::string &prefix, std::vector<std::string> &freeObjStatements) const
234 {
235 std::string tmpVarName = "enumTmp";
236 sb.Append(prefix).Append("{\n");
237 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
238 sb.Append(prefix + TAB).AppendFormat("if (!HdfSbufReadUint64(data, &%s)) {\n", tmpVarName.c_str());
239 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
240 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
241 sb.Append(prefix + TAB).Append("}\n");
242 sb.Append(prefix + TAB).AppendFormat("%s = (%s)%s;\n", name.c_str(), EmitCType().c_str(), tmpVarName.c_str());
243 sb.Append(prefix).Append("}\n");
244 }
245
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const246 void ASTEnumType::EmitCppMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
247 const std::string &prefix, unsigned int innerLevel) const
248 {
249 sb.Append(prefix).AppendFormat(
250 "if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.c_str(), name.c_str());
251 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
252 sb.Append(prefix + TAB).Append("return false;\n");
253 sb.Append(prefix).Append("}\n");
254 }
255
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool emitType,unsigned int innerLevel) const256 void ASTEnumType::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
257 const std::string &prefix, bool emitType, unsigned int innerLevel) const
258 {
259 std::string tmpVarName = "enumTmp";
260 if (emitType) {
261 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().c_str(), name.c_str(),
262 EmitCType().c_str());
263 }
264 sb.Append(prefix).Append("{\n");
265 sb.Append(prefix + TAB).AppendFormat("uint64_t %s = 0;\n", tmpVarName.c_str());
266 sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.c_str(), tmpVarName.c_str());
267 sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
268 name.c_str());
269 sb.Append(prefix + TAB + TAB).Append("return false;\n");
270 sb.Append(prefix + TAB).Append("}\n");
271 sb.Append(prefix + TAB).AppendFormat("%s = static_cast<%s>(%s);\n", name.c_str(), EmitCType().c_str(),
272 tmpVarName.c_str());
273 sb.Append(prefix).Append("}\n");
274 }
275 } // namespace HDI
276 } // namespace OHOS
277