1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "c_custom_types_code_emitter.h"
17 #include "util/file.h"
18 #include "util/logger.h"
19 #include "util/options.h"
20
21 namespace OHOS {
22 namespace Idl {
ResolveDirectory(const std::string & targetDirectory)23 bool CCustomTypesCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
24 {
25 if (ast_->GetASTFileType() != ASTFileType::AST_TYPES) {
26 return false;
27 }
28
29 directory_ = GetFileParentPath(targetDirectory);
30 if (!File::CreateParentDir(directory_)) {
31 Logger::E("CCustomTypesCodeEmitter", "Create '%s' failed!", directory_.c_str());
32 return false;
33 }
34
35 return true;
36 }
37
EmitCode()38 void CCustomTypesCodeEmitter::EmitCode()
39 {
40 switch (mode_) {
41 case GenMode::LOW:
42 case GenMode::PASSTHROUGH: {
43 EmitPassthroughCustomTypesHeaderFile();
44 break;
45 }
46 case GenMode::IPC:
47 case GenMode::KERNEL: {
48 EmitCustomTypesHeaderFile();
49 EmitCustomTypesSourceFile();
50 break;
51 }
52 default:
53 break;
54 }
55 }
56
EmitPassthroughCustomTypesHeaderFile()57 void CCustomTypesCodeEmitter::EmitPassthroughCustomTypesHeaderFile()
58 {
59 std::string filePath =
60 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
61 File file(filePath, File::WRITE);
62 StringBuilder sb;
63
64 EmitLicense(sb);
65 EmitHeadMacro(sb, baseName_);
66 sb.Append("\n");
67 EmitPassthroughHeaderInclusions(sb);
68 sb.Append("\n");
69 EmitHeadExternC(sb);
70 sb.Append("\n");
71 EmitCustomTypeDecls(sb);
72 EmitTailExternC(sb);
73 sb.Append("\n");
74 EmitTailMacro(sb, baseName_);
75
76 std::string data = sb.ToString();
77 file.WriteData(data.c_str(), data.size());
78 file.Flush();
79 file.Close();
80 }
81
EmitPassthroughHeaderInclusions(StringBuilder & sb)82 void CCustomTypesCodeEmitter::EmitPassthroughHeaderInclusions(StringBuilder &sb)
83 {
84 HeaderFile::HeaderFileSet headerFiles;
85 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
86 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
87 GetStdlibInclusions(headerFiles);
88
89 for (const auto &file : headerFiles) {
90 sb.AppendFormat("%s\n", file.ToString().c_str());
91 }
92 }
93
EmitCustomTypesHeaderFile()94 void CCustomTypesCodeEmitter::EmitCustomTypesHeaderFile()
95 {
96 std::string filePath =
97 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
98 File file(filePath, File::WRITE);
99 StringBuilder sb;
100
101 EmitLicense(sb);
102 EmitHeadMacro(sb, baseName_);
103 sb.Append("\n");
104 EmitHeaderInclusions(sb);
105 sb.Append("\n");
106 EmitInterfaceBuffSizeMacro(sb);
107 sb.Append("\n");
108 EmitHeadExternC(sb);
109 sb.Append("\n");
110 EmitForwardDeclaration(sb);
111 sb.Append("\n");
112 EmitCustomTypeDecls(sb);
113 sb.Append("\n");
114 EmitCustomTypeFuncDecl(sb);
115 sb.Append("\n");
116 EmitTailExternC(sb);
117 sb.Append("\n");
118 EmitTailMacro(sb, baseName_);
119
120 std::string data = sb.ToString();
121 file.WriteData(data.c_str(), data.size());
122 file.Flush();
123 file.Close();
124 }
125
EmitHeaderInclusions(StringBuilder & sb)126 void CCustomTypesCodeEmitter::EmitHeaderInclusions(StringBuilder &sb)
127 {
128 HeaderFile::HeaderFileSet headerFiles;
129 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
130 headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
131 GetStdlibInclusions(headerFiles);
132
133 for (const auto &file : headerFiles) {
134 sb.AppendFormat("%s\n", file.ToString().c_str());
135 }
136 }
137
EmitForwardDeclaration(StringBuilder & sb) const138 void CCustomTypesCodeEmitter::EmitForwardDeclaration(StringBuilder &sb) const
139 {
140 sb.Append("struct HdfSBuf;\n");
141 }
142
EmitCustomTypeDecls(StringBuilder & sb) const143 void CCustomTypesCodeEmitter::EmitCustomTypeDecls(StringBuilder &sb) const
144 {
145 for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
146 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(ast_->GetTypeDefintion(i));
147 if (typeEmitter == nullptr) {
148 continue;
149 }
150 sb.Append(typeEmitter->EmitCTypeDecl()).Append("\n");
151 if (i + 1 < ast_->GetTypeDefinitionNumber()) {
152 sb.Append("\n");
153 }
154 }
155 }
156
EmitCustomTypeFuncDecl(StringBuilder & sb) const157 void CCustomTypesCodeEmitter::EmitCustomTypeFuncDecl(StringBuilder &sb) const
158 {
159 for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
160 AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
161 if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
162 EmitCustomTypeMarshallFuncDecl(sb, type);
163 if (i + 1 < ast_->GetTypeDefinitionNumber()) {
164 sb.Append("\n");
165 }
166 }
167 }
168 }
169
EmitCustomTypeMarshallFuncDecl(StringBuilder & sb,const AutoPtr<ASTType> & type) const170 void CCustomTypesCodeEmitter::EmitCustomTypeMarshallFuncDecl(StringBuilder &sb, const AutoPtr<ASTType> &type) const
171 {
172 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
173 if (typeEmitter == nullptr) {
174 return;
175 }
176 std::string objName("dataBlock");
177 sb.AppendFormat("bool %sBlockMarshalling(struct HdfSBuf *data, const %s *%s);\n\n", type->GetName().c_str(),
178 typeEmitter->EmitCType().c_str(), objName.c_str());
179 sb.AppendFormat("bool %sBlockUnmarshalling(struct HdfSBuf *data, %s *%s);\n\n", type->GetName().c_str(),
180 typeEmitter->EmitCType().c_str(), objName.c_str());
181 sb.AppendFormat("void %sFree(%s *%s, bool freeSelf);\n", type->GetName().c_str(),
182 typeEmitter->EmitCType().c_str(), objName.c_str());
183 }
184
EmitCustomTypesSourceFile()185 void CCustomTypesCodeEmitter::EmitCustomTypesSourceFile()
186 {
187 std::string filePath =
188 File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_).c_str()));
189 File file(filePath, File::WRITE);
190 StringBuilder sb;
191
192 EmitLicense(sb);
193 EmitSoucreInclusions(sb);
194 sb.Append("\n");
195 EmitUtilMethods(sb, true);
196 sb.Append("\n");
197 EmitUtilMethods(sb, false);
198 sb.Append("\n");
199 EmitCustomTypeDataProcess(sb);
200
201 std::string data = sb.ToString();
202 file.WriteData(data.c_str(), data.size());
203 file.Flush();
204 file.Close();
205 }
206
EmitSoucreInclusions(StringBuilder & sb)207 void CCustomTypesCodeEmitter::EmitSoucreInclusions(StringBuilder &sb)
208 {
209 HeaderFile::HeaderFileSet headerFiles;
210 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(baseName_));
211 GetSourceOtherLibInclusions(headerFiles);
212
213 for (const auto &file : headerFiles) {
214 sb.AppendFormat("%s\n", file.ToString().c_str());
215 }
216 }
217
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const218 void CCustomTypesCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
219 {
220 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
221 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
222 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
223 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
224 }
225
EmitCustomTypeDataProcess(StringBuilder & sb)226 void CCustomTypesCodeEmitter::EmitCustomTypeDataProcess(StringBuilder &sb)
227 {
228 for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
229 AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
230 if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
231 AutoPtr<ASTStructType> structType = static_cast<ASTStructType *>(type.Get());
232 EmitCustomTypeMarshallingImpl(sb, structType);
233 EmitCustomTypeUnmarshallingImpl(sb, structType);
234 sb.Append("\n");
235 EmitCustomTypeFreeImpl(sb, structType);
236 if (i + 1 < ast_->GetTypeDefinitionNumber()) {
237 sb.Append("\n");
238 }
239 }
240 }
241 }
242
EmitCustomTypeMarshallingImpl(StringBuilder & sb,const AutoPtr<ASTStructType> & type)243 void CCustomTypesCodeEmitter::EmitCustomTypeMarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type)
244 {
245 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type.Get());
246 if (typeEmitter == nullptr) {
247 return;
248 }
249 std::string typeName = typeEmitter->EmitCType();
250 std::string objName("dataBlock");
251 sb.AppendFormat("bool %sBlockMarshalling(struct HdfSBuf *data, const %s *%s)\n", type->GetName().c_str(),
252 typeName.c_str(), objName.c_str());
253 sb.Append("{\n");
254 EmitMarshallingVarDecl(type, objName, sb, TAB);
255 EmitParamCheck(objName, sb, TAB);
256 sb.Append("\n");
257 if (type->IsPod()) {
258 if (Options::GetInstance().DoGenerateKernelCode()) {
259 sb.Append(TAB).AppendFormat("if (!HdfSbufWriteBuffer(data, (const void *)%s, sizeof(%s))) {\n",
260 objName.c_str(), typeName.c_str());
261 } else {
262 sb.Append(TAB).AppendFormat("if (!HdfSbufWriteUnpadBuffer(data, (const uint8_t *)%s, sizeof(%s))) {\n",
263 objName.c_str(), typeName.c_str());
264 }
265 sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to write buffer data\", __func__);\n");
266 sb.Append(TAB).Append(TAB).Append("return false;\n");
267 sb.Append(TAB).Append("}\n");
268 } else {
269 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
270 std::string memberName = type->GetMemberName(i);
271 std::string name = StringHelper::Format("%s->%s", objName.c_str(), memberName.c_str());
272 AutoPtr<HdiTypeEmitter> typeEmitterTmp = GetTypeEmitter(type->GetMemberType(i));
273 if (typeEmitterTmp == nullptr) {
274 continue;
275 }
276 typeEmitterTmp->EmitCMarshalling(name, sb, TAB);
277 sb.Append("\n");
278 }
279 }
280
281 sb.Append(TAB).Append("return true;\n");
282 sb.Append("}\n\n");
283 }
284
EmitCustomTypeUnmarshallingImpl(StringBuilder & sb,const AutoPtr<ASTStructType> & type)285 void CCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type)
286 {
287 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type.Get());
288 if (typeEmitter == nullptr) {
289 return;
290 }
291 std::string typeName = typeEmitter->EmitCType();
292 std::string objName("dataBlock");
293 freeObjStatements_.clear();
294 sb.AppendFormat("bool %sBlockUnmarshalling(struct HdfSBuf *data, %s *%s)\n", type->GetName().c_str(),
295 typeName.c_str(), objName.c_str());
296 sb.Append("{\n");
297 EmitUnmarshallingVarDecl(type, objName, sb, TAB);
298 EmitParamCheck(objName, sb, TAB);
299 sb.Append("\n");
300 if (type->IsPod()) {
301 EmitPodTypeUnmarshalling(typeName, objName, sb, TAB);
302 } else {
303 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
304 AutoPtr<ASTType> memberType = type->GetMemberType(i);
305 EmitMemberUnmarshalling(memberType, objName, type->GetMemberName(i), sb, TAB);
306 }
307 }
308 sb.Append(TAB).Append("return true;\n");
309 sb.AppendFormat("%s:\n", ERRORS_LABEL );
310 EmitCustomTypeMemoryRecycle(type, objName, sb, TAB);
311 sb.Append(TAB).Append("return false;\n");
312 sb.Append("}\n");
313 }
314
EmitMarshallingVarDecl(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const315 void CCustomTypesCodeEmitter::EmitMarshallingVarDecl(const AutoPtr<ASTStructType> &type,
316 const std::string &name, StringBuilder &sb, const std::string &prefix) const
317 {
318 (void)name;
319 if (!Options::GetInstance().DoGenerateKernelCode()) {
320 return;
321 }
322
323 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
324 if (EmitNeedLoopVar(type->GetMemberType(i), true, false)) {
325 sb.Append(prefix).Append("uint32_t i = 0;\n");
326 break;
327 }
328 }
329 }
330
EmitUnmarshallingVarDecl(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const331 void CCustomTypesCodeEmitter::EmitUnmarshallingVarDecl(
332 const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
333 {
334 if (!Options::GetInstance().DoGenerateKernelCode()) {
335 return;
336 }
337
338 if (type->IsPod()) {
339 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type.Get());
340 if (typeEmitter != nullptr) {
341 sb.Append(prefix).AppendFormat("%s *%sPtr = NULL;\n",
342 typeEmitter->EmitCType().c_str(), name.c_str());
343 }
344 sb.Append(prefix).AppendFormat("uint32_t %sLen = 0;\n\n", name.c_str());
345 return;
346 }
347
348 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
349 if (EmitNeedLoopVar(type->GetMemberType(i), true, true)) {
350 sb.Append(prefix).Append("uint32_t i = 0;\n");
351 break;
352 }
353 }
354 }
355
EmitParamCheck(const std::string & name,StringBuilder & sb,const std::string & prefix) const356 void CCustomTypesCodeEmitter::EmitParamCheck(
357 const std::string &name, StringBuilder &sb, const std::string &prefix) const
358 {
359 sb.Append(prefix).Append("if (data == NULL) {\n");
360 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
361 sb.Append(prefix + TAB).Append("return false;\n");
362 sb.Append(prefix).Append("}\n\n");
363 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
364 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid data block\", __func__);\n");
365 sb.Append(prefix + TAB).Append("return false;\n");
366 sb.Append(prefix).Append("}\n");
367 }
368
EmitPodTypeUnmarshalling(const std::string & typeName,const std::string & name,StringBuilder & sb,const std::string & prefix) const369 void CCustomTypesCodeEmitter::EmitPodTypeUnmarshalling(
370 const std::string &typeName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
371 {
372 std::string objPtrName = StringHelper::Format("%sPtr", name.c_str());
373 if (Options::GetInstance().DoGenerateKernelCode()) {
374 std::string lenName = StringHelper::Format("%sLen", name.c_str());
375 sb.Append(prefix).AppendFormat(
376 "if (!HdfSbufReadBuffer(data, (const void**)&%s, &%s)) {\n", objPtrName.c_str(), lenName.c_str());
377 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
378 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
379 sb.Append(prefix).Append("}\n\n");
380 sb.Append(prefix).AppendFormat(
381 "if (%s == NULL || %s != sizeof(%s)) {\n", objPtrName.c_str(), lenName.c_str(), typeName.c_str());
382 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid data from reading buffer\", __func__);\n");
383 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
384 sb.Append(prefix).Append("}\n");
385 } else {
386 sb.Append(prefix).AppendFormat("const %s *%s = (const %s *)HdfSbufReadUnpadBuffer(data, sizeof(%s));\n",
387 typeName.c_str(), objPtrName.c_str(), typeName.c_str(), typeName.c_str());
388 sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", objPtrName.c_str());
389 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
390 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
391 sb.Append(prefix).Append("}\n\n");
392 }
393
394 sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", name.c_str(),
395 typeName.c_str(), objPtrName.c_str(), typeName.c_str());
396 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy data\", __func__);\n");
397 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
398 sb.Append(prefix).Append("}\n\n");
399 }
400
EmitMemberUnmarshalling(const AutoPtr<ASTType> & type,const std::string & name,const std::string & memberName,StringBuilder & sb,const std::string & prefix)401 void CCustomTypesCodeEmitter::EmitMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &name,
402 const std::string &memberName, StringBuilder &sb, const std::string &prefix)
403 {
404 std::string varName = StringHelper::Format("%s->%s", name.c_str(), memberName.c_str());
405 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
406 if (typeEmitter == nullptr) {
407 return;
408 }
409 switch (type->GetTypeKind()) {
410 case TypeKind::TYPE_STRING: {
411 EmitStringMemberUnmarshalling(typeEmitter, memberName, varName, sb, prefix);
412 break;
413 }
414 case TypeKind::TYPE_STRUCT: {
415 std::string paramName = StringHelper::Format("&%s", varName.c_str());
416 typeEmitter->EmitCUnMarshalling(paramName, ERRORS_LABEL, sb, prefix, freeObjStatements_);
417 sb.Append("\n");
418 break;
419 }
420 case TypeKind::TYPE_UNION: {
421 std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
422 typeEmitter->EmitCUnMarshalling(tmpName, ERRORS_LABEL, sb, prefix, freeObjStatements_);
423 sb.Append(prefix).AppendFormat("if (memcpy_s(&%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", varName.c_str(),
424 typeEmitter->EmitCType().c_str(), tmpName.c_str(), typeEmitter->EmitCType().c_str());
425 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy data\", __func__);\n");
426 sb.Append(prefix + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
427 sb.Append(prefix).Append("}\n");
428 break;
429 }
430 case TypeKind::TYPE_ARRAY:
431 case TypeKind::TYPE_LIST: {
432 EmitArrayMemberUnmarshalling(type, memberName, varName, sb, prefix);
433 sb.Append("\n");
434 break;
435 }
436 default: {
437 typeEmitter->EmitCUnMarshalling(varName, ERRORS_LABEL, sb, prefix, freeObjStatements_);
438 sb.Append("\n");
439 }
440 }
441 }
442
EmitStringMemberUnmarshalling(const AutoPtr<HdiTypeEmitter> & typeEmitter,const std::string & memberName,const std::string & varName,StringBuilder & sb,const std::string & prefix)443 void CCustomTypesCodeEmitter::EmitStringMemberUnmarshalling(const AutoPtr<HdiTypeEmitter> &typeEmitter,
444 const std::string &memberName, const std::string &varName, StringBuilder &sb, const std::string &prefix)
445 {
446 std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
447 sb.Append(prefix).Append("{\n");
448 typeEmitter->EmitCUnMarshalling(tmpName, ERRORS_LABEL, sb, prefix + TAB, freeObjStatements_);
449 if (Options::GetInstance().DoGenerateKernelCode()) {
450 sb.Append(prefix + TAB)
451 .AppendFormat("%s = (char*)OsalMemCalloc(strlen(%s) + 1);\n", varName.c_str(), tmpName.c_str());
452 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", varName.c_str());
453 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
454 sb.Append(prefix + TAB).Append("}\n");
455 sb.Append(prefix + TAB).AppendFormat("if (strcpy_s(%s, (strlen(%s) + 1), %s) != EOK) {\n",
456 varName.c_str(), tmpName.c_str(), tmpName.c_str());
457 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
458 sb.Append(prefix + TAB).Append("}\n");
459 } else {
460 sb.Append(prefix + TAB).AppendFormat("%s = strdup(%s);\n", varName.c_str(), tmpName.c_str());
461 }
462
463 sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", varName.c_str());
464 sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", ERRORS_LABEL );
465 sb.Append(prefix + TAB).Append("}\n");
466 sb.Append(prefix).Append("}\n");
467 sb.Append("\n");
468 }
469
EmitArrayMemberUnmarshalling(const AutoPtr<ASTType> & type,const std::string & memberName,const std::string & varName,StringBuilder & sb,const std::string & prefix)470 void CCustomTypesCodeEmitter::EmitArrayMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &memberName,
471 const std::string &varName, StringBuilder &sb, const std::string &prefix)
472 {
473 std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
474 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
475 if (typeEmitter == nullptr) {
476 return;
477 }
478 AutoPtr<ASTType> elementType = nullptr;
479 if (type->GetTypeKind() == TypeKind::TYPE_ARRAY) {
480 AutoPtr<ASTArrayType> arrayType = static_cast<ASTArrayType *>(type.Get());
481 elementType = arrayType->GetElementType();
482 } else {
483 AutoPtr<ASTListType> listType = static_cast<ASTListType *>(type.Get());
484 elementType = listType->GetElementType();
485 }
486
487 if (elementType->IsStringType()) {
488 typeEmitter->EmitCUnMarshalling(varName, ERRORS_LABEL, sb, prefix, freeObjStatements_);
489 return;
490 }
491
492 sb.Append(prefix).Append("{\n");
493 AutoPtr<HdiTypeEmitter> elementTypeEmitter = GetTypeEmitter(elementType);
494 if (elementTypeEmitter == nullptr) {
495 return;
496 }
497 sb.Append(prefix + TAB).AppendFormat("%s* %s = NULL;\n",
498 elementTypeEmitter->EmitCType().c_str(), tmpName.c_str());
499 sb.Append(prefix + TAB).AppendFormat("uint32_t %sLen = 0;\n", tmpName.c_str());
500 typeEmitter->EmitCUnMarshalling(tmpName, ERRORS_LABEL, sb, prefix + TAB, freeObjStatements_);
501 sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", varName.c_str(), tmpName.c_str());
502 sb.Append(prefix + TAB).AppendFormat("%sLen = %sLen;\n", varName.c_str(), tmpName.c_str());
503 sb.Append(prefix).Append("}\n");
504 }
505
EmitCustomTypeFreeImpl(StringBuilder & sb,const AutoPtr<ASTStructType> & type) const506 void CCustomTypesCodeEmitter::EmitCustomTypeFreeImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
507 {
508 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type.Get());
509 if (typeEmitter == nullptr) {
510 return;
511 }
512 std::string objName("dataBlock");
513 sb.AppendFormat("void %sFree(%s *%s, bool freeSelf)\n", type->GetName().c_str(),
514 typeEmitter->EmitCType().c_str(), objName.c_str());
515 sb.Append("{\n");
516
517 if (mode_ == GenMode::KERNEL) {
518 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
519 AutoPtr<ASTType> memberType = type->GetMemberType(i);
520 if (EmitNeedLoopVar(memberType, false, true)) {
521 sb.Append(TAB).Append("uint32_t i = 0;\n");
522 break;
523 }
524 }
525 }
526
527 sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
528 sb.Append(TAB).Append(TAB).Append("return;\n");
529 sb.Append(TAB).Append("}\n");
530 sb.Append("\n");
531
532 EmitCustomTypeMemoryRecycle(type, objName, sb, TAB);
533
534 sb.Append(TAB).Append("if (freeSelf) {\n");
535 sb.Append(TAB).Append(TAB).Append("OsalMemFree(dataBlock);\n");
536 sb.Append(TAB).Append("}\n");
537 sb.Append("}\n");
538 }
539
EmitCustomTypeMemoryRecycle(const AutoPtr<ASTStructType> & type,const std::string & name,StringBuilder & sb,const std::string & prefix) const540 void CCustomTypesCodeEmitter::EmitCustomTypeMemoryRecycle(
541 const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
542 {
543 for (size_t i = 0; i < type->GetMemberNumber(); i++) {
544 AutoPtr<ASTType> memberType = type->GetMemberType(i);
545 std::string memberName = type->GetMemberName(i);
546 std::string varName = StringHelper::Format("%s->%s", name.c_str(), memberName.c_str());
547 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(memberType);
548 if (typeEmitter == nullptr) {
549 continue;
550 }
551 switch (memberType->GetTypeKind()) {
552 case TypeKind::TYPE_STRING:
553 case TypeKind::TYPE_STRUCT:
554 case TypeKind::TYPE_ARRAY:
555 case TypeKind::TYPE_LIST:
556 typeEmitter->EmitMemoryRecycle(varName, false, sb, prefix);
557 sb.Append("\n");
558 break;
559 default:
560 break;
561 }
562 }
563 }
564
EmitUtilMethods(StringBuilder & sb,bool isDecl)565 void CCustomTypesCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
566 {
567 UtilMethodMap methods;
568 for (const auto &typePair : ast_->GetTypes()) {
569 AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(typePair.second);
570 if (typeEmitter != nullptr) {
571 typeEmitter->EmitCWriteMethods(methods, "", "", isDecl);
572 typeEmitter->EmitCStubReadMethods(methods, "", "", isDecl);
573 }
574 }
575 EmitUtilMethodMap(sb, methods);
576 }
577 } // namespace Idl
578 } // namespace OHOS