13920e296Sopenharmony_ci/*
23920e296Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
33920e296Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43920e296Sopenharmony_ci * you may not use this file except in compliance with the License.
53920e296Sopenharmony_ci * You may obtain a copy of the License at
63920e296Sopenharmony_ci *
73920e296Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83920e296Sopenharmony_ci *
93920e296Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103920e296Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113920e296Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123920e296Sopenharmony_ci * See the License for the specific language governing permissions and
133920e296Sopenharmony_ci * limitations under the License.
143920e296Sopenharmony_ci */
153920e296Sopenharmony_ci
163920e296Sopenharmony_ci#include "key_parser.h"
173920e296Sopenharmony_ci#include <regex>
183920e296Sopenharmony_ci#include "resource_util.h"
193920e296Sopenharmony_ci
203920e296Sopenharmony_cinamespace OHOS {
213920e296Sopenharmony_cinamespace Global {
223920e296Sopenharmony_cinamespace Restool {
233920e296Sopenharmony_ciusing namespace std;
243920e296Sopenharmony_cimap<string, vector<KeyParam>> KeyParser::caches_ = {};
253920e296Sopenharmony_cibool KeyParser::Parse(const string &folderName, vector<KeyParam> &keyparams)
263920e296Sopenharmony_ci{
273920e296Sopenharmony_ci    if (folderName == "base") {
283920e296Sopenharmony_ci        return true;
293920e296Sopenharmony_ci    }
303920e296Sopenharmony_ci
313920e296Sopenharmony_ci    if (caches_.count(folderName) != 0) {
323920e296Sopenharmony_ci        keyparams = caches_[folderName];
333920e296Sopenharmony_ci        return true;
343920e296Sopenharmony_ci    }
353920e296Sopenharmony_ci    vector<string> keyParts;
363920e296Sopenharmony_ci    ResourceUtil::Split(folderName, keyParts, "-");
373920e296Sopenharmony_ci
383920e296Sopenharmony_ci    vector<parse_key_founction> founctions = {
393920e296Sopenharmony_ci        ParseMccMnc,
403920e296Sopenharmony_ci        ParseLSR,
413920e296Sopenharmony_ci        ParseOrientation,
423920e296Sopenharmony_ci        ParseDeviceType,
433920e296Sopenharmony_ci        ParseNightMode,
443920e296Sopenharmony_ci        ParseInputDevice,
453920e296Sopenharmony_ci        ParseResolution,
463920e296Sopenharmony_ci    };
473920e296Sopenharmony_ci
483920e296Sopenharmony_ci    if (!ParseMatch(keyParts, keyparams, founctions)) {
493920e296Sopenharmony_ci        return false;
503920e296Sopenharmony_ci    }
513920e296Sopenharmony_ci    caches_.emplace(folderName, keyparams);
523920e296Sopenharmony_ci    return true;
533920e296Sopenharmony_ci}
543920e296Sopenharmony_ci
553920e296Sopenharmony_cibool KeyParser::ParseMatch(const vector<string> &keys,
563920e296Sopenharmony_ci    vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
573920e296Sopenharmony_ci{
583920e296Sopenharmony_ci    size_t next = 0;
593920e296Sopenharmony_ci    for (const auto &key : keys) {
603920e296Sopenharmony_ci        bool parseMatch = false;
613920e296Sopenharmony_ci        for (size_t i = next; i < founctions.size(); i++) {
623920e296Sopenharmony_ci            if (founctions[i](key, keyparams)) {
633920e296Sopenharmony_ci                parseMatch = true;
643920e296Sopenharmony_ci                next = i;
653920e296Sopenharmony_ci                break;
663920e296Sopenharmony_ci            }
673920e296Sopenharmony_ci        }
683920e296Sopenharmony_ci
693920e296Sopenharmony_ci        if (!parseMatch) {
703920e296Sopenharmony_ci            return false;
713920e296Sopenharmony_ci        }
723920e296Sopenharmony_ci    }
733920e296Sopenharmony_ci    return true;
743920e296Sopenharmony_ci}
753920e296Sopenharmony_ci
763920e296Sopenharmony_cibool KeyParser::ParseLimit(const string &func, std::vector<std::string> &limitValues,
773920e296Sopenharmony_ci    TargetConfig &targetConfig)
783920e296Sopenharmony_ci{
793920e296Sopenharmony_ci    map<string, function<bool(const string &)>> parseLimitFunc {
803920e296Sopenharmony_ci        {"mccmnc", [&targetConfig](const string &limitValue) { return ParseMccMnc(limitValue,
813920e296Sopenharmony_ci            targetConfig.mccmnc); }},
823920e296Sopenharmony_ci        {"locale", [&targetConfig](const string &limitValue) { return ParseLSR(limitValue,
833920e296Sopenharmony_ci            targetConfig.locale); }},
843920e296Sopenharmony_ci        {"orientation", [&targetConfig](const string &limitValue) { return ParseOrientation(limitValue,
853920e296Sopenharmony_ci            targetConfig.orientation); }},
863920e296Sopenharmony_ci        {"device", [&targetConfig](const string &limitValue) { return ParseDeviceType(limitValue,
873920e296Sopenharmony_ci            targetConfig.device); }},
883920e296Sopenharmony_ci        {"colormode", [&targetConfig](const string &limitValue) { return ParseNightMode(limitValue,
893920e296Sopenharmony_ci            targetConfig.colormode); }},
903920e296Sopenharmony_ci        {"density", [&targetConfig](const string &limitValue) { return ParseResolution(limitValue,
913920e296Sopenharmony_ci            targetConfig.density); }}
923920e296Sopenharmony_ci    };
933920e296Sopenharmony_ci
943920e296Sopenharmony_ci    auto iter = parseLimitFunc.find(func);
953920e296Sopenharmony_ci    if (iter == parseLimitFunc.end()) {
963920e296Sopenharmony_ci        return false;
973920e296Sopenharmony_ci    }
983920e296Sopenharmony_ci    for (auto &limitValue : limitValues) {
993920e296Sopenharmony_ci        ResourceUtil::RemoveSpaces(limitValue);
1003920e296Sopenharmony_ci        if (!iter->second(limitValue)) {
1013920e296Sopenharmony_ci            return false;
1023920e296Sopenharmony_ci        }
1033920e296Sopenharmony_ci    }
1043920e296Sopenharmony_ci    return true;
1053920e296Sopenharmony_ci}
1063920e296Sopenharmony_ci
1073920e296Sopenharmony_cibool KeyParser::ParseMatchBySeq(const vector<string> &keys,
1083920e296Sopenharmony_ci    vector<KeyParam> &keyparams, const vector<parse_key_founction> &founctions)
1093920e296Sopenharmony_ci{
1103920e296Sopenharmony_ci    for (size_t i = 0; i < keys.size(); i++) {
1113920e296Sopenharmony_ci        if (!founctions[i](keys[i], keyparams)) {
1123920e296Sopenharmony_ci            return false;
1133920e296Sopenharmony_ci        }
1143920e296Sopenharmony_ci    }
1153920e296Sopenharmony_ci    return true;
1163920e296Sopenharmony_ci}
1173920e296Sopenharmony_ci
1183920e296Sopenharmony_cibool KeyParser::ParseMccMnc(const string &folderName, vector<KeyParam> &keyparams)
1193920e296Sopenharmony_ci{
1203920e296Sopenharmony_ci    vector<parse_key_founction> founctions = {
1213920e296Sopenharmony_ci        ParseMcc,
1223920e296Sopenharmony_ci        ParseMnc,
1233920e296Sopenharmony_ci    };
1243920e296Sopenharmony_ci
1253920e296Sopenharmony_ci    vector<string> keyParts;
1263920e296Sopenharmony_ci    ResourceUtil::Split(folderName, keyParts, "_");
1273920e296Sopenharmony_ci    if (keyParts.size() > founctions.size()) {
1283920e296Sopenharmony_ci        return false;
1293920e296Sopenharmony_ci    }
1303920e296Sopenharmony_ci    return ParseMatchBySeq(keyParts, keyparams, founctions);
1313920e296Sopenharmony_ci}
1323920e296Sopenharmony_ci
1333920e296Sopenharmony_cibool KeyParser::ParseMcc(const string &folderName, vector<KeyParam> &keyparams)
1343920e296Sopenharmony_ci{
1353920e296Sopenharmony_ci    regex mcc("mcc(\\d{3})");
1363920e296Sopenharmony_ci    if (!regex_match(folderName, mcc)) {
1373920e296Sopenharmony_ci        return false;
1383920e296Sopenharmony_ci    }
1393920e296Sopenharmony_ci
1403920e296Sopenharmony_ci    PushMccMnc(folderName, KeyType::MCC, keyparams);
1413920e296Sopenharmony_ci    return true;
1423920e296Sopenharmony_ci}
1433920e296Sopenharmony_ci
1443920e296Sopenharmony_cibool KeyParser::ParseMnc(const string &folderName, vector<KeyParam> &keyparams)
1453920e296Sopenharmony_ci{
1463920e296Sopenharmony_ci    regex mcc("mnc(\\d{2,3})");
1473920e296Sopenharmony_ci    if (!regex_match(folderName, mcc)) {
1483920e296Sopenharmony_ci        return false;
1493920e296Sopenharmony_ci    }
1503920e296Sopenharmony_ci
1513920e296Sopenharmony_ci    PushMccMnc(folderName, KeyType::MNC, keyparams);
1523920e296Sopenharmony_ci    return true;
1533920e296Sopenharmony_ci}
1543920e296Sopenharmony_ci
1553920e296Sopenharmony_cibool KeyParser::ParseLSR(const string &folderName, vector<KeyParam> &keyparams)
1563920e296Sopenharmony_ci{
1573920e296Sopenharmony_ci    map<string, vector<parse_key_founction>> founctionModels = {
1583920e296Sopenharmony_ci        { "all", { ParseLanguage, ParseScript, ParseRegion } },
1593920e296Sopenharmony_ci        { "language script", { ParseLanguage, ParseScript} },
1603920e296Sopenharmony_ci        { "language region", { ParseLanguage, ParseRegion } },
1613920e296Sopenharmony_ci    };
1623920e296Sopenharmony_ci
1633920e296Sopenharmony_ci    vector<string> keyParts;
1643920e296Sopenharmony_ci    ResourceUtil::Split(folderName, keyParts, "_");
1653920e296Sopenharmony_ci    if (keyParts.size() > founctionModels["all"].size()) {
1663920e296Sopenharmony_ci        return false;
1673920e296Sopenharmony_ci    }
1683920e296Sopenharmony_ci
1693920e296Sopenharmony_ci    for (auto model : founctionModels) {
1703920e296Sopenharmony_ci        vector<KeyParam> tmp;
1713920e296Sopenharmony_ci        if (ParseMatchBySeq(keyParts, tmp, model.second)) {
1723920e296Sopenharmony_ci            keyparams.insert(keyparams.end(), tmp.begin(), tmp.end());
1733920e296Sopenharmony_ci            return true;
1743920e296Sopenharmony_ci        }
1753920e296Sopenharmony_ci    }
1763920e296Sopenharmony_ci    return false;
1773920e296Sopenharmony_ci}
1783920e296Sopenharmony_ci
1793920e296Sopenharmony_cibool KeyParser::ParseLanguage(const string &folderName, vector<KeyParam> &keyparams)
1803920e296Sopenharmony_ci{
1813920e296Sopenharmony_ci    if (g_deviceMap.find(folderName) != g_deviceMap.end()) {
1823920e296Sopenharmony_ci        return false;
1833920e296Sopenharmony_ci    }
1843920e296Sopenharmony_ci
1853920e296Sopenharmony_ci    regex language("[a-z]{2,3}");
1863920e296Sopenharmony_ci    if (!regex_match(folderName, language)) {
1873920e296Sopenharmony_ci        return false;
1883920e296Sopenharmony_ci    }
1893920e296Sopenharmony_ci
1903920e296Sopenharmony_ci    PushLSR(folderName, KeyType::LANGUAGE, keyparams);
1913920e296Sopenharmony_ci    return true;
1923920e296Sopenharmony_ci}
1933920e296Sopenharmony_ci
1943920e296Sopenharmony_cibool KeyParser::ParseScript(const string &folderName, vector<KeyParam> &keyparams)
1953920e296Sopenharmony_ci{
1963920e296Sopenharmony_ci    if (folderName.length() != SCRIPT_LENGHT) {
1973920e296Sopenharmony_ci        return false;
1983920e296Sopenharmony_ci    }
1993920e296Sopenharmony_ci
2003920e296Sopenharmony_ci    regex script("^[A-Z][a-z]{3}");
2013920e296Sopenharmony_ci    if (!regex_match(folderName, script)) {
2023920e296Sopenharmony_ci        return false;
2033920e296Sopenharmony_ci    }
2043920e296Sopenharmony_ci
2053920e296Sopenharmony_ci    PushLSR(folderName, KeyType::SCRIPT, keyparams);
2063920e296Sopenharmony_ci    return true;
2073920e296Sopenharmony_ci}
2083920e296Sopenharmony_ci
2093920e296Sopenharmony_cibool KeyParser::ParseRegion(const string &folderName, vector<KeyParam> &keyparams)
2103920e296Sopenharmony_ci{
2113920e296Sopenharmony_ci    if (folderName.length() < MIN_REGION_LENGHT || folderName.length() > MAX_REGION_LENGHT) {
2123920e296Sopenharmony_ci        return false;
2133920e296Sopenharmony_ci    }
2143920e296Sopenharmony_ci
2153920e296Sopenharmony_ci    regex regionOfNumber("[0-9]{3}");
2163920e296Sopenharmony_ci    regex regionOfSupper("[A-Z]{2,3}");
2173920e296Sopenharmony_ci
2183920e296Sopenharmony_ci    if (!regex_match(folderName, regionOfNumber) && !regex_match(folderName, regionOfSupper)) {
2193920e296Sopenharmony_ci        return false;
2203920e296Sopenharmony_ci    }
2213920e296Sopenharmony_ci
2223920e296Sopenharmony_ci    PushLSR(folderName, KeyType::REGION, keyparams);
2233920e296Sopenharmony_ci    return true;
2243920e296Sopenharmony_ci}
2253920e296Sopenharmony_ci
2263920e296Sopenharmony_cibool KeyParser::ParseOrientation(const string &folderName, vector<KeyParam> &keyparams)
2273920e296Sopenharmony_ci{
2283920e296Sopenharmony_ci    auto it = g_orientaionMap.find(folderName);
2293920e296Sopenharmony_ci    if (it == g_orientaionMap.end()) {
2303920e296Sopenharmony_ci        return false;
2313920e296Sopenharmony_ci    }
2323920e296Sopenharmony_ci
2333920e296Sopenharmony_ci    PushValue(static_cast<uint32_t>(it->second), KeyType::ORIENTATION, keyparams);
2343920e296Sopenharmony_ci    return true;
2353920e296Sopenharmony_ci}
2363920e296Sopenharmony_ci
2373920e296Sopenharmony_cibool KeyParser::ParseDeviceType(const string &folderName, vector<KeyParam> &keyparams)
2383920e296Sopenharmony_ci{
2393920e296Sopenharmony_ci    auto it = g_deviceMap.find(folderName);
2403920e296Sopenharmony_ci    if (it == g_deviceMap.end()) {
2413920e296Sopenharmony_ci        return false;
2423920e296Sopenharmony_ci    }
2433920e296Sopenharmony_ci
2443920e296Sopenharmony_ci    PushValue(static_cast<uint32_t>(it->second), KeyType::DEVICETYPE, keyparams);
2453920e296Sopenharmony_ci    return true;
2463920e296Sopenharmony_ci}
2473920e296Sopenharmony_ci
2483920e296Sopenharmony_cibool KeyParser::ParseNightMode(const string &folderName, vector<KeyParam> &keyparams)
2493920e296Sopenharmony_ci{
2503920e296Sopenharmony_ci    auto it = g_nightModeMap.find(folderName);
2513920e296Sopenharmony_ci    if (it == g_nightModeMap.end()) {
2523920e296Sopenharmony_ci        return false;
2533920e296Sopenharmony_ci    }
2543920e296Sopenharmony_ci
2553920e296Sopenharmony_ci    PushValue(static_cast<uint32_t>(it->second), KeyType::NIGHTMODE, keyparams);
2563920e296Sopenharmony_ci    return true;
2573920e296Sopenharmony_ci}
2583920e296Sopenharmony_ci
2593920e296Sopenharmony_cibool KeyParser::ParseInputDevice(const string &folderName, vector<KeyParam> &keyparams)
2603920e296Sopenharmony_ci{
2613920e296Sopenharmony_ci    auto it = g_inputDeviceMap.find(folderName);
2623920e296Sopenharmony_ci    if (it == g_inputDeviceMap.end()) {
2633920e296Sopenharmony_ci        return false;
2643920e296Sopenharmony_ci    }
2653920e296Sopenharmony_ci
2663920e296Sopenharmony_ci    PushValue(static_cast<uint32_t>(it->second), KeyType::INPUTDEVICE, keyparams);
2673920e296Sopenharmony_ci    return true;
2683920e296Sopenharmony_ci}
2693920e296Sopenharmony_ci
2703920e296Sopenharmony_cibool KeyParser::ParseResolution(const string &folderName, vector<KeyParam> &keyparams)
2713920e296Sopenharmony_ci{
2723920e296Sopenharmony_ci    auto it = g_resolutionMap.find(folderName);
2733920e296Sopenharmony_ci    if (it == g_resolutionMap.end()) {
2743920e296Sopenharmony_ci        return false;
2753920e296Sopenharmony_ci    }
2763920e296Sopenharmony_ci
2773920e296Sopenharmony_ci    PushValue(static_cast<uint32_t>(it->second), KeyType::RESOLUTION, keyparams);
2783920e296Sopenharmony_ci    return true;
2793920e296Sopenharmony_ci}
2803920e296Sopenharmony_ci
2813920e296Sopenharmony_civoid KeyParser::PushMccMnc(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
2823920e296Sopenharmony_ci{
2833920e296Sopenharmony_ci    KeyParam keyParam;
2843920e296Sopenharmony_ci    keyParam.keyType = type;
2853920e296Sopenharmony_ci    keyParam.value = static_cast<uint32_t>(atoi(folderName.substr(MCC_MNC_KEY_LENGHT).c_str()));
2863920e296Sopenharmony_ci    keyparams.push_back(keyParam);
2873920e296Sopenharmony_ci}
2883920e296Sopenharmony_ci
2893920e296Sopenharmony_civoid KeyParser::PushLSR(const string &folderName, KeyType type, vector<KeyParam> &keyparams)
2903920e296Sopenharmony_ci{
2913920e296Sopenharmony_ci    KeyParam keyParam;
2923920e296Sopenharmony_ci    keyParam.keyType = type;
2933920e296Sopenharmony_ci    keyParam.value = 0;
2943920e296Sopenharmony_ci    for (size_t i = 0; i < folderName.size(); i++) {
2953920e296Sopenharmony_ci        keyParam.value = (keyParam.value << 8) | (folderName[i] & 0xff); // Move 8 bits to the left
2963920e296Sopenharmony_ci    }
2973920e296Sopenharmony_ci    keyparams.push_back(keyParam);
2983920e296Sopenharmony_ci}
2993920e296Sopenharmony_ci
3003920e296Sopenharmony_civoid KeyParser::PushValue(uint32_t value, KeyType type, vector<KeyParam> &keyparams)
3013920e296Sopenharmony_ci{
3023920e296Sopenharmony_ci    KeyParam keyParam;
3033920e296Sopenharmony_ci    keyParam.keyType = type;
3043920e296Sopenharmony_ci    keyParam.value = value;
3053920e296Sopenharmony_ci    keyparams.push_back(keyParam);
3063920e296Sopenharmony_ci}
3073920e296Sopenharmony_ci}
3083920e296Sopenharmony_ci}
3093920e296Sopenharmony_ci}
310