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 pThis = new (std::nothrow) OH_Utd();
122 if (pThis == nullptr) {
123 LOG_ERROR(UDMF_CAPI, "Failed to apply for memory.");
124 return nullptr;
125 }
126 auto typeDescriptor = GetTypeDescriptorByUtdClient(typeId);
127 if (typeDescriptor == nullptr) {
128 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
129 delete pThis;
130 return nullptr;
131 }
132 pThis->typeId = typeDescriptor->GetTypeId();
133 pThis->description = typeDescriptor->GetDescription();
134 pThis->referenceURL = typeDescriptor->GetReferenceURL();
135 pThis->iconFile = typeDescriptor->GetIconFile();
136 pThis->belongingToTypes =
137 CreateStrArrByVector(typeDescriptor->GetBelongingToTypes(), &(pThis->belongingToTypesCount));
138 pThis->filenameExtensions =
139 CreateStrArrByVector(typeDescriptor->GetFilenameExtensions(), &(pThis->filenameExtensionsCount));
140 pThis->mimeTypes = CreateStrArrByVector(typeDescriptor->GetMimeTypes(), &(pThis->mimeTypeCount));
141 return pThis;
142 }
143
OH_Utd_Destroy(OH_Utd * pThis)144 void OH_Utd_Destroy(OH_Utd* pThis)
145 {
146 if (IsUtdInvalid(pThis)) {
147 LOG_ERROR(UDMF_CAPI, "Failed to Destroy UTD, because pThis maybe nullptr or non-UTD struct ptr.");
148 return;
149 }
150 DestroyArrayPtr(pThis->belongingToTypes, pThis->belongingToTypesCount);
151 DestroyArrayPtr(pThis->filenameExtensions, pThis->filenameExtensionsCount);
152 DestroyArrayPtr(pThis->mimeTypes, pThis->mimeTypeCount);
153 delete pThis;
154 LOG_INFO(UDMF_CAPI, "OH_Utd ptr already be delete");
155 }
156
OH_Utd_GetTypeId(OH_Utd * pThis)157 const char* OH_Utd_GetTypeId(OH_Utd* pThis)
158 {
159 return IsUtdInvalid(pThis) ? nullptr : pThis->typeId.c_str();
160 }
161
OH_Utd_GetDescription(OH_Utd * pThis)162 const char* OH_Utd_GetDescription(OH_Utd* pThis)
163 {
164 return IsUtdInvalid(pThis) ? nullptr : pThis->description.c_str();
165 }
166
OH_Utd_GetReferenceUrl(OH_Utd * pThis)167 const char* OH_Utd_GetReferenceUrl(OH_Utd* pThis)
168 {
169 return IsUtdInvalid(pThis) ? nullptr : pThis->referenceURL.c_str();
170 }
171
OH_Utd_GetIconFile(OH_Utd * pThis)172 const char* OH_Utd_GetIconFile(OH_Utd* pThis)
173 {
174 return IsUtdInvalid(pThis) ? nullptr : pThis->iconFile.c_str();
175 }
176
OH_Utd_GetBelongingToTypes(OH_Utd * pThis,unsigned int * count)177 const char** OH_Utd_GetBelongingToTypes(OH_Utd* pThis, unsigned int* count)
178 {
179 if (IsUtdInvalid(pThis) || count == nullptr) {
180 return nullptr;
181 }
182 *count = pThis->belongingToTypesCount;
183 return pThis->belongingToTypes;
184 }
185
OH_Utd_GetFilenameExtensions(OH_Utd * pThis,unsigned int * count)186 const char** OH_Utd_GetFilenameExtensions(OH_Utd* pThis, unsigned int* count)
187 {
188 if (IsUtdInvalid(pThis) || count == nullptr) {
189 return nullptr;
190 }
191 *count = pThis->filenameExtensionsCount;
192 return pThis->filenameExtensions;
193 }
194
OH_Utd_GetMimeTypes(OH_Utd * pThis,unsigned int * count)195 const char** OH_Utd_GetMimeTypes(OH_Utd* pThis, unsigned int* count)
196 {
197 if (IsUtdInvalid(pThis) || count == nullptr) {
198 return nullptr;
199 }
200 *count = pThis->mimeTypeCount;
201 return pThis->mimeTypes;
202 }
203
OH_Utd_GetTypesByFilenameExtension(const char * extension,unsigned int * count)204 const char** OH_Utd_GetTypesByFilenameExtension(const char* extension, unsigned int* count)
205 {
206 return GetTypesByCondition(extension, count, &UtdClient::GetUniformDataTypeByFilenameExtension);
207 }
208
OH_Utd_GetTypesByMimeType(const char * mimeType,unsigned int * count)209 const char** OH_Utd_GetTypesByMimeType(const char* mimeType, unsigned int* count)
210 {
211 return GetTypesByCondition(mimeType, count, &UtdClient::GetUniformDataTypeByMIMEType);
212 }
213
OH_Utd_BelongsTo(const char * srcTypeId,const char * destTypeId)214 bool OH_Utd_BelongsTo(const char* srcTypeId, const char* destTypeId)
215 {
216 if (srcTypeId == nullptr || destTypeId == nullptr) {
217 LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
218 return false;
219 }
220 auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
221 if (typeDescriptor == nullptr) {
222 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
223 return false;
224 }
225 bool checkResult{false};
226 if (typeDescriptor->BelongsTo(destTypeId, checkResult) != Status::E_OK) {
227 LOG_ERROR(UDMF_CAPI, "invoke the native function error.");
228 }
229 return checkResult;
230 }
231
OH_Utd_IsLower(const char * srcTypeId,const char * destTypeId)232 bool OH_Utd_IsLower(const char* srcTypeId, const char* destTypeId)
233 {
234 if (srcTypeId == nullptr || destTypeId == nullptr) {
235 LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
236 return false;
237 }
238 auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
239 if (typeDescriptor == nullptr) {
240 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
241 return false;
242 }
243 bool checkResult{false};
244 if (typeDescriptor->IsLowerLevelType(destTypeId, checkResult) != Status::E_OK) {
245 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
246 }
247 return checkResult;
248 }
249
OH_Utd_IsHigher(const char * srcTypeId,const char * destTypeId)250 bool OH_Utd_IsHigher(const char* srcTypeId, const char* destTypeId)
251 {
252 if (srcTypeId == nullptr || destTypeId == nullptr) {
253 LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
254 return false;
255 }
256 auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
257 if (typeDescriptor == nullptr) {
258 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
259 return false;
260 }
261 bool checkResult{false};
262 if (typeDescriptor->IsHigherLevelType(destTypeId, checkResult) != Status::E_OK) {
263 LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
264 }
265 return checkResult;
266 }
267
OH_Utd_Equals(OH_Utd * utd1,OH_Utd * utd2)268 bool OH_Utd_Equals(OH_Utd* utd1, OH_Utd* utd2)
269 {
270 if (IsUtdInvalid(utd1) || IsUtdInvalid(utd2)) {
271 LOG_ERROR(UDMF_CAPI, "The input parameter is invalid");
272 return false;
273 }
274 auto typeDescriptor1 = GetTypeDescriptorByUtdClient(utd1->typeId.c_str());
275 if (typeDescriptor1 == nullptr) {
276 LOG_ERROR(UDMF_CAPI, "utd1 failed to create by invoking the native function.");
277 return false;
278 }
279 auto typeDescriptor2 = GetTypeDescriptorByUtdClient(utd2->typeId.c_str());
280 if (typeDescriptor2 == nullptr) {
281 LOG_ERROR(UDMF_CAPI, "utd2 failed to create by invoking the native function.");
282 return false;
283 }
284 return typeDescriptor1->Equals(typeDescriptor2);
285 }
286
OH_Utd_DestroyStringList(const char ** list,unsigned int count)287 void OH_Utd_DestroyStringList(const char** list, unsigned int count)
288 {
289 DestroyArrayPtr(list, count);
290 }
291