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 #define LOG_TAG "Utd"
17 #include "utd.h"
18
19 #include "securec.h"
20 #include "logger.h"
21 #include "utd_client.h"
22 #include "udmf_capi_common.h"
23 #include "udmf_err_code.h"
24
25 using namespace OHOS::UDMF;
26
27 static constexpr const int32_t MAX_UTD_SIZE = 50;
28
29 typedef Status (UtdClient::*GetUtdByConditionPtr)(const std::string&, std::string&, std::string);
30
DestroyArrayPtr(const char ** & arrayPtr,unsigned int & count)31 static void DestroyArrayPtr(const char** &arrayPtr, unsigned int& count)
32 {
33 if (arrayPtr == nullptr) {
34 LOG_ERROR(UDMF_CAPI, "Cannot delete arrayPtr because it's a nullptr.");
35 return;
36 }
37 for (unsigned int i = 0; i < count; i++) {
38 if (arrayPtr[i] != nullptr) {
39 delete[] arrayPtr[i];
40 arrayPtr[i] = nullptr;
41 }
42 }
43 delete[] arrayPtr;
44 arrayPtr = nullptr;
45 count = 0;
46 LOG_INFO(UDMF_CAPI, "delete arrayPtr finish.");
47 }
48
CreateStrArrByVector(const std::vector<std::string> & paramVector,unsigned int * count)49 static const char** CreateStrArrByVector(const std::vector<std::string>& paramVector, unsigned int* count)
50 {
51 unsigned int size = paramVector.size();
52 if (size == 0 || size > MAX_UTD_SIZE) {
53 LOG_ERROR(UDMF_CAPI, "Cannot create array, because size is illegal or exceeds the max value of UTD.");
54 *count = 0;
55 return nullptr;
56 }
57 auto charPtr = new (std::nothrow) char* [size];
58 if (charPtr == nullptr) {
59 *count = 0;
60 return nullptr;
61 }
62 for (unsigned int i = 0; i < size; i++) {
63 charPtr[i] = new (std::nothrow) char[paramVector[i].size() + 1];
64 if (charPtr[i] == nullptr ||
65 strcpy_s(charPtr[i], paramVector[i].size() + 1, paramVector[i].c_str()) != UDMF_E_OK) {
66 LOG_ERROR(UDMF_CAPI, "obtain the memory error, or str copy error!");
67 const char** arrayPtr = const_cast<const char**>(charPtr);
68 DestroyArrayPtr(arrayPtr, size);
69 *count = 0;
70 return nullptr;
71 }
72 }
73 *count = size;
74 return const_cast<const char**>(charPtr);
75 }
76
GetTypeDescriptorByUtdClient(const char * typeId)77 static std::shared_ptr<TypeDescriptor> GetTypeDescriptorByUtdClient(const char* typeId)
78 {
79 std::shared_ptr<TypeDescriptor> typeDescriptor;
80 UtdClient::GetInstance().GetTypeDescriptor(typeId, typeDescriptor);
81 return typeDescriptor;
82 }
83
IsUtdInvalid(OH_Utd * pThis)84 static bool IsUtdInvalid(OH_Utd* pThis)
85 {
86 return pThis == nullptr || pThis->cid != NdkStructId::UTD_STRUCT_ID;
87 }
88
GetTypesByCondition(const char * condition,unsigned int * count,GetUtdByConditionPtr funcPtr)89 static const char** GetTypesByCondition(const char* condition, unsigned int* count, GetUtdByConditionPtr funcPtr)
90 {
91 if (condition == nullptr || count == nullptr || funcPtr == nullptr) {
92 return nullptr;
93 }
94 std::string typeIdStr;
95 Status result = (UtdClient::GetInstance().*funcPtr)(condition, typeIdStr, DEFAULT_TYPE_ID);
96 if (result != Status::E_OK || typeIdStr.empty()) {
97 LOG_ERROR(UDMF_CAPI, "Failed to obtain typeId by invoking the native function.");
98 return nullptr;
99 }
100 auto typeId = new (std::nothrow) char[typeIdStr.size() + 1];
101 if (typeId == nullptr) {
102 LOG_ERROR(UDMF_CAPI, "obtain typeId's memory error!");
103 return nullptr;
104 }
105 if (strcpy_s(typeId, typeIdStr.size() + 1, typeIdStr.c_str()) != UDMF_E_OK) {
106 LOG_ERROR(UDMF_CAPI, "str copy error!");
107 delete[] typeId;
108 return nullptr;
109 }
110 *count = 1;
111 auto typeIds = new char* [*count];
112 typeIds[0] = typeId;
113 return const_cast<const char**>(typeIds);
114 }
115
OH_Utd_Create(const char * typeId)116 OH_Utd* OH_Utd_Create(const char* typeId)
117 {
118 if (typeId == nullptr) {
119 return nullptr;
120 }
121 auto typeDescriptor = GetTypeDescriptorByUtdClient(typeId);
122 if (typeDescriptor == nullptr) {
123 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
124 return nullptr;
125 }
126 auto pThis = new (std::nothrow) OH_Utd();
127 if (pThis == nullptr) {
128 LOG_ERROR(UDMF_CAPI, "Failed to apply for memory.");
129 return nullptr;
130 }
131 pThis->typeId = typeDescriptor->GetTypeId();
132 pThis->description = typeDescriptor->GetDescription();
133 pThis->referenceURL = typeDescriptor->GetReferenceURL();
134 pThis->iconFile = typeDescriptor->GetIconFile();
135 pThis->belongingToTypes =
136 CreateStrArrByVector(typeDescriptor->GetBelongingToTypes(), &(pThis->belongingToTypesCount));
137 pThis->filenameExtensions =
138 CreateStrArrByVector(typeDescriptor->GetFilenameExtensions(), &(pThis->filenameExtensionsCount));
139 pThis->mimeTypes = CreateStrArrByVector(typeDescriptor->GetMimeTypes(), &(pThis->mimeTypeCount));
140 return pThis;
141 }
142
OH_Utd_Destroy(OH_Utd * pThis)143 void OH_Utd_Destroy(OH_Utd* pThis)
144 {
145 if (IsUtdInvalid(pThis)) {
146 LOG_ERROR(UDMF_CAPI, "Failed to Destroy UTD, because pThis maybe nullptr or non-UTD struct ptr.");
147 return;
148 }
149 DestroyArrayPtr(pThis->belongingToTypes, pThis->belongingToTypesCount);
150 DestroyArrayPtr(pThis->filenameExtensions, pThis->filenameExtensionsCount);
151 DestroyArrayPtr(pThis->mimeTypes, pThis->mimeTypeCount);
152 delete pThis;
153 LOG_INFO(UDMF_CAPI, "OH_Utd ptr already be delete");
154 }
155
OH_Utd_GetTypeId(OH_Utd * pThis)156 const char* OH_Utd_GetTypeId(OH_Utd* pThis)
157 {
158 return IsUtdInvalid(pThis) ? nullptr : pThis->typeId.c_str();
159 }
160
OH_Utd_GetDescription(OH_Utd * pThis)161 const char* OH_Utd_GetDescription(OH_Utd* pThis)
162 {
163 return IsUtdInvalid(pThis) ? nullptr : pThis->description.c_str();
164 }
165
OH_Utd_GetReferenceUrl(OH_Utd * pThis)166 const char* OH_Utd_GetReferenceUrl(OH_Utd* pThis)
167 {
168 return IsUtdInvalid(pThis) ? nullptr : pThis->referenceURL.c_str();
169 }
170
OH_Utd_GetIconFile(OH_Utd * pThis)171 const char* OH_Utd_GetIconFile(OH_Utd* pThis)
172 {
173 return IsUtdInvalid(pThis) ? nullptr : pThis->iconFile.c_str();
174 }
175
OH_Utd_GetBelongingToTypes(OH_Utd * pThis,unsigned int * count)176 const char** OH_Utd_GetBelongingToTypes(OH_Utd* pThis, unsigned int* count)
177 {
178 if (IsUtdInvalid(pThis) || count == nullptr) {
179 return nullptr;
180 }
181 *count = pThis->belongingToTypesCount;
182 return pThis->belongingToTypes;
183 }
184
OH_Utd_GetFilenameExtensions(OH_Utd * pThis,unsigned int * count)185 const char** OH_Utd_GetFilenameExtensions(OH_Utd* pThis, unsigned int* count)
186 {
187 if (IsUtdInvalid(pThis) || count == nullptr) {
188 return nullptr;
189 }
190 *count = pThis->filenameExtensionsCount;
191 return pThis->filenameExtensions;
192 }
193
OH_Utd_GetMimeTypes(OH_Utd * pThis,unsigned int * count)194 const char** OH_Utd_GetMimeTypes(OH_Utd* pThis, unsigned int* count)
195 {
196 if (IsUtdInvalid(pThis) || count == nullptr) {
197 return nullptr;
198 }
199 *count = pThis->mimeTypeCount;
200 return pThis->mimeTypes;
201 }
202
OH_Utd_GetTypesByFilenameExtension(const char * extension,unsigned int * count)203 const char** OH_Utd_GetTypesByFilenameExtension(const char* extension, unsigned int* count)
204 {
205 return GetTypesByCondition(extension, count, &UtdClient::GetUniformDataTypeByFilenameExtension);
206 }
207
OH_Utd_GetTypesByMimeType(const char * mimeType,unsigned int * count)208 const char** OH_Utd_GetTypesByMimeType(const char* mimeType, unsigned int* count)
209 {
210 return GetTypesByCondition(mimeType, count, &UtdClient::GetUniformDataTypeByMIMEType);
211 }
212
OH_Utd_BelongsTo(const char * srcTypeId,const char * destTypeId)213 bool OH_Utd_BelongsTo(const char* srcTypeId, const char* destTypeId)
214 {
215 if (srcTypeId == nullptr || destTypeId == nullptr) {
216 LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
217 return false;
218 }
219 auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
220 if (typeDescriptor == nullptr) {
221 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
222 return false;
223 }
224 bool checkResult{false};
225 if (typeDescriptor->BelongsTo(destTypeId, checkResult) != Status::E_OK) {
226 LOG_ERROR(UDMF_CAPI, "invoke the native function error.");
227 }
228 return checkResult;
229 }
230
OH_Utd_IsLower(const char * srcTypeId,const char * destTypeId)231 bool OH_Utd_IsLower(const char* srcTypeId, const char* destTypeId)
232 {
233 if (srcTypeId == nullptr || destTypeId == nullptr) {
234 LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
235 return false;
236 }
237 auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
238 if (typeDescriptor == nullptr) {
239 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
240 return false;
241 }
242 bool checkResult{false};
243 if (typeDescriptor->IsLowerLevelType(destTypeId, checkResult) != Status::E_OK) {
244 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
245 }
246 return checkResult;
247 }
248
OH_Utd_IsHigher(const char * srcTypeId,const char * destTypeId)249 bool OH_Utd_IsHigher(const char* srcTypeId, const char* destTypeId)
250 {
251 if (srcTypeId == nullptr || destTypeId == nullptr) {
252 LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
253 return false;
254 }
255 auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
256 if (typeDescriptor == nullptr) {
257 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
258 return false;
259 }
260 bool checkResult{false};
261 if (typeDescriptor->IsHigherLevelType(destTypeId, checkResult) != Status::E_OK) {
262 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
263 }
264 return checkResult;
265 }
266
OH_Utd_Equals(OH_Utd * utd1,OH_Utd * utd2)267 bool OH_Utd_Equals(OH_Utd* utd1, OH_Utd* utd2)
268 {
269 if (IsUtdInvalid(utd1) || IsUtdInvalid(utd2)) {
270 LOG_ERROR(UDMF_CAPI, "The input parameter is invalid");
271 return false;
272 }
273 auto typeDescriptor1 = GetTypeDescriptorByUtdClient(utd1->typeId.c_str());
274 if (typeDescriptor1 == nullptr) {
275 LOG_ERROR(UDMF_CAPI, "utd1 failed to create by invoking the native function.");
276 return false;
277 }
278 auto typeDescriptor2 = GetTypeDescriptorByUtdClient(utd2->typeId.c_str());
279 if (typeDescriptor2 == nullptr) {
280 LOG_ERROR(UDMF_CAPI, "utd2 failed to create by invoking the native function.");
281 return false;
282 }
283 return typeDescriptor1->Equals(typeDescriptor2);
284 }
285
OH_Utd_DestroyStringList(const char ** list,unsigned int count)286 void OH_Utd_DestroyStringList(const char** list, unsigned int count)
287 {
288 DestroyArrayPtr(list, count);
289 }
290