1 /*
2 * Copyright (c) 2021 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()32 String ASTEnumType::ToString()
33 {
34 return "enum " + name_;
35 }
36
Dump(const String & prefix)37 String ASTEnumType::Dump(const String& prefix)
38 {
39 StringBuilder sb;
40
41 std::vector<String> attributes;
42 if (isFull_) attributes.push_back("full");
43 if (isLite_) attributes.push_back("lite");
44 if (attributes.size() > 0) {
45 sb.Append("[");
46 for (size_t i = 0; i < attributes.size(); i++) {
47 sb.Append(attributes[i]);
48 if (i < attributes.size() - 1) {
49 sb.Append(',');
50 }
51 }
52 sb.Append("] ");
53 }
54
55 if (isDisplayBase_ && baseType_ != nullptr) {
56 sb.AppendFormat("enum %s : %s {\n", name_.string(), baseType_->ToString().string());
57 } else {
58 sb.AppendFormat("enum %s {\n", name_.string());
59 }
60
61 if (members_.size() > 0) {
62 for (auto it : members_) {
63 if (it->isDefaultValue()) {
64 sb.Append(" ").AppendFormat("%s,\n", it->GetName().string());
65 } else {
66 sb.Append(" ").AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetValue());
67 }
68 }
69 }
70
71 sb.Append(prefix).Append("};\n");
72
73 return sb.ToString();
74 }
75
GetTypeKind()76 TypeKind ASTEnumType::GetTypeKind()
77 {
78 return TypeKind::TYPE_ENUM;
79 }
80
EmitCType(TypeMode mode) const81 String ASTEnumType::EmitCType(TypeMode mode) const
82 {
83 switch (mode) {
84 case TypeMode::NO_MODE:
85 return String::Format("enum %s", name_.string());
86 case TypeMode::PARAM_IN:
87 return String::Format("enum %s", name_.string());
88 case TypeMode::PARAM_OUT:
89 return String::Format("enum %s*", name_.string());
90 case TypeMode::LOCAL_VAR:
91 return String::Format("enum %s", name_.string());
92 default:
93 return "unknow type";
94 }
95 }
96
EmitCppType(TypeMode mode) const97 String ASTEnumType::EmitCppType(TypeMode mode) const
98 {
99 switch (mode) {
100 case TypeMode::NO_MODE:
101 return String::Format("%s", name_.string());
102 case TypeMode::PARAM_IN:
103 return String::Format("%s", name_.string());
104 case TypeMode::PARAM_OUT:
105 return String::Format("%s&", name_.string());
106 case TypeMode::LOCAL_VAR:
107 return String::Format("%s", name_.string());
108 default:
109 return "unknow type";
110 }
111 }
112
EmitJavaType(TypeMode mode,bool isInnerType) const113 String ASTEnumType::EmitJavaType(TypeMode mode, bool isInnerType) const
114 {
115 // currently, Java does not support the enum type.
116 return "/";
117 }
118
EmitCTypeDecl() const119 String ASTEnumType::EmitCTypeDecl() const
120 {
121 StringBuilder sb;
122 sb.AppendFormat("enum %s {\n", name_.string());
123
124 for (auto it : members_) {
125 if (it->isDefaultValue()) {
126 sb.Append(" ").AppendFormat("%s,\n", it->GetName().string());
127 } else {
128 sb.Append(" ").AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetValue());
129 }
130 }
131
132 sb.Append("};");
133 return sb.ToString();
134 }
135
EmitCppTypeDecl() const136 String ASTEnumType::EmitCppTypeDecl() const
137 {
138 StringBuilder sb;
139 if (isDisplayBase_ && baseType_ != nullptr) {
140 sb.AppendFormat("enum %s : %s {\n", name_.string(), baseType_->EmitCppType().string());
141 } else {
142 sb.AppendFormat("enum %s {\n", name_.string());
143 }
144
145 for (auto it : members_) {
146 if (it->isDefaultValue()) {
147 sb.Append(" ").AppendFormat("%s,\n", it->GetName().string());
148 } else {
149 sb.Append(" ").AppendFormat("%s = %lu,\n", it->GetName().string(), it->GetValue());
150 }
151 }
152
153 sb.Append("};");
154 return sb.ToString();
155 }
156
EmitJavaTypeDecl() const157 String ASTEnumType::EmitJavaTypeDecl() const
158 {
159 StringBuilder sb;
160
161 return sb.ToString();
162 }
163
EmitCWriteVar(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const164 void ASTEnumType::EmitCWriteVar(const String& parcelName, const String& name, const String& ecName,
165 const String& gotoLabel, StringBuilder& sb, const String& prefix) const
166 {
167 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(%s, (uint64_t)%s)) {\n",
168 parcelName.string(), name.string());
169 sb.Append(prefix + g_tab).AppendFormat(
170 "HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string());
171 sb.Append(prefix + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
172 sb.Append(prefix + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
173 sb.Append(prefix).Append("}\n");
174 }
175
EmitCProxyReadVar(const String & parcelName,const String & name,bool isInnerType,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const176 void ASTEnumType::EmitCProxyReadVar(const String& parcelName, const String& name, bool isInnerType,
177 const String& ecName, const String& gotoLabel, StringBuilder& sb, const String& prefix) const
178 {
179 String tmpVarName = "enumTmp";
180 sb.Append(prefix).Append("{\n");
181 sb.Append(prefix + g_tab).AppendFormat("uint64_t %s = 0;\n", tmpVarName.string());
182 sb.Append(prefix + g_tab)
183 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.string(), tmpVarName.string());
184 sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
185 name.string());
186 sb.Append(prefix + g_tab + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
187 sb.Append(prefix + g_tab + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
188 sb.Append(prefix + g_tab).Append("}\n\n");
189 sb.Append(prefix + g_tab).AppendFormat("if (%s == NULL) {\n", name.string());
190 sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: invlid parameter %s\", __func__);\n",
191 name.string());
192 sb.Append(prefix + g_tab + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
193 sb.Append(prefix + g_tab + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
194 sb.Append(prefix + g_tab).Append("}\n\n");
195 sb.Append(prefix + g_tab).AppendFormat("*%s = (%s)%s;\n", name.string(), EmitCType().string(),
196 tmpVarName.string());
197 sb.Append(prefix).Append("}\n");
198 }
199
EmitCStubReadVar(const String & parcelName,const String & name,const String & ecName,const String & gotoLabel,StringBuilder & sb,const String & prefix) const200 void ASTEnumType::EmitCStubReadVar(const String& parcelName, const String& name, const String& ecName,
201 const String& gotoLabel, StringBuilder& sb, const String& prefix) const
202 {
203 String tmpVarName = "enumTmp";
204 sb.Append(prefix).Append("{\n");
205 sb.Append(prefix + g_tab).AppendFormat("uint64_t %s = 0;\n", tmpVarName.string());
206 sb.Append(prefix + g_tab)
207 .AppendFormat("if (!HdfSbufReadUint64(%s, &%s)) {\n", parcelName.string(), tmpVarName.string());
208 sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
209 name.string());
210 sb.Append(prefix + g_tab + g_tab).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.string());
211 sb.Append(prefix + g_tab + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
212 sb.Append(prefix + g_tab).Append("}\n");
213 sb.Append(prefix + g_tab).AppendFormat("%s = (%s)%s;\n", name.string(), EmitCType().string(), tmpVarName.string());
214 sb.Append(prefix).Append("}\n");
215 }
216
EmitCppWriteVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,unsigned int innerLevel) const217 void ASTEnumType::EmitCppWriteVar(const String& parcelName, const String& name, StringBuilder& sb,
218 const String& prefix, unsigned int innerLevel) const
219 {
220 sb.Append(prefix).AppendFormat("if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.string(),
221 name.string());
222 sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string());
223 sb.Append(prefix + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
224 sb.Append(prefix).Append("}\n");
225 }
226
EmitCppReadVar(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,bool initVariable,unsigned int innerLevel) const227 void ASTEnumType::EmitCppReadVar(const String& parcelName, const String& name, StringBuilder& sb,
228 const String& prefix, bool initVariable, unsigned int innerLevel) const
229 {
230 String tmpVarName = "enumTmp";
231 if (initVariable) {
232 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().string(), name.string(),
233 EmitCType().string());
234 }
235 sb.Append(prefix).Append("{\n");
236 sb.Append(prefix + g_tab).AppendFormat("uint64_t %s = 0;\n", tmpVarName.string());
237 sb.Append(prefix + g_tab).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.string(), tmpVarName.string());
238 sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
239 name.string());
240 sb.Append(prefix + g_tab + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n");
241 sb.Append(prefix + g_tab).Append("}\n");
242 sb.Append(prefix + g_tab).AppendFormat("%s = static_cast<%s>(%s);\n", name.string(), EmitCType().string(),
243 tmpVarName.string());
244 sb.Append(prefix).Append("}\n");
245 }
246
EmitCMarshalling(const String & name,StringBuilder & sb,const String & prefix) const247 void ASTEnumType::EmitCMarshalling(const String& name, StringBuilder& sb, const String& prefix) const
248 {
249 sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint64(data, (uint64_t)%s)) {\n", name.string());
250 sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string());
251 sb.Append(prefix + g_tab).Append("return false;\n");
252 sb.Append(prefix).Append("}\n");
253 }
254
EmitCUnMarshalling(const String & name,const String & gotoLabel,StringBuilder & sb,const String & prefix,std::vector<String> & freeObjStatements) const255 void ASTEnumType::EmitCUnMarshalling(const String& name, const String& gotoLabel, StringBuilder& sb,
256 const String& prefix, std::vector<String>& freeObjStatements) const
257 {
258 String tmpVarName = "enumTmp";
259 sb.Append(prefix).Append("{\n");
260 sb.Append(prefix + g_tab).AppendFormat("uint64_t %s = 0;\n", tmpVarName.string());
261 sb.Append(prefix + g_tab).AppendFormat("if (!HdfSbufReadUint64(data, &%s)) {\n", tmpVarName.string());
262 sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n",
263 name.string());
264 sb.Append(prefix + g_tab + g_tab).AppendFormat("goto %s;\n", gotoLabel.string());
265 sb.Append(prefix + g_tab).Append("}\n");
266 sb.Append(prefix + g_tab).AppendFormat("%s = (%s)%s;\n", name.string(), EmitCType().string(), tmpVarName.string());
267 sb.Append(prefix).Append("}\n");
268 }
269
EmitCppMarshalling(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,unsigned int innerLevel) const270 void ASTEnumType::EmitCppMarshalling(const String& parcelName, const String& name, StringBuilder& sb,
271 const String& prefix, unsigned int innerLevel) const
272 {
273 sb.Append(prefix).AppendFormat(
274 "if (!%s.WriteUint64(static_cast<uint64_t>(%s))) {\n", parcelName.string(), name.string());
275 sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string());
276 sb.Append(prefix + g_tab).Append("return false;\n");
277 sb.Append(prefix).Append("}\n");
278 }
279
EmitCppUnMarshalling(const String & parcelName,const String & name,StringBuilder & sb,const String & prefix,bool emitType,unsigned int innerLevel) const280 void ASTEnumType::EmitCppUnMarshalling(const String& parcelName, const String& name, StringBuilder& sb,
281 const String& prefix, bool emitType, unsigned int innerLevel) const
282 {
283 String tmpVarName = "enumTmp";
284 if (emitType) {
285 sb.Append(prefix).AppendFormat("%s %s = static_cast<%s>(0);\n", EmitCppType().string(), name.string(),
286 EmitCType().string());
287 }
288 sb.Append(prefix).Append("{\n");
289 sb.Append(prefix + g_tab).AppendFormat("uint64_t %s = 0;\n", tmpVarName.string());
290 sb.Append(prefix + g_tab).AppendFormat("if (!%s.ReadUint64(%s)) {\n", parcelName.string(), tmpVarName.string());
291 sb.Append(prefix + g_tab + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n",
292 name.string());
293 sb.Append(prefix + g_tab + g_tab).Append("return false;\n");
294 sb.Append(prefix + g_tab).Append("}\n");
295 sb.Append(prefix + g_tab).AppendFormat("%s = static_cast<%s>(%s);\n", name.string(), EmitCType().string(),
296 tmpVarName.string());
297 sb.Append(prefix).Append("}\n");
298 }
299 } // namespace HDI
300 } // namespace OHOS