• 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 
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