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