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_struct_type.h"
10 #include "util/string_builder.h"
11
12 namespace OHOS {
13 namespace HDI {
SetParentType(const AutoPtr<ASTStructType> & parentType)14 void ASTStructType::SetParentType(const AutoPtr<ASTStructType> &parentType)
15 {
16 if (parentType == nullptr) {
17 return;
18 }
19
20 std::vector<std::tuple<std::string, AutoPtr<ASTType>>> parentMembers = parentType->GetMembers();
21 for (auto member : parentMembers) {
22 AddMember(std::get<1>(member), std::get<0>(member));
23 }
24 parentType_ = parentType;
25 }
26
AddMember(const AutoPtr<ASTType> & typeName,std::string name)27 void ASTStructType::AddMember(const AutoPtr<ASTType> &typeName, std::string name)
28 {
29 for (auto it : members_) {
30 if (std::get<0>(it) == name) {
31 return;
32 }
33 }
34 members_.push_back(std::make_tuple(name, typeName));
35
36 if (!typeName->IsPod()) {
37 isPod_ = false;
38 }
39 }
40
IsStructType()41 bool ASTStructType::IsStructType()
42 {
43 return true;
44 }
45
Dump(const std::string & prefix)46 std::string ASTStructType::Dump(const std::string &prefix)
47 {
48 StringBuilder sb;
49 sb.Append(prefix).Append(attr_->Dump(prefix)).Append(" ");
50 if (parentType_ == nullptr) {
51 sb.AppendFormat("struct %s {\n", name_.c_str());
52 } else {
53 sb.AppendFormat("struct %s : %s {\n", name_.c_str(), parentType_->ToString().c_str());
54 }
55 if (members_.size() > 0) {
56 for (auto it : members_) {
57 sb.Append(prefix + " ");
58 sb.AppendFormat("%s %s;\n", std::get<1>(it)->ToString().c_str(), std::get<0>(it).c_str());
59 }
60 }
61 sb.Append(prefix).Append("};\n");
62 return sb.ToString();
63 }
64
GetTypeKind()65 TypeKind ASTStructType::GetTypeKind()
66 {
67 return TypeKind::TYPE_STRUCT;
68 }
69
EmitCType(TypeMode mode) const70 std::string ASTStructType::EmitCType(TypeMode mode) const
71 {
72 switch (mode) {
73 case TypeMode::NO_MODE:
74 return StringHelper::Format("struct %s", name_.c_str());
75 case TypeMode::PARAM_IN:
76 return StringHelper::Format("const struct %s*", name_.c_str());
77 case TypeMode::PARAM_OUT:
78 return StringHelper::Format("struct %s*", name_.c_str());
79 case TypeMode::LOCAL_VAR:
80 return StringHelper::Format("struct %s*", name_.c_str());
81 default:
82 return "unknow type";
83 }
84 }
85
EmitCppType(TypeMode mode) const86 std::string ASTStructType::EmitCppType(TypeMode mode) const
87 {
88 switch (mode) {
89 case TypeMode::NO_MODE:
90 return StringHelper::Format("%s", GetNameWithNamespace(namespace_, name_).c_str());
91 case TypeMode::PARAM_IN:
92 return StringHelper::Format("const %s&", GetNameWithNamespace(namespace_, name_).c_str());
93 case TypeMode::PARAM_OUT:
94 return StringHelper::Format("%s&", GetNameWithNamespace(namespace_, name_).c_str());
95 case TypeMode::LOCAL_VAR:
96 return StringHelper::Format("%s", GetNameWithNamespace(namespace_, name_).c_str());
97 default:
98 return "unknow type";
99 }
100 }
101
EmitJavaType(TypeMode mode,bool isInnerType) const102 std::string ASTStructType::EmitJavaType(TypeMode mode, bool isInnerType) const
103 {
104 // currently, Java does not support the struct type.
105 return "/";
106 }
107
EmitCTypeDecl() const108 std::string ASTStructType::EmitCTypeDecl() const
109 {
110 StringBuilder sb;
111 sb.AppendFormat("struct %s {\n", name_.c_str());
112
113 for (auto it : members_) {
114 AutoPtr<ASTType> member = std::get<1>(it);
115 std::string memberName = std::get<0>(it);
116 sb.Append(TAB).AppendFormat("%s %s;\n", member->EmitCType().c_str(), memberName.c_str());
117 if (member->GetTypeKind() == TypeKind::TYPE_ARRAY || member->GetTypeKind() == TypeKind::TYPE_LIST) {
118 sb.Append(TAB).AppendFormat("uint32_t %sLen;\n", memberName.c_str());
119 }
120 }
121
122 sb.Append("}");
123 if (IsPod()) {
124 sb.Append(" __attribute__ ((aligned(8)))");
125 }
126 sb.Append(";");
127
128 return sb.ToString();
129 }
130
EmitCppTypeDecl() const131 std::string ASTStructType::EmitCppTypeDecl() const
132 {
133 StringBuilder sb;
134 sb.AppendFormat("struct %s {\n", name_.c_str());
135
136 for (auto it : members_) {
137 AutoPtr<ASTType> member = std::get<1>(it);
138 std::string memberName = std::get<0>(it);
139 sb.Append(TAB).AppendFormat("%s %s;\n", member->EmitCppType().c_str(), memberName.c_str());
140 }
141
142 sb.Append("}");
143 if (IsPod()) {
144 sb.Append(" __attribute__ ((aligned(8)))");
145 }
146 sb.Append(";");
147 return sb.ToString();
148 }
149
EmitJavaTypeDecl() const150 std::string ASTStructType::EmitJavaTypeDecl() const
151 {
152 StringBuilder sb;
153
154 return sb.ToString();
155 }
156
EmitCWriteVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const157 void ASTStructType::EmitCWriteVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
158 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
159 {
160 sb.Append(prefix).AppendFormat(
161 "if (!%sBlockMarshalling(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str());
162 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
163 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
164 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
165 sb.Append(prefix).Append("}\n");
166 }
167
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) const168 void ASTStructType::EmitCProxyReadVar(const std::string &parcelName, const std::string &name, bool isInnerType,
169 const std::string &ecName, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
170 {
171 sb.Append(prefix).AppendFormat(
172 "if (!%sBlockUnmarshalling(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str());
173 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
174 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
175 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
176 sb.Append(prefix).Append("}\n");
177 }
178
EmitCStubReadVar(const std::string & parcelName,const std::string & name,const std::string & ecName,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix) const179 void ASTStructType::EmitCStubReadVar(const std::string &parcelName, const std::string &name, const std::string &ecName,
180 const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
181 {
182 sb.Append(prefix).AppendFormat(
183 "if (!%sBlockUnmarshalling(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str());
184 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
185 sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", ecName.c_str());
186 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
187 sb.Append(prefix).AppendFormat("}\n");
188 }
189
EmitCppWriteVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const190 void ASTStructType::EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
191 const std::string &prefix, unsigned int innerLevel) const
192 {
193 sb.Append(prefix).AppendFormat(
194 "if (!%sBlockMarshalling(%s, %s)) {\n", EmitCppType().c_str(), parcelName.c_str(), name.c_str());
195 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
196 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
197 sb.Append(prefix).Append("}\n");
198 }
199
EmitCppReadVar(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool initVariable,unsigned int innerLevel) const200 void ASTStructType::EmitCppReadVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
201 const std::string &prefix, bool initVariable, unsigned int innerLevel) const
202 {
203 if (initVariable) {
204 sb.Append(prefix).AppendFormat("%s %s;\n", EmitCppType().c_str(), name.c_str());
205 }
206 sb.Append(prefix).AppendFormat(
207 "if (!%sBlockUnmarshalling(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str());
208 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
209 sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
210 sb.Append(prefix).Append("}\n");
211 }
212
EmitCMarshalling(const std::string & name,StringBuilder & sb,const std::string & prefix) const213 void ASTStructType::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
214 {
215 sb.Append(prefix).AppendFormat("if (!%sBlockMarshalling(data, &%s)) {\n", name_.c_str(), name.c_str());
216 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
217 sb.Append(prefix + TAB).Append("return false;\n");
218 sb.Append(prefix).Append("}\n");
219 }
220
EmitCUnMarshalling(const std::string & name,const std::string & gotoLabel,StringBuilder & sb,const std::string & prefix,std::vector<std::string> & freeObjStatements) const221 void ASTStructType::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
222 const std::string &prefix, std::vector<std::string> &freeObjStatements) const
223 {
224 sb.Append(prefix).AppendFormat("if (!%sBlockUnmarshalling(data, %s)) {\n", name_.c_str(), name.c_str());
225 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
226 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
227 sb.Append(prefix).Append("}\n");
228 }
229
EmitCppMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,unsigned int innerLevel) const230 void ASTStructType::EmitCppMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
231 const std::string &prefix, unsigned int innerLevel) const
232 {
233 sb.Append(prefix).AppendFormat(
234 "if (!%sBlockMarshalling(%s, %s)) {\n", name_.c_str(), parcelName.c_str(), name.c_str());
235 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.c_str());
236 sb.Append(prefix + TAB).Append("return false;\n");
237 sb.Append(prefix).Append("}\n");
238 }
239
EmitCppUnMarshalling(const std::string & parcelName,const std::string & name,StringBuilder & sb,const std::string & prefix,bool emitType,unsigned int innerLevel) const240 void ASTStructType::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
241 const std::string &prefix, bool emitType, unsigned int innerLevel) const
242 {
243 sb.Append(prefix).AppendFormat("if (!%sBlockUnmarshalling(data, %s)) {\n", EmitCppType().c_str(), name.c_str());
244 sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
245 sb.Append(prefix + TAB).Append("return false;\n");
246 sb.Append(prefix).Append("}\n");
247 }
248
EmitMemoryRecycle(const std::string & name,bool ownership,StringBuilder & sb,const std::string & prefix) const249 void ASTStructType::EmitMemoryRecycle(
250 const std::string &name, bool ownership, StringBuilder &sb, const std::string &prefix) const
251 {
252 std::string varName = name;
253 if (ownership) {
254 sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", varName.c_str());
255 sb.Append(prefix + TAB).AppendFormat("%sFree(%s, true);\n", name_.c_str(), varName.c_str());
256 sb.Append(prefix + TAB).AppendFormat("%s = NULL;\n", varName.c_str());
257 sb.Append(prefix).Append("}\n");
258 } else {
259 sb.Append(prefix).AppendFormat("%sFree(&%s, false);\n", name_.c_str(), name.c_str());
260 }
261 }
262 } // namespace HDI
263 } // namespace OHOS