114cf0368Sopenharmony_ci/*
214cf0368Sopenharmony_ci * Copyright (c) 2023 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#define LOG_TAG "UnifiedKey"
1614cf0368Sopenharmony_ci#include "unified_key.h"
1714cf0368Sopenharmony_ci
1814cf0368Sopenharmony_ci#include "logger.h"
1914cf0368Sopenharmony_ci
2014cf0368Sopenharmony_cinamespace OHOS {
2114cf0368Sopenharmony_cinamespace UDMF {
2214cf0368Sopenharmony_cistatic std::bitset<MAX_BIT_SIZE> g_ruleIntention;
2314cf0368Sopenharmony_cistatic std::bitset<MAX_BIT_SIZE> g_ruleBundleName;
2414cf0368Sopenharmony_cistatic std::bitset<MAX_BIT_SIZE> g_ruleGroupId;
2514cf0368Sopenharmony_cistatic constexpr const char *UNIFIED_KEY_SCHEMA = "udmf://";
2614cf0368Sopenharmony_cistatic constexpr const char *ALPHA_AGGREGATE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
2714cf0368Sopenharmony_cistatic constexpr const char *DIGIT_AGGREGATE = "0123456789";
2814cf0368Sopenharmony_cistatic constexpr const char *SYMBOL_AGGREGATE = ":;<=>?@[\\]_`";
2914cf0368Sopenharmony_ciUnifiedKey::UnifiedKey(std::string key)
3014cf0368Sopenharmony_ci{
3114cf0368Sopenharmony_ci    this->key = std::move(key);
3214cf0368Sopenharmony_ci}
3314cf0368Sopenharmony_ci
3414cf0368Sopenharmony_ciUnifiedKey::UnifiedKey(std::string intention, std::string bundle, std::string groupId)
3514cf0368Sopenharmony_ci{
3614cf0368Sopenharmony_ci    this->intention = std::move(intention);
3714cf0368Sopenharmony_ci    this->bundleName = std::move(bundle);
3814cf0368Sopenharmony_ci    this->groupId = std::move(groupId);
3914cf0368Sopenharmony_ci}
4014cf0368Sopenharmony_ci
4114cf0368Sopenharmony_cistd::string UnifiedKey::GetUnifiedKey()
4214cf0368Sopenharmony_ci{
4314cf0368Sopenharmony_ci    if (!this->key.empty()) {
4414cf0368Sopenharmony_ci        return this->key;
4514cf0368Sopenharmony_ci    }
4614cf0368Sopenharmony_ci    if (this->intention.empty() || this->groupId.empty()) {
4714cf0368Sopenharmony_ci        return "";
4814cf0368Sopenharmony_ci    }
4914cf0368Sopenharmony_ci    // Uri-compliant structure, example: udmf://drag/com.ohos.test/012345679abc
5014cf0368Sopenharmony_ci    this->key = UNIFIED_KEY_SCHEMA + this->intention + "/" + this->bundleName + "/" + this->groupId;
5114cf0368Sopenharmony_ci    return this->key;
5214cf0368Sopenharmony_ci}
5314cf0368Sopenharmony_ci
5414cf0368Sopenharmony_cibool UnifiedKey::IsValid()
5514cf0368Sopenharmony_ci{
5614cf0368Sopenharmony_ci    if (this->key.empty()) {
5714cf0368Sopenharmony_ci        LOG_DEBUG(UDMF_FRAMEWORK, "empty key");
5814cf0368Sopenharmony_ci        return false;
5914cf0368Sopenharmony_ci    }
6014cf0368Sopenharmony_ci    PreliminaryWork();
6114cf0368Sopenharmony_ci
6214cf0368Sopenharmony_ci    std::string data = this->key; // schema/intention/groupId
6314cf0368Sopenharmony_ci    std::string separator = "://";
6414cf0368Sopenharmony_ci    size_t pos = data.find(separator);
6514cf0368Sopenharmony_ci    if (pos == std::string::npos) {
6614cf0368Sopenharmony_ci        return false;
6714cf0368Sopenharmony_ci    }
6814cf0368Sopenharmony_ci    std::string schema = data.substr(0, pos + separator.size()); // schema
6914cf0368Sopenharmony_ci    if (UNIFIED_KEY_SCHEMA != schema) {
7014cf0368Sopenharmony_ci        LOG_DEBUG(UDMF_FRAMEWORK, "wrong schema");
7114cf0368Sopenharmony_ci        return false;
7214cf0368Sopenharmony_ci    }
7314cf0368Sopenharmony_ci
7414cf0368Sopenharmony_ci    data = data.substr(pos + separator.size()); // intention/bundleName/groupId
7514cf0368Sopenharmony_ci    pos = data.find('/');        // intention
7614cf0368Sopenharmony_ci    if (pos == std::string::npos) {
7714cf0368Sopenharmony_ci        return false;
7814cf0368Sopenharmony_ci    }
7914cf0368Sopenharmony_ci    std::string intentionTmp = data.substr(0, pos);
8014cf0368Sopenharmony_ci    if (!CheckCharacter(intentionTmp, g_ruleIntention)) {
8114cf0368Sopenharmony_ci        return false;
8214cf0368Sopenharmony_ci    }
8314cf0368Sopenharmony_ci    this->intention = intentionTmp;
8414cf0368Sopenharmony_ci
8514cf0368Sopenharmony_ci    data = data.substr(pos + 1);
8614cf0368Sopenharmony_ci    pos = data.find('/'); // bundleName
8714cf0368Sopenharmony_ci    if (pos == std::string::npos) {
8814cf0368Sopenharmony_ci        return false;
8914cf0368Sopenharmony_ci    }
9014cf0368Sopenharmony_ci    std::string bundle = data.substr(0, pos);
9114cf0368Sopenharmony_ci    if (!CheckCharacter(bundle, g_ruleBundleName)) {
9214cf0368Sopenharmony_ci        LOG_DEBUG(UDMF_FRAMEWORK, "wrong bundle");
9314cf0368Sopenharmony_ci        return false;
9414cf0368Sopenharmony_ci    }
9514cf0368Sopenharmony_ci    this->bundleName = bundle;
9614cf0368Sopenharmony_ci
9714cf0368Sopenharmony_ci    data = data.substr(pos + 1); // groupId
9814cf0368Sopenharmony_ci    if (data.empty()) {
9914cf0368Sopenharmony_ci        return false;
10014cf0368Sopenharmony_ci    }
10114cf0368Sopenharmony_ci    if (!CheckCharacter(data, g_ruleGroupId)) {
10214cf0368Sopenharmony_ci        LOG_DEBUG(UDMF_FRAMEWORK, "wrong groupId");
10314cf0368Sopenharmony_ci        return false;
10414cf0368Sopenharmony_ci    }
10514cf0368Sopenharmony_ci    this->groupId = data;
10614cf0368Sopenharmony_ci    return true;
10714cf0368Sopenharmony_ci}
10814cf0368Sopenharmony_ci
10914cf0368Sopenharmony_cibool UnifiedKey::CheckCharacter(std::string data, std::bitset<MAX_BIT_SIZE> rule)
11014cf0368Sopenharmony_ci{
11114cf0368Sopenharmony_ci    if (data.empty()) {
11214cf0368Sopenharmony_ci        LOG_DEBUG(UDMF_FRAMEWORK, "empty key");
11314cf0368Sopenharmony_ci        return false;
11414cf0368Sopenharmony_ci    }
11514cf0368Sopenharmony_ci    size_t dataLen = data.size();
11614cf0368Sopenharmony_ci    for (size_t i = 0; i < dataLen; ++i) {
11714cf0368Sopenharmony_ci        if (static_cast<int>(data[i]) >= 0 && static_cast<int>(data[i]) < 128) { // 128:ASCII Max Number
11814cf0368Sopenharmony_ci            bool isLegal = rule.test(data[i]);
11914cf0368Sopenharmony_ci            if (!isLegal) {
12014cf0368Sopenharmony_ci                return false;
12114cf0368Sopenharmony_ci            }
12214cf0368Sopenharmony_ci        }
12314cf0368Sopenharmony_ci    }
12414cf0368Sopenharmony_ci    return true;
12514cf0368Sopenharmony_ci}
12614cf0368Sopenharmony_ci
12714cf0368Sopenharmony_civoid UnifiedKey::PreliminaryWork()
12814cf0368Sopenharmony_ci{
12914cf0368Sopenharmony_ci    // All intentions are composed of uppercase and lowercase letters and underscores.
13014cf0368Sopenharmony_ci    if (g_ruleIntention.none()) {
13114cf0368Sopenharmony_ci        std::string intentionTmp = std::string(ALPHA_AGGREGATE) + "_";
13214cf0368Sopenharmony_ci        for (char i : intentionTmp) {
13314cf0368Sopenharmony_ci            g_ruleIntention.set(i);
13414cf0368Sopenharmony_ci        }
13514cf0368Sopenharmony_ci    }
13614cf0368Sopenharmony_ci    // All bundle name are composed of uppercase and lowercase letters and dots.
13714cf0368Sopenharmony_ci    if (g_ruleBundleName.none()) {
13814cf0368Sopenharmony_ci        std::string bundleAggregate = std::string(ALPHA_AGGREGATE) + DIGIT_AGGREGATE + "._";
13914cf0368Sopenharmony_ci        for (char i : bundleAggregate) {
14014cf0368Sopenharmony_ci            g_ruleBundleName.set(i);
14114cf0368Sopenharmony_ci        }
14214cf0368Sopenharmony_ci    }
14314cf0368Sopenharmony_ci    // Characters of groupId are taken from Ascii codes 48 to 122.
14414cf0368Sopenharmony_ci    if (g_ruleGroupId.none()) {
14514cf0368Sopenharmony_ci        std::string idAggregate = std::string(DIGIT_AGGREGATE) + ALPHA_AGGREGATE + SYMBOL_AGGREGATE;
14614cf0368Sopenharmony_ci        for (char i : idAggregate) {
14714cf0368Sopenharmony_ci            g_ruleGroupId.set(i);
14814cf0368Sopenharmony_ci        }
14914cf0368Sopenharmony_ci    }
15014cf0368Sopenharmony_ci}
15114cf0368Sopenharmony_ci} // namespace UDMF
15214cf0368Sopenharmony_ci} // namespace OHOS