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