• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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