114cf0368Sopenharmony_ci/*
214cf0368Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
314cf0368Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
414cf0368Sopenharmony_ci * you may not use this file except in compliance with the License.
514cf0368Sopenharmony_ci * You may obtain a copy of the License at
614cf0368Sopenharmony_ci *
714cf0368Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
814cf0368Sopenharmony_ci *
914cf0368Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1014cf0368Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1114cf0368Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1214cf0368Sopenharmony_ci * See the License for the specific language governing permissions and
1314cf0368Sopenharmony_ci * limitations under the License.
1414cf0368Sopenharmony_ci */
1514cf0368Sopenharmony_ci
1614cf0368Sopenharmony_ci#define LOG_TAG "Utd"
1714cf0368Sopenharmony_ci#include "utd.h"
1814cf0368Sopenharmony_ci
1914cf0368Sopenharmony_ci#include "securec.h"
2014cf0368Sopenharmony_ci#include "logger.h"
2114cf0368Sopenharmony_ci#include "utd_client.h"
2214cf0368Sopenharmony_ci#include "udmf_capi_common.h"
2314cf0368Sopenharmony_ci#include "udmf_err_code.h"
2414cf0368Sopenharmony_ci
2514cf0368Sopenharmony_ciusing namespace OHOS::UDMF;
2614cf0368Sopenharmony_ci
2714cf0368Sopenharmony_cistatic constexpr const int32_t MAX_UTD_SIZE = 50;
2814cf0368Sopenharmony_ci
2914cf0368Sopenharmony_citypedef Status (UtdClient::*GetUtdByConditionPtr)(const std::string&, std::string&, std::string);
3014cf0368Sopenharmony_ci
3114cf0368Sopenharmony_cistatic void DestroyArrayPtr(const char** &arrayPtr, unsigned int& count)
3214cf0368Sopenharmony_ci{
3314cf0368Sopenharmony_ci    if (arrayPtr == nullptr) {
3414cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Cannot delete arrayPtr because it's a nullptr.");
3514cf0368Sopenharmony_ci        return;
3614cf0368Sopenharmony_ci    }
3714cf0368Sopenharmony_ci    for (unsigned int i = 0; i < count; i++) {
3814cf0368Sopenharmony_ci        if (arrayPtr[i] != nullptr) {
3914cf0368Sopenharmony_ci            delete[] arrayPtr[i];
4014cf0368Sopenharmony_ci            arrayPtr[i] = nullptr;
4114cf0368Sopenharmony_ci        }
4214cf0368Sopenharmony_ci    }
4314cf0368Sopenharmony_ci    delete[] arrayPtr;
4414cf0368Sopenharmony_ci    arrayPtr = nullptr;
4514cf0368Sopenharmony_ci    count = 0;
4614cf0368Sopenharmony_ci    LOG_INFO(UDMF_CAPI, "delete arrayPtr finish.");
4714cf0368Sopenharmony_ci}
4814cf0368Sopenharmony_ci
4914cf0368Sopenharmony_cistatic const char** CreateStrArrByVector(const std::vector<std::string>& paramVector, unsigned int* count)
5014cf0368Sopenharmony_ci{
5114cf0368Sopenharmony_ci    unsigned int size = paramVector.size();
5214cf0368Sopenharmony_ci    if (size == 0 || size > MAX_UTD_SIZE) {
5314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Cannot create array, because size is illegal or exceeds the max value of UTD.");
5414cf0368Sopenharmony_ci        *count = 0;
5514cf0368Sopenharmony_ci        return nullptr;
5614cf0368Sopenharmony_ci    }
5714cf0368Sopenharmony_ci    auto charPtr = new (std::nothrow) char* [size];
5814cf0368Sopenharmony_ci    if (charPtr == nullptr) {
5914cf0368Sopenharmony_ci        *count = 0;
6014cf0368Sopenharmony_ci        return nullptr;
6114cf0368Sopenharmony_ci    }
6214cf0368Sopenharmony_ci    for (unsigned int i = 0; i < size; i++) {
6314cf0368Sopenharmony_ci        charPtr[i] = new (std::nothrow) char[paramVector[i].size() + 1];
6414cf0368Sopenharmony_ci        if (charPtr[i] == nullptr ||
6514cf0368Sopenharmony_ci            strcpy_s(charPtr[i], paramVector[i].size() + 1, paramVector[i].c_str()) != UDMF_E_OK) {
6614cf0368Sopenharmony_ci            LOG_ERROR(UDMF_CAPI, "obtain the memory error, or str copy error!");
6714cf0368Sopenharmony_ci            const char** arrayPtr = const_cast<const char**>(charPtr);
6814cf0368Sopenharmony_ci            DestroyArrayPtr(arrayPtr, size);
6914cf0368Sopenharmony_ci            *count = 0;
7014cf0368Sopenharmony_ci            return nullptr;
7114cf0368Sopenharmony_ci        }
7214cf0368Sopenharmony_ci    }
7314cf0368Sopenharmony_ci    *count = size;
7414cf0368Sopenharmony_ci    return const_cast<const char**>(charPtr);
7514cf0368Sopenharmony_ci}
7614cf0368Sopenharmony_ci
7714cf0368Sopenharmony_cistatic std::shared_ptr<TypeDescriptor> GetTypeDescriptorByUtdClient(const char* typeId)
7814cf0368Sopenharmony_ci{
7914cf0368Sopenharmony_ci    std::shared_ptr<TypeDescriptor> typeDescriptor;
8014cf0368Sopenharmony_ci    UtdClient::GetInstance().GetTypeDescriptor(typeId, typeDescriptor);
8114cf0368Sopenharmony_ci    return typeDescriptor;
8214cf0368Sopenharmony_ci}
8314cf0368Sopenharmony_ci
8414cf0368Sopenharmony_cistatic bool IsUtdInvalid(OH_Utd* pThis)
8514cf0368Sopenharmony_ci{
8614cf0368Sopenharmony_ci    return pThis == nullptr || pThis->cid != NdkStructId::UTD_STRUCT_ID;
8714cf0368Sopenharmony_ci}
8814cf0368Sopenharmony_ci
8914cf0368Sopenharmony_cistatic const char** GetTypesByCondition(const char* condition, unsigned int* count, GetUtdByConditionPtr funcPtr)
9014cf0368Sopenharmony_ci{
9114cf0368Sopenharmony_ci    if (condition == nullptr || count == nullptr || funcPtr == nullptr) {
9214cf0368Sopenharmony_ci        return nullptr;
9314cf0368Sopenharmony_ci    }
9414cf0368Sopenharmony_ci    std::string typeIdStr;
9514cf0368Sopenharmony_ci    Status result = (UtdClient::GetInstance().*funcPtr)(condition, typeIdStr, DEFAULT_TYPE_ID);
9614cf0368Sopenharmony_ci    if (result != Status::E_OK || typeIdStr.empty()) {
9714cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to obtain typeId by invoking the native function.");
9814cf0368Sopenharmony_ci        return nullptr;
9914cf0368Sopenharmony_ci    }
10014cf0368Sopenharmony_ci    auto typeId = new (std::nothrow) char[typeIdStr.size() + 1];
10114cf0368Sopenharmony_ci    if (typeId == nullptr) {
10214cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "obtain typeId's memory error!");
10314cf0368Sopenharmony_ci        return nullptr;
10414cf0368Sopenharmony_ci    }
10514cf0368Sopenharmony_ci    if (strcpy_s(typeId, typeIdStr.size() + 1, typeIdStr.c_str()) != UDMF_E_OK) {
10614cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "str copy error!");
10714cf0368Sopenharmony_ci        delete[] typeId;
10814cf0368Sopenharmony_ci        return nullptr;
10914cf0368Sopenharmony_ci    }
11014cf0368Sopenharmony_ci    *count = 1;
11114cf0368Sopenharmony_ci    auto typeIds = new char* [*count];
11214cf0368Sopenharmony_ci    typeIds[0] = typeId;
11314cf0368Sopenharmony_ci    return const_cast<const char**>(typeIds);
11414cf0368Sopenharmony_ci}
11514cf0368Sopenharmony_ci
11614cf0368Sopenharmony_ciOH_Utd* OH_Utd_Create(const char* typeId)
11714cf0368Sopenharmony_ci{
11814cf0368Sopenharmony_ci    if (typeId == nullptr) {
11914cf0368Sopenharmony_ci        return nullptr;
12014cf0368Sopenharmony_ci    }
12114cf0368Sopenharmony_ci    auto pThis = new (std::nothrow) OH_Utd();
12214cf0368Sopenharmony_ci    if (pThis == nullptr) {
12314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to apply for memory.");
12414cf0368Sopenharmony_ci        return nullptr;
12514cf0368Sopenharmony_ci    }
12614cf0368Sopenharmony_ci    auto typeDescriptor = GetTypeDescriptorByUtdClient(typeId);
12714cf0368Sopenharmony_ci    if (typeDescriptor == nullptr) {
12814cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
12914cf0368Sopenharmony_ci        delete pThis;
13014cf0368Sopenharmony_ci        return nullptr;
13114cf0368Sopenharmony_ci    }
13214cf0368Sopenharmony_ci    pThis->typeId = typeDescriptor->GetTypeId();
13314cf0368Sopenharmony_ci    pThis->description = typeDescriptor->GetDescription();
13414cf0368Sopenharmony_ci    pThis->referenceURL = typeDescriptor->GetReferenceURL();
13514cf0368Sopenharmony_ci    pThis->iconFile = typeDescriptor->GetIconFile();
13614cf0368Sopenharmony_ci    pThis->belongingToTypes =
13714cf0368Sopenharmony_ci        CreateStrArrByVector(typeDescriptor->GetBelongingToTypes(), &(pThis->belongingToTypesCount));
13814cf0368Sopenharmony_ci    pThis->filenameExtensions =
13914cf0368Sopenharmony_ci        CreateStrArrByVector(typeDescriptor->GetFilenameExtensions(), &(pThis->filenameExtensionsCount));
14014cf0368Sopenharmony_ci    pThis->mimeTypes = CreateStrArrByVector(typeDescriptor->GetMimeTypes(), &(pThis->mimeTypeCount));
14114cf0368Sopenharmony_ci    return pThis;
14214cf0368Sopenharmony_ci}
14314cf0368Sopenharmony_ci
14414cf0368Sopenharmony_civoid OH_Utd_Destroy(OH_Utd* pThis)
14514cf0368Sopenharmony_ci{
14614cf0368Sopenharmony_ci    if (IsUtdInvalid(pThis)) {
14714cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to Destroy UTD, because pThis maybe nullptr or non-UTD struct ptr.");
14814cf0368Sopenharmony_ci        return;
14914cf0368Sopenharmony_ci    }
15014cf0368Sopenharmony_ci    DestroyArrayPtr(pThis->belongingToTypes, pThis->belongingToTypesCount);
15114cf0368Sopenharmony_ci    DestroyArrayPtr(pThis->filenameExtensions, pThis->filenameExtensionsCount);
15214cf0368Sopenharmony_ci    DestroyArrayPtr(pThis->mimeTypes, pThis->mimeTypeCount);
15314cf0368Sopenharmony_ci    delete pThis;
15414cf0368Sopenharmony_ci    LOG_INFO(UDMF_CAPI, "OH_Utd ptr already be delete");
15514cf0368Sopenharmony_ci}
15614cf0368Sopenharmony_ci
15714cf0368Sopenharmony_ciconst char* OH_Utd_GetTypeId(OH_Utd* pThis)
15814cf0368Sopenharmony_ci{
15914cf0368Sopenharmony_ci    return IsUtdInvalid(pThis) ? nullptr : pThis->typeId.c_str();
16014cf0368Sopenharmony_ci}
16114cf0368Sopenharmony_ci
16214cf0368Sopenharmony_ciconst char* OH_Utd_GetDescription(OH_Utd* pThis)
16314cf0368Sopenharmony_ci{
16414cf0368Sopenharmony_ci    return IsUtdInvalid(pThis) ? nullptr : pThis->description.c_str();
16514cf0368Sopenharmony_ci}
16614cf0368Sopenharmony_ci
16714cf0368Sopenharmony_ciconst char* OH_Utd_GetReferenceUrl(OH_Utd* pThis)
16814cf0368Sopenharmony_ci{
16914cf0368Sopenharmony_ci    return IsUtdInvalid(pThis) ? nullptr : pThis->referenceURL.c_str();
17014cf0368Sopenharmony_ci}
17114cf0368Sopenharmony_ci
17214cf0368Sopenharmony_ciconst char* OH_Utd_GetIconFile(OH_Utd* pThis)
17314cf0368Sopenharmony_ci{
17414cf0368Sopenharmony_ci    return IsUtdInvalid(pThis) ? nullptr : pThis->iconFile.c_str();
17514cf0368Sopenharmony_ci}
17614cf0368Sopenharmony_ci
17714cf0368Sopenharmony_ciconst char** OH_Utd_GetBelongingToTypes(OH_Utd* pThis, unsigned int* count)
17814cf0368Sopenharmony_ci{
17914cf0368Sopenharmony_ci    if (IsUtdInvalid(pThis) || count == nullptr) {
18014cf0368Sopenharmony_ci        return nullptr;
18114cf0368Sopenharmony_ci    }
18214cf0368Sopenharmony_ci    *count = pThis->belongingToTypesCount;
18314cf0368Sopenharmony_ci    return pThis->belongingToTypes;
18414cf0368Sopenharmony_ci}
18514cf0368Sopenharmony_ci
18614cf0368Sopenharmony_ciconst char** OH_Utd_GetFilenameExtensions(OH_Utd* pThis, unsigned int* count)
18714cf0368Sopenharmony_ci{
18814cf0368Sopenharmony_ci    if (IsUtdInvalid(pThis) || count == nullptr) {
18914cf0368Sopenharmony_ci        return nullptr;
19014cf0368Sopenharmony_ci    }
19114cf0368Sopenharmony_ci    *count = pThis->filenameExtensionsCount;
19214cf0368Sopenharmony_ci    return pThis->filenameExtensions;
19314cf0368Sopenharmony_ci}
19414cf0368Sopenharmony_ci
19514cf0368Sopenharmony_ciconst char** OH_Utd_GetMimeTypes(OH_Utd* pThis, unsigned int* count)
19614cf0368Sopenharmony_ci{
19714cf0368Sopenharmony_ci    if (IsUtdInvalid(pThis) || count == nullptr) {
19814cf0368Sopenharmony_ci        return nullptr;
19914cf0368Sopenharmony_ci    }
20014cf0368Sopenharmony_ci    *count = pThis->mimeTypeCount;
20114cf0368Sopenharmony_ci    return pThis->mimeTypes;
20214cf0368Sopenharmony_ci}
20314cf0368Sopenharmony_ci
20414cf0368Sopenharmony_ciconst char** OH_Utd_GetTypesByFilenameExtension(const char* extension, unsigned int* count)
20514cf0368Sopenharmony_ci{
20614cf0368Sopenharmony_ci    return GetTypesByCondition(extension, count, &UtdClient::GetUniformDataTypeByFilenameExtension);
20714cf0368Sopenharmony_ci}
20814cf0368Sopenharmony_ci
20914cf0368Sopenharmony_ciconst char** OH_Utd_GetTypesByMimeType(const char* mimeType, unsigned int* count)
21014cf0368Sopenharmony_ci{
21114cf0368Sopenharmony_ci    return GetTypesByCondition(mimeType, count, &UtdClient::GetUniformDataTypeByMIMEType);
21214cf0368Sopenharmony_ci}
21314cf0368Sopenharmony_ci
21414cf0368Sopenharmony_cibool OH_Utd_BelongsTo(const char* srcTypeId, const char* destTypeId)
21514cf0368Sopenharmony_ci{
21614cf0368Sopenharmony_ci    if (srcTypeId == nullptr || destTypeId == nullptr) {
21714cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
21814cf0368Sopenharmony_ci        return false;
21914cf0368Sopenharmony_ci    }
22014cf0368Sopenharmony_ci    auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
22114cf0368Sopenharmony_ci    if (typeDescriptor == nullptr) {
22214cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
22314cf0368Sopenharmony_ci        return false;
22414cf0368Sopenharmony_ci    }
22514cf0368Sopenharmony_ci    bool checkResult{false};
22614cf0368Sopenharmony_ci    if (typeDescriptor->BelongsTo(destTypeId, checkResult) != Status::E_OK) {
22714cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "invoke the native function error.");
22814cf0368Sopenharmony_ci    }
22914cf0368Sopenharmony_ci    return checkResult;
23014cf0368Sopenharmony_ci}
23114cf0368Sopenharmony_ci
23214cf0368Sopenharmony_cibool OH_Utd_IsLower(const char* srcTypeId, const char* destTypeId)
23314cf0368Sopenharmony_ci{
23414cf0368Sopenharmony_ci    if (srcTypeId == nullptr || destTypeId == nullptr) {
23514cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
23614cf0368Sopenharmony_ci        return false;
23714cf0368Sopenharmony_ci    }
23814cf0368Sopenharmony_ci    auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
23914cf0368Sopenharmony_ci    if (typeDescriptor == nullptr) {
24014cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
24114cf0368Sopenharmony_ci        return false;
24214cf0368Sopenharmony_ci    }
24314cf0368Sopenharmony_ci    bool checkResult{false};
24414cf0368Sopenharmony_ci    if (typeDescriptor->IsLowerLevelType(destTypeId, checkResult) != Status::E_OK) {
24514cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
24614cf0368Sopenharmony_ci    }
24714cf0368Sopenharmony_ci    return checkResult;
24814cf0368Sopenharmony_ci}
24914cf0368Sopenharmony_ci
25014cf0368Sopenharmony_cibool OH_Utd_IsHigher(const char* srcTypeId, const char* destTypeId)
25114cf0368Sopenharmony_ci{
25214cf0368Sopenharmony_ci    if (srcTypeId == nullptr || destTypeId == nullptr) {
25314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "The input parameter is nullptr");
25414cf0368Sopenharmony_ci        return false;
25514cf0368Sopenharmony_ci    }
25614cf0368Sopenharmony_ci    auto typeDescriptor = GetTypeDescriptorByUtdClient(srcTypeId);
25714cf0368Sopenharmony_ci    if (typeDescriptor == nullptr) {
25814cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
25914cf0368Sopenharmony_ci        return false;
26014cf0368Sopenharmony_ci    }
26114cf0368Sopenharmony_ci    bool checkResult{false};
26214cf0368Sopenharmony_ci    if (typeDescriptor->IsHigherLevelType(destTypeId, checkResult) != Status::E_OK) {
26314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "Failed to create by invoking the native function.");
26414cf0368Sopenharmony_ci    }
26514cf0368Sopenharmony_ci    return checkResult;
26614cf0368Sopenharmony_ci}
26714cf0368Sopenharmony_ci
26814cf0368Sopenharmony_cibool OH_Utd_Equals(OH_Utd* utd1, OH_Utd* utd2)
26914cf0368Sopenharmony_ci{
27014cf0368Sopenharmony_ci    if (IsUtdInvalid(utd1) || IsUtdInvalid(utd2)) {
27114cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "The input parameter is invalid");
27214cf0368Sopenharmony_ci        return false;
27314cf0368Sopenharmony_ci    }
27414cf0368Sopenharmony_ci    auto typeDescriptor1 = GetTypeDescriptorByUtdClient(utd1->typeId.c_str());
27514cf0368Sopenharmony_ci    if (typeDescriptor1 == nullptr) {
27614cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "utd1 failed to create by invoking the native function.");
27714cf0368Sopenharmony_ci        return false;
27814cf0368Sopenharmony_ci    }
27914cf0368Sopenharmony_ci    auto typeDescriptor2 = GetTypeDescriptorByUtdClient(utd2->typeId.c_str());
28014cf0368Sopenharmony_ci    if (typeDescriptor2 == nullptr) {
28114cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CAPI, "utd2 failed to create by invoking the native function.");
28214cf0368Sopenharmony_ci        return false;
28314cf0368Sopenharmony_ci    }
28414cf0368Sopenharmony_ci    return typeDescriptor1->Equals(typeDescriptor2);
28514cf0368Sopenharmony_ci}
28614cf0368Sopenharmony_ci
28714cf0368Sopenharmony_civoid OH_Utd_DestroyStringList(const char** list, unsigned int count)
28814cf0368Sopenharmony_ci{
28914cf0368Sopenharmony_ci    DestroyArrayPtr(list, count);
29014cf0368Sopenharmony_ci}
291